456 files

This commit is contained in:
Home Assistant Version Control
2026-10-01 05:38:21 +00:00
parent 4192ecbaae
commit 5d6d845ebf
456 changed files with 64951 additions and 3828 deletions
@@ -55,6 +55,8 @@ interface SettingsResponse {
shopping_list_entity?: string;
panel_enabled: boolean;
panel_title: string;
/** 2.94: the sidebar title an empty field means (server language). */
panel_title_default?: string;
/** Opt-in copy of the shipped Assist sentences into the config dir. */
install_assist_sentences?: boolean;
/** #146: household "low" floors (percent) for discovery + battery fleet. */
@@ -207,7 +209,7 @@ export class MaintenanceSettingsView extends LitElement {
@state() private _vacSaving = false;
// Print QR codes section state
@state() private _qrObjects: Array<{ entry_id: string; name: string; task_count: number }> = [];
@state() private _qrObjects: Array<{ entry_id: string; name: string; task_count: number; quick_count: number }> = [];
@state() private _qrSelectedEntries = new Set<string>();
@state() private _qrActions = new Set<string>(["view"]);
@state() private _qrUrlMode: "server" | "local" | "companion" = "companion";
@@ -220,7 +222,7 @@ export class MaintenanceSettingsView extends LitElement {
@state() private _qrObjectsLoaded = false;
// Export/Import selective-object picker state
@state() private _exportObjects: Array<{ entry_id: string; name: string; task_count: number }> = [];
@state() private _exportObjects: Array<{ entry_id: string; name: string; task_count: number; quick_count: number }> = [];
@state() private _exportSelectedEntries = new Set<string>();
@state() private _exportObjectsLoaded = false;
@state() private _docArchiveLoading = false;
@@ -1063,7 +1065,7 @@ export class MaintenanceSettingsView extends LitElement {
<label class="setting-row">
<span class="setting-label">${t("settings_panel_title", L)}</span>
<input type="text" .value=${g.panel_title ?? ""}
placeholder="Maintenance"
placeholder=${g.panel_title_default || "Maintenance"}
maxlength="50"
@change=${(e: Event) => this._updateSetting("panel_title", (e.target as HTMLInputElement).value.trim())} />
</label>
@@ -1684,10 +1686,22 @@ export class MaintenanceSettingsView extends LitElement {
// --- Section: Print QR codes (v1.1.0) ---
/** The objects the batch prints for: the ticked ones, or all when none is. */
private _qrSelectedRows(): Array<{ entry_id: string; task_count: number; quick_count: number }> {
return this._qrSelectedEntries.size === 0 ? this._qrObjects : this._qrObjects.filter((o) => this._qrSelectedEntries.has(o.entry_id));
}
private _renderPrintQr(L: string) {
const selectedCount = this._qrSelectedEntries.size || this._qrObjects.length;
const rows = this._qrSelectedRows();
const taskCount = rows.reduce((n, o) => n + o.task_count, 0);
// #192: the quick-complete code only exists for tasks with defaults —
// offered when the chosen objects have any (not tied to the completion-
// actions switch: defaults set before it was turned off still work).
const quickCount = rows.reduce((n, o) => n + o.quick_count, 0);
// One code per TASK and action (the estimate multiplied OBJECTS, so the
// 200 warning came too late and the server refused the batch).
const estimatedQrs = [...this._qrActions].reduce((n, a) => n + (a === "quick_complete" ? quickCount : taskCount), 0);
const actionCount = this._qrActions.size;
const estimatedQrs = selectedCount * actionCount;
const overLimit = estimatedQrs > 200;
return html`
@@ -1721,15 +1735,21 @@ export class MaintenanceSettingsView extends LitElement {
<div class="qr-filter-group">
<div class="qr-filter-label">${t("qr_print_actions", L)}</div>
<div class="qr-action-chips">
${["view", "complete", "skip"].map((a) => html`
<label class="qr-action-chip ${this._qrActions.has(a) ? "active" : ""}">
${["view", "complete", "skip", "quick_complete"].map((a) => {
const quickNone = a === "quick_complete" && quickCount === 0;
return html`
<label class="qr-action-chip ${this._qrActions.has(a) && !quickNone ? "active" : ""} ${quickNone ? "disabled" : ""}"
title=${quickNone ? t("qr_print_quick_none", L) : nothing}>
<input type="checkbox"
.checked=${this._qrActions.has(a)}
.checked=${this._qrActions.has(a) && !quickNone}
.disabled=${quickNone}
@change=${(e: Event) => this._toggleQrAction(a, (e.target as HTMLInputElement).checked)} />
${t("qr_action_" + a, L)}
${t("qr_action_" + a, L)}${a === "quick_complete" && quickCount > 0 ? ` (${quickCount})` : ""}
</label>
`)}
`;
})}
</div>
${quickCount === 0 ? html`<div class="hint qr-quick-hint">${t("qr_print_quick_none", L)}</div>` : nothing}
</div>
<div class="qr-filter-group">
@@ -1787,10 +1807,14 @@ export class MaintenanceSettingsView extends LitElement {
this._qrObjectsLoaded = true;
}
/** {entry_id, name, task_count} of every object, name-sorted — the QR
* batch and the export section both pick objects from this list. */
private async _loadObjectRows(): Promise<Array<{ entry_id: string; name: string; task_count: number }> | undefined> {
const result = await this._ws<{ objects: Array<{ entry_id: string; object: { name: string }; tasks: unknown[] }> }>({
/** {entry_id, name, task_count, quick_count} of every object, name-sorted —
* the QR batch and the export section both pick objects from this list.
* ``quick_count``: tasks with quick-complete defaults (#192), the only
* ones a quick-complete code is printed for. */
private async _loadObjectRows(): Promise<Array<{ entry_id: string; name: string; task_count: number; quick_count: number }> | undefined> {
const result = await this._ws<{
objects: Array<{ entry_id: string; object: { name: string }; tasks: Array<{ quick_complete_defaults?: Record<string, unknown> | null }> }>;
}>({
type: "maintenance_supporter/objects",
});
if (!result) return undefined;
@@ -1798,6 +1822,7 @@ export class MaintenanceSettingsView extends LitElement {
entry_id: o.entry_id,
name: o.object.name,
task_count: (o.tasks || []).length,
quick_count: (o.tasks || []).filter((tk) => tk.quick_complete_defaults && Object.keys(tk.quick_complete_defaults).length > 0).length,
})).sort((a, b) => a.name.localeCompare(b.name));
}
@@ -2596,6 +2621,10 @@ export class MaintenanceSettingsView extends LitElement {
cursor: pointer;
user-select: none;
}
.qr-action-chip.disabled {
opacity: 0.5;
cursor: default;
}
.qr-action-chip.active {
background: var(--primary-color, #03a9f4);
color: #fff;