393 files
This commit is contained in:
+33
-29
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user