393 files

This commit is contained in:
Home Assistant Version Control
2026-09-27 17:16:54 +00:00
parent b05b7a897e
commit 39d97ac2db
404 changed files with 54006 additions and 11034 deletions
@@ -10,7 +10,7 @@ import { LitElement, html, css, nothing } from "lit";
import { docDisplayName } from "../helpers/document-categories";
import { property, state } from "lit/decorators.js";
import { t, ensureLocale, langOf } from "../styles";
import { describeWsError } from "../ws-errors";
import { runWs } from "../helpers/ws-run";
import { openSignedDocument } from "../helpers/document-url";
import { isSafeHttpUrl } from "../helpers/url";
import { formatBytes } from "../helpers/format-bytes";
@@ -58,6 +58,9 @@ export class MaintenanceStorageSectionCard extends LitElement {
private _initiallyLoaded = false;
private _searchTimer = 0;
/** Only the newest query's answer may land: a slow reply for "fil" used to
* overwrite the one for "filter" (bug audit 2026-09-26). */
private _searchSeq = 0;
private get _lang(): string {
return langOf(this.hass);
@@ -75,18 +78,14 @@ export class MaintenanceStorageSectionCard extends LitElement {
}
private async _load(): Promise<void> {
this._busy = true;
try {
this._summary = await this.hass.connection.sendMessagePromise<StorageSummary>({
type: "maintenance_supporter/documents/storage",
});
this._error = "";
} catch (e) {
this._error = describeWsError(e, this._lang);
} finally {
this._loaded = true;
this._busy = false;
}
const r = await runWs<StorageSummary>(this, { type: "maintenance_supporter/documents/storage" }, {
busy: (b) => { this._busy = b; },
onError: (m) => { this._error = m; },
});
this._loaded = true;
if (r === undefined) return;
this._summary = r;
this._error = "";
}
private _nameFor(objectId: string): string {
@@ -121,20 +120,24 @@ export class MaintenanceStorageSectionCard extends LitElement {
private async _doSearch(): Promise<void> {
const q = this._query.trim();
const seq = ++this._searchSeq;
if (!q) {
this._results = [];
return;
}
try {
const r = await this.hass.connection.sendMessagePromise<{ results: SearchResult[] }>({
type: "maintenance_supporter/documents/search",
query: q,
});
this._results = r.results || [];
} catch (e) {
this._error = describeWsError(e, this._lang);
let failure = "";
const r = await runWs<{ results: SearchResult[] }>(
this,
{ type: "maintenance_supporter/documents/search", query: q },
{ onError: (m) => { failure = m; } },
);
if (seq !== this._searchSeq) return;
if (r === undefined) {
this._error = failure;
this._results = [];
return;
}
this._results = r?.results || [];
}
private async _openResult(doc: SearchResult): Promise<void> {
@@ -145,11 +148,7 @@ export class MaintenanceStorageSectionCard extends LitElement {
if (isSafeHttpUrl(doc.url)) window.open(doc.url, "_blank", "noopener");
return;
}
try {
await openSignedDocument(this.hass, doc.id);
} catch (e) {
this._error = describeWsError(e, this._lang);
}
await runWs(this, () => openSignedDocument(this.hass, doc.id), { onError: (m) => { this._error = m; } });
}
private _renderResult(doc: SearchResult, L: string) {
@@ -320,16 +319,21 @@ export class MaintenanceStorageSectionCard extends LitElement {
.result-open { color: var(--secondary-text-color, #888); --mdc-icon-size: 18px; flex: none; }
.search-empty { color: var(--secondary-text-color, #888); font-size: 13px; padding: 8px 2px; }
.header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* Phone width (2026-09-27): the size moves to a line of its own before
it could slide under the refresh button; only the title shortens. */
.toggle {
display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0;
display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; flex: 1; min-width: 0;
background: none; border: none; padding: 4px 0; margin: 0; cursor: pointer;
font: inherit; color: var(--primary-text-color); text-align: left;
}
.toggle:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; border-radius: 6px; }
.chevron { --mdc-icon-size: 22px; color: var(--secondary-text-color, #888); flex: none; }
.title-text { font-size: 16px; font-weight: 500; }
.title-text {
font-size: 16px; font-weight: 500; min-width: 0;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.header-summary {
margin-left: auto; display: flex; align-items: center; gap: 8px;
margin-left: auto; display: flex; align-items: center; gap: 8px; flex: none;
font-size: 14px; font-weight: 600; white-space: nowrap;
}
.header-summary .saved { color: var(--success-color, #4caf50); font-weight: 500; }