329 files
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
import { html, nothing } from "lit";
|
||||
import { isSafeHttpUrl } from "../helpers/url";
|
||||
import { t, formatDate, formatDateTime, formatRecurrence } from "../styles";
|
||||
import type { AdvancedFeatures, HomeAssistant, MaintenanceTask } from "../types";
|
||||
import type { AdvancedFeatures, HomeAssistant, MaintenanceTask, ManualDocRef } from "../types";
|
||||
import { renderTriggerSection, type SparklineContext } from "./sparkline";
|
||||
import { renderPredictionSection } from "./prediction";
|
||||
import { renderWeibullSection } from "./weibull";
|
||||
@@ -32,6 +32,13 @@ export interface TaskDetailContext {
|
||||
objectName: string;
|
||||
/** Parent object's documentation_url (raw; sanitised here). */
|
||||
objectDocUrl: string | null | undefined;
|
||||
/** Parent object's manual-tagged documents — the fallback for the manual
|
||||
* row when documentation_url is empty (same rule as the objects table). */
|
||||
objectManualDocs: ManualDocRef[];
|
||||
/** Opens a manual document (signed path / weblink) — panel-owned. */
|
||||
openManualDoc: (doc: ManualDocRef) => void;
|
||||
/** #73: persist one checklist tick (panel sends the full state via WS). */
|
||||
setChecklistItem: (item: string, done: boolean) => void;
|
||||
isOperator: boolean;
|
||||
actionLoading: boolean;
|
||||
moreMenuOpen: boolean;
|
||||
@@ -178,22 +185,38 @@ function collapsible(key: string, titleKey: string, body: unknown, ctx: TaskDeta
|
||||
`;
|
||||
}
|
||||
|
||||
/** Read-only preview of the configured checklist steps so users can see
|
||||
* the steps without having to open the Edit or Complete dialog. Only
|
||||
* rendered when the Checklists feature is enabled and steps are set. */
|
||||
/** Interactive checklist (#73): steps can be ticked off DURING the cycle
|
||||
* without completing the task — progress persists server-side (survives
|
||||
* reloads, prefills the complete dialog) and resets when the task is
|
||||
* completed or skipped. Only rendered when the Checklists feature is
|
||||
* enabled and steps are set. */
|
||||
function renderChecklistCard(task: MaintenanceTask, ctx: TaskDetailContext) {
|
||||
if (!ctx.features.checklists) return nothing;
|
||||
const items = task.checklist || [];
|
||||
if (items.length === 0) return nothing;
|
||||
const L = ctx.lang;
|
||||
const progress = task.checklist_progress || {};
|
||||
const done = items.filter((item) => progress[item]).length;
|
||||
return html`
|
||||
<div class="checklist-preview-card">
|
||||
<div class="checklist-preview-header">
|
||||
<ha-icon icon="mdi:format-list-checks"></ha-icon>
|
||||
<span>${t("checklist", L)} (${items.length})</span>
|
||||
<span>${t("checklist", L)} (${done}/${items.length})</span>
|
||||
</div>
|
||||
<ol class="checklist-preview-list">
|
||||
${items.map((item) => html`<li>${item}</li>`)}
|
||||
${items.map((item) => html`
|
||||
<li class=${progress[item] ? "checked" : ""}>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${!!progress[item]}
|
||||
@change=${(e: Event) =>
|
||||
ctx.setChecklistItem(item, (e.target as HTMLInputElement).checked)}
|
||||
/>
|
||||
<span>${item}</span>
|
||||
</label>
|
||||
</li>
|
||||
`)}
|
||||
</ol>
|
||||
</div>
|
||||
`;
|
||||
@@ -206,7 +229,10 @@ function renderTaskMeta(task: MaintenanceTask, ctx: TaskDetailContext) {
|
||||
const safeTaskUrl = isSafeHttpUrl(task.documentation_url)
|
||||
? task.documentation_url : null;
|
||||
const safeObjUrl = isSafeHttpUrl(ctx.objectDocUrl) ? ctx.objectDocUrl : null;
|
||||
if (!task.notes && !safeTaskUrl && !safeObjUrl) return nothing;
|
||||
// Same fallback rule as the objects table: an UPLOADED manual (category
|
||||
// "manual") stands in when the object's URL field is empty.
|
||||
const manualDoc = safeObjUrl ? null : (ctx.objectManualDocs || [])[0];
|
||||
if (!task.notes && !safeTaskUrl && !safeObjUrl && !manualDoc) return nothing;
|
||||
const L = ctx.lang;
|
||||
return html`
|
||||
<div class="task-meta-card">
|
||||
@@ -227,6 +253,13 @@ function renderTaskMeta(task: MaintenanceTask, ctx: TaskDetailContext) {
|
||||
<ha-icon icon="mdi:book-open-variant"></ha-icon>
|
||||
<a href="${safeObjUrl}" target="_blank" rel="noopener noreferrer">${t("documentation_url_label", L)} (${ctx.objectName})</a>
|
||||
</div>
|
||||
` : manualDoc ? html`
|
||||
<div class="task-meta-row task-meta-link">
|
||||
<ha-icon icon="mdi:book-open-variant"></ha-icon>
|
||||
<a href="#" title=${manualDoc.title}
|
||||
@click=${(e: Event) => { e.preventDefault(); ctx.openManualDoc(manualDoc); }}
|
||||
>${t("documentation_url_label", L)} (${ctx.objectName})</a>
|
||||
</div>
|
||||
` : nothing}
|
||||
</div>
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user