/** Dialog for editing manual seasonal factor overrides (12 months). */ import { css, html, LitElement, nothing } from "lit"; import { property, state } from "lit/decorators.js"; import { t } from "../styles"; import { describeWsError } from "../ws-errors"; import type { HomeAssistant } from "../types"; const MONTH_KEYS = [ "month_jan", "month_feb", "month_mar", "month_apr", "month_may", "month_jun", "month_jul", "month_aug", "month_sep", "month_oct", "month_nov", "month_dec", ]; export class SeasonalOverridesDialog extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @state() private _open = false; @state() private _loading = false; @state() private _error = ""; @state() private _entryId = ""; @state() private _taskId = ""; @state() private _values: string[] = new Array(12).fill(""); private get _lang(): string { return this.hass?.language ?? navigator.language.split("-")[0] ?? "en"; } public open(entryId: string, taskId: string, currentOverrides: Record | null | undefined): void { this._entryId = entryId; this._taskId = taskId; this._values = new Array(12).fill(""); if (currentOverrides) { for (const [k, v] of Object.entries(currentOverrides)) { const m = parseInt(k, 10); if (m >= 1 && m <= 12 && typeof v === "number") { this._values[m - 1] = v.toString(); } } } this._error = ""; this._open = true; } private _close(): void { this._open = false; } private _buildOverrides(): Record | null { const out: Record = {}; for (let i = 0; i < 12; i++) { const raw = this._values[i].trim(); if (!raw) continue; const num = parseFloat(raw); if (Number.isNaN(num)) { this._error = `${t("month_" + ["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"][i], this._lang)}: ${t("seasonal_override_invalid", this._lang)}`; return null; } if (num < 0.1 || num > 5.0) { this._error = t("seasonal_override_range", this._lang); return null; } out[i + 1] = num; } return out; } private _save = async (): Promise => { const overrides = this._buildOverrides(); if (overrides === null) return; this._loading = true; this._error = ""; try { await this.hass.connection.sendMessagePromise({ type: "maintenance_supporter/task/seasonal_overrides", entry_id: this._entryId, task_id: this._taskId, overrides, }); this._open = false; this.dispatchEvent(new CustomEvent("overrides-saved")); } catch (e) { this._error = describeWsError(e, this._lang, t("save_error", this._lang)); } finally { this._loading = false; } }; private _clearAll = async (): Promise => { this._loading = true; this._error = ""; try { await this.hass.connection.sendMessagePromise({ type: "maintenance_supporter/task/seasonal_overrides", entry_id: this._entryId, task_id: this._taskId, overrides: {}, }); this._values = new Array(12).fill(""); this._open = false; this.dispatchEvent(new CustomEvent("overrides-saved")); } catch (e) { this._error = describeWsError(e, this._lang, t("save_error", this._lang)); } finally { this._loading = false; } }; render() { if (!this._open) return html``; const L = this._lang; return html`

${t("seasonal_overrides_hint", L)}

${this._error ? html`
${this._error}
` : nothing}
${MONTH_KEYS.map((key, i) => html` `)}
${t("clear_all", L)}
${t("cancel", L)} ${this._loading ? t("saving", L) : t("save", L)}
`; } static styles = css` .content { min-width: 320px; max-width: 480px; } .hint { color: var(--secondary-text-color); font-size: 13px; margin: 0 0 12px 0; } .error { color: var(--error-color, #f44336); font-size: 13px; margin-bottom: 8px; } .months { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } .month { display: flex; align-items: center; gap: 8px; } .mn { min-width: 70px; font-size: 14px; } input[type="number"] { flex: 1; padding: 6px 8px; font-size: 14px; border-radius: 4px; border: 1px solid var(--divider-color); background: var(--card-background-color); color: var(--primary-text-color); } .dialog-actions { display: flex; align-items: center; gap: 8px; padding-top: 16px; } .spacer { flex: 1; } `; } if (!customElements.get("maintenance-seasonal-overrides-dialog")) { customElements.define("maintenance-seasonal-overrides-dialog", SeasonalOverridesDialog); }