393 files

This commit is contained in:
Home Assistant Version Control committed 2026-09-27 17:16:54 +00:00
1 parent b05b7a897e
commit 39d97ac2db
404 files changed
+54006 -11034

No files matched your search

@@ -15,8 +15,8 @@
import { LitElement, html, css, nothing } from "lit";
import { isSafeHttpUrl } from "../helpers/url";
import { property, state } from "lit/decorators.js";
import { t, ensureLocale, langOf, formatCost } from "../styles";
import { describeWsError } from "../ws-errors";
import { t, ensureLocale, langOf, formatCost, formatNumber, formatQty } from "../styles";
import { runWs } from "../helpers/ws-run";
import type { HomeAssistant, MaintenancePart } from "../types";
// Per-part document links (v2.26) — the task-documents component in part mode.
import "./task-documents";
@@ -83,17 +83,14 @@ export class MaintenancePartsSection extends LitElement {
this.dispatchEvent(new CustomEvent("parts-changed", { bubbles: true, composed: true }));
}
private async _send<T>(msg: Record<string, unknown>): Promise<T | null> {
this._busy = true;
/** helpers/ws-run runWs bound to the busy flag and the error line;
* undefined = refused (the reason is on the error line). */
private _send<T>(msg: Record<string, unknown>): Promise<T | null | undefined> {
this._error = "";
try {
return await this.hass.connection.sendMessagePromise<T>(msg);
} catch (err) {
this._error = describeWsError(err, this._lang);
return null;
} finally {
this._busy = false;
}
return runWs<T>(this, msg, {
busy: (b) => { this._busy = b; },
onError: (m) => { this._error = m; },
});
}
private _openAdd(): void {
@@ -141,11 +138,11 @@ export class MaintenancePartsSection extends LitElement {
private async _save(): Promise<void> {
const f = this._editing;
if (!f || !f.name.trim()) return;
if (this._busy || !f || !f.name.trim()) return;
const payload = this._formValue(f);
const type = f.id ? "maintenance_supporter/part/update" : "maintenance_supporter/part/create";
const result = await this._send<{ part_id?: string }>(f.id ? { type, part_id: f.id, ...payload } : { type, ...payload });
if (result !== null) {
if (result !== undefined) {
this._editing = null;
this._notifyChanged();
}
@@ -160,10 +157,14 @@ export class MaintenancePartsSection extends LitElement {
entry_id: this.entryId,
part_id: part.id,
});
if (result !== null) this._notifyChanged();
if (result !== undefined) this._notifyChanged();
}
private async _restock(part: MaintenancePart): Promise<void> {
// Enter + a click on ✓ (or a double Enter) fired two restocks — the
// stock went up twice (bug audit 2026-09-26). _send sets _busy before
// its first await, so the second call lands here and stops.
if (this._busy) return;
const qty = parseFloat(this._restockQty);
if (!Number.isFinite(qty) || qty === 0) {
// Don't silently swallow a no-op amount — keep the input open and mark
@@ -179,9 +180,9 @@ export class MaintenancePartsSection extends LitElement {
delta: qty,
});
this._restockFor = null;
if (result !== null) {
if (result !== undefined) {
// Instant local feedback; the panel refresh follows via parts-changed.
part.stock = result.stock;
part.stock = result?.stock;
this.requestUpdate();
this._notifyChanged();
}
@@ -208,8 +209,8 @@ export class MaintenancePartsSection extends LitElement {
: part.name}
${tracked
? html`<span class="stock-badge ${part.is_low ? "low" : ""}"
>${part.stock}${part.unit ? ` ${part.unit}` : ""}${part.reorder_threshold != null
? html`<span class="threshold">/${part.reorder_threshold}</span>`
>${formatQty(part.stock!, part.unit, L)}${part.reorder_threshold != null
? html`<span class="threshold">/${formatNumber(part.reorder_threshold, L)}</span>`
: nothing}</span
>`
: nothing}
@@ -242,7 +243,7 @@ export class MaintenancePartsSection extends LitElement {
if (e.key === "Escape") this._restockFor = null;
}}
/>
<ha-icon-button title=${t("save", L)} @click=${() => this._restock(part)}
<ha-icon-button title=${t("save", L)} .disabled=${this._busy} @click=${() => this._restock(part)}
><ha-icon icon="mdi:check"></ha-icon
></ha-icon-button>
`