108 files
This commit is contained in:
1 parent
d851c2a3a5
commit
4e0539a155
108 files changed
+1977
-9644
No files matched your search
@@ -1025,17 +1025,39 @@ class MaintenanceCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
actual_interval = None
|
||||
|
||||
# #99: enrich the per-completion parts selection with names so the
|
||||
# history entry is readable without a part-id lookup.
|
||||
# history entry is readable without a part-id lookup. Since #130 the
|
||||
# AUTOMATIC path records too: with no explicit selection, the task's
|
||||
# consumes_parts links — exactly what async_handle_completion_parts
|
||||
# will consume below — go on the record, so completions from the
|
||||
# no-dialog surfaces (service, button, QR, to-do, voice, recovery)
|
||||
# stay correctable through the history editor like dialog ones.
|
||||
record_links = (
|
||||
used_parts if used_parts is not None else (merged[task_id].get("consumes_parts") or [])
|
||||
)
|
||||
enriched_used: list[dict[str, Any]] | None = None
|
||||
if used_parts is not None:
|
||||
parts_catalog = self.entry.data.get("parts") or {}
|
||||
if used_parts is not None or record_links:
|
||||
own_catalog = self.entry.data.get("parts") or {}
|
||||
|
||||
def _part_name(link: dict[str, Any]) -> str:
|
||||
owner_id = link.get("entry_id")
|
||||
catalog: dict[str, Any] = own_catalog
|
||||
if owner_id and owner_id != self.entry.entry_id:
|
||||
owner = self.hass.config_entries.async_get_entry(owner_id)
|
||||
catalog = (owner.data.get("parts") or {}) if owner else {}
|
||||
name = (catalog.get(link["part_id"]) or {}).get("name")
|
||||
return str(name) if name else str(link["part_id"])
|
||||
|
||||
enriched_used = [
|
||||
{
|
||||
"part_id": link["part_id"],
|
||||
"name": (parts_catalog.get(link["part_id"]) or {}).get("name") or link["part_id"],
|
||||
"name": _part_name(link),
|
||||
"quantity": link.get("quantity", 1),
|
||||
# #130: keep the pool owner on the record so a later
|
||||
# history edit can resolve the part without guessing.
|
||||
**({"entry_id": link["entry_id"]} if link.get("entry_id") else {}),
|
||||
}
|
||||
for link in used_parts
|
||||
for link in record_links
|
||||
if isinstance(link, dict) and link.get("part_id")
|
||||
]
|
||||
|
||||
task.complete(
|
||||
|
||||
@@ -126,6 +126,10 @@ def _build_export_object(
|
||||
"on_complete_action": tdata.get("on_complete_action"),
|
||||
"quick_complete_defaults": tdata.get("quick_complete_defaults"),
|
||||
"assignee_pool": tdata.get("assignee_pool") or [],
|
||||
# v2.44: demanded completion details — the import has mirrored this
|
||||
# key from day one; the export builder lost it (found by the #130
|
||||
# export audit), so backups silently dropped the requirement.
|
||||
"required_completion_fields": tdata.get("required_completion_fields"),
|
||||
"rotation_strategy": tdata.get("rotation_strategy"),
|
||||
"reading_unit": tdata.get("reading_unit"),
|
||||
# Spare parts: consumption links + the auto-buy-task marker.
|
||||
|
||||
+136
@@ -23,6 +23,19 @@ export interface HistoryEntryDraft {
|
||||
cost: number | null;
|
||||
duration: number | null;
|
||||
completed_by: string | null;
|
||||
// #130: the entry's recorded part consumption ({part_id, name, quantity,
|
||||
// entry_id? for pooled parts}); absent/empty = nothing consumed.
|
||||
used_parts?: Array<{ part_id: string; name?: string; quantity: number; entry_id?: string }> | null;
|
||||
}
|
||||
|
||||
/** One selectable part option in the edit dialog — the object's own parts
|
||||
* plus pooled parts this task links to, fetched via parts/overview. */
|
||||
interface PartOption {
|
||||
part_id: string;
|
||||
name: string;
|
||||
entry_id: string; // owning object
|
||||
foreign: boolean; // pooled (#111) — carried into the saved link
|
||||
object_name: string | null;
|
||||
}
|
||||
|
||||
export class MaintenanceHistoryEditDialog extends LitElement {
|
||||
@@ -40,6 +53,12 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
||||
return this.hass?.language || "en";
|
||||
}
|
||||
|
||||
// #130: selectable parts + the edited selection (part key -> quantity;
|
||||
// 0/absent = not consumed). Key = `${entry_id}:${part_id}` (pool-safe).
|
||||
@state() private _partOptions: PartOption[] | null = null;
|
||||
@state() private _partQty: Record<string, number> = {};
|
||||
private _partQtyOriginal = "";
|
||||
|
||||
/** Open the dialog with the given history-entry data. The caller must
|
||||
* pass `original_timestamp` (the entry's current timestamp before edit)
|
||||
* so the backend can find the entry. */
|
||||
@@ -48,6 +67,71 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
||||
this._originalSnapshot = { ...draft };
|
||||
this._error = "";
|
||||
this._open = true;
|
||||
this._partOptions = null;
|
||||
this._partQty = {};
|
||||
this._partQtyOriginal = "";
|
||||
void this._loadPartOptions();
|
||||
}
|
||||
|
||||
/** The object's own parts + pooled parts this task draws on — from the
|
||||
* instance-wide overview so pooled owners resolve without extra calls. */
|
||||
private async _loadPartOptions(): Promise<void> {
|
||||
const draft = this._draft;
|
||||
if (!draft) return;
|
||||
try {
|
||||
const result = await this.hass.connection.sendMessagePromise({
|
||||
type: "maintenance_supporter/parts/overview",
|
||||
}) as {
|
||||
parts: Array<{
|
||||
part_id: string; name: string; entry_id: string; object_name: string | null;
|
||||
consumers: Array<{ entry_id: string; task_id: string }>;
|
||||
}>;
|
||||
};
|
||||
const options: PartOption[] = [];
|
||||
for (const row of result.parts || []) {
|
||||
const own = row.entry_id === draft.entry_id;
|
||||
const linked = row.consumers.some((c) => c.entry_id === draft.entry_id && c.task_id === draft.task_id);
|
||||
if (!own && !linked) continue;
|
||||
options.push({
|
||||
part_id: row.part_id,
|
||||
name: row.name,
|
||||
entry_id: row.entry_id,
|
||||
foreign: !own,
|
||||
object_name: row.object_name,
|
||||
});
|
||||
}
|
||||
// Recorded parts whose catalog entry vanished stay selectable so a
|
||||
// correction can still zero them out.
|
||||
for (const link of draft.used_parts || []) {
|
||||
const owner = link.entry_id || draft.entry_id;
|
||||
if (!options.some((o) => o.part_id === link.part_id && o.entry_id === owner)) {
|
||||
options.push({
|
||||
part_id: link.part_id,
|
||||
name: link.name || link.part_id,
|
||||
entry_id: owner,
|
||||
foreign: owner !== draft.entry_id,
|
||||
object_name: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
const qty: Record<string, number> = {};
|
||||
for (const link of draft.used_parts || []) {
|
||||
qty[`${link.entry_id || draft.entry_id}:${link.part_id}`] = link.quantity ?? 1;
|
||||
}
|
||||
this._partOptions = options;
|
||||
this._partQty = qty;
|
||||
this._partQtyOriginal = this._partSelectionKey();
|
||||
} catch {
|
||||
this._partOptions = []; // parts UI unavailable — the rest still edits
|
||||
}
|
||||
}
|
||||
|
||||
private _partSelectionKey(): string {
|
||||
return JSON.stringify(
|
||||
Object.entries(this._partQty)
|
||||
.filter(([, q]) => q > 0)
|
||||
.sort(([a], [b]) => a.localeCompare(b)),
|
||||
);
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
@@ -92,6 +176,17 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
||||
if (this._draft.completed_by !== this._originalSnapshot.completed_by) {
|
||||
patch.completed_by = this._draft.completed_by;
|
||||
}
|
||||
// #130: send the parts selection only when it actually changed — the
|
||||
// backend reconciles stock by the delta, so a no-op must stay silent.
|
||||
if (this._partOptions !== null && this._partSelectionKey() !== this._partQtyOriginal) {
|
||||
patch.used_parts = (this._partOptions || [])
|
||||
.filter((o) => (this._partQty[`${o.entry_id}:${o.part_id}`] || 0) > 0)
|
||||
.map((o) => ({
|
||||
part_id: o.part_id,
|
||||
quantity: this._partQty[`${o.entry_id}:${o.part_id}`],
|
||||
...(o.foreign ? { entry_id: o.entry_id } : {}),
|
||||
}));
|
||||
}
|
||||
// Nothing changed → close without WS call
|
||||
const changedKeys = Object.keys(patch).filter(
|
||||
(k) => !["type", "entry_id", "task_id", "original_timestamp"].includes(k),
|
||||
@@ -173,6 +268,33 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
||||
}} />
|
||||
</label>
|
||||
</div>
|
||||
${this._partOptions && this._partOptions.length > 0 ? html`
|
||||
<div class="parts-block">
|
||||
<span class="parts-title">${t("complete_parts_used", L)}</span>
|
||||
${this._partOptions.map((o) => {
|
||||
const key = `${o.entry_id}:${o.part_id}`;
|
||||
const qty = this._partQty[key] || 0;
|
||||
return html`
|
||||
<label class="part-row-edit">
|
||||
<input type="checkbox" .checked=${qty > 0}
|
||||
@change=${(e: Event) => {
|
||||
const on = (e.target as HTMLInputElement).checked;
|
||||
this._partQty = { ...this._partQty, [key]: on ? 1 : 0 };
|
||||
}} />
|
||||
<span class="part-label">${o.name}${o.foreign && o.object_name ? ` (${o.object_name})` : ""}</span>
|
||||
${qty > 0 ? html`
|
||||
<input class="part-qty" type="number" min="0.01" max="999" step="0.01"
|
||||
.value=${String(qty)}
|
||||
@input=${(e: Event) => {
|
||||
const v = parseFloat((e.target as HTMLInputElement).value);
|
||||
if (!isNaN(v) && v > 0) this._partQty = { ...this._partQty, [key]: v };
|
||||
}} />
|
||||
` : nothing}
|
||||
</label>
|
||||
`;
|
||||
})}
|
||||
</div>
|
||||
` : nothing}
|
||||
${this._error ? html`<div class="error">${this._error}</div>` : nothing}
|
||||
<div class="actions">
|
||||
<button class="cancel" @click=${this.close} ?disabled=${this._saving}>
|
||||
@@ -248,6 +370,20 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
||||
background: rgba(211,47,47,0.1);
|
||||
border-radius: 6px;
|
||||
}
|
||||
/* #130: parts on the entry */
|
||||
.parts-block {
|
||||
display: flex; flex-direction: column; gap: 6px;
|
||||
border: 1px solid var(--divider-color, #444);
|
||||
border-radius: 6px; padding: 8px;
|
||||
}
|
||||
.parts-title { color: var(--secondary-text-color); font-size: 13px; }
|
||||
.part-row-edit {
|
||||
display: flex; flex-direction: row; align-items: center; gap: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.part-row-edit input[type="checkbox"] { width: auto; }
|
||||
.part-label { flex: 1; color: var(--primary-text-color); }
|
||||
.part-qty { width: 76px; }
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -320,6 +320,7 @@ export class MaintenanceTaskQuickActionsDialog extends LitElement {
|
||||
cost: entry.cost ?? null,
|
||||
duration: entry.duration ?? null,
|
||||
completed_by: entry.completed_by ?? null,
|
||||
used_parts: entry.used_parts ?? null,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Typ",
|
||||
"sort_task_name": "Název úkolu",
|
||||
"all_objects": "Všechny objekty",
|
||||
"all_parts": "Všechny díly",
|
||||
"tasks_lower": "úkolů",
|
||||
"no_tasks_yet": "Zatím žádné úkoly",
|
||||
"add_first_task": "Přidat první úkol",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Množství doplnění",
|
||||
"part_auto_buy": "Úkol nákupu při nízké zásobě",
|
||||
"part_restock": "Upravit zásobu",
|
||||
"parts_used_by": "Používá",
|
||||
"restock_quantity_label": "Zakoupené množství",
|
||||
"consumes_parts_label": "Spotřebovává díly",
|
||||
"shared_parts_other_objects": "Díly z jiných objektů",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "stav při posledním servisu (volitelné)",
|
||||
"baseline_start_help_edit": "Ponechte prázdné pro zachování stávajícího počítání. Zadaná hodnota počítání znovu ukotví (např. stav při posledním servisu).",
|
||||
"baseline_current_effective": "Aktuálně platná počáteční hodnota: {value}",
|
||||
"runtime_on_states": "Aktivní stavy (oddělené čárkami)",
|
||||
"runtime_on_states": "Aktivní stavy",
|
||||
"runtime_on_states_help": "Stavy počítané jako doba běhu — výchozí: on. Např. mowing, cleaning, printing. Při zvoleném atributu se porovnávají jeho hodnoty.",
|
||||
"setups_target_new": "Vytvořit nový: {name}",
|
||||
"schedule_preview_title": "Nejbližší termíny",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Opgavenavn",
|
||||
"all_objects": "Alle objekter",
|
||||
"all_parts": "Alle dele",
|
||||
"tasks_lower": "opgaver",
|
||||
"no_tasks_yet": "Ingen opgaver endnu",
|
||||
"add_first_task": "Tilføj første opgave",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Genopfyldningsmængde",
|
||||
"part_auto_buy": "Købsopgave ved lav beholdning",
|
||||
"part_restock": "Justér lager",
|
||||
"parts_used_by": "Bruges af",
|
||||
"restock_quantity_label": "Købt mængde",
|
||||
"consumes_parts_label": "Forbruger dele",
|
||||
"shared_parts_other_objects": "Dele fra andre objekter",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "aflæsning ved sidste service (valgfrit)",
|
||||
"baseline_start_help_edit": "Lad feltet stå tomt for at beholde den eksisterende tælling. En indtastet værdi forankrer tællingen på ny (f.eks. aflæsningen ved sidste service).",
|
||||
"baseline_current_effective": "Aktuelt gældende startværdi: {value}",
|
||||
"runtime_on_states": "Aktive tilstande (kommaseparerede)",
|
||||
"runtime_on_states": "Aktive tilstande",
|
||||
"runtime_on_states_help": "Tilstande der tæller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med en valgt attribut sammenlignes dens værdier i stedet.",
|
||||
"setups_target_new": "Opret ny: {name}",
|
||||
"schedule_preview_title": "Kommende datoer",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Typ",
|
||||
"sort_task_name": "Aufgaben-Name",
|
||||
"all_objects": "Alle Objekte",
|
||||
"all_parts": "Alle Teile",
|
||||
"tasks_lower": "Aufgaben",
|
||||
"no_tasks_yet": "Noch keine Aufgaben",
|
||||
"add_first_task": "Erste Aufgabe hinzufügen",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Auffüllmenge",
|
||||
"part_auto_buy": "Kauf-Task bei Niedrigbestand",
|
||||
"part_restock": "Bestand anpassen",
|
||||
"parts_used_by": "Verwendet von",
|
||||
"restock_quantity_label": "Gekaufte Menge",
|
||||
"consumes_parts_label": "Verbraucht Teile",
|
||||
"shared_parts_other_objects": "Teile anderer Objekte",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "Stand beim letzten Service (optional)",
|
||||
"baseline_start_help_edit": "Leer lassen, um die bestehende Zählung zu behalten. Ein eingetragener Wert verankert die Zählung neu (z. B. der Stand beim letzten Service).",
|
||||
"baseline_current_effective": "Aktuell wirksamer Startwert: {value}",
|
||||
"runtime_on_states": "Aktive Zustände (kommagetrennt)",
|
||||
"runtime_on_states": "Aktive Zustände",
|
||||
"runtime_on_states_help": "Zustände, die als Laufzeit zählen — Standard: on. Z. B. mowing, cleaning, printing. Bei gewähltem Attribut werden dessen Werte verglichen.",
|
||||
"setups_target_new": "Neu anlegen: {name}",
|
||||
"schedule_preview_title": "Nächste Termine",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Task name",
|
||||
"all_objects": "All objects",
|
||||
"all_parts": "All parts",
|
||||
"tasks_lower": "tasks",
|
||||
"no_tasks_yet": "No tasks yet",
|
||||
"add_first_task": "Add first task",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "Restock quantity",
|
||||
"part_auto_buy": "Auto-create buy task when low",
|
||||
"part_restock": "Adjust stock",
|
||||
"parts_used_by": "Used by",
|
||||
"restock_quantity_label": "Quantity bought",
|
||||
"consumes_parts_label": "Consumes parts",
|
||||
"shared_parts_other_objects": "Parts from other objects",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "reading at last service (optional)",
|
||||
"baseline_start_help_edit": "Leave empty to keep the existing counting. Entering a value re-anchors the counting (e.g. the reading at the last service).",
|
||||
"baseline_current_effective": "Currently effective start value: {value}",
|
||||
"runtime_on_states": "Active states (comma-separated)",
|
||||
"runtime_on_states": "Active states",
|
||||
"runtime_on_states_help": "States that count as running — default: on. E.g. mowing, cleaning, printing. With an attribute selected, its values are matched instead.",
|
||||
"setups_target_new": "Create new: {name}",
|
||||
"schedule_preview_title": "Next dates",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Tipo",
|
||||
"sort_task_name": "Nombre de la tarea",
|
||||
"all_objects": "Todos los objetos",
|
||||
"all_parts": "Todas las piezas",
|
||||
"tasks_lower": "tareas",
|
||||
"no_tasks_yet": "Aún no hay tareas",
|
||||
"add_first_task": "Agregar primera tarea",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Cantidad de reposición",
|
||||
"part_auto_buy": "Crear tarea de compra si bajo",
|
||||
"part_restock": "Ajustar existencias",
|
||||
"parts_used_by": "Usado por",
|
||||
"restock_quantity_label": "Cantidad comprada",
|
||||
"consumes_parts_label": "Consume piezas",
|
||||
"shared_parts_other_objects": "Piezas de otros objetos",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "lectura en el último mantenimiento (opcional)",
|
||||
"baseline_start_help_edit": "Déjalo vacío para mantener el conteo actual. Un valor introducido reancla el conteo (p. ej., la lectura del último mantenimiento).",
|
||||
"baseline_current_effective": "Valor inicial vigente: {value}",
|
||||
"runtime_on_states": "Estados activos (separados por comas)",
|
||||
"runtime_on_states": "Estados activos",
|
||||
"runtime_on_states_help": "Estados que cuentan como en funcionamiento — predeterminado: on. P. ej. mowing, cleaning, printing. Con un atributo seleccionado se comparan sus valores.",
|
||||
"setups_target_new": "Crear nuevo: {name}",
|
||||
"schedule_preview_title": "Próximas fechas",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Tyyppi",
|
||||
"sort_task_name": "Tehtävän nimi",
|
||||
"all_objects": "Kaikki kohteet",
|
||||
"all_parts": "Kaikki osat",
|
||||
"tasks_lower": "tehtävää",
|
||||
"no_tasks_yet": "Ei vielä tehtäviä",
|
||||
"add_first_task": "Lisää ensimmäinen tehtävä",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Täydennysmäärä",
|
||||
"part_auto_buy": "Ostotehtävä kun vähissä",
|
||||
"part_restock": "Muuta varastoa",
|
||||
"parts_used_by": "Käyttäjät",
|
||||
"restock_quantity_label": "Ostettu määrä",
|
||||
"consumes_parts_label": "Kuluttaa osia",
|
||||
"shared_parts_other_objects": "Muiden kohteiden osat",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "lukema viime huollossa (valinnainen)",
|
||||
"baseline_start_help_edit": "Jätä tyhjäksi säilyttääksesi nykyisen laskennan. Syötetty arvo ankkuroi laskennan uudelleen (esim. viimeisimmän huollon lukema).",
|
||||
"baseline_current_effective": "Nyt voimassa oleva aloitusarvo: {value}",
|
||||
"runtime_on_states": "Aktiiviset tilat (pilkuin eroteltuina)",
|
||||
"runtime_on_states": "Aktiiviset tilat",
|
||||
"runtime_on_states_help": "Tilat, jotka lasketaan käyntiajaksi — oletus: on. Esim. mowing, cleaning, printing. Jos attribuutti on valittu, verrataan sen arvoja.",
|
||||
"setups_target_new": "Luo uusi: {name}",
|
||||
"schedule_preview_title": "Seuraavat päivämäärät",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Nom de la tâche",
|
||||
"all_objects": "Tous les objets",
|
||||
"all_parts": "Toutes les pièces",
|
||||
"tasks_lower": "tâches",
|
||||
"no_tasks_yet": "Pas encore de tâches",
|
||||
"add_first_task": "Ajouter la première tâche",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Quantité de réappro",
|
||||
"part_auto_buy": "Tâche d'achat auto si bas",
|
||||
"part_restock": "Ajuster le stock",
|
||||
"parts_used_by": "Utilisé par",
|
||||
"restock_quantity_label": "Quantité achetée",
|
||||
"consumes_parts_label": "Consomme des pièces",
|
||||
"shared_parts_other_objects": "Pièces d'autres objets",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "relevé au dernier entretien (facultatif)",
|
||||
"baseline_start_help_edit": "Laissez vide pour conserver le comptage existant. Une valeur saisie réancre le comptage (p. ex. le relevé du dernier entretien).",
|
||||
"baseline_current_effective": "Valeur de départ actuellement en vigueur : {value}",
|
||||
"runtime_on_states": "États actifs (séparés par des virgules)",
|
||||
"runtime_on_states": "États actifs",
|
||||
"runtime_on_states_help": "États comptés comme en fonctionnement — par défaut : on. P. ex. mowing, cleaning, printing. Si un attribut est sélectionné, ce sont ses valeurs qui sont comparées.",
|
||||
"setups_target_new": "Créer : {name}",
|
||||
"schedule_preview_title": "Prochaines échéances",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "प्रकार",
|
||||
"sort_task_name": "कार्य का नाम",
|
||||
"all_objects": "सभी वस्तुएँ",
|
||||
"all_parts": "सभी पुर्ज़े",
|
||||
"tasks_lower": "कार्य",
|
||||
"no_tasks_yet": "अभी कोई कार्य नहीं",
|
||||
"add_first_task": "पहला कार्य जोड़ें",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "पुनःपूर्ति मात्रा",
|
||||
"part_auto_buy": "कम होने पर खरीद कार्य",
|
||||
"part_restock": "स्टॉक समायोजित करें",
|
||||
"parts_used_by": "द्वारा उपयोग",
|
||||
"restock_quantity_label": "खरीदी गई मात्रा",
|
||||
"consumes_parts_label": "पुर्ज़े खपत",
|
||||
"shared_parts_other_objects": "अन्य वस्तुओं के पुर्ज़े",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "पिछली सर्विस पर रीडिंग (वैकल्पिक)",
|
||||
"baseline_start_help_edit": "मौजूदा गिनती बनाए रखने के लिए खाली छोड़ें। दर्ज किया गया मान गिनती को फिर से स्थिर करता है (जैसे पिछली सर्विस के समय की रीडिंग)।",
|
||||
"baseline_current_effective": "वर्तमान में प्रभावी प्रारंभिक मान: {value}",
|
||||
"runtime_on_states": "सक्रिय अवस्थाएँ (अल्पविराम से अलग)",
|
||||
"runtime_on_states": "सक्रिय अवस्थाएँ",
|
||||
"runtime_on_states_help": "वे अवस्थाएँ जो चालू समय में गिनी जाती हैं — डिफ़ॉल्ट: on। जैसे mowing, cleaning, printing। विशेषता चुनी होने पर उसकी मानों की तुलना होती है।",
|
||||
"setups_target_new": "नया बनाएँ: {name}",
|
||||
"schedule_preview_title": "अगली तिथियाँ",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Típus",
|
||||
"sort_task_name": "Feladat neve",
|
||||
"all_objects": "Minden objektum",
|
||||
"all_parts": "Összes alkatrész",
|
||||
"tasks_lower": "feladat",
|
||||
"no_tasks_yet": "Még nincs feladat",
|
||||
"add_first_task": "Első feladat hozzáadása",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "Feltöltési mennyiség",
|
||||
"part_auto_buy": "Vásárlási feladat automatikus létrehozása, ha kevés van",
|
||||
"part_restock": "Készlet módosítása",
|
||||
"parts_used_by": "Használja",
|
||||
"restock_quantity_label": "Vásárolt mennyiség",
|
||||
"consumes_parts_label": "Felhasznált alkatrészek",
|
||||
"shared_parts_other_objects": "Más objektumok alkatrészei",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "érték az utolsó szerviznél (opcionális)",
|
||||
"baseline_start_help_edit": "Üresen hagyva a meglévő számlálás marad. Érték megadása újrahorgonyozza a számlálást (pl. az utolsó szerviz leolvasott értéke).",
|
||||
"baseline_current_effective": "Jelenleg érvényes kezdőérték: {value}",
|
||||
"runtime_on_states": "Aktív állapotok (vesszővel elválasztva)",
|
||||
"runtime_on_states": "Aktív állapotok",
|
||||
"runtime_on_states_help": "Működésként számító állapotok — alapértelmezés: on. Pl. mowing, cleaning, printing. Attribútum kiválasztásakor annak értékei számítanak.",
|
||||
"setups_target_new": "Új létrehozása: {name}",
|
||||
"schedule_preview_title": "Következő dátumok",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Tipo",
|
||||
"sort_task_name": "Nome attività",
|
||||
"all_objects": "Tutti gli oggetti",
|
||||
"all_parts": "Tutti i ricambi",
|
||||
"tasks_lower": "attività",
|
||||
"no_tasks_yet": "Nessuna attività",
|
||||
"add_first_task": "Aggiungi prima attività",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Quantità di riordino",
|
||||
"part_auto_buy": "Task d'acquisto se scarso",
|
||||
"part_restock": "Correggi scorta",
|
||||
"parts_used_by": "Usato da",
|
||||
"restock_quantity_label": "Quantità acquistata",
|
||||
"consumes_parts_label": "Consuma ricambi",
|
||||
"shared_parts_other_objects": "Ricambi di altri oggetti",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "lettura all'ultima manutenzione (facoltativo)",
|
||||
"baseline_start_help_edit": "Lascia vuoto per mantenere il conteggio esistente. Un valore inserito riancora il conteggio (ad es. la lettura dell'ultima manutenzione).",
|
||||
"baseline_current_effective": "Valore iniziale attualmente in vigore: {value}",
|
||||
"runtime_on_states": "Stati attivi (separati da virgole)",
|
||||
"runtime_on_states": "Stati attivi",
|
||||
"runtime_on_states_help": "Stati che contano come in funzione — predefinito: on. Ad es. mowing, cleaning, printing. Con un attributo selezionato vengono confrontati i suoi valori.",
|
||||
"setups_target_new": "Crea nuovo: {name}",
|
||||
"schedule_preview_title": "Prossime date",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "種別",
|
||||
"sort_task_name": "タスク名",
|
||||
"all_objects": "すべての対象",
|
||||
"all_parts": "すべての部品",
|
||||
"tasks_lower": "タスク",
|
||||
"no_tasks_yet": "タスクがまだありません",
|
||||
"add_first_task": "最初のタスクを追加",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "補充数量",
|
||||
"part_auto_buy": "在庫少で購入タスク",
|
||||
"part_restock": "在庫を調整",
|
||||
"parts_used_by": "使用タスク",
|
||||
"restock_quantity_label": "購入数量",
|
||||
"consumes_parts_label": "部品を消費",
|
||||
"shared_parts_other_objects": "他の対象の部品",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "前回整備時の値(任意)",
|
||||
"baseline_start_help_edit": "空欄のままにすると現在のカウントを維持します。値を入力するとカウントの起点を再設定します(例:前回整備時の値)。",
|
||||
"baseline_current_effective": "現在有効な開始値:{value}",
|
||||
"runtime_on_states": "稼働中とみなす状態(カンマ区切り)",
|
||||
"runtime_on_states": "稼働中とみなす状態",
|
||||
"runtime_on_states_help": "稼働時間として数える状態 — 既定値:on。例:mowing, cleaning, printing。属性を選択している場合はその値が比較されます。",
|
||||
"setups_target_new": "新規作成:{name}",
|
||||
"schedule_preview_title": "次回の予定日",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "유형",
|
||||
"sort_task_name": "작업 이름",
|
||||
"all_objects": "모든 객체",
|
||||
"all_parts": "모든 부품",
|
||||
"tasks_lower": "작업",
|
||||
"no_tasks_yet": "아직 작업 없음",
|
||||
"add_first_task": "첫 작업 추가",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "보충 수량",
|
||||
"part_auto_buy": "재고 부족 시 구매 작업 자동 생성",
|
||||
"part_restock": "재고 조정",
|
||||
"parts_used_by": "사용처",
|
||||
"restock_quantity_label": "구매 수량",
|
||||
"consumes_parts_label": "사용하는 부품",
|
||||
"shared_parts_other_objects": "다른 객체의 부품",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "마지막 정비 시점의 값 (선택)",
|
||||
"baseline_start_help_edit": "비워두면 기존 계수를 유지합니다. 값을 입력하면 계수 기준이 다시 설정됩니다 (예: 마지막 정비 시점의 값).",
|
||||
"baseline_current_effective": "현재 적용 중인 시작 값: {value}",
|
||||
"runtime_on_states": "활성 상태 (쉼표로 구분)",
|
||||
"runtime_on_states": "활성 상태",
|
||||
"runtime_on_states_help": "가동 중으로 계산할 상태입니다 — 기본값: on. 예: mowing, cleaning, printing. 속성을 선택한 경우 해당 속성 값과 비교합니다.",
|
||||
"setups_target_new": "새로 만들기: {name}",
|
||||
"schedule_preview_title": "다음 예정일",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Oppgavenavn",
|
||||
"all_objects": "Alle objekter",
|
||||
"all_parts": "Alle deler",
|
||||
"tasks_lower": "oppgaver",
|
||||
"no_tasks_yet": "Ingen oppgaver ennå",
|
||||
"add_first_task": "Legg til første oppgave",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Påfyllingsmengde",
|
||||
"part_auto_buy": "Kjøpsoppgave ved lavt lager",
|
||||
"part_restock": "Juster lager",
|
||||
"parts_used_by": "Brukes av",
|
||||
"restock_quantity_label": "Kjøpt mengde",
|
||||
"consumes_parts_label": "Forbruker deler",
|
||||
"shared_parts_other_objects": "Deler fra andre objekter",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "avlesning ved forrige service (valgfritt)",
|
||||
"baseline_start_help_edit": "La stå tomt for å beholde den eksisterende tellingen. En angitt verdi forankrer tellingen på nytt (f.eks. avlesningen ved forrige service).",
|
||||
"baseline_current_effective": "Gjeldende startverdi: {value}",
|
||||
"runtime_on_states": "Aktive tilstander (kommaseparert)",
|
||||
"runtime_on_states": "Aktive tilstander",
|
||||
"runtime_on_states_help": "Tilstander som teller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med et valgt attributt sammenlignes verdiene dets i stedet.",
|
||||
"setups_target_new": "Opprett ny: {name}",
|
||||
"schedule_preview_title": "Kommende datoer",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Taaknaam",
|
||||
"all_objects": "Alle objecten",
|
||||
"all_parts": "Alle onderdelen",
|
||||
"tasks_lower": "taken",
|
||||
"no_tasks_yet": "Nog geen taken",
|
||||
"add_first_task": "Eerste taak toevoegen",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Aanvulhoeveelheid",
|
||||
"part_auto_buy": "Kooptaak bij lage voorraad",
|
||||
"part_restock": "Voorraad aanpassen",
|
||||
"parts_used_by": "Gebruikt door",
|
||||
"restock_quantity_label": "Gekochte hoeveelheid",
|
||||
"consumes_parts_label": "Verbruikt onderdelen",
|
||||
"shared_parts_other_objects": "Onderdelen van andere objecten",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "stand bij laatste onderhoud (optioneel)",
|
||||
"baseline_start_help_edit": "Laat leeg om de bestaande telling te behouden. Een ingevulde waarde verankert de telling opnieuw (bijv. de stand bij de laatste servicebeurt).",
|
||||
"baseline_current_effective": "Momenteel geldende startwaarde: {value}",
|
||||
"runtime_on_states": "Actieve statussen (kommagescheiden)",
|
||||
"runtime_on_states": "Actieve statussen",
|
||||
"runtime_on_states_help": "Statussen die als draaitijd tellen — standaard: on. Bijv. mowing, cleaning, printing. Met een geselecteerd attribuut worden de waarden daarvan vergeleken.",
|
||||
"setups_target_new": "Nieuw aanmaken: {name}",
|
||||
"schedule_preview_title": "Volgende data",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Typ",
|
||||
"sort_task_name": "Nazwa zadania",
|
||||
"all_objects": "Wszystkie obiekty",
|
||||
"all_parts": "Wszystkie części",
|
||||
"tasks_lower": "zadań",
|
||||
"no_tasks_yet": "Jeszcze brak zadań",
|
||||
"add_first_task": "Dodaj pierwsze zadanie",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Ilość uzupełnienia",
|
||||
"part_auto_buy": "Zadanie zakupu przy niskim stanie",
|
||||
"part_restock": "Koryguj stan",
|
||||
"parts_used_by": "Używane przez",
|
||||
"restock_quantity_label": "Kupiona ilość",
|
||||
"consumes_parts_label": "Zużywa części",
|
||||
"shared_parts_other_objects": "Części z innych obiektów",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "stan przy ostatnim serwisie (opcjonalnie)",
|
||||
"baseline_start_help_edit": "Pozostaw puste, aby zachować dotychczasowe liczenie. Wpisana wartość zakotwicza liczenie na nowo (np. stan przy ostatnim serwisie).",
|
||||
"baseline_current_effective": "Obecnie obowiązująca wartość początkowa: {value}",
|
||||
"runtime_on_states": "Stany aktywne (rozdzielone przecinkami)",
|
||||
"runtime_on_states": "Stany aktywne",
|
||||
"runtime_on_states_help": "Stany liczone jako czas pracy — domyślnie: on. Np. mowing, cleaning, printing. Przy wybranym atrybucie porównywane są jego wartości.",
|
||||
"setups_target_new": "Utwórz nowy: {name}",
|
||||
"schedule_preview_title": "Najbliższe terminy",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Tipo",
|
||||
"sort_task_name": "Nome da tarefa",
|
||||
"all_objects": "Todos os objetos",
|
||||
"all_parts": "Todas as peças",
|
||||
"tasks_lower": "tarefas",
|
||||
"no_tasks_yet": "Ainda sem tarefas",
|
||||
"add_first_task": "Adicionar a primeira tarefa",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "Quantidade de reposição",
|
||||
"part_auto_buy": "Criar tarefa de compra automaticamente quando estiver baixo",
|
||||
"part_restock": "Ajustar estoque",
|
||||
"parts_used_by": "Usado por",
|
||||
"restock_quantity_label": "Quantidade comprada",
|
||||
"consumes_parts_label": "Consome peças",
|
||||
"shared_parts_other_objects": "Peças de outros objetos",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
||||
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Informar um valor reancora a contagem (ex.: a leitura da última manutenção).",
|
||||
"baseline_current_effective": "Valor inicial efetivo atual: {value}",
|
||||
"runtime_on_states": "Estados ativos (separados por vírgula)",
|
||||
"runtime_on_states": "Estados ativos",
|
||||
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. Ex.: mowing, cleaning, printing. Com um atributo selecionado, os valores dele são comparados.",
|
||||
"setups_target_new": "Criar novo: {name}",
|
||||
"schedule_preview_title": "Próximas datas",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Tipo",
|
||||
"sort_task_name": "Nome da tarefa",
|
||||
"all_objects": "Todos os objetos",
|
||||
"all_parts": "Todas as peças",
|
||||
"tasks_lower": "tarefas",
|
||||
"no_tasks_yet": "Ainda sem tarefas",
|
||||
"add_first_task": "Adicionar primeira tarefa",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Quantidade de reposição",
|
||||
"part_auto_buy": "Tarefa de compra se baixo",
|
||||
"part_restock": "Ajustar estoque",
|
||||
"parts_used_by": "Usado por",
|
||||
"restock_quantity_label": "Quantidade comprada",
|
||||
"consumes_parts_label": "Consome peças",
|
||||
"shared_parts_other_objects": "Peças de outros objetos",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
||||
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Um valor introduzido reancora a contagem (p. ex., a leitura da última manutenção).",
|
||||
"baseline_current_effective": "Valor inicial atualmente em vigor: {value}",
|
||||
"runtime_on_states": "Estados ativos (separados por vírgulas)",
|
||||
"runtime_on_states": "Estados ativos",
|
||||
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. P. ex. mowing, cleaning, printing. Com um atributo selecionado, são comparados os valores dele.",
|
||||
"setups_target_new": "Criar novo: {name}",
|
||||
"schedule_preview_title": "Próximas datas",
|
||||
|
||||
@@ -176,6 +176,7 @@
|
||||
"sort_type": "Тип",
|
||||
"sort_task_name": "Имя задачи",
|
||||
"all_objects": "Все объекты",
|
||||
"all_parts": "Все детали",
|
||||
"tasks_lower": "задач",
|
||||
"no_tasks_yet": "Пока нет задач",
|
||||
"add_first_task": "Добавить первую задачу",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Количество пополнения",
|
||||
"part_auto_buy": "Задача покупки при малом запасе",
|
||||
"part_restock": "Изменить запас",
|
||||
"parts_used_by": "Используется",
|
||||
"restock_quantity_label": "Куплено, шт.",
|
||||
"consumes_parts_label": "Расходует детали",
|
||||
"shared_parts_other_objects": "Детали других объектов",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "показание при последнем обслуживании (необязательно)",
|
||||
"baseline_start_help_edit": "Оставьте пустым, чтобы сохранить текущий отсчёт. Введённое значение заново привязывает отсчёт (например, показание при последнем обслуживании).",
|
||||
"baseline_current_effective": "Действующее начальное значение: {value}",
|
||||
"runtime_on_states": "Активные состояния (через запятую)",
|
||||
"runtime_on_states": "Активные состояния",
|
||||
"runtime_on_states_help": "Состояния, засчитываемые как работа — по умолчанию: on. Напр. mowing, cleaning, printing. Если выбран атрибут, сравниваются его значения.",
|
||||
"setups_target_new": "Создать новый: {name}",
|
||||
"schedule_preview_title": "Ближайшие даты",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Typ",
|
||||
"sort_task_name": "Uppgiftsnamn",
|
||||
"all_objects": "Alla objekt",
|
||||
"all_parts": "Alla delar",
|
||||
"tasks_lower": "uppgifter",
|
||||
"no_tasks_yet": "Inga uppgifter ännu",
|
||||
"add_first_task": "Lägg till första uppgift",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Påfyllningsantal",
|
||||
"part_auto_buy": "Köpuppgift vid lågt lager",
|
||||
"part_restock": "Justera lager",
|
||||
"parts_used_by": "Används av",
|
||||
"restock_quantity_label": "Köpt antal",
|
||||
"consumes_parts_label": "Förbrukar delar",
|
||||
"shared_parts_other_objects": "Delar från andra objekt",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "mätarställning vid senaste service (valfritt)",
|
||||
"baseline_start_help_edit": "Lämna tomt för att behålla den befintliga räkningen. Ett angivet värde förankrar räkningen på nytt (t.ex. mätarställningen vid senaste servicen).",
|
||||
"baseline_current_effective": "Nu gällande startvärde: {value}",
|
||||
"runtime_on_states": "Aktiva tillstånd (kommaseparerade)",
|
||||
"runtime_on_states": "Aktiva tillstånd",
|
||||
"runtime_on_states_help": "Tillstånd som räknas som drifttid — standard: on. T.ex. mowing, cleaning, printing. Med ett valt attribut jämförs dess värden i stället.",
|
||||
"setups_target_new": "Skapa ny: {name}",
|
||||
"schedule_preview_title": "Kommande datum",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Tür",
|
||||
"sort_task_name": "Görev adı",
|
||||
"all_objects": "Tüm nesneler",
|
||||
"all_parts": "Tüm parçalar",
|
||||
"tasks_lower": "görev",
|
||||
"no_tasks_yet": "Henüz görev yok",
|
||||
"add_first_task": "İlk görevi ekle",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "Stok yenileme miktarı",
|
||||
"part_auto_buy": "Azaldığında otomatik satın alma görevi oluştur",
|
||||
"part_restock": "Stoku ayarla",
|
||||
"parts_used_by": "Kullanan",
|
||||
"restock_quantity_label": "Satın alınan miktar",
|
||||
"consumes_parts_label": "Parça tüketir",
|
||||
"shared_parts_other_objects": "Diğer nesnelerin parçaları",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "son servisteki okuma (isteğe bağlı)",
|
||||
"baseline_start_help_edit": "Mevcut sayımı korumak için boş bırakın. Bir değer girmek sayımı yeniden sabitler (örn. son servisteki okuma).",
|
||||
"baseline_current_effective": "Şu anda geçerli başlangıç değeri: {value}",
|
||||
"runtime_on_states": "Etkin durumlar (virgülle ayrılmış)",
|
||||
"runtime_on_states": "Etkin durumlar",
|
||||
"runtime_on_states_help": "Çalışıyor sayılan durumlar — varsayılan: on. Örn. mowing, cleaning, printing. Bir öznitelik seçiliyse onun değerleri eşleştirilir.",
|
||||
"setups_target_new": "Yeni oluştur: {name}",
|
||||
"schedule_preview_title": "Sonraki tarihler",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Тип",
|
||||
"sort_task_name": "Назва завдання",
|
||||
"all_objects": "Всі об'єкти",
|
||||
"all_parts": "Усі деталі",
|
||||
"tasks_lower": "завдань",
|
||||
"no_tasks_yet": "Завдань ще немає",
|
||||
"add_first_task": "Додати перше завдання",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Кількість поповнення",
|
||||
"part_auto_buy": "Завдання купівлі при малому запасі",
|
||||
"part_restock": "Змінити запас",
|
||||
"parts_used_by": "Використовується",
|
||||
"restock_quantity_label": "Куплена кількість",
|
||||
"consumes_parts_label": "Витрачає деталі",
|
||||
"shared_parts_other_objects": "Деталі інших об'єктів",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "показання під час останнього обслуговування (необов'язково)",
|
||||
"baseline_start_help_edit": "Залиште порожнім, щоб зберегти поточний відлік. Введене значення заново прив'язує відлік (наприклад, показання під час останнього обслуговування).",
|
||||
"baseline_current_effective": "Чинне початкове значення: {value}",
|
||||
"runtime_on_states": "Активні стани (через кому)",
|
||||
"runtime_on_states": "Активні стани",
|
||||
"runtime_on_states_help": "Стани, що зараховуються як робота — типово: on. Напр. mowing, cleaning, printing. Якщо вибрано атрибут, порівнюються його значення.",
|
||||
"setups_target_new": "Створити новий: {name}",
|
||||
"schedule_preview_title": "Найближчі дати",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "类型",
|
||||
"sort_task_name": "任务名称",
|
||||
"all_objects": "所有维护项",
|
||||
"all_parts": "所有配件",
|
||||
"tasks_lower": "任务",
|
||||
"no_tasks_yet": "尚无任务",
|
||||
"add_first_task": "添加首个任务",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "补货数量",
|
||||
"part_auto_buy": "库存低时自动建购买任务",
|
||||
"part_restock": "调整库存",
|
||||
"parts_used_by": "使用于",
|
||||
"restock_quantity_label": "购买数量",
|
||||
"consumes_parts_label": "消耗配件",
|
||||
"shared_parts_other_objects": "其他设备的配件",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "上次保养时的读数(可选)",
|
||||
"baseline_start_help_edit": "留空以保留现有计数。填写数值会重新锚定计数(例如上次保养时的读数)。",
|
||||
"baseline_current_effective": "当前生效的起始读数:{value}",
|
||||
"runtime_on_states": "活动状态(逗号分隔)",
|
||||
"runtime_on_states": "活动状态",
|
||||
"runtime_on_states_help": "计入运行时间的状态 — 默认:on。例如 mowing、cleaning、printing。选择了属性时将比较该属性的值。",
|
||||
"setups_target_new": "新建:{name}",
|
||||
"schedule_preview_title": "下次日期",
|
||||
|
||||
@@ -1142,6 +1142,7 @@ function registerLlCustomHandler(): void {
|
||||
cost: (histEntry.cost as number | undefined) ?? null,
|
||||
duration: (histEntry.duration as number | undefined) ?? null,
|
||||
completed_by: (histEntry.completed_by as string) ?? null,
|
||||
used_parts: (histEntry.used_parts as Array<{ part_id: string; name?: string; quantity: number; entry_id?: string }> | null) ?? null,
|
||||
});
|
||||
} catch {
|
||||
deepLink("/maintenance-supporter");
|
||||
|
||||
@@ -79,7 +79,32 @@ import { renderUserBadge, type TaskDetailContext } from "./renderers/task-detail
|
||||
import "./components/task-detail-view";
|
||||
import { computeWindow, VIRTUAL_MIN_ROWS } from "./helpers/virtual-window";
|
||||
|
||||
type View = "overview" | "object" | "task" | "all_objects";
|
||||
type View = "overview" | "object" | "task" | "all_objects" | "all_parts";
|
||||
|
||||
/** One row of the instance-wide parts overview (#130) — the WS response of
|
||||
* `parts/overview`: the stored part fields plus owner, live stock and the
|
||||
* consuming tasks (own + pooled #111 links). */
|
||||
interface PartsOverviewRow {
|
||||
part_id: string;
|
||||
entry_id: string;
|
||||
object_name: string | null;
|
||||
name: string;
|
||||
unit?: string | null;
|
||||
cost?: number | null;
|
||||
storage_location?: string | null;
|
||||
vendor?: string | null;
|
||||
reorder_threshold?: number | null;
|
||||
stock: number | null;
|
||||
low: boolean;
|
||||
consumers: Array<{
|
||||
entry_id: string;
|
||||
object_name: string | null;
|
||||
task_id: string;
|
||||
task_name: string | null;
|
||||
quantity: number;
|
||||
pooled: boolean;
|
||||
}>;
|
||||
}
|
||||
type SortMode = "due_date" | "object" | "type" | "task_name" | "area" | "assigned_user" | "group";
|
||||
type ObjectSortMode = "alphabetical" | "due_soonest" | "task_count";
|
||||
type GroupByMode = "none" | "area" | "group" | "user";
|
||||
@@ -95,6 +120,8 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
@state() private _objects: MaintenanceObjectResponse[] = [];
|
||||
@state() private _stats: StatisticsResponse | null = null;
|
||||
@state() private _view: View = "overview";
|
||||
// #130: rows of the all-parts view; null until first load.
|
||||
@state() private _allParts: PartsOverviewRow[] | null = null;
|
||||
@state() private _selectedEntryId: string | null = null;
|
||||
@state() private _selectedTaskId: string | null = null;
|
||||
@state() private _filterStatus = "";
|
||||
@@ -813,6 +840,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
this._selectedEntryId = s.msp_entry || null;
|
||||
this._selectedTaskId = s.msp_task || null;
|
||||
this._moreMenuOpen = false;
|
||||
if (s.msp_view === "all_parts") void this._loadAllParts();
|
||||
if (s.msp_view === "task" && s.msp_entry && s.msp_task) {
|
||||
this._historyFilter = null;
|
||||
const task = this._getTask(s.msp_entry, s.msp_task);
|
||||
@@ -839,6 +867,27 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
this._scrollContentToTop();
|
||||
}
|
||||
|
||||
// #130: instance-wide parts inventory, sibling view of All objects.
|
||||
private _showAllParts(): void {
|
||||
this._pushPanelState("all_parts");
|
||||
this._view = "all_parts";
|
||||
this._selectedEntryId = null;
|
||||
this._selectedTaskId = null;
|
||||
this._scrollContentToTop();
|
||||
void this._loadAllParts();
|
||||
}
|
||||
|
||||
private async _loadAllParts(): Promise<void> {
|
||||
try {
|
||||
const result = await this.hass.connection.sendMessagePromise({
|
||||
type: "maintenance_supporter/parts/overview",
|
||||
}) as { parts: PartsOverviewRow[] };
|
||||
this._allParts = result.parts || [];
|
||||
} catch {
|
||||
this._allParts = [];
|
||||
}
|
||||
}
|
||||
|
||||
/** v2.1.0 (Discussion #49 — @byoung79): tap a KPI value to auto-filter
|
||||
* the task list. Empty string clears the filter (used by "Tasks" KPI). */
|
||||
private _filterByStatus(status: string): void {
|
||||
@@ -1990,6 +2039,8 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
? this._renderOverview()
|
||||
: this._view === "all_objects"
|
||||
? this._renderAllObjects()
|
||||
: this._view === "all_parts"
|
||||
? this._renderAllParts()
|
||||
: this._view === "object"
|
||||
? this._renderObjectDetail()
|
||||
: this._renderTaskDetail()}
|
||||
@@ -2703,6 +2754,9 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
<ha-icon icon="mdi:arrow-left"></ha-icon>
|
||||
</ha-icon-button>
|
||||
<span>${t("all_objects", L)}</span>
|
||||
<button class="sibling-view-chip" @click=${() => this._showAllParts()}>
|
||||
<ha-icon icon="mdi:package-variant-closed"></ha-icon> ${t("all_parts", L)}
|
||||
</button>
|
||||
</div>
|
||||
<div class="filter-bar">
|
||||
<label class="filter-field">
|
||||
@@ -2792,6 +2846,106 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
localStorage.setItem(LS_KEYS.objectView, mode);
|
||||
}
|
||||
|
||||
// ── #130: instance-wide parts overview ────────────────────────────────────
|
||||
|
||||
private _renderAllParts() {
|
||||
const L = this._lang;
|
||||
const rows = this._allParts;
|
||||
const currency = this._budget?.currency_symbol || "";
|
||||
return html`
|
||||
<div class="breadcrumb">
|
||||
<ha-icon-button @click=${() => this._showAllObjects()}>
|
||||
<ha-icon icon="mdi:arrow-left"></ha-icon>
|
||||
</ha-icon-button>
|
||||
<span>${t("all_parts", L)}</span>
|
||||
<button class="sibling-view-chip" @click=${() => this._showAllObjects()}>
|
||||
<ha-icon icon="mdi:devices"></ha-icon> ${t("all_objects", L)}
|
||||
</button>
|
||||
</div>
|
||||
<div class="filter-bar">
|
||||
<ha-button appearance="plain" @click=${() => this._exportPartsCsv()}>
|
||||
<ha-icon icon="mdi:file-delimited-outline"></ha-icon> ${t("settings_export_csv", L)}
|
||||
</ha-button>
|
||||
</div>
|
||||
${rows === null
|
||||
? html`<div class="empty-state">…</div>`
|
||||
: rows.length === 0
|
||||
? html`<div class="empty-state">${t("parts_section", L)}: 0</div>`
|
||||
: html`
|
||||
<div class="objects-table-wrap">
|
||||
<table class="objects-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>${t("part_name", L)}</th>
|
||||
<th>${t("object", L)}</th>
|
||||
<th>${t("part_stock", L)}</th>
|
||||
<th>${t("part_reorder_threshold", L)}</th>
|
||||
<th>${t("part_cost", L)}</th>
|
||||
<th>${t("part_storage_location", L)}</th>
|
||||
<th>${t("parts_used_by", L)}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${rows.map((row) => html`
|
||||
<tr class="objects-table-row" @click=${() => this._showObject(row.entry_id)}>
|
||||
<td>
|
||||
<span class="objects-table-name">${row.name}</span>
|
||||
${row.low
|
||||
? html`<ha-icon class="part-low-icon" icon="mdi:cart-arrow-down"
|
||||
title="${t("part_reorder_threshold", L)}: ${row.reorder_threshold}"></ha-icon>`
|
||||
: nothing}
|
||||
</td>
|
||||
<td>${row.object_name || "—"}</td>
|
||||
<td>${row.stock !== null ? `${row.stock}${row.unit ? ` ${row.unit}` : ""}` : "—"}</td>
|
||||
<td>${row.reorder_threshold ?? "—"}</td>
|
||||
<td>${row.cost != null ? `${row.cost} ${currency}`.trim() : "—"}</td>
|
||||
<td>${row.storage_location || "—"}</td>
|
||||
<td>
|
||||
${row.consumers.length === 0
|
||||
? "—"
|
||||
: row.consumers.map((c) => html`
|
||||
<span
|
||||
class="part-consumer-chip${c.pooled ? " pooled" : ""}"
|
||||
title=${`${c.object_name ?? ""}: ${c.task_name ?? c.task_id} (×${c.quantity})`}
|
||||
>${c.pooled ? `${c.object_name} · ` : ""}${c.task_name ?? c.task_id}</span>
|
||||
`)}
|
||||
</td>
|
||||
</tr>
|
||||
`)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
`}
|
||||
`;
|
||||
}
|
||||
|
||||
/** Client-side CSV of the loaded overview rows (the objects table's CSV is
|
||||
* server-built; the parts rows are already fully materialized here). */
|
||||
private _exportPartsCsv(): void {
|
||||
const rows = this._allParts || [];
|
||||
const esc = (v: unknown): string => {
|
||||
const s = v == null ? "" : String(v);
|
||||
return /[",\n;]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
||||
};
|
||||
const header = ["name", "object", "stock", "unit", "reorder_threshold", "unit_cost", "storage_location", "vendor", "used_by"];
|
||||
const lines = [header.join(",")];
|
||||
for (const row of rows) {
|
||||
lines.push([
|
||||
esc(row.name),
|
||||
esc(row.object_name),
|
||||
esc(row.stock),
|
||||
esc(row.unit),
|
||||
esc(row.reorder_threshold),
|
||||
esc(row.cost),
|
||||
esc(row.storage_location),
|
||||
esc(row.vendor),
|
||||
esc(row.consumers.map((c) => `${c.object_name ?? ""}/${c.task_name ?? c.task_id}×${c.quantity}`).join(" | ")),
|
||||
].join(","));
|
||||
}
|
||||
const ts = new Date().toISOString().slice(0, 10);
|
||||
downloadTextFile(lines.join("\n"), `maintenance_parts_${ts}.csv`, "text/csv;charset=utf-8");
|
||||
}
|
||||
|
||||
// (#67 / Phase 3) Download all objects as a one-row-per-object CSV.
|
||||
private async _exportObjectsCsv(): Promise<void> {
|
||||
try {
|
||||
@@ -3602,6 +3756,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
cost: entry.cost ?? null,
|
||||
duration: entry.duration ?? null,
|
||||
completed_by: entry.completed_by ?? null,
|
||||
used_parts: entry.used_parts ?? null,
|
||||
};
|
||||
this.shadowRoot
|
||||
?.querySelector<MaintenanceHistoryEditDialog>("maintenance-history-edit-dialog")
|
||||
|
||||
@@ -605,6 +605,43 @@ export const panelStyles = css`
|
||||
}
|
||||
.view-toggle-btn ha-icon { --mdc-icon-size: 18px; }
|
||||
|
||||
/* (#130) All-parts view: sibling chip in the breadcrumb + table extras */
|
||||
.sibling-view-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-left: 12px;
|
||||
padding: 4px 10px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 14px;
|
||||
background: none;
|
||||
color: var(--secondary-text-color);
|
||||
font: inherit;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.sibling-view-chip:hover {
|
||||
background: var(--secondary-background-color, rgba(0, 0, 0, 0.04));
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.sibling-view-chip ha-icon { --mdc-icon-size: 16px; }
|
||||
.part-low-icon {
|
||||
--mdc-icon-size: 16px;
|
||||
color: var(--warning-color, #ff9800);
|
||||
vertical-align: middle;
|
||||
margin-left: 6px;
|
||||
}
|
||||
.part-consumer-chip {
|
||||
display: inline-block;
|
||||
margin: 1px 4px 1px 0;
|
||||
padding: 1px 8px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.part-consumer-chip.pooled { border-style: dashed; }
|
||||
|
||||
/* (#67) Objects table (desktop All-Objects view) */
|
||||
.objects-table-wrap {
|
||||
overflow-x: auto;
|
||||
|
||||
@@ -94,6 +94,8 @@ export interface HistoryEntry {
|
||||
photo_doc_id?: string | null;
|
||||
/** v2.20 (#83): recorded value for `reading`-type tasks. */
|
||||
reading_value?: number | null;
|
||||
/** #99/#130: the completion's part consumption (entry_id set for pooled). */
|
||||
used_parts?: Array<{ part_id: string; name?: string; quantity: number; entry_id?: string }> | null;
|
||||
/** v2.37: completion recorded by the system itself (trigger recovered),
|
||||
* not performed by a user in the UI. */
|
||||
auto?: boolean;
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Typ",
|
||||
"sort_task_name": "Název úkolu",
|
||||
"all_objects": "Všechny objekty",
|
||||
"all_parts": "Všechny díly",
|
||||
"tasks_lower": "úkolů",
|
||||
"no_tasks_yet": "Zatím žádné úkoly",
|
||||
"add_first_task": "Přidat první úkol",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Množství doplnění",
|
||||
"part_auto_buy": "Úkol nákupu při nízké zásobě",
|
||||
"part_restock": "Upravit zásobu",
|
||||
"parts_used_by": "Používá",
|
||||
"restock_quantity_label": "Zakoupené množství",
|
||||
"consumes_parts_label": "Spotřebovává díly",
|
||||
"shared_parts_other_objects": "Díly z jiných objektů",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "stav při posledním servisu (volitelné)",
|
||||
"baseline_start_help_edit": "Ponechte prázdné pro zachování stávajícího počítání. Zadaná hodnota počítání znovu ukotví (např. stav při posledním servisu).",
|
||||
"baseline_current_effective": "Aktuálně platná počáteční hodnota: {value}",
|
||||
"runtime_on_states": "Aktivní stavy (oddělené čárkami)",
|
||||
"runtime_on_states": "Aktivní stavy",
|
||||
"runtime_on_states_help": "Stavy počítané jako doba běhu — výchozí: on. Např. mowing, cleaning, printing. Při zvoleném atributu se porovnávají jeho hodnoty.",
|
||||
"setups_target_new": "Vytvořit nový: {name}",
|
||||
"schedule_preview_title": "Nejbližší termíny",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Opgavenavn",
|
||||
"all_objects": "Alle objekter",
|
||||
"all_parts": "Alle dele",
|
||||
"tasks_lower": "opgaver",
|
||||
"no_tasks_yet": "Ingen opgaver endnu",
|
||||
"add_first_task": "Tilføj første opgave",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Genopfyldningsmængde",
|
||||
"part_auto_buy": "Købsopgave ved lav beholdning",
|
||||
"part_restock": "Justér lager",
|
||||
"parts_used_by": "Bruges af",
|
||||
"restock_quantity_label": "Købt mængde",
|
||||
"consumes_parts_label": "Forbruger dele",
|
||||
"shared_parts_other_objects": "Dele fra andre objekter",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "aflæsning ved sidste service (valgfrit)",
|
||||
"baseline_start_help_edit": "Lad feltet stå tomt for at beholde den eksisterende tælling. En indtastet værdi forankrer tællingen på ny (f.eks. aflæsningen ved sidste service).",
|
||||
"baseline_current_effective": "Aktuelt gældende startværdi: {value}",
|
||||
"runtime_on_states": "Aktive tilstande (kommaseparerede)",
|
||||
"runtime_on_states": "Aktive tilstande",
|
||||
"runtime_on_states_help": "Tilstande der tæller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med en valgt attribut sammenlignes dens værdier i stedet.",
|
||||
"setups_target_new": "Opret ny: {name}",
|
||||
"schedule_preview_title": "Kommende datoer",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Typ",
|
||||
"sort_task_name": "Aufgaben-Name",
|
||||
"all_objects": "Alle Objekte",
|
||||
"all_parts": "Alle Teile",
|
||||
"tasks_lower": "Aufgaben",
|
||||
"no_tasks_yet": "Noch keine Aufgaben",
|
||||
"add_first_task": "Erste Aufgabe hinzufügen",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Auffüllmenge",
|
||||
"part_auto_buy": "Kauf-Task bei Niedrigbestand",
|
||||
"part_restock": "Bestand anpassen",
|
||||
"parts_used_by": "Verwendet von",
|
||||
"restock_quantity_label": "Gekaufte Menge",
|
||||
"consumes_parts_label": "Verbraucht Teile",
|
||||
"shared_parts_other_objects": "Teile anderer Objekte",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "Stand beim letzten Service (optional)",
|
||||
"baseline_start_help_edit": "Leer lassen, um die bestehende Zählung zu behalten. Ein eingetragener Wert verankert die Zählung neu (z. B. der Stand beim letzten Service).",
|
||||
"baseline_current_effective": "Aktuell wirksamer Startwert: {value}",
|
||||
"runtime_on_states": "Aktive Zustände (kommagetrennt)",
|
||||
"runtime_on_states": "Aktive Zustände",
|
||||
"runtime_on_states_help": "Zustände, die als Laufzeit zählen — Standard: on. Z. B. mowing, cleaning, printing. Bei gewähltem Attribut werden dessen Werte verglichen.",
|
||||
"setups_target_new": "Neu anlegen: {name}",
|
||||
"schedule_preview_title": "Nächste Termine",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Task name",
|
||||
"all_objects": "All objects",
|
||||
"all_parts": "All parts",
|
||||
"tasks_lower": "tasks",
|
||||
"no_tasks_yet": "No tasks yet",
|
||||
"add_first_task": "Add first task",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "Restock quantity",
|
||||
"part_auto_buy": "Auto-create buy task when low",
|
||||
"part_restock": "Adjust stock",
|
||||
"parts_used_by": "Used by",
|
||||
"restock_quantity_label": "Quantity bought",
|
||||
"consumes_parts_label": "Consumes parts",
|
||||
"shared_parts_other_objects": "Parts from other objects",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "reading at last service (optional)",
|
||||
"baseline_start_help_edit": "Leave empty to keep the existing counting. Entering a value re-anchors the counting (e.g. the reading at the last service).",
|
||||
"baseline_current_effective": "Currently effective start value: {value}",
|
||||
"runtime_on_states": "Active states (comma-separated)",
|
||||
"runtime_on_states": "Active states",
|
||||
"runtime_on_states_help": "States that count as running — default: on. E.g. mowing, cleaning, printing. With an attribute selected, its values are matched instead.",
|
||||
"setups_target_new": "Create new: {name}",
|
||||
"schedule_preview_title": "Next dates",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Tipo",
|
||||
"sort_task_name": "Nombre de la tarea",
|
||||
"all_objects": "Todos los objetos",
|
||||
"all_parts": "Todas las piezas",
|
||||
"tasks_lower": "tareas",
|
||||
"no_tasks_yet": "Aún no hay tareas",
|
||||
"add_first_task": "Agregar primera tarea",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Cantidad de reposición",
|
||||
"part_auto_buy": "Crear tarea de compra si bajo",
|
||||
"part_restock": "Ajustar existencias",
|
||||
"parts_used_by": "Usado por",
|
||||
"restock_quantity_label": "Cantidad comprada",
|
||||
"consumes_parts_label": "Consume piezas",
|
||||
"shared_parts_other_objects": "Piezas de otros objetos",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "lectura en el último mantenimiento (opcional)",
|
||||
"baseline_start_help_edit": "Déjalo vacío para mantener el conteo actual. Un valor introducido reancla el conteo (p. ej., la lectura del último mantenimiento).",
|
||||
"baseline_current_effective": "Valor inicial vigente: {value}",
|
||||
"runtime_on_states": "Estados activos (separados por comas)",
|
||||
"runtime_on_states": "Estados activos",
|
||||
"runtime_on_states_help": "Estados que cuentan como en funcionamiento — predeterminado: on. P. ej. mowing, cleaning, printing. Con un atributo seleccionado se comparan sus valores.",
|
||||
"setups_target_new": "Crear nuevo: {name}",
|
||||
"schedule_preview_title": "Próximas fechas",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Tyyppi",
|
||||
"sort_task_name": "Tehtävän nimi",
|
||||
"all_objects": "Kaikki kohteet",
|
||||
"all_parts": "Kaikki osat",
|
||||
"tasks_lower": "tehtävää",
|
||||
"no_tasks_yet": "Ei vielä tehtäviä",
|
||||
"add_first_task": "Lisää ensimmäinen tehtävä",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Täydennysmäärä",
|
||||
"part_auto_buy": "Ostotehtävä kun vähissä",
|
||||
"part_restock": "Muuta varastoa",
|
||||
"parts_used_by": "Käyttäjät",
|
||||
"restock_quantity_label": "Ostettu määrä",
|
||||
"consumes_parts_label": "Kuluttaa osia",
|
||||
"shared_parts_other_objects": "Muiden kohteiden osat",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "lukema viime huollossa (valinnainen)",
|
||||
"baseline_start_help_edit": "Jätä tyhjäksi säilyttääksesi nykyisen laskennan. Syötetty arvo ankkuroi laskennan uudelleen (esim. viimeisimmän huollon lukema).",
|
||||
"baseline_current_effective": "Nyt voimassa oleva aloitusarvo: {value}",
|
||||
"runtime_on_states": "Aktiiviset tilat (pilkuin eroteltuina)",
|
||||
"runtime_on_states": "Aktiiviset tilat",
|
||||
"runtime_on_states_help": "Tilat, jotka lasketaan käyntiajaksi — oletus: on. Esim. mowing, cleaning, printing. Jos attribuutti on valittu, verrataan sen arvoja.",
|
||||
"setups_target_new": "Luo uusi: {name}",
|
||||
"schedule_preview_title": "Seuraavat päivämäärät",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Nom de la tâche",
|
||||
"all_objects": "Tous les objets",
|
||||
"all_parts": "Toutes les pièces",
|
||||
"tasks_lower": "tâches",
|
||||
"no_tasks_yet": "Pas encore de tâches",
|
||||
"add_first_task": "Ajouter la première tâche",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Quantité de réappro",
|
||||
"part_auto_buy": "Tâche d'achat auto si bas",
|
||||
"part_restock": "Ajuster le stock",
|
||||
"parts_used_by": "Utilisé par",
|
||||
"restock_quantity_label": "Quantité achetée",
|
||||
"consumes_parts_label": "Consomme des pièces",
|
||||
"shared_parts_other_objects": "Pièces d'autres objets",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "relevé au dernier entretien (facultatif)",
|
||||
"baseline_start_help_edit": "Laissez vide pour conserver le comptage existant. Une valeur saisie réancre le comptage (p. ex. le relevé du dernier entretien).",
|
||||
"baseline_current_effective": "Valeur de départ actuellement en vigueur : {value}",
|
||||
"runtime_on_states": "États actifs (séparés par des virgules)",
|
||||
"runtime_on_states": "États actifs",
|
||||
"runtime_on_states_help": "États comptés comme en fonctionnement — par défaut : on. P. ex. mowing, cleaning, printing. Si un attribut est sélectionné, ce sont ses valeurs qui sont comparées.",
|
||||
"setups_target_new": "Créer : {name}",
|
||||
"schedule_preview_title": "Prochaines échéances",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "प्रकार",
|
||||
"sort_task_name": "कार्य का नाम",
|
||||
"all_objects": "सभी वस्तुएँ",
|
||||
"all_parts": "सभी पुर्ज़े",
|
||||
"tasks_lower": "कार्य",
|
||||
"no_tasks_yet": "अभी कोई कार्य नहीं",
|
||||
"add_first_task": "पहला कार्य जोड़ें",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "पुनःपूर्ति मात्रा",
|
||||
"part_auto_buy": "कम होने पर खरीद कार्य",
|
||||
"part_restock": "स्टॉक समायोजित करें",
|
||||
"parts_used_by": "द्वारा उपयोग",
|
||||
"restock_quantity_label": "खरीदी गई मात्रा",
|
||||
"consumes_parts_label": "पुर्ज़े खपत",
|
||||
"shared_parts_other_objects": "अन्य वस्तुओं के पुर्ज़े",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "पिछली सर्विस पर रीडिंग (वैकल्पिक)",
|
||||
"baseline_start_help_edit": "मौजूदा गिनती बनाए रखने के लिए खाली छोड़ें। दर्ज किया गया मान गिनती को फिर से स्थिर करता है (जैसे पिछली सर्विस के समय की रीडिंग)।",
|
||||
"baseline_current_effective": "वर्तमान में प्रभावी प्रारंभिक मान: {value}",
|
||||
"runtime_on_states": "सक्रिय अवस्थाएँ (अल्पविराम से अलग)",
|
||||
"runtime_on_states": "सक्रिय अवस्थाएँ",
|
||||
"runtime_on_states_help": "वे अवस्थाएँ जो चालू समय में गिनी जाती हैं — डिफ़ॉल्ट: on। जैसे mowing, cleaning, printing। विशेषता चुनी होने पर उसकी मानों की तुलना होती है।",
|
||||
"setups_target_new": "नया बनाएँ: {name}",
|
||||
"schedule_preview_title": "अगली तिथियाँ",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Típus",
|
||||
"sort_task_name": "Feladat neve",
|
||||
"all_objects": "Minden objektum",
|
||||
"all_parts": "Összes alkatrész",
|
||||
"tasks_lower": "feladat",
|
||||
"no_tasks_yet": "Még nincs feladat",
|
||||
"add_first_task": "Első feladat hozzáadása",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "Feltöltési mennyiség",
|
||||
"part_auto_buy": "Vásárlási feladat automatikus létrehozása, ha kevés van",
|
||||
"part_restock": "Készlet módosítása",
|
||||
"parts_used_by": "Használja",
|
||||
"restock_quantity_label": "Vásárolt mennyiség",
|
||||
"consumes_parts_label": "Felhasznált alkatrészek",
|
||||
"shared_parts_other_objects": "Más objektumok alkatrészei",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "érték az utolsó szerviznél (opcionális)",
|
||||
"baseline_start_help_edit": "Üresen hagyva a meglévő számlálás marad. Érték megadása újrahorgonyozza a számlálást (pl. az utolsó szerviz leolvasott értéke).",
|
||||
"baseline_current_effective": "Jelenleg érvényes kezdőérték: {value}",
|
||||
"runtime_on_states": "Aktív állapotok (vesszővel elválasztva)",
|
||||
"runtime_on_states": "Aktív állapotok",
|
||||
"runtime_on_states_help": "Működésként számító állapotok — alapértelmezés: on. Pl. mowing, cleaning, printing. Attribútum kiválasztásakor annak értékei számítanak.",
|
||||
"setups_target_new": "Új létrehozása: {name}",
|
||||
"schedule_preview_title": "Következő dátumok",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Tipo",
|
||||
"sort_task_name": "Nome attività",
|
||||
"all_objects": "Tutti gli oggetti",
|
||||
"all_parts": "Tutti i ricambi",
|
||||
"tasks_lower": "attività",
|
||||
"no_tasks_yet": "Nessuna attività",
|
||||
"add_first_task": "Aggiungi prima attività",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Quantità di riordino",
|
||||
"part_auto_buy": "Task d'acquisto se scarso",
|
||||
"part_restock": "Correggi scorta",
|
||||
"parts_used_by": "Usato da",
|
||||
"restock_quantity_label": "Quantità acquistata",
|
||||
"consumes_parts_label": "Consuma ricambi",
|
||||
"shared_parts_other_objects": "Ricambi di altri oggetti",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "lettura all'ultima manutenzione (facoltativo)",
|
||||
"baseline_start_help_edit": "Lascia vuoto per mantenere il conteggio esistente. Un valore inserito riancora il conteggio (ad es. la lettura dell'ultima manutenzione).",
|
||||
"baseline_current_effective": "Valore iniziale attualmente in vigore: {value}",
|
||||
"runtime_on_states": "Stati attivi (separati da virgole)",
|
||||
"runtime_on_states": "Stati attivi",
|
||||
"runtime_on_states_help": "Stati che contano come in funzione — predefinito: on. Ad es. mowing, cleaning, printing. Con un attributo selezionato vengono confrontati i suoi valori.",
|
||||
"setups_target_new": "Crea nuovo: {name}",
|
||||
"schedule_preview_title": "Prossime date",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "種別",
|
||||
"sort_task_name": "タスク名",
|
||||
"all_objects": "すべての対象",
|
||||
"all_parts": "すべての部品",
|
||||
"tasks_lower": "タスク",
|
||||
"no_tasks_yet": "タスクがまだありません",
|
||||
"add_first_task": "最初のタスクを追加",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "補充数量",
|
||||
"part_auto_buy": "在庫少で購入タスク",
|
||||
"part_restock": "在庫を調整",
|
||||
"parts_used_by": "使用タスク",
|
||||
"restock_quantity_label": "購入数量",
|
||||
"consumes_parts_label": "部品を消費",
|
||||
"shared_parts_other_objects": "他の対象の部品",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "前回整備時の値(任意)",
|
||||
"baseline_start_help_edit": "空欄のままにすると現在のカウントを維持します。値を入力するとカウントの起点を再設定します(例:前回整備時の値)。",
|
||||
"baseline_current_effective": "現在有効な開始値:{value}",
|
||||
"runtime_on_states": "稼働中とみなす状態(カンマ区切り)",
|
||||
"runtime_on_states": "稼働中とみなす状態",
|
||||
"runtime_on_states_help": "稼働時間として数える状態 — 既定値:on。例:mowing, cleaning, printing。属性を選択している場合はその値が比較されます。",
|
||||
"setups_target_new": "新規作成:{name}",
|
||||
"schedule_preview_title": "次回の予定日",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "유형",
|
||||
"sort_task_name": "작업 이름",
|
||||
"all_objects": "모든 객체",
|
||||
"all_parts": "모든 부품",
|
||||
"tasks_lower": "작업",
|
||||
"no_tasks_yet": "아직 작업 없음",
|
||||
"add_first_task": "첫 작업 추가",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "보충 수량",
|
||||
"part_auto_buy": "재고 부족 시 구매 작업 자동 생성",
|
||||
"part_restock": "재고 조정",
|
||||
"parts_used_by": "사용처",
|
||||
"restock_quantity_label": "구매 수량",
|
||||
"consumes_parts_label": "사용하는 부품",
|
||||
"shared_parts_other_objects": "다른 객체의 부품",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "마지막 정비 시점의 값 (선택)",
|
||||
"baseline_start_help_edit": "비워두면 기존 계수를 유지합니다. 값을 입력하면 계수 기준이 다시 설정됩니다 (예: 마지막 정비 시점의 값).",
|
||||
"baseline_current_effective": "현재 적용 중인 시작 값: {value}",
|
||||
"runtime_on_states": "활성 상태 (쉼표로 구분)",
|
||||
"runtime_on_states": "활성 상태",
|
||||
"runtime_on_states_help": "가동 중으로 계산할 상태입니다 — 기본값: on. 예: mowing, cleaning, printing. 속성을 선택한 경우 해당 속성 값과 비교합니다.",
|
||||
"setups_target_new": "새로 만들기: {name}",
|
||||
"schedule_preview_title": "다음 예정일",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Oppgavenavn",
|
||||
"all_objects": "Alle objekter",
|
||||
"all_parts": "Alle deler",
|
||||
"tasks_lower": "oppgaver",
|
||||
"no_tasks_yet": "Ingen oppgaver ennå",
|
||||
"add_first_task": "Legg til første oppgave",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Påfyllingsmengde",
|
||||
"part_auto_buy": "Kjøpsoppgave ved lavt lager",
|
||||
"part_restock": "Juster lager",
|
||||
"parts_used_by": "Brukes av",
|
||||
"restock_quantity_label": "Kjøpt mengde",
|
||||
"consumes_parts_label": "Forbruker deler",
|
||||
"shared_parts_other_objects": "Deler fra andre objekter",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "avlesning ved forrige service (valgfritt)",
|
||||
"baseline_start_help_edit": "La stå tomt for å beholde den eksisterende tellingen. En angitt verdi forankrer tellingen på nytt (f.eks. avlesningen ved forrige service).",
|
||||
"baseline_current_effective": "Gjeldende startverdi: {value}",
|
||||
"runtime_on_states": "Aktive tilstander (kommaseparert)",
|
||||
"runtime_on_states": "Aktive tilstander",
|
||||
"runtime_on_states_help": "Tilstander som teller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med et valgt attributt sammenlignes verdiene dets i stedet.",
|
||||
"setups_target_new": "Opprett ny: {name}",
|
||||
"schedule_preview_title": "Kommende datoer",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Type",
|
||||
"sort_task_name": "Taaknaam",
|
||||
"all_objects": "Alle objecten",
|
||||
"all_parts": "Alle onderdelen",
|
||||
"tasks_lower": "taken",
|
||||
"no_tasks_yet": "Nog geen taken",
|
||||
"add_first_task": "Eerste taak toevoegen",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Aanvulhoeveelheid",
|
||||
"part_auto_buy": "Kooptaak bij lage voorraad",
|
||||
"part_restock": "Voorraad aanpassen",
|
||||
"parts_used_by": "Gebruikt door",
|
||||
"restock_quantity_label": "Gekochte hoeveelheid",
|
||||
"consumes_parts_label": "Verbruikt onderdelen",
|
||||
"shared_parts_other_objects": "Onderdelen van andere objecten",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "stand bij laatste onderhoud (optioneel)",
|
||||
"baseline_start_help_edit": "Laat leeg om de bestaande telling te behouden. Een ingevulde waarde verankert de telling opnieuw (bijv. de stand bij de laatste servicebeurt).",
|
||||
"baseline_current_effective": "Momenteel geldende startwaarde: {value}",
|
||||
"runtime_on_states": "Actieve statussen (kommagescheiden)",
|
||||
"runtime_on_states": "Actieve statussen",
|
||||
"runtime_on_states_help": "Statussen die als draaitijd tellen — standaard: on. Bijv. mowing, cleaning, printing. Met een geselecteerd attribuut worden de waarden daarvan vergeleken.",
|
||||
"setups_target_new": "Nieuw aanmaken: {name}",
|
||||
"schedule_preview_title": "Volgende data",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Typ",
|
||||
"sort_task_name": "Nazwa zadania",
|
||||
"all_objects": "Wszystkie obiekty",
|
||||
"all_parts": "Wszystkie części",
|
||||
"tasks_lower": "zadań",
|
||||
"no_tasks_yet": "Jeszcze brak zadań",
|
||||
"add_first_task": "Dodaj pierwsze zadanie",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Ilość uzupełnienia",
|
||||
"part_auto_buy": "Zadanie zakupu przy niskim stanie",
|
||||
"part_restock": "Koryguj stan",
|
||||
"parts_used_by": "Używane przez",
|
||||
"restock_quantity_label": "Kupiona ilość",
|
||||
"consumes_parts_label": "Zużywa części",
|
||||
"shared_parts_other_objects": "Części z innych obiektów",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "stan przy ostatnim serwisie (opcjonalnie)",
|
||||
"baseline_start_help_edit": "Pozostaw puste, aby zachować dotychczasowe liczenie. Wpisana wartość zakotwicza liczenie na nowo (np. stan przy ostatnim serwisie).",
|
||||
"baseline_current_effective": "Obecnie obowiązująca wartość początkowa: {value}",
|
||||
"runtime_on_states": "Stany aktywne (rozdzielone przecinkami)",
|
||||
"runtime_on_states": "Stany aktywne",
|
||||
"runtime_on_states_help": "Stany liczone jako czas pracy — domyślnie: on. Np. mowing, cleaning, printing. Przy wybranym atrybucie porównywane są jego wartości.",
|
||||
"setups_target_new": "Utwórz nowy: {name}",
|
||||
"schedule_preview_title": "Najbliższe terminy",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Tipo",
|
||||
"sort_task_name": "Nome da tarefa",
|
||||
"all_objects": "Todos os objetos",
|
||||
"all_parts": "Todas as peças",
|
||||
"tasks_lower": "tarefas",
|
||||
"no_tasks_yet": "Ainda sem tarefas",
|
||||
"add_first_task": "Adicionar a primeira tarefa",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "Quantidade de reposição",
|
||||
"part_auto_buy": "Criar tarefa de compra automaticamente quando estiver baixo",
|
||||
"part_restock": "Ajustar estoque",
|
||||
"parts_used_by": "Usado por",
|
||||
"restock_quantity_label": "Quantidade comprada",
|
||||
"consumes_parts_label": "Consome peças",
|
||||
"shared_parts_other_objects": "Peças de outros objetos",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
||||
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Informar um valor reancora a contagem (ex.: a leitura da última manutenção).",
|
||||
"baseline_current_effective": "Valor inicial efetivo atual: {value}",
|
||||
"runtime_on_states": "Estados ativos (separados por vírgula)",
|
||||
"runtime_on_states": "Estados ativos",
|
||||
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. Ex.: mowing, cleaning, printing. Com um atributo selecionado, os valores dele são comparados.",
|
||||
"setups_target_new": "Criar novo: {name}",
|
||||
"schedule_preview_title": "Próximas datas",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Tipo",
|
||||
"sort_task_name": "Nome da tarefa",
|
||||
"all_objects": "Todos os objetos",
|
||||
"all_parts": "Todas as peças",
|
||||
"tasks_lower": "tarefas",
|
||||
"no_tasks_yet": "Ainda sem tarefas",
|
||||
"add_first_task": "Adicionar primeira tarefa",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Quantidade de reposição",
|
||||
"part_auto_buy": "Tarefa de compra se baixo",
|
||||
"part_restock": "Ajustar estoque",
|
||||
"parts_used_by": "Usado por",
|
||||
"restock_quantity_label": "Quantidade comprada",
|
||||
"consumes_parts_label": "Consome peças",
|
||||
"shared_parts_other_objects": "Peças de outros objetos",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
||||
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Um valor introduzido reancora a contagem (p. ex., a leitura da última manutenção).",
|
||||
"baseline_current_effective": "Valor inicial atualmente em vigor: {value}",
|
||||
"runtime_on_states": "Estados ativos (separados por vírgulas)",
|
||||
"runtime_on_states": "Estados ativos",
|
||||
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. P. ex. mowing, cleaning, printing. Com um atributo selecionado, são comparados os valores dele.",
|
||||
"setups_target_new": "Criar novo: {name}",
|
||||
"schedule_preview_title": "Próximas datas",
|
||||
|
||||
@@ -176,6 +176,7 @@
|
||||
"sort_type": "Тип",
|
||||
"sort_task_name": "Имя задачи",
|
||||
"all_objects": "Все объекты",
|
||||
"all_parts": "Все детали",
|
||||
"tasks_lower": "задач",
|
||||
"no_tasks_yet": "Пока нет задач",
|
||||
"add_first_task": "Добавить первую задачу",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Количество пополнения",
|
||||
"part_auto_buy": "Задача покупки при малом запасе",
|
||||
"part_restock": "Изменить запас",
|
||||
"parts_used_by": "Используется",
|
||||
"restock_quantity_label": "Куплено, шт.",
|
||||
"consumes_parts_label": "Расходует детали",
|
||||
"shared_parts_other_objects": "Детали других объектов",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "показание при последнем обслуживании (необязательно)",
|
||||
"baseline_start_help_edit": "Оставьте пустым, чтобы сохранить текущий отсчёт. Введённое значение заново привязывает отсчёт (например, показание при последнем обслуживании).",
|
||||
"baseline_current_effective": "Действующее начальное значение: {value}",
|
||||
"runtime_on_states": "Активные состояния (через запятую)",
|
||||
"runtime_on_states": "Активные состояния",
|
||||
"runtime_on_states_help": "Состояния, засчитываемые как работа — по умолчанию: on. Напр. mowing, cleaning, printing. Если выбран атрибут, сравниваются его значения.",
|
||||
"setups_target_new": "Создать новый: {name}",
|
||||
"schedule_preview_title": "Ближайшие даты",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Typ",
|
||||
"sort_task_name": "Uppgiftsnamn",
|
||||
"all_objects": "Alla objekt",
|
||||
"all_parts": "Alla delar",
|
||||
"tasks_lower": "uppgifter",
|
||||
"no_tasks_yet": "Inga uppgifter ännu",
|
||||
"add_first_task": "Lägg till första uppgift",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Påfyllningsantal",
|
||||
"part_auto_buy": "Köpuppgift vid lågt lager",
|
||||
"part_restock": "Justera lager",
|
||||
"parts_used_by": "Används av",
|
||||
"restock_quantity_label": "Köpt antal",
|
||||
"consumes_parts_label": "Förbrukar delar",
|
||||
"shared_parts_other_objects": "Delar från andra objekt",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "mätarställning vid senaste service (valfritt)",
|
||||
"baseline_start_help_edit": "Lämna tomt för att behålla den befintliga räkningen. Ett angivet värde förankrar räkningen på nytt (t.ex. mätarställningen vid senaste servicen).",
|
||||
"baseline_current_effective": "Nu gällande startvärde: {value}",
|
||||
"runtime_on_states": "Aktiva tillstånd (kommaseparerade)",
|
||||
"runtime_on_states": "Aktiva tillstånd",
|
||||
"runtime_on_states_help": "Tillstånd som räknas som drifttid — standard: on. T.ex. mowing, cleaning, printing. Med ett valt attribut jämförs dess värden i stället.",
|
||||
"setups_target_new": "Skapa ny: {name}",
|
||||
"schedule_preview_title": "Kommande datum",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "Tür",
|
||||
"sort_task_name": "Görev adı",
|
||||
"all_objects": "Tüm nesneler",
|
||||
"all_parts": "Tüm parçalar",
|
||||
"tasks_lower": "görev",
|
||||
"no_tasks_yet": "Henüz görev yok",
|
||||
"add_first_task": "İlk görevi ekle",
|
||||
@@ -742,6 +743,7 @@
|
||||
"part_restock_quantity": "Stok yenileme miktarı",
|
||||
"part_auto_buy": "Azaldığında otomatik satın alma görevi oluştur",
|
||||
"part_restock": "Stoku ayarla",
|
||||
"parts_used_by": "Kullanan",
|
||||
"restock_quantity_label": "Satın alınan miktar",
|
||||
"consumes_parts_label": "Parça tüketir",
|
||||
"shared_parts_other_objects": "Diğer nesnelerin parçaları",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "son servisteki okuma (isteğe bağlı)",
|
||||
"baseline_start_help_edit": "Mevcut sayımı korumak için boş bırakın. Bir değer girmek sayımı yeniden sabitler (örn. son servisteki okuma).",
|
||||
"baseline_current_effective": "Şu anda geçerli başlangıç değeri: {value}",
|
||||
"runtime_on_states": "Etkin durumlar (virgülle ayrılmış)",
|
||||
"runtime_on_states": "Etkin durumlar",
|
||||
"runtime_on_states_help": "Çalışıyor sayılan durumlar — varsayılan: on. Örn. mowing, cleaning, printing. Bir öznitelik seçiliyse onun değerleri eşleştirilir.",
|
||||
"setups_target_new": "Yeni oluştur: {name}",
|
||||
"schedule_preview_title": "Sonraki tarihler",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"sort_type": "Тип",
|
||||
"sort_task_name": "Назва завдання",
|
||||
"all_objects": "Всі об'єкти",
|
||||
"all_parts": "Усі деталі",
|
||||
"tasks_lower": "завдань",
|
||||
"no_tasks_yet": "Завдань ще немає",
|
||||
"add_first_task": "Додати перше завдання",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "Кількість поповнення",
|
||||
"part_auto_buy": "Завдання купівлі при малому запасі",
|
||||
"part_restock": "Змінити запас",
|
||||
"parts_used_by": "Використовується",
|
||||
"restock_quantity_label": "Куплена кількість",
|
||||
"consumes_parts_label": "Витрачає деталі",
|
||||
"shared_parts_other_objects": "Деталі інших об'єктів",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "показання під час останнього обслуговування (необов'язково)",
|
||||
"baseline_start_help_edit": "Залиште порожнім, щоб зберегти поточний відлік. Введене значення заново прив'язує відлік (наприклад, показання під час останнього обслуговування).",
|
||||
"baseline_current_effective": "Чинне початкове значення: {value}",
|
||||
"runtime_on_states": "Активні стани (через кому)",
|
||||
"runtime_on_states": "Активні стани",
|
||||
"runtime_on_states_help": "Стани, що зараховуються як робота — типово: on. Напр. mowing, cleaning, printing. Якщо вибрано атрибут, порівнюються його значення.",
|
||||
"setups_target_new": "Створити новий: {name}",
|
||||
"schedule_preview_title": "Найближчі дати",
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"sort_type": "类型",
|
||||
"sort_task_name": "任务名称",
|
||||
"all_objects": "所有维护项",
|
||||
"all_parts": "所有配件",
|
||||
"tasks_lower": "任务",
|
||||
"no_tasks_yet": "尚无任务",
|
||||
"add_first_task": "添加首个任务",
|
||||
@@ -736,6 +737,7 @@
|
||||
"part_restock_quantity": "补货数量",
|
||||
"part_auto_buy": "库存低时自动建购买任务",
|
||||
"part_restock": "调整库存",
|
||||
"parts_used_by": "使用于",
|
||||
"restock_quantity_label": "购买数量",
|
||||
"consumes_parts_label": "消耗配件",
|
||||
"shared_parts_other_objects": "其他设备的配件",
|
||||
@@ -800,7 +802,7 @@
|
||||
"setups_baseline_hint": "上次保养时的读数(可选)",
|
||||
"baseline_start_help_edit": "留空以保留现有计数。填写数值会重新锚定计数(例如上次保养时的读数)。",
|
||||
"baseline_current_effective": "当前生效的起始读数:{value}",
|
||||
"runtime_on_states": "活动状态(逗号分隔)",
|
||||
"runtime_on_states": "活动状态",
|
||||
"runtime_on_states_help": "计入运行时间的状态 — 默认:on。例如 mowing、cleaning、printing。选择了属性时将比较该属性的值。",
|
||||
"setups_target_new": "新建:{name}",
|
||||
"schedule_preview_title": "下次日期",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
var it=Object.defineProperty;var lt=Object.getOwnPropertyDescriptor;var x=(a,e,t,o)=>{for(var r=o>1?void 0:o?lt(e,t):e,n=a.length-1,s;n>=0;n--)(s=a[n])&&(r=(o?s(e,t,r):s(r))||r);return o&&r&&it(e,t,r),r};var ee=globalThis,te=ee.ShadowRoot&&(ee.ShadyCSS===void 0||ee.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,de=Symbol(),Se=new WeakMap,q=class{constructor(e,t,o){if(this._$cssResult$=!0,o!==de)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o,t=this.t;if(te&&e===void 0){let o=t!==void 0&&t.length===1;o&&(e=Se.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),o&&Se.set(t,e))}return e}toString(){return this.cssText}},$e=a=>new q(typeof a=="string"?a:a+"",void 0,de),k=(a,...e)=>{let t=a.length===1?a[0]:e.reduce((o,r,n)=>o+(s=>{if(s._$cssResult$===!0)return s.cssText;if(typeof s=="number")return s;throw Error("Value passed to 'css' function must be a 'css' function result: "+s+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(r)+a[n+1],a[0]);return new q(t,a,de)},Ae=(a,e)=>{if(te)a.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of e){let o=document.createElement("style"),r=ee.litNonce;r!==void 0&&o.setAttribute("nonce",r),o.textContent=t.cssText,a.appendChild(o)}},pe=te?a=>a:a=>a instanceof CSSStyleSheet?(e=>{let t="";for(let o of e.cssRules)t+=o.cssText;return $e(t)})(a):a;var{is:ct,defineProperty:dt,getOwnPropertyDescriptor:pt,getOwnPropertyNames:ut,getOwnPropertySymbols:_t,getPrototypeOf:ht}=Object,oe=globalThis,je=oe.trustedTypes,gt=je?je.emptyScript:"",ft=oe.reactiveElementPolyfillSupport,F=(a,e)=>a,B={toAttribute(a,e){switch(e){case Boolean:a=a?gt:null;break;case Object:case Array:a=a==null?a:JSON.stringify(a)}return a},fromAttribute(a,e){let t=a;switch(e){case Boolean:t=a!==null;break;case Number:t=a===null?null:Number(a);break;case Object:case Array:try{t=JSON.parse(a)}catch{t=null}}return t}},re=(a,e)=>!ct(a,e),Ee={attribute:!0,type:String,converter:B,reflect:!1,useDefault:!1,hasChanged:re};Symbol.metadata??=Symbol("metadata"),oe.litPropertyMetadata??=new WeakMap;var S=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=Ee){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){let o=Symbol(),r=this.getPropertyDescriptor(e,o,t);r!==void 0&&dt(this.prototype,e,r)}}static getPropertyDescriptor(e,t,o){let{get:r,set:n}=pt(this.prototype,e)??{get(){return this[t]},set(s){this[t]=s}};return{get:r,set(s){let l=r?.call(this);n?.call(this,s),this.requestUpdate(e,l,o)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??Ee}static _$Ei(){if(this.hasOwnProperty(F("elementProperties")))return;let e=ht(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(F("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(F("properties"))){let t=this.properties,o=[...ut(t),..._t(t)];for(let r of o)this.createProperty(r,t[r])}let e=this[Symbol.metadata];if(e!==null){let t=litPropertyMetadata.get(e);if(t!==void 0)for(let[o,r]of t)this.elementProperties.set(o,r)}this._$Eh=new Map;for(let[t,o]of this.elementProperties){let r=this._$Eu(t,o);r!==void 0&&this._$Eh.set(r,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){let t=[];if(Array.isArray(e)){let o=new Set(e.flat(1/0).reverse());for(let r of o)t.unshift(pe(r))}else e!==void 0&&t.push(pe(e));return t}static _$Eu(e,t){let o=t.attribute;return o===!1?void 0:typeof o=="string"?o:typeof e=="string"?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),this.renderRoot!==void 0&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){let e=new Map,t=this.constructor.elementProperties;for(let o of t.keys())this.hasOwnProperty(o)&&(e.set(o,this[o]),delete this[o]);e.size>0&&(this._$Ep=e)}createRenderRoot(){let e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return Ae(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,o){this._$AK(e,o)}_$ET(e,t){let o=this.constructor.elemenLine truncated
|
||||
\f\r]`,W=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,De=/-->/g,Ne=/>/g,E=RegExp(`>|${ue}(?:([^\\s"'>=/]+)(${ue}*=${ue}*(?:[^
|
||||
\f\r"'\`<>=]|("|')|))|$)`,"g"),Re=/'/g,Pe=/"/g,Me=/^(?:script|style|textarea|title)$/i,ve=a=>(e,...t)=>({_$litType$:a,strings:e,values:t}),m=ve(1),It=ve(2),qt=ve(3),D=Symbol.for("lit-noChange"),g=Symbol.for("lit-nothing"),ze=new WeakMap,C=T.createTreeWalker(T,129);function Ue(a,e){if(!ye(a)||!a.hasOwnProperty("raw"))throw Error("invalid template strings array");return Te!==void 0?Te.createHTML(e):e}var yt=(a,e)=>{let t=a.length-1,o=[],r,n=e===2?"<svg>":e===3?"<math>":"",s=W;for(let l=0;l<t;l++){let d=a[l],p,u,c=-1,_=0;for(;_<d.length&&(s.lastIndex=_,u=s.exec(d),u!==null);)_=s.lastIndex,s===W?u[1]==="!--"?s=De:u[1]!==void 0?s=Ne:u[2]!==void 0?(Me.test(u[2])&&(r=RegExp("</"+u[2],"g")),s=E):u[3]!==void 0&&(s=E):s===E?u[0]===">"?(s=r??W,c=-1):u[1]===void 0?c=-2:(c=s.lastIndex-u[2].length,p=u[1],s=u[3]===void 0?E:u[3]==='"'?Pe:Re):s===Pe||s===Re?s=E:s===De||s===Ne?s=W:(s=E,r=void 0);let h=s===E&&a[l+1].startsWith("/>")?" ":"";n+=s===W?d+mt:c>=0?(o.push(p),d.slice(0,c)+Oe+d.slice(c)+A+h):d+A+(c===-2?l:h)}return[Ue(a,n+(a[t]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),o]},V=class a{constructor({strings:e,_$litType$:t},o){let r;this.parts=[];let n=0,s=0,l=e.length-1,d=this.parts,[p,u]=yt(e,t);if(this.el=a.createElement(p,o),C.currentNode=this.el.content,t===2||t===3){let c=this.el.content.firstChild;c.replaceWith(...c.childNodes)}for(;(r=C.nextNode())!==null&&d.length<l;){if(r.nodeType===1){if(r.hasAttributes())for(let c of r.getAttributeNames())if(c.endsWith(Oe)){let _=u[s++],h=r.getAttribute(c).split(A),b=/([.?@])?(.*)/.exec(_);d.push({type:1,index:n,name:b[2],strings:h,ctor:b[1]==="."?he:b[1]==="?"?ge:b[1]==="@"?fe:O}),r.removeAttribute(c)}else c.startsWith(A)&&(d.push({type:6,index:n}),r.removeAttribute(c));if(Me.test(r.tagName)){let c=r.textContent.split(A),_=c.length-1;if(_>0){r.textContent=ae?ae.emptyScript:"";for(let h=0;h<_;h++)r.append(c[h],Y()),C.nextNode(),d.push({type:2,index:++n});r.append(c[_],Y())}}}else if(r.nodeType===8)if(r.data===Le)d.push({type:2,index:n});else{let c=-1;for(;(c=r.data.indexOf(A,c+1))!==-1;)d.push({type:7,index:n}),c+=A.length-1}n++}}static createElement(e,t){let o=T.createElement("template");return o.innerHTML=e,o}};function z(a,e,t=a,o){if(e===D)return e;let r=o!==void 0?t._$Co?.[o]:t._$Cl,n=G(e)?void 0:e._$litDirective$;return r?.constructor!==n&&(r?._$AO?.(!1),n===void 0?r=void 0:(r=new n(a),r._$AT(a,t,o)),o!==void 0?(t._$Co??=[])[o]=r:t._$Cl=r),r!==void 0&&(e=z(a,r._$AS(a,e.values),r,o)),e}var _e=class{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){let{el:{content:t},parts:o}=this._$AD,r=(e?.creationScope??T).importNode(t,!0);C.currentNode=r;let n=C.nextNode(),s=0,l=0,d=o[0];for(;d!==void 0;){if(s===d.index){let p;d.type===2?p=new K(n,n.nextSibling,this,e):d.type===1?p=new d.ctor(n,d.name,d.strings,this,e):d.type===6&&(p=new me(n,this,e)),this._$AV.push(p),d=o[++l]}s!==d?.index&&(n=C.nextNode(),s++)}return C.currentNode=T,r}p(e){let t=0;for(let o of this._$AV)o!==void 0&&(o.strings!==void 0?(o._$AI(e,o,t),t+=o.strings.length-2):o._$AI(e[t])),t++}},K=class a{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,o,r){this.type=2,this._$AH=g,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=o,this.options=r,this._$Cv=r?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode,t=this._$AM;return t!==void 0&&e?.nodeType===11&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,t=this){e=z(this,e,t),G(e)?e===g||e==null||e===""?(this._$AH!==g&&this._$AR(),this._$AH=g):e!==this._$AH&&e!==D&&this._(e):e._$litType$!==void 0?this.$(e):e.nodeType!==void 0?this.T(e):bt(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==g&&G(this._$AH)?this._$AA.nextSibling.data=e:this.T(T.createTextNode(e)),this._$AH=e}$(e){let{values:t,_$litType$:o}=e,r=typeof o=="number"?this._$AC(e):(o.el===void 0&&(o.el=V.createElement(Ue(o.h,o.h[0]),this.options)),o);if(this._$AH?._$AD===r)this._$AH.p(t);else{let n=new _e(r,this),s=n.u(this.options);n.p(t),this.T(s),this._$AH=n}}_$AC(e){let t=ze.get(e.strings);return t===void 0&&ze.set(e.strings,t=new V(e)),t}k(e){ye(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,o,r=0;for(let n of e)r===t.length?t.push(o=new a(this.O(Y()),this.O(Y()),this,this.options)):o=t[r],o._$AI(n),r++;r<t.length&&(this._$AR(o&&o._$AB.nextSibling,r),t.length=r)}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);e!==this._$AB;){let o=Ce(e).nextSibling;Ce(e).remove(),e=o}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e))}},O=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,o,r,n){this.type=1,this._$AH=g,this._$AN=void 0,this.element=e,this.name=t,this._$AM=r,this.options=n,o.length>2||o[0]!==""||o[1]!==""?(this._$AH=Array(o.length-1).fill(new String),this.strings=Line truncated
|
||||
@@ -200,7 +200,7 @@ var it=Object.defineProperty;var lt=Object.getOwnPropertyDescriptor;var x=(a,e,t
|
||||
}
|
||||
`;var Ge={maintenance:"Maintenance",objects:"Objects",tasks:"Tasks",overdue:"Overdue",due_soon:"Due Soon",triggered:"Triggered",trigger_replaced:"Trigger replaced",ok:"OK",all:"All",new_object:"+ New Object",templates_from:"From template",templates_title:"Start from a template",templates_task_count:"{n} tasks",template_created:"Created from template",onboard_hint:"Add your first object to start tracking maintenance.",edit:"Edit",duplicate:"Duplicate",task_duplicated:"Task duplicated",object_duplicated:"Object duplicated",delete:"Delete",add_task:"+ Add Task",complete:"Complete",completed:"Completed",skip:"Skip",skipped:"Skipped",missed:"Missed",reset:"Reset",snooze:"Snooze",snoozed:"Snoozed",cancel:"Cancel",bulk_select:"Select",bulk_select_all:"Select all",bulk_n_selected:"{n} selected",bulk_completed:"{n} tasks completed",bulk_archived:"{n} tasks archived",completing:"Completing\u2026",interval:"Interval",warning:"Warning",last_performed:"Last performed",next_due:"Next due",days_until_due:"Days until due",avg_duration:"Avg duration",trigger:"Trigger",trigger_type:"Trigger type",threshold_above:"Upper limit",threshold_below:"Lower limit",threshold:"Threshold",counter:"Counter",state_change:"State change",runtime:"Runtime",runtime_hours:"Target runtime (hours)",target_value:"Target value",baseline:"Baseline",target_changes:"Target changes",for_minutes:"For (minutes)",time_based:"Time-based",sensor_based:"Sensor-based",manual:"Manual",one_time:"One-time",weekdays:"Weekdays",nth_weekday:"Nth weekday of month",day_of_month:"Day of month",recurrence_on_days:"Repeat on",recurrence_occurrence:"Occurrence",recurrence_weekday:"Weekday",recurrence_day:"Day of month (1\u201331)",recurrence_last_day:"Last day of the month",recurrence_business_day:"Business days only (roll back from weekend)",recurrence_offset:"Offset (days, \xB1)",recurrence_offset_help:"Shift the date by \xB1N days, e.g. -2 = two days before.",last_day_month:"Last day of month",last_business_day_month:"Last business day",ord_1:"1st",ord_2:"2nd",ord_3:"3rd",ord_4:"4th",ord_5:"5th",ord_last:"Last",day_word:"Day",interval_value:"Interval",interval_unit:"Unit",unit_days:"Days",unit_weeks:"Weeks",unit_months:"Months",unit_years:"Years",due_date:"Due date",cleaning:"Cleaning",inspection:"Inspection",replacement:"Replacement",calibration:"Calibration",service:"Service",reading:"Reading",custom:"Custom",history:"History",cost:"Cost",report_button:"Report",report_title:"Maintenance report",report_generated:"Generated",report_times_done:"Done",report_total_cost:"Total cost",report_every:"every {n} {unit}",report_notes:"Notes",report_col_type:"Type",report_col_status:"Status",report_col_schedule:"Schedule",duration:"Duration",both:"Both",trigger_val:"Trigger value",complete_title:"Complete: ",checklist:"Checklist",require_on_completion:"Require on completion",checklist_steps_optional:"Checklist steps (optional)",checklist_placeholder:`Clean filter
|
||||
Replace seal
|
||||
Test pressure`,checklist_help:"One step per line. Max 100 items.",err_too_long:"{field}: too long (max {n} characters)",err_too_short:"{field}: too short (min {n} characters)",err_value_too_high:"{field}: too large (max {n})",err_value_too_low:"{field}: too small (min {n})",err_required:"{field}: required",err_wrong_type:"{field}: wrong type (expected: {type})",err_invalid_choice:"{field}: not an allowed value",err_invalid_value:"{field}: invalid value",feat_schedule_time:"Time-of-day scheduling",feat_schedule_time_desc:"Tasks become overdue at a specific time of day instead of midnight.",schedule_time_optional:"Due at time (optional, HH:MM)",schedule_time_help:"Empty = midnight (default). HA timezone.",at_time:"at",notes_optional:"Notes (optional)",cost_optional:"Cost (optional)",duration_minutes:"Duration in minutes (optional)",days:"days",day:"day",today:"Today",d_overdue:"d overdue",no_tasks:"No maintenance tasks yet. Create an object to get started.",no_tasks_short:"No tasks",no_history:"No history entries yet.",show_all:"Show all",cost_duration_chart:"Cost & Duration",installed:"Installed",confirm_delete_object:"Delete this object and all its tasks?",confirm_delete_task:"Delete this task?",min:"Min",max:"Max",save:"Save",saving:"Saving\u2026",edit_task:"Edit Task",new_task:"New Maintenance Task",task_name:"Task name",maintenance_type:"Maintenance type",priority:"Priority",labels:"Labels",labels_placeholder:"e.g. safety, seasonal, tenant-visible",labels_help:"Comma-separated tags for filtering and reporting.",priority_low:"Low",priority_normal:"Normal",priority_high:"High",schedule_type:"Schedule type",interval_days:"Interval (days)",warning_days:"Warning days",earliest_completion_days:"Earliest completion (days before due)",earliest_completion_days_help:"Leave empty to allow completing any time. 0 = only on/after the due date.",last_performed_optional:"Last performed (optional)",interval_anchor:"Interval anchor",anchor_completion:"From completion date",anchor_planned:"From planned date (no drift)",edit_object:"Edit Object",name:"Name",manufacturer_optional:"Manufacturer (optional)",model_optional:"Model (optional)",serial_number_optional:"Serial number (optional)",serial_number_label:"S/N",documentation_url_label:"Manual",object_notes_label:"Notes",sort_due_date:"Due date",sort_object:"Object name",sort_type:"Type",sort_task_name:"Task name",all_objects:"All objects",tasks_lower:"tasks",no_tasks_yet:"No tasks yet",add_first_task:"Add first task",trigger_configuration:"Trigger Configuration",entity_id:"Entity ID",comma_separated:"comma-separated",entity_logic:"Entity logic",entity_logic_any:"Any entity triggers",entity_logic_all:"All entities must trigger",entities:"entities",attribute_optional:"Attribute (optional, blank = state)",use_entity_state:"Use entity state (no attribute)",trigger_above:"Trigger above",trigger_below:"Trigger below",for_at_least_minutes:"For at least (minutes)",safety_interval_days:"Safety interval (days, optional)",safety_interval:"Safety interval (optional)",delta_mode:"Delta mode",from_state_optional:"From state (optional)",to_state_optional:"To state (optional)",documentation_url_optional:"Documentation URL (optional)",object_notes_optional:"Notes (optional)",nfc_tag_id_optional:"NFC Tag ID (optional)",nfc_tags_empty_help:"No NFC tags registered in Home Assistant yet.",nfc_tags_open_settings:"Open Tags settings",nfc_tags_refresh:"Refresh",environmental_entity_optional:"Environmental sensor (optional)",environmental_entity_helper:"e.g. sensor.outdoor_temperature \u2014 adjusts the interval based on environmental conditions",adaptive_prediction_enabled:"Enable sensor-driven predictions",adaptive_seasonal_enabled:"Enable seasonal awareness",adaptive_max_interval:"Maximum interval (days)",adaptive_min_interval:"Minimum interval (days)",adaptive_ewa_alpha:"Learning rate (alpha)",adaptive_enabled:"Enable adaptive scheduling",adaptive_section_title:"Adaptive Scheduling",environmental_attribute_optional:"Environmental attribute (optional)",nfc_tag_id:"NFC Tag ID",nfc_linked:"NFC tag linked",nfc_link_hint:"Click to link NFC tag",responsible_user:"Responsible User",shared_with:"Shared with (rotation)",shared_with_help:"Pick multiple people to share this task; the responsible person rotates on each completion.",rotation_strategy:"Rotation",rotation_none:"No rotation",rotation_round_robin:"Round-robin",rotation_least_completed:"Least completed",rotation_random:"Random",no_user_assigned:"(No user assigned)",all_users:"All Users",my_tasks:"My Tasks",tab_calendar:"Calendar",cal_no_events:"No maintenance",cal_window_7:"7 days",cal_window_14:"14 days",cal_window_30:"30 days",cal_window_365:"1 year",cal_every_n_days:"every {n} days",cal_source_time:"Time-based",cal_source_time_adaptive:"Time-based (adaptive)",cal_source_sensor:"Sensor-based",cal_predicted:"predicted",cal_confidence_high:"high confidence",cal_confidence_medium:"medium confidence",cal_confidence_low:"low confidence",budget_mo
Line truncated
|
||||
Test pressure`,checklist_help:"One step per line. Max 100 items.",err_too_long:"{field}: too long (max {n} characters)",err_too_short:"{field}: too short (min {n} characters)",err_value_too_high:"{field}: too large (max {n})",err_value_too_low:"{field}: too small (min {n})",err_required:"{field}: required",err_wrong_type:"{field}: wrong type (expected: {type})",err_invalid_choice:"{field}: not an allowed value",err_invalid_value:"{field}: invalid value",feat_schedule_time:"Time-of-day scheduling",feat_schedule_time_desc:"Tasks become overdue at a specific time of day instead of midnight.",schedule_time_optional:"Due at time (optional, HH:MM)",schedule_time_help:"Empty = midnight (default). HA timezone.",at_time:"at",notes_optional:"Notes (optional)",cost_optional:"Cost (optional)",duration_minutes:"Duration in minutes (optional)",days:"days",day:"day",today:"Today",d_overdue:"d overdue",no_tasks:"No maintenance tasks yet. Create an object to get started.",no_tasks_short:"No tasks",no_history:"No history entries yet.",show_all:"Show all",cost_duration_chart:"Cost & Duration",installed:"Installed",confirm_delete_object:"Delete this object and all its tasks?",confirm_delete_task:"Delete this task?",min:"Min",max:"Max",save:"Save",saving:"Saving\u2026",edit_task:"Edit Task",new_task:"New Maintenance Task",task_name:"Task name",maintenance_type:"Maintenance type",priority:"Priority",labels:"Labels",labels_placeholder:"e.g. safety, seasonal, tenant-visible",labels_help:"Comma-separated tags for filtering and reporting.",priority_low:"Low",priority_normal:"Normal",priority_high:"High",schedule_type:"Schedule type",interval_days:"Interval (days)",warning_days:"Warning days",earliest_completion_days:"Earliest completion (days before due)",earliest_completion_days_help:"Leave empty to allow completing any time. 0 = only on/after the due date.",last_performed_optional:"Last performed (optional)",interval_anchor:"Interval anchor",anchor_completion:"From completion date",anchor_planned:"From planned date (no drift)",edit_object:"Edit Object",name:"Name",manufacturer_optional:"Manufacturer (optional)",model_optional:"Model (optional)",serial_number_optional:"Serial number (optional)",serial_number_label:"S/N",documentation_url_label:"Manual",object_notes_label:"Notes",sort_due_date:"Due date",sort_object:"Object name",sort_type:"Type",sort_task_name:"Task name",all_objects:"All objects",all_parts:"All parts",tasks_lower:"tasks",no_tasks_yet:"No tasks yet",add_first_task:"Add first task",trigger_configuration:"Trigger Configuration",entity_id:"Entity ID",comma_separated:"comma-separated",entity_logic:"Entity logic",entity_logic_any:"Any entity triggers",entity_logic_all:"All entities must trigger",entities:"entities",attribute_optional:"Attribute (optional, blank = state)",use_entity_state:"Use entity state (no attribute)",trigger_above:"Trigger above",trigger_below:"Trigger below",for_at_least_minutes:"For at least (minutes)",safety_interval_days:"Safety interval (days, optional)",safety_interval:"Safety interval (optional)",delta_mode:"Delta mode",from_state_optional:"From state (optional)",to_state_optional:"To state (optional)",documentation_url_optional:"Documentation URL (optional)",object_notes_optional:"Notes (optional)",nfc_tag_id_optional:"NFC Tag ID (optional)",nfc_tags_empty_help:"No NFC tags registered in Home Assistant yet.",nfc_tags_open_settings:"Open Tags settings",nfc_tags_refresh:"Refresh",environmental_entity_optional:"Environmental sensor (optional)",environmental_entity_helper:"e.g. sensor.outdoor_temperature \u2014 adjusts the interval based on environmental conditions",adaptive_prediction_enabled:"Enable sensor-driven predictions",adaptive_seasonal_enabled:"Enable seasonal awareness",adaptive_max_interval:"Maximum interval (days)",adaptive_min_interval:"Minimum interval (days)",adaptive_ewa_alpha:"Learning rate (alpha)",adaptive_enabled:"Enable adaptive scheduling",adaptive_section_title:"Adaptive Scheduling",environmental_attribute_optional:"Environmental attribute (optional)",nfc_tag_id:"NFC Tag ID",nfc_linked:"NFC tag linked",nfc_link_hint:"Click to link NFC tag",responsible_user:"Responsible User",shared_with:"Shared with (rotation)",shared_with_help:"Pick multiple people to share this task; the responsible person rotates on each completion.",rotation_strategy:"Rotation",rotation_none:"No rotation",rotation_round_robin:"Round-robin",rotation_least_completed:"Least completed",rotation_random:"Random",no_user_assigned:"(No user assigned)",all_users:"All Users",my_tasks:"My Tasks",tab_calendar:"Calendar",cal_no_events:"No maintenance",cal_window_7:"7 days",cal_window_14:"14 days",cal_window_30:"30 days",cal_window_365:"1 year",cal_every_n_days:"every {n} days",cal_source_time:"Time-based",cal_source_time_adaptive:"Time-based (adaptive)",cal_source_sensor:"Sensor-based",cal_predicted:"predicted",cal_confidence_high:"high confidence",cal_confidence_medium:"medium confidence",cal_confidence_low:"low
Line truncated
|
||||
.field { display: flex; flex-direction: column; gap: 4px; }
|
||||
.field-label { font-size: 12px; color: var(--secondary-text-color); }
|
||||
.field-input {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
var S="2.56.0";var l="maintenance-supporter",T=`ll-strategy-dashboard-${l}`,D="hui-maintenance-supporter-strategy-editor",C=`/maintenance_supporter_strategy/maintenance-dashboard-strategy.js?v=${S}`,m=null;function v(){return m||(m=import(C)),m}async function I(){let r=await v();if(!r.MaintenanceDashboardStrategy)throw new Error("[maintenance-supporter] strategy bundle loaded but did not export MaintenanceDashboardStrategy");return r.MaintenanceDashboardStrategy}var p=class extends HTMLElement{static getCreateSuggestions(c){return{title:"Maintenance Supporter",icon:"mdi:wrench-clock"}}static async getConfigElement(){return await v(),document.createElement(D)}static async generate(c,f){return(await I()).generate(c,f)}};function M(){try{customElements.define(T,p)}catch{}}M();var w=window;w.customStrategies=w.customStrategies||[];w.customStrategies.some(r=>r.type===l&&r.strategyType==="dashboard")||w.customStrategies.push({type:l,strategyType:"dashboard",name:"Maintenance Supporter",description:"Auto-generated dashboard. Group views by area, status, floor, or due date \u2014 picked from the strategy editor or YAML.",documentationURL:"https://github.com/iluebbe/maintenance_supporter#dashboard-strategy"});(()=>{let r=window;if(r.__msStrategyHealActive)return;r.__msStrategyHealActive=!0;let c=/^\/(auth|config|developer-tools|profile|hassio|history|logbook|map|media-browser|energy|todo|calendar)\b/,f=/Timeout waiting for strategy element ll-strategy-(dashboard-)?maintenance-supporter/i,g=`custom:${l}`;function R(a){let t=[document.documentElement],n=0;for(;t.length&&n<9e3;){let o=t.pop();if(n++,!o)continue;let e=o;if(e.nodeType===1&&e.tagName&&e.tagName.toLowerCase()===a)return e;e.shadowRoot&&t.push(e.shadowRoot);let i=o.children;if(i)for(let d of Array.from(i))t.push(d)}return null}function k(a){let t=a?.views;if(!Array.isArray(t)||!t.length)return null;let n=window.location.pathname.split("/").filter(Boolean).pop()||"",o=t.find(i=>i?.path===n);if(o)return o;let e=Number(n);return Number.isInteger(e)&&t[e]?t[e]:t[0]}function b(){try{let t=R("ha-panel-lovelace")?.lovelace;if(!t)return!1;let n=o=>o?.type;for(let o of[t.config,t.rawConfig]){if(!o)continue;if(n(o.strategy)===g)return!0;let e=k(o);if(e&&n(e.strategy)===g)return!0}return!1}catch{return!1}}function A(){let a=!1,t=0,n=!1,o=!1,e=[document.documentElement],i=0;for(;e.length&&i<9e3;){let d=e.pop();if(i++,!d)continue;let u=d;if(u.nodeType===1&&u.tagName){let s=u.tagName.toLowerCase();(s==="hui-view"||s==="hui-sections-view")&&(a=!0),(s==="ha-card"||s==="hui-card")&&t++,s==="hui-empty-state-card"&&(o=!0),s==="hui-error-card"&&f.test(u.textContent||"")&&(n=!0)}u.shadowRoot&&e.push(u.shadowRoot);let E=d.children;if(E)for(let s of Array.from(E))e.push(s)}return n?!0:o?!1:a&&t<3&&b()}let N="/maintenance_supporter_strategy_shim.js",y=0,_=0;function L(){let a=Date.now();a-_<5e3||y>=3||(_=a,y+=1,import(`${N}?heal=${a}`).catch(()=>{}).finally(()=>{let t=window.location.pathname+window.location.search;history.pushState(null,"","/lovelace"),window.dispatchEvent(new CustomEvent("location-changed")),window.setTimeout(()=>{history.pushState(null,"",t),window.dispatchEvent(new CustomEvent("location-changed"))},200)}))}function h(){if(c.test(window.location.pathname))return;let a=0,t=Date.now(),n=window.setInterval(()=>{a++;try{if(Date.now()-t<6e3)return;if(c.test(window.location.pathname)){window.clearInterval(n);return}A()?L():window.clearInterval(n),a>=30&&window.clearInterval(n)}catch{window.clearInterval(n)}},500)}try{document.readyState==="loading"?window.addEventListener("DOMContentLoaded",h):h(),window.addEventListener("location-changed",()=>{c.test(window.location.pathname)||h()})}catch{}})();
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
var S="2.57.0";var l="maintenance-supporter",T=`ll-strategy-dashboard-${l}`,D="hui-maintenance-supporter-strategy-editor",C=`/maintenance_supporter_strategy/maintenance-dashboard-strategy.js?v=${S}`,m=null;function v(){return m||(m=import(C)),m}async function I(){let r=await v();if(!r.MaintenanceDashboardStrategy)throw new Error("[maintenance-supporter] strategy bundle loaded but did not export MaintenanceDashboardStrategy");return r.MaintenanceDashboardStrategy}var p=class extends HTMLElement{static getCreateSuggestions(c){return{title:"Maintenance Supporter",icon:"mdi:wrench-clock"}}static async getConfigElement(){return await v(),document.createElement(D)}static async generate(c,f){return(await I()).generate(c,f)}};function M(){try{customElements.define(T,p)}catch{}}M();var w=window;w.customStrategies=w.customStrategies||[];w.customStrategies.some(r=>r.type===l&&r.strategyType==="dashboard")||w.customStrategies.push({type:l,strategyType:"dashboard",name:"Maintenance Supporter",description:"Auto-generated dashboard. Group views by area, status, floor, or due date \u2014 picked from the strategy editor or YAML.",documentationURL:"https://github.com/iluebbe/maintenance_supporter#dashboard-strategy"});(()=>{let r=window;if(r.__msStrategyHealActive)return;r.__msStrategyHealActive=!0;let c=/^\/(auth|config|developer-tools|profile|hassio|history|logbook|map|media-browser|energy|todo|calendar)\b/,f=/Timeout waiting for strategy element ll-strategy-(dashboard-)?maintenance-supporter/i,g=`custom:${l}`;function R(a){let t=[document.documentElement],n=0;for(;t.length&&n<9e3;){let o=t.pop();if(n++,!o)continue;let e=o;if(e.nodeType===1&&e.tagName&&e.tagName.toLowerCase()===a)return e;e.shadowRoot&&t.push(e.shadowRoot);let i=o.children;if(i)for(let d of Array.from(i))t.push(d)}return null}function k(a){let t=a?.views;if(!Array.isArray(t)||!t.length)return null;let n=window.location.pathname.split("/").filter(Boolean).pop()||"",o=t.find(i=>i?.path===n);if(o)return o;let e=Number(n);return Number.isInteger(e)&&t[e]?t[e]:t[0]}function b(){try{let t=R("ha-panel-lovelace")?.lovelace;if(!t)return!1;let n=o=>o?.type;for(let o of[t.config,t.rawConfig]){if(!o)continue;if(n(o.strategy)===g)return!0;let e=k(o);if(e&&n(e.strategy)===g)return!0}return!1}catch{return!1}}function A(){let a=!1,t=0,n=!1,o=!1,e=[document.documentElement],i=0;for(;e.length&&i<9e3;){let d=e.pop();if(i++,!d)continue;let u=d;if(u.nodeType===1&&u.tagName){let s=u.tagName.toLowerCase();(s==="hui-view"||s==="hui-sections-view")&&(a=!0),(s==="ha-card"||s==="hui-card")&&t++,s==="hui-empty-state-card"&&(o=!0),s==="hui-error-card"&&f.test(u.textContent||"")&&(n=!0)}u.shadowRoot&&e.push(u.shadowRoot);let E=d.children;if(E)for(let s of Array.from(E))e.push(s)}return n?!0:o?!1:a&&t<3&&b()}let N="/maintenance_supporter_strategy_shim.js",y=0,_=0;function L(){let a=Date.now();a-_<5e3||y>=3||(_=a,y+=1,import(`${N}?heal=${a}`).catch(()=>{}).finally(()=>{let t=window.location.pathname+window.location.search;history.pushState(null,"","/lovelace"),window.dispatchEvent(new CustomEvent("location-changed")),window.setTimeout(()=>{history.pushState(null,"",t),window.dispatchEvent(new CustomEvent("location-changed"))},200)}))}function h(){if(c.test(window.location.pathname))return;let a=0,t=Date.now(),n=window.setInterval(()=>{a++;try{if(Date.now()-t<6e3)return;if(c.test(window.location.pathname)){window.clearInterval(n);return}A()?L():window.clearInterval(n),a>=30&&window.clearInterval(n)}catch{window.clearInterval(n)}},500)}try{document.readyState==="loading"?window.addEventListener("DOMContentLoaded",h):h(),window.addEventListener("location-changed",()=>{c.test(window.location.pathname)||h()})}catch{}})();
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6RMRSFSY.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,p as v}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var r=class extends h{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._users=[];this._responsible="";this._localeReady=!1;this._userService=null;this._toggle=s=>{let o=new Set(this._selected);o.has(s)?o.delete(s):o.add(s),this._selected=o};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(s=>s.entity_id))};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let s=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:e.suggested_entry_id??void 0,object_name:e.suggested_object_name,device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0})),o=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/adopt",selections:s});this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:o})),this._open=!1}catch(s){this._error=d(s,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,v(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._sensors=[],this._selected=new Set,this._responsible="";try{this._userService?this._userService.updateHass(this.hass):this._userService=new u(this.hass);let[s,o]=await Promise.all([this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/discover"}),this._userService.getUsers().catch(()=>[])]);this._sensors=s.sensors||[],this._selected=new Set(this._sensors.map(e=>e.entity_id)),this._users=o}catch(s){this._error=d(s,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return t``;let s=this._lang,o=this._sensors.length>0&&this._selected.size===this._sensors.length;return t`
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NU5DR7VT.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GKQ6LXK5.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,p as v}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var r=class extends h{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._users=[];this._responsible="";this._localeReady=!1;this._userService=null;this._toggle=s=>{let o=new Set(this._selected);o.has(s)?o.delete(s):o.add(s),this._selected=o};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(s=>s.entity_id))};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let s=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:e.suggested_entry_id??void 0,object_name:e.suggested_object_name,device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0})),o=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/adopt",selections:s});this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:o})),this._open=!1}catch(s){this._error=d(s,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,v(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._sensors=[],this._selected=new Set,this._responsible="";try{this._userService?this._userService.updateHass(this.hass):this._userService=new u(this.hass);let[s,o]=await Promise.all([this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/discover"}),this._userService.getUsers().catch(()=>[])]);this._sensors=s.sensors||[],this._selected=new Set(this._sensors.map(e=>e.entity_id)),this._users=o}catch(s){this._error=d(s,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return t``;let s=this._lang,o=this._sensors.length>0&&this._selected.size===this._sensors.length;return t`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||
<div class="title">${i("adopt_problem_title",s)}</div>
|
||||
-222
@@ -1,222 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LJXSDCLS.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-I7J3AORE.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,p as v}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var r=class extends h{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._users=[];this._responsible="";this._localeReady=!1;this._userService=null;this._toggle=s=>{let o=new Set(this._selected);o.has(s)?o.delete(s):o.add(s),this._selected=o};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(s=>s.entity_id))};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let s=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:e.suggested_entry_id??void 0,object_name:e.suggested_object_name,device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0})),o=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/adopt",selections:s});this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:o})),this._open=!1}catch(s){this._error=d(s,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,v(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._sensors=[],this._selected=new Set,this._responsible="";try{this._userService?this._userService.updateHass(this.hass):this._userService=new u(this.hass);let[s,o]=await Promise.all([this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/discover"}),this._userService.getUsers().catch(()=>[])]);this._sensors=s.sensors||[],this._selected=new Set(this._sensors.map(e=>e.entity_id)),this._users=o}catch(s){this._error=d(s,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return t``;let s=this._lang,o=this._sensors.length>0&&this._selected.size===this._sensors.length;return t`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||
<div class="title">${i("adopt_problem_title",s)}</div>
|
||||
<div class="hint">${i("adopt_problem_hint",s)}</div>
|
||||
${this._error?t`<div class="error">${this._error}</div>`:l}
|
||||
|
||||
${this._loading?t`<div class="loading">…</div>`:this._sensors.length===0?t`<div class="empty">${i("adopt_problem_none",s)}</div>`:t`
|
||||
<label class="select-all">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${o}
|
||||
@change=${this._toggleAll}
|
||||
/>
|
||||
<span>${i("selected",s)}: ${this._selected.size} / ${this._sensors.length}</span>
|
||||
</label>
|
||||
<div class="list">
|
||||
${this._sensors.map(e=>{let m=this._selected.has(e.entity_id),p=e.state==="on",c=[e.device_name,e.area_name].filter(Boolean).join(" \xB7 ");return t`
|
||||
<label class="row">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${m}
|
||||
@change=${()=>this._toggle(e.entity_id)}
|
||||
/>
|
||||
<div class="row-main">
|
||||
<div class="row-top">
|
||||
<span class="row-name">${e.name}</span>
|
||||
<span class="chip ${p?"chip-active":"chip-ok"}">
|
||||
${p?i("adopt_problem_active",s):i("adopt_problem_ok",s)}
|
||||
</span>
|
||||
</div>
|
||||
${c?t`<div class="row-sub">${c}</div>`:l}
|
||||
<div class="row-target">
|
||||
→ ${e.suggested_object_name}${e.suggested_entry_id?l:t` <span class="new-tag">${i("adopt_problem_new_object",s)}</span>`}
|
||||
</div>
|
||||
${e.suggested_part_name?t`<div class="row-part">
|
||||
<ha-icon icon="mdi:package-variant-closed"></ha-icon>
|
||||
${i("adopt_problem_part",s).replace("{name}",e.suggested_part_name)}
|
||||
</div>`:l}
|
||||
</div>
|
||||
</label>
|
||||
`})}
|
||||
</div>
|
||||
`}
|
||||
|
||||
${!this._loading&&this._sensors.length>0&&this._users.length>0?t`
|
||||
<label class="responsible">
|
||||
<span>${i("adopt_problem_responsible",s)}</span>
|
||||
<select
|
||||
.value=${this._responsible}
|
||||
@change=${e=>{this._responsible=e.target.value}}
|
||||
>
|
||||
<option value="" ?selected=${!this._responsible}>${i("no_user_assigned",s)}</option>
|
||||
${this._users.map(e=>t`<option value=${e.id} ?selected=${e.id===this._responsible}>${e.name}</option>`)}
|
||||
</select>
|
||||
</label>
|
||||
`:l}
|
||||
|
||||
<div class="actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${i("cancel",s)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._adopt}
|
||||
.disabled=${this._selected.size===0||this._adopting}
|
||||
>
|
||||
${i("adopt_problem_adopt",s)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`}};r.styles=_`
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
min-width: min(360px, calc(100vw - 24px));
|
||||
max-width: 560px;
|
||||
width: 90vw;
|
||||
max-height: 80vh;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.hint {
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 13px;
|
||||
}
|
||||
.error {
|
||||
color: var(--error-color, #f44336);
|
||||
font-size: 13px;
|
||||
}
|
||||
.loading,
|
||||
.empty {
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 14px;
|
||||
padding: 12px 0;
|
||||
}
|
||||
.select-all {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
.select-all input {
|
||||
cursor: pointer;
|
||||
}
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
overflow-y: auto;
|
||||
max-height: 50vh;
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
padding: 8px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.row input {
|
||||
margin-top: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.row-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
.row-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.row-name {
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
}
|
||||
.row-sub {
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 12px;
|
||||
}
|
||||
.row-target {
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 12px;
|
||||
}
|
||||
.row-part {
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.row-part ha-icon {
|
||||
--mdc-icon-size: 14px;
|
||||
}
|
||||
.new-tag {
|
||||
font-style: italic;
|
||||
}
|
||||
.chip {
|
||||
font-size: 11px;
|
||||
padding: 1px 8px;
|
||||
border-radius: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.chip-active {
|
||||
background: var(--error-color, #f44336);
|
||||
color: #fff;
|
||||
}
|
||||
.chip-ok {
|
||||
background: var(--divider-color);
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.responsible {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.responsible select {
|
||||
flex: 1;
|
||||
min-width: 140px;
|
||||
padding: 4px 6px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--divider-color);
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
font-size: 13px;
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
`,a([g({attribute:!1})],r.prototype,"hass",2),a([n()],r.prototype,"_open",2),a([n()],r.prototype,"_loading",2),a([n()],r.prototype,"_adopting",2),a([n()],r.prototype,"_error",2),a([n()],r.prototype,"_sensors",2),a([n()],r.prototype,"_selected",2),a([n()],r.prototype,"_users",2),a([n()],r.prototype,"_responsible",2);customElements.get("maintenance-adopt-problem-sensors-dialog")||customElements.define("maintenance-adopt-problem-sensors-dialog",r);export{r as MaintenanceAdoptProblemSensorsDialog};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";function _(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let t=!!e.entry_id&&e.entry_id!==r,a=t?e.entry_id:r,o=s.find(p=>p.entry_id===a),n=(o?.parts||[]).find(p=>p.id===e.part_id)||null,d=t&&o?.object?.name||"",i=n?.name||u("shared_part_unknown",c);return{part:n,foreign:t,ownerName:d,label:d?`${i} (${d})`:i}}function f(e,r,s,c){let{part:t,label:a}=l(e,r,s,c),o=t&&t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:"",n=t?.storage_location?` \u2014 ${t.storage_location}`:"";return`${e.quantity}\xD7 ${a}${o}${n}`}function g(e,r,s,c){let a=(s.find(n=>n.entry_id===r)?.parts||[]).map(n=>({...n})),o=new Set(a.map(n=>_({part_id:n.id})));for(let n of e?.consumes_parts||[]){if(!n.entry_id||n.entry_id===r)continue;let d=_(n);if(o.has(d))continue;o.add(d);let{part:i,ownerName:p}=l(n,r,s,c);a.push({id:n.part_id,name:i?.name||u("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:n.entry_id,owner_name:p})}return a}export{_ as a,f as b,g as c};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
var r=class{constructor(s){this.usersCache=null;this.cacheTimestamp=0;this.CACHE_TTL_MS=6e4;this.hass=s}updateHass(s){this.hass=s}async getUsers(s=!1){let e=Date.now();if(!s&&this.usersCache&&e-this.cacheTimestamp<this.CACHE_TTL_MS)return this.usersCache;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/users/list"});return this.usersCache=t.users,this.cacheTimestamp=e,this.usersCache}catch(t){return console.error("Failed to fetch users:",t),this.usersCache||[]}}async assignUser(s,e,t){await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/assign_user",entry_id:s,task_id:e,user_id:t})}async getTasksByUser(s){return(await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/tasks/by_user",user_id:s})).tasks}getUserName(s){return!s||!this.usersCache?null:this.usersCache.find(t=>t.id===s)?.name||null}getUser(s){return!s||!this.usersCache?null:this.usersCache.find(e=>e.id===s)||null}getCurrentUserId(){return this.hass.user?.id||null}isCurrentUser(s){return s?s===this.getCurrentUserId():!1}clearCache(){this.usersCache=null,this.cacheTimestamp=0}};export{r as a};
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";function _(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let t=!!e.entry_id&&e.entry_id!==r,a=t?e.entry_id:r,o=s.find(p=>p.entry_id===a),n=(o?.parts||[]).find(p=>p.id===e.part_id)||null,d=t&&o?.object?.name||"",i=n?.name||u("shared_part_unknown",c);return{part:n,foreign:t,ownerName:d,label:d?`${i} (${d})`:i}}function f(e,r,s,c){let{part:t,label:a}=l(e,r,s,c),o=t&&t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:"",n=t?.storage_location?` \u2014 ${t.storage_location}`:"";return`${e.quantity}\xD7 ${a}${o}${n}`}function g(e,r,s,c){let a=(s.find(n=>n.entry_id===r)?.parts||[]).map(n=>({...n})),o=new Set(a.map(n=>_({part_id:n.id})));for(let n of e?.consumes_parts||[]){if(!n.entry_id||n.entry_id===r)continue;let d=_(n);if(o.has(d))continue;o.add(d);let{part:i,ownerName:p}=l(n,r,s,c);a.push({id:n.part_id,name:i?.name||u("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:n.entry_id,owner_name:p})}return a}export{_ as a,f as b,g as c};
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";function _(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let t=!!e.entry_id&&e.entry_id!==r,a=t?e.entry_id:r,o=s.find(p=>p.entry_id===a),n=(o?.parts||[]).find(p=>p.id===e.part_id)||null,d=t&&o?.object?.name||"",i=n?.name||u("shared_part_unknown",c);return{part:n,foreign:t,ownerName:d,label:d?`${i} (${d})`:i}}function f(e,r,s,c){let{part:t,label:a}=l(e,r,s,c),o=t&&t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:"",n=t?.storage_location?` \u2014 ${t.storage_location}`:"";return`${e.quantity}\xD7 ${a}${o}${n}`}function g(e,r,s,c){let a=(s.find(n=>n.entry_id===r)?.parts||[]).map(n=>({...n})),o=new Set(a.map(n=>_({part_id:n.id})));for(let n of e?.consumes_parts||[]){if(!n.entry_id||n.entry_id===r)continue;let d=_(n);if(o.has(d))continue;o.add(d);let{part:i,ownerName:p}=l(n,r,s,c);a.push({id:n.part_id,name:i?.name||u("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:n.entry_id,owner_name:p})}return a}export{_ as a,f as b,g as c};
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
var r=class{constructor(s){this.usersCache=null;this.cacheTimestamp=0;this.CACHE_TTL_MS=6e4;this.hass=s}updateHass(s){this.hass=s}async getUsers(s=!1){let e=Date.now();if(!s&&this.usersCache&&e-this.cacheTimestamp<this.CACHE_TTL_MS)return this.usersCache;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/users/list"});return this.usersCache=t.users,this.cacheTimestamp=e,this.usersCache}catch(t){return console.error("Failed to fetch users:",t),this.usersCache||[]}}async assignUser(s,e,t){await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/assign_user",entry_id:s,task_id:e,user_id:t})}async getTasksByUser(s){return(await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/tasks/by_user",user_id:s})).tasks}getUserName(s){return!s||!this.usersCache?null:this.usersCache.find(t=>t.id===s)?.name||null}getUser(s){return!s||!this.usersCache?null:this.usersCache.find(e=>e.id===s)||null}getCurrentUserId(){return this.hass.user?.id||null}isCurrentUser(s){return s?s===this.getCurrentUserId():!1}clearCache(){this.usersCache=null,this.cacheTimestamp=0}};export{r as a};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
var o=["notes","cost","duration","photo","user"],t={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};export{o as a,t as b};
|
||||
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var s={name:"name",task_type:"maintenance_type",schedule_type:"schedule_type",interval_days:"interval_days",interval_anchor:"interval_anchor",warning_days:"warning_days",last_performed:"last_performed_optional",notes:"notes_optional",documentation_url:"documentation_url_optional",custom_icon:"custom_icon_optional",nfc_tag_id:"nfc_tag_id_optional",responsible_user_id:"responsible_user",entity_slug:"entity_slug",entity_id:"entity_id",area_id:"area_id_optional",manufacturer:"manufacturer_optional",model:"model_optional",serial_number:"serial_number_optional",installation_date:"installation_date_optional",warranty_expiry:"warranty_expiry_optional",checklist:"checklist_steps_optional",reason:"reason",feedback:"feedback",cost:"cost",duration:"duration",description:"description_optional",group_name:"name",group_description:"description_optional",environmental_entity:"environmental_entity_optional",environmental_attribute:"environmental_attribute_optional",trigger_above:"trigger_above",trigger_below:"trigger_below",trigger_for_minutes:"trigger_for_minutes"};function c(r,o){let e=s[r];if(!e)return r;let t=a(e,o);return t&&t!==e?t:r}function d(r){let e=r.match(/data\['([^']+)'\]/)?.[1],t;return(t=r.match(/length of value must be at most (\d+)/))?{field:e,rule:"too_long",param:t[1]}:(t=r.match(/length of value must be at least (\d+)/))?{field:e,rule:"too_short",param:t[1]}:(t=r.match(/value must be at most (\S+)/))?{field:e,rule:"value_too_high",param:t[1]}:(t=r.match(/value must be at least (\S+)/))?{field:e,rule:"value_too_low",param:t[1]}:/required key not provided/.test(r)?{field:e,rule:"required"}:(t=r.match(/expected (\w+)/))?{field:e,rule:"wrong_type",param:t[1]}:/value must be one of/.test(r)?{field:e,rule:"invalid_choice"}:/not a valid value/.test(r)?{field:e,rule:"invalid_value"}:{field:e,rule:"unknown"}}function g(r,o,e){if(e=e??a("action_error",o),typeof r=="string")return r;if(typeof r!="object"||r===null)return e;let t=r,_=t.message||t.error?.message||"";if(!_)return e;let i=d(_),l=i.field?c(i.field,o):"",n=u=>a(u,o).replace("{field}",l).replace("{n}",i.param??"");switch(i.rule){case"too_long":return n("err_too_long");case"too_short":return n("err_too_short");case"value_too_high":return n("err_value_too_high");case"value_too_low":return n("err_value_too_low");case"required":return n("err_required");case"wrong_type":return n("err_wrong_type").replace("{type}",i.param??"");case"invalid_choice":return n("err_invalid_choice");case"invalid_value":return n("err_invalid_value");default:return _||e}}export{g as a};
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var s={name:"name",task_type:"maintenance_type",schedule_type:"schedule_type",interval_days:"interval_days",interval_anchor:"interval_anchor",warning_days:"warning_days",last_performed:"last_performed_optional",notes:"notes_optional",documentation_url:"documentation_url_optional",custom_icon:"custom_icon_optional",nfc_tag_id:"nfc_tag_id_optional",responsible_user_id:"responsible_user",entity_slug:"entity_slug",entity_id:"entity_id",area_id:"area_id_optional",manufacturer:"manufacturer_optional",model:"model_optional",serial_number:"serial_number_optional",installation_date:"installation_date_optional",warranty_expiry:"warranty_expiry_optional",checklist:"checklist_steps_optional",reason:"reason",feedback:"feedback",cost:"cost",duration:"duration",description:"description_optional",group_name:"name",group_description:"description_optional",environmental_entity:"environmental_entity_optional",environmental_attribute:"environmental_attribute_optional",trigger_above:"trigger_above",trigger_below:"trigger_below",trigger_for_minutes:"trigger_for_minutes"};function c(r,o){let e=s[r];if(!e)return r;let t=a(e,o);return t&&t!==e?t:r}function d(r){let e=r.match(/data\['([^']+)'\]/)?.[1],t;return(t=r.match(/length of value must be at most (\d+)/))?{field:e,rule:"too_long",param:t[1]}:(t=r.match(/length of value must be at least (\d+)/))?{field:e,rule:"too_short",param:t[1]}:(t=r.match(/value must be at most (\S+)/))?{field:e,rule:"value_too_high",param:t[1]}:(t=r.match(/value must be at least (\S+)/))?{field:e,rule:"value_too_low",param:t[1]}:/required key not provided/.test(r)?{field:e,rule:"required"}:(t=r.match(/expected (\w+)/))?{field:e,rule:"wrong_type",param:t[1]}:/value must be one of/.test(r)?{field:e,rule:"invalid_choice"}:/not a valid value/.test(r)?{field:e,rule:"invalid_value"}:{field:e,rule:"unknown"}}function g(r,o,e){if(e=e??a("action_error",o),typeof r=="string")return r;if(typeof r!="object"||r===null)return e;let t=r,_=t.message||t.error?.message||"";if(!_)return e;let i=d(_),l=i.field?c(i.field,o):"",n=u=>a(u,o).replace("{field}",l).replace("{n}",i.param??"");switch(i.rule){case"too_long":return n("err_too_long");case"too_short":return n("err_too_short");case"value_too_high":return n("err_value_too_high");case"value_too_low":return n("err_value_too_low");case"required":return n("err_required");case"wrong_type":return n("err_wrong_type").replace("{type}",i.param??"");case"invalid_choice":return n("err_invalid_choice");case"invalid_value":return n("err_invalid_value");default:return _||e}}export{g as a};
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
var o=["notes","cost","duration","photo","user"],t={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};export{o as a,t as b};
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
var i=[{key:"name",labelKey:"name",required:!0},{key:"manufacturer",labelKey:"manufacturer"},{key:"model",labelKey:"model"},{key:"serial_number",labelKey:"serial_number_label"},{key:"installation_date",labelKey:"installed"},{key:"warranty_expiry",labelKey:"warranty"},{key:"area_id",labelKey:"area"},{key:"documentation_url",labelKey:"documentation_url_label"},{key:"notes",labelKey:"object_notes_label"},{key:"task_count",labelKey:"tasks"},{key:"actions",labelKey:"actions"}],s=i.map(n=>n.key),l=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function c(n){if(!Array.isArray(n))return[...l];let o=new Set,e=[];for(let a of n)typeof a=="string"&&s.includes(a)&&!o.has(a)&&(o.add(a),e.push(a));return e.length?(e.includes("name")||e.unshift("name"),e):[...l]}function u(n,o,e){let a=new Blob([n],{type:e}),r=URL.createObjectURL(a),t=document.createElement("a");t.href=r,t.download=o,t.target="_blank",t.rel="noopener",t.style.display="none",document.body.appendChild(t),t.dispatchEvent(new MouseEvent("click")),document.body.removeChild(t),setTimeout(()=>URL.revokeObjectURL(r),6e4)}function y(n,o){let e=document.createElement("a");e.href=n,e.download=o,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}export{i as a,l as b,c,u as d,y as e};
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
var Te=Object.defineProperty;var je=Object.getOwnPropertyDescriptor;var Xe=(o,e,t,r)=>{for(var a=r>1?void 0:r?je(e,t):e,n=o.length-1,i;n>=0;n--)(i=o[n])&&(a=(r?i(e,t,a):i(a))||a);return r&&a&&Te(e,t,a),a};var L=globalThis,M=L.ShadowRoot&&(L.ShadyCSS===void 0||L.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,G=Symbol(),ne=new WeakMap,$=class{constructor(e,t,r){if(this._$cssResult$=!0,r!==G)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o,t=this.t;if(M&&e===void 0){let r=t!==void 0&&t.length===1;r&&(e=ne.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),r&&ne.set(t,e))}return e}toString(){return this.cssText}},ie=o=>new $(typeof o=="string"?o:o+"",void 0,G),U=(o,...e)=>{let t=o.length===1?o[0]:e.reduce((r,a,n)=>r+(i=>{if(i._$cssResult$===!0)return i.cssText;if(typeof i=="number")return i;throw Error("Value passed to 'css' function must be a 'css' function result: "+i+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(a)+o[n+1],o[0]);return new $(t,o,G)},se=(o,e)=>{if(M)o.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of e){let r=document.createElement("style"),a=L.litNonce;a!==void 0&&r.setAttribute("nonce",a),r.textContent=t.cssText,o.appendChild(r)}},V=M?o=>o:o=>o instanceof CSSStyleSheet?(e=>{let t="";for(let r of e.cssRules)t+=r.cssText;return ie(t)})(o):o;var{is:Ne,defineProperty:Pe,getOwnPropertyDescriptor:Re,getOwnPropertyNames:ze,getOwnPropertySymbols:Oe,getPrototypeOf:De}=Object,q=globalThis,le=q.trustedTypes,Le=le?le.emptyScript:"",Me=q.reactiveElementPolyfillSupport,C=(o,e)=>o,E={toAttribute(o,e){switch(e){case Boolean:o=o?Le:null;break;case Object:case Array:o=o==null?o:JSON.stringify(o)}return o},fromAttribute(o,e){let t=o;switch(e){case Boolean:t=o!==null;break;case Number:t=o===null?null:Number(o);break;case Object:case Array:try{t=JSON.parse(o)}catch{t=null}}return t}},H=(o,e)=>!Ne(o,e),ce={attribute:!0,type:String,converter:E,reflect:!1,useDefault:!1,hasChanged:H};Symbol.metadata??=Symbol("metadata"),q.litPropertyMetadata??=new WeakMap;var g=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=ce){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){let r=Symbol(),a=this.getPropertyDescriptor(e,r,t);a!==void 0&&Pe(this.prototype,e,a)}}static getPropertyDescriptor(e,t,r){let{get:a,set:n}=Re(this.prototype,e)??{get(){return this[t]},set(i){this[t]=i}};return{get:a,set(i){let l=a?.call(this);n?.call(this,i),this.requestUpdate(e,l,r)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??ce}static _$Ei(){if(this.hasOwnProperty(C("elementProperties")))return;let e=De(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(C("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(C("properties"))){let t=this.properties,r=[...ze(t),...Oe(t)];for(let a of r)this.createProperty(a,t[a])}let e=this[Symbol.metadata];if(e!==null){let t=litPropertyMetadata.get(e);if(t!==void 0)for(let[r,a]of t)this.elementProperties.set(r,a)}this._$Eh=new Map;for(let[t,r]of this.elementProperties){let a=this._$Eu(t,r);a!==void 0&&this._$Eh.set(a,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){let t=[];if(Array.isArray(e)){let r=new Set(e.flat(1/0).reverse());for(let a of r)t.unshift(V(a))}else e!==void 0&&t.push(V(e));return t}static _$Eu(e,t){let r=t.attribute;return r===!1?void 0:typeof r=="string"?r:typeof e=="string"?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),this.renderRoot!==void 0&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){let e=new Map,t=this.constructor.elementProperties;for(let r of t.keys())this.hasOwnProperty(r)&&(e.set(r,this[r]),delete this[r]);e.size>0&&(this._$Ep=e)}createRenderRoot(){let e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return se(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,r){this._$AK(e,r)}_$ET(e,t){let r=this.constructor.elementProperties.get(e),a=Line truncated
|
||||
\f\r]`,T=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,_e=/-->/g,ue=/>/g,b=RegExp(`>|${K}(?:([^\\s"'>=/]+)(${K}*=${K}*(?:[^
|
||||
\f\r"'\`<>=]|("|')|))|$)`,"g"),he=/'/g,ge=/"/g,ye=/^(?:script|style|textarea|title)$/i,oe=o=>(e,...t)=>({_$litType$:o,strings:e,values:t}),nt=oe(1),it=oe(2),st=oe(3),x=Symbol.for("lit-noChange"),p=Symbol.for("lit-nothing"),me=new WeakMap,y=v.createTreeWalker(v,129);function ve(o,e){if(!te(o)||!o.hasOwnProperty("raw"))throw Error("invalid template strings array");return pe!==void 0?pe.createHTML(e):e}var He=(o,e)=>{let t=o.length-1,r=[],a,n=e===2?"<svg>":e===3?"<math>":"",i=T;for(let l=0;l<t;l++){let s=o[l],d,_,c=-1,h=0;for(;h<s.length&&(i.lastIndex=h,_=i.exec(s),_!==null);)h=i.lastIndex,i===T?_[1]==="!--"?i=_e:_[1]!==void 0?i=ue:_[2]!==void 0?(ye.test(_[2])&&(a=RegExp("</"+_[2],"g")),i=b):_[3]!==void 0&&(i=b):i===b?_[0]===">"?(i=a??T,c=-1):_[1]===void 0?c=-2:(c=i.lastIndex-_[2].length,d=_[1],i=_[3]===void 0?b:_[3]==='"'?ge:he):i===ge||i===he?i=b:i===_e||i===ue?i=T:(i=b,a=void 0);let m=i===b&&o[l+1].startsWith("/>")?" ":"";n+=i===T?s+Ue:c>=0?(r.push(d),s.slice(0,c)+fe+s.slice(c)+f+m):s+f+(c===-2?l:m)}return[ve(o,n+(o[t]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),r]},P=class o{constructor({strings:e,_$litType$:t},r){let a;this.parts=[];let n=0,i=0,l=e.length-1,s=this.parts,[d,_]=He(e,t);if(this.el=o.createElement(d,r),y.currentNode=this.el.content,t===2||t===3){let c=this.el.content.firstChild;c.replaceWith(...c.childNodes)}for(;(a=y.nextNode())!==null&&s.length<l;){if(a.nodeType===1){if(a.hasAttributes())for(let c of a.getAttributeNames())if(c.endsWith(fe)){let h=_[i++],m=a.getAttribute(c).split(f),D=/([.?@])?(.*)/.exec(h);s.push({type:1,index:n,name:D[2],strings:m,ctor:D[1]==="."?Y:D[1]==="?"?J:D[1]==="@"?Z:S}),a.removeAttribute(c)}else c.startsWith(f)&&(s.push({type:6,index:n}),a.removeAttribute(c));if(ye.test(a.tagName)){let c=a.textContent.split(f),h=c.length-1;if(h>0){a.textContent=I?I.emptyScript:"";for(let m=0;m<h;m++)a.append(c[m],j()),y.nextNode(),s.push({type:2,index:++n});a.append(c[h],j())}}}else if(a.nodeType===8)if(a.data===be)s.push({type:2,index:n});else{let c=-1;for(;(c=a.data.indexOf(f,c+1))!==-1;)s.push({type:7,index:n}),c+=f.length-1}n++}}static createElement(e,t){let r=v.createElement("template");return r.innerHTML=e,r}};function k(o,e,t=o,r){if(e===x)return e;let a=r!==void 0?t._$Co?.[r]:t._$Cl,n=N(e)?void 0:e._$litDirective$;return a?.constructor!==n&&(a?._$AO?.(!1),n===void 0?a=void 0:(a=new n(o),a._$AT(o,t,r)),r!==void 0?(t._$Co??=[])[r]=a:t._$Cl=a),a!==void 0&&(e=k(o,a._$AS(o,e.values),a,r)),e}var Q=class{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){let{el:{content:t},parts:r}=this._$AD,a=(e?.creationScope??v).importNode(t,!0);y.currentNode=a;let n=y.nextNode(),i=0,l=0,s=r[0];for(;s!==void 0;){if(i===s.index){let d;s.type===2?d=new R(n,n.nextSibling,this,e):s.type===1?d=new s.ctor(n,s.name,s.strings,this,e):s.type===6&&(d=new X(n,this,e)),this._$AV.push(d),s=r[++l]}i!==s?.index&&(n=y.nextNode(),i++)}return y.currentNode=v,a}p(e){let t=0;for(let r of this._$AV)r!==void 0&&(r.strings!==void 0?(r._$AI(e,r,t),t+=r.strings.length-2):r._$AI(e[t])),t++}},R=class o{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,r,a){this.type=2,this._$AH=p,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=r,this.options=a,this._$Cv=a?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode,t=this._$AM;return t!==void 0&&e?.nodeType===11&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,t=this){e=k(this,e,t),N(e)?e===p||e==null||e===""?(this._$AH!==p&&this._$AR(),this._$AH=p):e!==this._$AH&&e!==x&&this._(e):e._$litType$!==void 0?this.$(e):e.nodeType!==void 0?this.T(e):qe(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==p&&N(this._$AH)?this._$AA.nextSibling.data=e:this.T(v.createTextNode(e)),this._$AH=e}$(e){let{values:t,_$litType$:r}=e,a=typeof r=="number"?this._$AC(e):(r.el===void 0&&(r.el=P.createElement(ve(r.h,r.h[0]),this.options)),r);if(this._$AH?._$AD===a)this._$AH.p(t);else{let n=new Q(a,this),i=n.u(this.options);n.p(t),this.T(i),this._$AH=n}}_$AC(e){let t=me.get(e.strings);return t===void 0&&me.set(e.strings,t=new P(e)),t}k(e){te(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,r,a=0;for(let n of e)a===t.length?t.push(r=new o(this.O(j()),this.O(j()),this,this.options)):r=t[a],r._$AI(n),a++;a<t.length&&(this._$AR(r&&r._$AB.nextSibling,a),t.length=a)}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);e!==this._$AB;){let r=de(e).nextSibling;de(e).remove(),e=r}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e))}},S=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,r,a,n){this.type=1,this._$AH=p,this._$AN=void 0,this.element=e,this.name=t,this._$AM=a,this.options=n,r.length>2||r[0]!==""||r[1]!==""?(this._$AH=Array(r.length-1).fill(new String),this.strings=r):thisLine truncated
|
||||
Replace seal
|
||||
Test pressure`,checklist_help:"One step per line. Max 100 items.",err_too_long:"{field}: too long (max {n} characters)",err_too_short:"{field}: too short (min {n} characters)",err_value_too_high:"{field}: too large (max {n})",err_value_too_low:"{field}: too small (min {n})",err_required:"{field}: required",err_wrong_type:"{field}: wrong type (expected: {type})",err_invalid_choice:"{field}: not an allowed value",err_invalid_value:"{field}: invalid value",feat_schedule_time:"Time-of-day scheduling",feat_schedule_time_desc:"Tasks become overdue at a specific time of day instead of midnight.",schedule_time_optional:"Due at time (optional, HH:MM)",schedule_time_help:"Empty = midnight (default). HA timezone.",at_time:"at",notes_optional:"Notes (optional)",cost_optional:"Cost (optional)",duration_minutes:"Duration in minutes (optional)",days:"days",day:"day",today:"Today",d_overdue:"d overdue",no_tasks:"No maintenance tasks yet. Create an object to get started.",no_tasks_short:"No tasks",no_history:"No history entries yet.",show_all:"Show all",cost_duration_chart:"Cost & Duration",installed:"Installed",confirm_delete_object:"Delete this object and all its tasks?",confirm_delete_task:"Delete this task?",min:"Min",max:"Max",save:"Save",saving:"Saving\u2026",edit_task:"Edit Task",new_task:"New Maintenance Task",task_name:"Task name",maintenance_type:"Maintenance type",priority:"Priority",labels:"Labels",labels_placeholder:"e.g. safety, seasonal, tenant-visible",labels_help:"Comma-separated tags for filtering and reporting.",priority_low:"Low",priority_normal:"Normal",priority_high:"High",schedule_type:"Schedule type",interval_days:"Interval (days)",warning_days:"Warning days",earliest_completion_days:"Earliest completion (days before due)",earliest_completion_days_help:"Leave empty to allow completing any time. 0 = only on/after the due date.",last_performed_optional:"Last performed (optional)",interval_anchor:"Interval anchor",anchor_completion:"From completion date",anchor_planned:"From planned date (no drift)",edit_object:"Edit Object",name:"Name",manufacturer_optional:"Manufacturer (optional)",model_optional:"Model (optional)",serial_number_optional:"Serial number (optional)",serial_number_label:"S/N",documentation_url_label:"Manual",object_notes_label:"Notes",sort_due_date:"Due date",sort_object:"Object name",sort_type:"Type",sort_task_name:"Task name",all_objects:"All objects",tasks_lower:"tasks",no_tasks_yet:"No tasks yet",add_first_task:"Add first task",trigger_configuration:"Trigger Configuration",entity_id:"Entity ID",comma_separated:"comma-separated",entity_logic:"Entity logic",entity_logic_any:"Any entity triggers",entity_logic_all:"All entities must trigger",entities:"entities",attribute_optional:"Attribute (optional, blank = state)",use_entity_state:"Use entity state (no attribute)",trigger_above:"Trigger above",trigger_below:"Trigger below",for_at_least_minutes:"For at least (minutes)",safety_interval_days:"Safety interval (days, optional)",safety_interval:"Safety interval (optional)",delta_mode:"Delta mode",from_state_optional:"From state (optional)",to_state_optional:"To state (optional)",documentation_url_optional:"Documentation URL (optional)",object_notes_optional:"Notes (optional)",nfc_tag_id_optional:"NFC Tag ID (optional)",nfc_tags_empty_help:"No NFC tags registered in Home Assistant yet.",nfc_tags_open_settings:"Open Tags settings",nfc_tags_refresh:"Refresh",environmental_entity_optional:"Environmental sensor (optional)",environmental_entity_helper:"e.g. sensor.outdoor_temperature \u2014 adjusts the interval based on environmental conditions",adaptive_prediction_enabled:"Enable sensor-driven predictions",adaptive_seasonal_enabled:"Enable seasonal awareness",adaptive_max_interval:"Maximum interval (days)",adaptive_min_interval:"Minimum interval (days)",adaptive_ewa_alpha:"Learning rate (alpha)",adaptive_enabled:"Enable adaptive scheduling",adaptive_section_title:"Adaptive Scheduling",environmental_attribute_optional:"Environmental attribute (optional)",nfc_tag_id:"NFC Tag ID",nfc_linked:"NFC tag linked",nfc_link_hint:"Click to link NFC tag",responsible_user:"Responsible User",shared_with:"Shared with (rotation)",shared_with_help:"Pick multiple people to share this task; the responsible person rotates on each completion.",rotation_strategy:"Rotation",rotation_none:"No rotation",rotation_round_robin:"Round-robin",rotation_least_completed:"Least completed",rotation_random:"Random",no_user_assigned:"(No user assigned)",all_users:"All Users",my_tasks:"My Tasks",tab_calendar:"Calendar",cal_no_events:"No maintenance",cal_window_7:"7 days",cal_window_14:"14 days",cal_window_30:"30 days",cal_window_365:"1 year",cal_every_n_days:"every {n} days",cal_source_time:"Time-based",cal_source_time_adaptive:"Time-based (adaptive)",cal_source_sensor:"Sensor-based",cal_predicted:"predicted",cal_confidence_high:"high confidence",cal_confidence_medium:"medium confidence",cal_confidence_low:"low confidence",budget_mo
Line truncated
|
||||
Test pressure`,checklist_help:"One step per line. Max 100 items.",err_too_long:"{field}: too long (max {n} characters)",err_too_short:"{field}: too short (min {n} characters)",err_value_too_high:"{field}: too large (max {n})",err_value_too_low:"{field}: too small (min {n})",err_required:"{field}: required",err_wrong_type:"{field}: wrong type (expected: {type})",err_invalid_choice:"{field}: not an allowed value",err_invalid_value:"{field}: invalid value",feat_schedule_time:"Time-of-day scheduling",feat_schedule_time_desc:"Tasks become overdue at a specific time of day instead of midnight.",schedule_time_optional:"Due at time (optional, HH:MM)",schedule_time_help:"Empty = midnight (default). HA timezone.",at_time:"at",notes_optional:"Notes (optional)",cost_optional:"Cost (optional)",duration_minutes:"Duration in minutes (optional)",days:"days",day:"day",today:"Today",d_overdue:"d overdue",no_tasks:"No maintenance tasks yet. Create an object to get started.",no_tasks_short:"No tasks",no_history:"No history entries yet.",show_all:"Show all",cost_duration_chart:"Cost & Duration",installed:"Installed",confirm_delete_object:"Delete this object and all its tasks?",confirm_delete_task:"Delete this task?",min:"Min",max:"Max",save:"Save",saving:"Saving\u2026",edit_task:"Edit Task",new_task:"New Maintenance Task",task_name:"Task name",maintenance_type:"Maintenance type",priority:"Priority",labels:"Labels",labels_placeholder:"e.g. safety, seasonal, tenant-visible",labels_help:"Comma-separated tags for filtering and reporting.",priority_low:"Low",priority_normal:"Normal",priority_high:"High",schedule_type:"Schedule type",interval_days:"Interval (days)",warning_days:"Warning days",earliest_completion_days:"Earliest completion (days before due)",earliest_completion_days_help:"Leave empty to allow completing any time. 0 = only on/after the due date.",last_performed_optional:"Last performed (optional)",interval_anchor:"Interval anchor",anchor_completion:"From completion date",anchor_planned:"From planned date (no drift)",edit_object:"Edit Object",name:"Name",manufacturer_optional:"Manufacturer (optional)",model_optional:"Model (optional)",serial_number_optional:"Serial number (optional)",serial_number_label:"S/N",documentation_url_label:"Manual",object_notes_label:"Notes",sort_due_date:"Due date",sort_object:"Object name",sort_type:"Type",sort_task_name:"Task name",all_objects:"All objects",all_parts:"All parts",tasks_lower:"tasks",no_tasks_yet:"No tasks yet",add_first_task:"Add first task",trigger_configuration:"Trigger Configuration",entity_id:"Entity ID",comma_separated:"comma-separated",entity_logic:"Entity logic",entity_logic_any:"Any entity triggers",entity_logic_all:"All entities must trigger",entities:"entities",attribute_optional:"Attribute (optional, blank = state)",use_entity_state:"Use entity state (no attribute)",trigger_above:"Trigger above",trigger_below:"Trigger below",for_at_least_minutes:"For at least (minutes)",safety_interval_days:"Safety interval (days, optional)",safety_interval:"Safety interval (optional)",delta_mode:"Delta mode",from_state_optional:"From state (optional)",to_state_optional:"To state (optional)",documentation_url_optional:"Documentation URL (optional)",object_notes_optional:"Notes (optional)",nfc_tag_id_optional:"NFC Tag ID (optional)",nfc_tags_empty_help:"No NFC tags registered in Home Assistant yet.",nfc_tags_open_settings:"Open Tags settings",nfc_tags_refresh:"Refresh",environmental_entity_optional:"Environmental sensor (optional)",environmental_entity_helper:"e.g. sensor.outdoor_temperature \u2014 adjusts the interval based on environmental conditions",adaptive_prediction_enabled:"Enable sensor-driven predictions",adaptive_seasonal_enabled:"Enable seasonal awareness",adaptive_max_interval:"Maximum interval (days)",adaptive_min_interval:"Minimum interval (days)",adaptive_ewa_alpha:"Learning rate (alpha)",adaptive_enabled:"Enable adaptive scheduling",adaptive_section_title:"Adaptive Scheduling",environmental_attribute_optional:"Environmental attribute (optional)",nfc_tag_id:"NFC Tag ID",nfc_linked:"NFC tag linked",nfc_link_hint:"Click to link NFC tag",responsible_user:"Responsible User",shared_with:"Shared with (rotation)",shared_with_help:"Pick multiple people to share this task; the responsible person rotates on each completion.",rotation_strategy:"Rotation",rotation_none:"No rotation",rotation_round_robin:"Round-robin",rotation_least_completed:"Least completed",rotation_random:"Random",no_user_assigned:"(No user assigned)",all_users:"All Users",my_tasks:"My Tasks",tab_calendar:"Calendar",cal_no_events:"No maintenance",cal_window_7:"7 days",cal_window_14:"14 days",cal_window_30:"30 days",cal_window_365:"1 year",cal_every_n_days:"every {n} days",cal_source_time:"Time-based",cal_source_time_adaptive:"Time-based (adaptive)",cal_source_sensor:"Sensor-based",cal_predicted:"predicted",cal_confidence_high:"high confidence",cal_confidence_medium:"medium confidence",cal_confidence_low:"low
Line truncated
|
||||
.field { display: flex; flex-direction: column; gap: 4px; }
|
||||
.field-label { font-size: 12px; color: var(--secondary-text-color); }
|
||||
.field-input {
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as t,b as a,c as i,f as l,g as p,i as r}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var e=class extends p{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1}_onInput(n){let o=n.target.value;this.value=o,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:o}}))}render(){return i`
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{a as t,b as a,c as i,f as l,g as p,i as r}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var e=class extends p{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1}_onInput(n){let o=n.target.value;this.value=o,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:o}}))}render(){return i`
|
||||
<label class="field">
|
||||
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:l}</span>`:l}
|
||||
<input
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var s={name:"name",task_type:"maintenance_type",schedule_type:"schedule_type",interval_days:"interval_days",interval_anchor:"interval_anchor",warning_days:"warning_days",last_performed:"last_performed_optional",notes:"notes_optional",documentation_url:"documentation_url_optional",custom_icon:"custom_icon_optional",nfc_tag_id:"nfc_tag_id_optional",responsible_user_id:"responsible_user",entity_slug:"entity_slug",entity_id:"entity_id",area_id:"area_id_optional",manufacturer:"manufacturer_optional",model:"model_optional",serial_number:"serial_number_optional",installation_date:"installation_date_optional",warranty_expiry:"warranty_expiry_optional",checklist:"checklist_steps_optional",reason:"reason",feedback:"feedback",cost:"cost",duration:"duration",description:"description_optional",group_name:"name",group_description:"description_optional",environmental_entity:"environmental_entity_optional",environmental_attribute:"environmental_attribute_optional",trigger_above:"trigger_above",trigger_below:"trigger_below",trigger_for_minutes:"trigger_for_minutes"};function c(r,o){let e=s[r];if(!e)return r;let t=a(e,o);return t&&t!==e?t:r}function d(r){let e=r.match(/data\['([^']+)'\]/)?.[1],t;return(t=r.match(/length of value must be at most (\d+)/))?{field:e,rule:"too_long",param:t[1]}:(t=r.match(/length of value must be at least (\d+)/))?{field:e,rule:"too_short",param:t[1]}:(t=r.match(/value must be at most (\S+)/))?{field:e,rule:"value_too_high",param:t[1]}:(t=r.match(/value must be at least (\S+)/))?{field:e,rule:"value_too_low",param:t[1]}:/required key not provided/.test(r)?{field:e,rule:"required"}:(t=r.match(/expected (\w+)/))?{field:e,rule:"wrong_type",param:t[1]}:/value must be one of/.test(r)?{field:e,rule:"invalid_choice"}:/not a valid value/.test(r)?{field:e,rule:"invalid_value"}:{field:e,rule:"unknown"}}function g(r,o,e){if(e=e??a("action_error",o),typeof r=="string")return r;if(typeof r!="object"||r===null)return e;let t=r,_=t.message||t.error?.message||"";if(!_)return e;let i=d(_),l=i.field?c(i.field,o):"",n=u=>a(u,o).replace("{field}",l).replace("{n}",i.param??"");switch(i.rule){case"too_long":return n("err_too_long");case"too_short":return n("err_too_short");case"value_too_high":return n("err_value_too_high");case"value_too_low":return n("err_value_too_low");case"required":return n("err_required");case"wrong_type":return n("err_wrong_type").replace("{type}",i.param??"");case"invalid_choice":return n("err_invalid_choice");case"invalid_value":return n("err_invalid_value");default:return _||e}}export{g as a};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
var i=[{key:"name",labelKey:"name",required:!0},{key:"manufacturer",labelKey:"manufacturer"},{key:"model",labelKey:"model"},{key:"serial_number",labelKey:"serial_number_label"},{key:"installation_date",labelKey:"installed"},{key:"warranty_expiry",labelKey:"warranty"},{key:"area_id",labelKey:"area"},{key:"documentation_url",labelKey:"documentation_url_label"},{key:"notes",labelKey:"object_notes_label"},{key:"task_count",labelKey:"tasks"},{key:"actions",labelKey:"actions"}],s=i.map(n=>n.key),l=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function c(n){if(!Array.isArray(n))return[...l];let o=new Set,e=[];for(let a of n)typeof a=="string"&&s.includes(a)&&!o.has(a)&&(o.add(a),e.push(a));return e.length?(e.includes("name")||e.unshift("name"),e):[...l]}function u(n,o,e){let a=new Blob([n],{type:e}),r=URL.createObjectURL(a),t=document.createElement("a");t.href=r,t.download=o,t.target="_blank",t.rel="noopener",t.style.display="none",document.body.appendChild(t),t.dispatchEvent(new MouseEvent("click")),document.body.removeChild(t),setTimeout(()=>URL.revokeObjectURL(r),6e4)}function y(n,o){let e=document.createElement("a");e.href=n,e.download=o,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}export{i as a,l as b,c,u as d,y as e};
|
||||
@@ -1,54 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{a as t,b as a,c as i,f as l,g as p,i as r}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var e=class extends p{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1}_onInput(n){let o=n.target.value;this.value=o,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:o}}))}render(){return i`
|
||||
<label class="field">
|
||||
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:l}</span>`:l}
|
||||
<input
|
||||
.value=${this.value??""}
|
||||
.type=${this.type}
|
||||
?required=${this.required}
|
||||
?disabled=${this.disabled}
|
||||
placeholder=${this.placeholder}
|
||||
step=${this.step??l}
|
||||
min=${this.min??l}
|
||||
max=${this.max??l}
|
||||
pattern=${this.pattern??l}
|
||||
@input=${this._onInput}
|
||||
@change=${this._onInput}
|
||||
/>
|
||||
${this.helper?i`<span class="helper">${this.helper}</span>`:l}
|
||||
</label>
|
||||
`}};e.styles=a`
|
||||
:host { display: block; }
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.label {
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color, #888);
|
||||
font-weight: 500;
|
||||
}
|
||||
.req { color: var(--error-color, #f44336); margin-left: 2px; }
|
||||
input {
|
||||
padding: 8px 10px;
|
||||
font-size: 14px;
|
||||
background: var(--secondary-background-color, rgba(0,0,0,0.06));
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color, rgba(255,255,255,0.12));
|
||||
border-radius: 6px;
|
||||
font-family: inherit;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
}
|
||||
input:focus {
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
input:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.helper {
|
||||
font-size: 11px;
|
||||
color: var(--secondary-text-color);
|
||||
font-style: italic;
|
||||
}
|
||||
`,t([r()],e.prototype,"label",2),t([r()],e.prototype,"value",2),t([r()],e.prototype,"placeholder",2),t([r()],e.prototype,"type",2),t([r({type:Boolean})],e.prototype,"required",2),t([r({type:Boolean})],e.prototype,"disabled",2),t([r()],e.prototype,"step",2),t([r()],e.prototype,"min",2),t([r()],e.prototype,"max",2),t([r()],e.prototype,"pattern",2),t([r()],e.prototype,"helper",2);customElements.get("ms-textfield")||customElements.define("ms-textfield",e);
|
||||
-292
@@ -1,292 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-7QFSK25W.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4HD7ODUX.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,x as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var i=class extends v{constructor(){super(...arguments);this.entryId="";this.taskId="";this.taskName="";this.lang="en";this.checklist=[];this.adaptiveEnabled=!1;this.taskType="";this.readingUnit="";this.restockDefault=null;this.restockUnitCost=null;this.currencySymbol="";this.parts=[];this.consumesParts=[];this.consumesInfo=[];this.requiredFields=[];this._open=!1;this._notes="";this._cost="";this._duration="";this._loading=!1;this._error="";this._checklistState={};this._feedback="needed";this._photoDocId="";this._photoPreview="";this._photoUploading=!1;this._readingValue="";this._restockQty="";this._usedParts={};this.checklistPrefill={}}open(){this._open||(this._open=!0,this._notes="",this._cost="",this._duration="",this._error="",this._checklistState=Object.fromEntries(this.checklist.map((e,t)=>[String(t),!!this.checklistPrefill[e]]).filter(([,e])=>e)),this._feedback="needed",this._photoDocId="",this._photoPreview="",this._photoUploading=!1,this._readingValue="",this._restockQty=this.restockDefault!==null?String(this.restockDefault):"",this._usedParts=Object.fromEntries(this.consumesParts.map(e=>[_(e),{...e}])))}_toggleCheck(e){let t=String(e);this._checklistState={...this._checklistState,[t]:!this._checklistState[t]}}_setFeedback(e){this._feedback=e}async _onPhotoInput(e){let t=e.target,o=t.files?.[0];if(t.value="",!!o){this._photoUploading=!0,this._error="";try{let c=new FormData;c.append("entry_id",this.entryId),c.append("tags","photo"),c.append("file",o,o.name);let p=await fetch("/api/maintenance_supporter/document/upload",{method:"POST",headers:{Authorization:`Bearer ${this.hass.auth?.data?.access_token??""}`},body:c});if(!p.ok){this._error=p.status===413?r("doc_too_large",this.lang):r("doc_upload_failed",this.lang);return}let u=await p.json();u.id&&(this._photoDocId=u.id,this._photoPreview=URL.createObjectURL(o))}catch{this._error=r("doc_upload_failed",this.lang)}finally{this._photoUploading=!1}}}_removePhoto(){this._photoPreview&&URL.revokeObjectURL(this._photoPreview),this._photoDocId="",this._photoPreview=""}async _complete(){this._loading=!0,this._error="";try{let e={type:"maintenance_supporter/task/complete",entry_id:this.entryId,task_id:this.taskId};if(this._notes&&(e.notes=this._notes),this._cost){let t=parseFloat(this._cost);!isNaN(t)&&t>=0&&(e.cost=t)}if(this._duration){let t=parseInt(this._duration,10);!isNaN(t)&&t>=0&&(e.duration=t)}if(this.checklist.length>0&&(e.checklist_state=this._checklistState),this.adaptiveEnabled&&(e.feedback=this._feedback),this._photoDocId&&(e.photo_doc_id=this._photoDocId),this._readingValue!==""){let t=parseFloat(this._readingValue);isNaN(t)||(e.reading_value=t)}if(this.restockDefault!==null&&this._restockQty!==""){let t=parseFloat(this._restockQty);!isNaN(t)&&t>=1&&(e.restock_quantity=t)}this.parts.length>0&&(e.used_parts=Object.values(this._usedParts).filter(t=>Number.isFinite(t.quantity)&&t.quantity>0).map(t=>t.entry_id?{part_id:t.part_id,quantity:t.quantity,entry_id:t.entry_id}:{part_id:t.part_id,quantity:t.quantity})),await this.hass.connection.sendMessagePromise(e),this._open=!1,this.dispatchEvent(new CustomEvent("task-completed"))}catch(e){this._error=g(e,this.lang,r("save_error",this.lang))}finally{this._loading=!1}}get _missingRequired(){let e={notes:this._notes.trim()!=="",cost:this._cost.trim()!=="",duration:this._duration.trim()!=="",photo:this._photoDocId!=="",user:!!this.hass?.user};return this.requiredFields.filter(t=>!e[t])}_req(e){return this.requiredFields.includes(e)?a`<span class="req-mark" aria-hidden="true">*</span>`:d}_partsCostSuggestion(){if(this.restockDefault!==null){let o=parseFloat(this._restockQty);return this.restockUnitCost==null||!Number.isFinite(o)||o<=0?null:Math.round(this.restockUnitCost*o*100)/100}if(!this.parts.length)return null;let e=0,t=!1;for(let o of Object.values(this._usedParts)){let c=this.parts.find(p=>_({part_id:p.id,entry_id:p.entry_id})===_(o));c?.cost!=null&&(e+=c.cost*(o.quantity||1),t=!0)}return t?Math.round(e*100)/100:null}_renderCostSuggestion(e){if(this._cost.trim()!=="")return d;let t=this._partsCostSuggestion();if(t==null||t<=0)return d;let o=`${t.toFixed(2)}${this.currencySymbol?` ${this.currencySymbol}`:""}`;return a`<button
|
||||
type="button"
|
||||
class="cost-suggestion"
|
||||
@click=${()=>this._cost=t.toFixed(2)}
|
||||
>${r("cost_from_parts",e).replace("{amount}",o)}</button>`}_close(){this._open=!1}render(){if(!this._open)return a``;let e=this.lang||this.hass?.language||"en";return a`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${r("complete_title",e)}${this.taskName}</div>
|
||||
<div class="content">
|
||||
${this._error?a`<div class="error">${this._error}</div>`:d}
|
||||
${this.checklist.length>0?a`
|
||||
<div class="checklist-section">
|
||||
<label class="checklist-label">${r("checklist",e)}</label>
|
||||
${this.checklist.map((t,o)=>a`
|
||||
<label class="checklist-item" @click=${()=>this._toggleCheck(o)}>
|
||||
<input type="checkbox" .checked=${!!this._checklistState[String(o)]} />
|
||||
<span>${t}</span>
|
||||
</label>
|
||||
`)}
|
||||
</div>
|
||||
`:d}
|
||||
${this.taskType==="reading"?a`
|
||||
<label class="field">
|
||||
<span class="field-label">${r("reading_value_label",e)}${this.readingUnit?` (${this.readingUnit})`:""}</span>
|
||||
<input type="number" step="any" class="field-input"
|
||||
.value=${this._readingValue}
|
||||
@input=${t=>this._readingValue=t.target.value} />
|
||||
</label>`:d}
|
||||
${this.parts.length?a`<div class="used-parts">
|
||||
<span class="field-label">${r("complete_parts_used",e)}</span>
|
||||
${this.parts.map(t=>{let o=_({part_id:t.id,entry_id:t.entry_id}),c=this._usedParts[o],p=c!==void 0,u=t.entry_id?{part_id:t.id,quantity:1,entry_id:t.entry_id}:{part_id:t.id,quantity:1};return a`<div class="used-part-row">
|
||||
<label class="used-part-check">
|
||||
<input type="checkbox" .checked=${p}
|
||||
@change=${f=>{let h={...this._usedParts};f.target.checked?h[o]=h[o]||u:delete h[o],this._usedParts=h}} />
|
||||
<span
|
||||
>${t.name}${t.owner_name?a`<span class="used-part-owner"> (${t.owner_name})</span>`:d}${t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:""}</span
|
||||
>
|
||||
</label>
|
||||
${p?a`<input class="used-part-qty" type="number" min="0.01" max="999" step="0.01"
|
||||
.value=${String(c.quantity)}
|
||||
@input=${f=>{let h=parseFloat(f.target.value);this._usedParts={...this._usedParts,[o]:{...u,quantity:Number.isFinite(h)&&h>=.01?h:1}}}} />`:d}
|
||||
</div>`})}
|
||||
</div>`:this.consumesInfo.length?a`<div class="consumes-hint">
|
||||
${this.consumesInfo.map(t=>a`<div>${t}</div>`)}
|
||||
</div>`:d}
|
||||
${this.restockDefault!==null?a`
|
||||
<label class="field">
|
||||
<span class="field-label">${r("restock_quantity_label",e)}</span>
|
||||
<input type="number" step="0.01" min="0.01" class="field-input"
|
||||
.value=${this._restockQty}
|
||||
@input=${t=>this._restockQty=t.target.value} />
|
||||
</label>`:d}
|
||||
<!-- Native <input>s rather than <ha-textfield>: when this dialog
|
||||
is opened from a Lovelace card via dialog-mount, ha-textfield
|
||||
isn't yet registered (HA loads it lazily when its own panels
|
||||
need it) so the elements render with zero height and the user
|
||||
only sees the title + Cancel/Complete buttons — the original
|
||||
bug report. Native inputs always render. -->
|
||||
<label class="field">
|
||||
<span class="field-label">${r("notes_optional",e)}${this._req("notes")}</span>
|
||||
<input type="text" class="field-input"
|
||||
.value=${this._notes}
|
||||
@input=${t=>this._notes=t.target.value} />
|
||||
</label>
|
||||
<label class="field">
|
||||
<span class="field-label">${r("cost_optional",e)}${this._req("cost")}</span>
|
||||
<input type="number" step="0.01" min="0" class="field-input"
|
||||
.value=${this._cost}
|
||||
@input=${t=>this._cost=t.target.value} />
|
||||
${this._renderCostSuggestion(e)}
|
||||
</label>
|
||||
<label class="field">
|
||||
<span class="field-label">${r("duration_minutes",e)}${this._req("duration")}</span>
|
||||
<input type="number" step="0.01" min="0" class="field-input"
|
||||
.value=${this._duration}
|
||||
@input=${t=>this._duration=t.target.value} />
|
||||
</label>
|
||||
<div class="field">
|
||||
<span class="field-label">${r("completion_photo_optional",e)}${this._req("photo")}</span>
|
||||
${this._photoPreview?a`
|
||||
<div class="photo-preview">
|
||||
<img src=${this._photoPreview} alt="" />
|
||||
<button type="button" class="photo-remove" @click=${this._removePhoto}
|
||||
title="${r("remove",e)}">✕</button>
|
||||
</div>`:a`
|
||||
<label class="photo-pick">
|
||||
<ha-icon icon="mdi:camera"></ha-icon>
|
||||
<span>${this._photoUploading?r("uploading",e):r("add_photo",e)}</span>
|
||||
<input type="file" accept="image/*" capture="environment"
|
||||
?disabled=${this._photoUploading}
|
||||
@change=${this._onPhotoInput} />
|
||||
</label>`}
|
||||
</div>
|
||||
${this.adaptiveEnabled?a`
|
||||
<div class="feedback-section">
|
||||
<label class="feedback-label">${r("was_maintenance_needed",e)}</label>
|
||||
<div class="feedback-buttons">
|
||||
<button
|
||||
class="feedback-btn ${this._feedback==="needed"?"selected":""}"
|
||||
@click=${()=>this._setFeedback("needed")}
|
||||
>${r("feedback_needed",e)}</button>
|
||||
<button
|
||||
class="feedback-btn ${this._feedback==="not_needed"?"selected":""}"
|
||||
@click=${()=>this._setFeedback("not_needed")}
|
||||
>${r("feedback_not_needed",e)}</button>
|
||||
<button
|
||||
class="feedback-btn ${this._feedback==="not_sure"?"selected":""}"
|
||||
@click=${()=>this._setFeedback("not_sure")}
|
||||
>${r("feedback_not_sure",e)}</button>
|
||||
</div>
|
||||
</div>
|
||||
`:d}
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${r("cancel",e)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._complete}
|
||||
.disabled=${this._loading||this._missingRequired.length>0}
|
||||
title=${this._missingRequired.length?this._missingRequired.map(t=>r("err_required",e).replace("{field}",r(m[t]??t,e))).join(" \xB7 "):""}
|
||||
>
|
||||
${this._loading?r("completing",e):r("complete",e)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}};i.styles=[k,b`
|
||||
.req-mark {
|
||||
color: var(--error-color, #f44336);
|
||||
margin-left: 2px;
|
||||
font-weight: 600;
|
||||
}
|
||||
/* #104: one-click cost suggestion from parts — quiet link-style chip. */
|
||||
.cost-suggestion {
|
||||
align-self: flex-start;
|
||||
margin-top: 4px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--primary-color);
|
||||
font-size: 12.5px;
|
||||
cursor: pointer;
|
||||
text-decoration: underline dotted;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
.dialog-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
min-width: 300px;
|
||||
}
|
||||
.dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
.consumes-hint {
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
border-left: 3px solid var(--primary-color);
|
||||
padding: 4px 8px;
|
||||
margin: 4px 0 8px;
|
||||
}
|
||||
/* #99: editable per-completion parts selection */
|
||||
.used-parts { margin: 4px 0 8px; display: flex; flex-direction: column; gap: 4px; }
|
||||
.used-part-row { display: flex; align-items: center; gap: 8px; }
|
||||
.used-part-check {
|
||||
display: flex; align-items: center; gap: 6px; flex: 1;
|
||||
font-size: 13px; cursor: pointer;
|
||||
}
|
||||
.used-part-check input { cursor: pointer; }
|
||||
/* #111: whose stock this row draws on. Muted but never omitted — an
|
||||
unlabelled foreign pool is indistinguishable from an own part. */
|
||||
.used-part-owner { color: var(--secondary-text-color); }
|
||||
.used-part-qty {
|
||||
width: 76px; padding: 4px 6px; border-radius: 4px; font: inherit; font-size: 13px;
|
||||
border: 1px solid var(--divider-color);
|
||||
background: var(--card-background-color);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.error {
|
||||
color: var(--error-color, #f44336);
|
||||
font-size: 13px;
|
||||
}
|
||||
/* .field/.field-label/.field-input come from nativeFieldStyles */
|
||||
.photo-pick {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
border: 1px dashed var(--divider-color);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
width: fit-content;
|
||||
}
|
||||
.photo-pick:hover { border-color: var(--primary-color); }
|
||||
.photo-pick input[type="file"] { display: none; }
|
||||
.photo-preview {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
}
|
||||
.photo-preview img {
|
||||
max-width: 160px;
|
||||
max-height: 160px;
|
||||
border-radius: 8px;
|
||||
display: block;
|
||||
}
|
||||
.photo-remove {
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
background: var(--error-color, #db4437);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
.checklist-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.checklist-label {
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.checklist-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
padding: 4px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
.checklist-item input[type="checkbox"] {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.feedback-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 8px 0;
|
||||
border-top: 1px solid var(--divider-color);
|
||||
}
|
||||
.feedback-label {
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.feedback-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
.feedback-btn {
|
||||
flex: 1;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 8px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.feedback-btn:hover {
|
||||
background: var(--secondary-background-color, #f5f5f5);
|
||||
}
|
||||
.feedback-btn.selected {
|
||||
background: var(--primary-color);
|
||||
color: var(--text-primary-color, #fff);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
`],s([n({attribute:!1})],i.prototype,"hass",2),s([n()],i.prototype,"entryId",2),s([n()],i.prototype,"taskId",2),s([n()],i.prototype,"taskName",2),s([n()],i.prototype,"lang",2),s([n({type:Array})],i.prototype,"checklist",2),s([n({type:Boolean})],i.prototype,"adaptiveEnabled",2),s([n()],i.prototype,"taskType",2),s([n()],i.prototype,"readingUnit",2),s([n({attribute:!1})],i.prototype,"restockDefault",2),s([n({attribute:!1})],i.prototype,"restockUnitCost",2),s([n()],i.prototype,"currencySymbol",2),s([n({attribute:!1})],i.prototype,"parts",2),s([n({attribute:!1})],i.prototype,"consumesParts",2),s([n({type:Array})],i.prototype,"consumesInfo",2),s([n({type:Array})],i.prototype,"requiredFields",2),s([l()],i.prototype,"_open",2),s([l()],i.prototype,"_notes",2),s([l()],i.prototype,"_cost",2),s([l()],i.prototype,"_duration",2),s([l()],i.prototype,"_loading",2),s([l()],i.prototype,"_error",2),s([l()],i.prototype,"_checklistState",2),s([l()],i.prototype,"_feedback",2),s([l()],i.prototype,"_photoDocId",2),s([l()],i.prototype,"_photoPreview",2),s([l()],i.prototype,"_photoUploading",2),s([l()],i.prototype,"_readingValue",2),s([l()],i.prototype,"_restockQty",2),s([l()],i.prototype,"_usedParts",2),s([n({attribute:!1})],i.prototype,"checklistPrefill",2);customElements.get("maintenance-complete-dialog")||customElements.define("maintenance-complete-dialog",i);export{i as MaintenanceCompleteDialog};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NGMG4DEY.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-SD6IEJBA.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LJXSDCLS.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,x as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var i=class extends v{constructor(){super(...arguments);this.entryId="";this.taskId="";this.taskName="";this.lang="en";this.checklist=[];this.adaptiveEnabled=!1;this.taskType="";this.readingUnit="";this.restockDefault=null;this.restockUnitCost=null;this.currencySymbol="";this.parts=[];this.consumesParts=[];this.consumesInfo=[];this.requiredFields=[];this._open=!1;this._notes="";this._cost="";this._duration="";this._loading=!1;this._error="";this._checklistState={};this._feedback="needed";this._photoDocId="";this._photoPreview="";this._photoUploading=!1;this._readingValue="";this._restockQty="";this._usedParts={};this.checklistPrefill={}}open(){this._open||(this._open=!0,this._notes="",this._cost="",this._duration="",this._error="",this._checklistState=Object.fromEntries(this.checklist.map((e,t)=>[String(t),!!this.checklistPrefill[e]]).filter(([,e])=>e)),this._feedback="needed",this._photoDocId="",this._photoPreview="",this._photoUploading=!1,this._readingValue="",this._restockQty=this.restockDefault!==null?String(this.restockDefault):"",this._usedParts=Object.fromEntries(this.consumesParts.map(e=>[_(e),{...e}])))}_toggleCheck(e){let t=String(e);this._checklistState={...this._checklistState,[t]:!this._checklistState[t]}}_setFeedback(e){this._feedback=e}async _onPhotoInput(e){let t=e.target,o=t.files?.[0];if(t.value="",!!o){this._photoUploading=!0,this._error="";try{let c=new FormData;c.append("entry_id",this.entryId),c.append("tags","photo"),c.append("file",o,o.name);let p=await fetch("/api/maintenance_supporter/document/upload",{method:"POST",headers:{Authorization:`Bearer ${this.hass.auth?.data?.access_token??""}`},body:c});if(!p.ok){this._error=p.status===413?r("doc_too_large",this.lang):r("doc_upload_failed",this.lang);return}let u=await p.json();u.id&&(this._photoDocId=u.id,this._photoPreview=URL.createObjectURL(o))}catch{this._error=r("doc_upload_failed",this.lang)}finally{this._photoUploading=!1}}}_removePhoto(){this._photoPreview&&URL.revokeObjectURL(this._photoPreview),this._photoDocId="",this._photoPreview=""}async _complete(){this._loading=!0,this._error="";try{let e={type:"maintenance_supporter/task/complete",entry_id:this.entryId,task_id:this.taskId};if(this._notes&&(e.notes=this._notes),this._cost){let t=parseFloat(this._cost);!isNaN(t)&&t>=0&&(e.cost=t)}if(this._duration){let t=parseInt(this._duration,10);!isNaN(t)&&t>=0&&(e.duration=t)}if(this.checklist.length>0&&(e.checklist_state=this._checklistState),this.adaptiveEnabled&&(e.feedback=this._feedback),this._photoDocId&&(e.photo_doc_id=this._photoDocId),this._readingValue!==""){let t=parseFloat(this._readingValue);isNaN(t)||(e.reading_value=t)}if(this.restockDefault!==null&&this._restockQty!==""){let t=parseFloat(this._restockQty);!isNaN(t)&&t>=1&&(e.restock_quantity=t)}this.parts.length>0&&(e.used_parts=Object.values(this._usedParts).filter(t=>Number.isFinite(t.quantity)&&t.quantity>0).map(t=>t.entry_id?{part_id:t.part_id,quantity:t.quantity,entry_id:t.entry_id}:{part_id:t.part_id,quantity:t.quantity})),await this.hass.connection.sendMessagePromise(e),this._open=!1,this.dispatchEvent(new CustomEvent("task-completed"))}catch(e){this._error=g(e,this.lang,r("save_error",this.lang))}finally{this._loading=!1}}get _missingRequired(){let e={notes:this._notes.trim()!=="",cost:this._cost.trim()!=="",duration:this._duration.trim()!=="",photo:this._photoDocId!=="",user:!!this.hass?.user};return this.requiredFields.filter(t=>!e[t])}_req(e){return this.requiredFields.includes(e)?a`<span class="req-mark" aria-hidden="true">*</span>`:d}_partsCostSuggestion(){if(this.restockDefault!==null){let o=parseFloat(this._restockQty);return this.restockUnitCost==null||!Number.isFinite(o)||o<=0?null:Math.round(this.restockUnitCost*o*100)/100}if(!this.parts.length)return null;let e=0,t=!1;for(let o of Object.values(this._usedParts)){let c=this.parts.find(p=>_({part_id:p.id,entry_id:p.entry_id})===_(o));c?.cost!=null&&(e+=c.cost*(o.quantity||1),t=!0)}return t?Math.round(e*100)/100:null}_renderCostSuggestion(e){if(this._cost.trim()!=="")return d;let t=this._partsCostSuggestion();if(t==null||t<=0)return d;let o=`${t.toFixed(2)}${this.currencySymbol?` ${this.currencySymbol}`:""}`;return a`<button
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-RCMO6YCL.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-AIMCOREG.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NU5DR7VT.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,x as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var i=class extends v{constructor(){super(...arguments);this.entryId="";this.taskId="";this.taskName="";this.lang="en";this.checklist=[];this.adaptiveEnabled=!1;this.taskType="";this.readingUnit="";this.restockDefault=null;this.restockUnitCost=null;this.currencySymbol="";this.parts=[];this.consumesParts=[];this.consumesInfo=[];this.requiredFields=[];this._open=!1;this._notes="";this._cost="";this._duration="";this._loading=!1;this._error="";this._checklistState={};this._feedback="needed";this._photoDocId="";this._photoPreview="";this._photoUploading=!1;this._readingValue="";this._restockQty="";this._usedParts={};this.checklistPrefill={}}open(){this._open||(this._open=!0,this._notes="",this._cost="",this._duration="",this._error="",this._checklistState=Object.fromEntries(this.checklist.map((e,t)=>[String(t),!!this.checklistPrefill[e]]).filter(([,e])=>e)),this._feedback="needed",this._photoDocId="",this._photoPreview="",this._photoUploading=!1,this._readingValue="",this._restockQty=this.restockDefault!==null?String(this.restockDefault):"",this._usedParts=Object.fromEntries(this.consumesParts.map(e=>[_(e),{...e}])))}_toggleCheck(e){let t=String(e);this._checklistState={...this._checklistState,[t]:!this._checklistState[t]}}_setFeedback(e){this._feedback=e}async _onPhotoInput(e){let t=e.target,o=t.files?.[0];if(t.value="",!!o){this._photoUploading=!0,this._error="";try{let c=new FormData;c.append("entry_id",this.entryId),c.append("tags","photo"),c.append("file",o,o.name);let p=await fetch("/api/maintenance_supporter/document/upload",{method:"POST",headers:{Authorization:`Bearer ${this.hass.auth?.data?.access_token??""}`},body:c});if(!p.ok){this._error=p.status===413?r("doc_too_large",this.lang):r("doc_upload_failed",this.lang);return}let u=await p.json();u.id&&(this._photoDocId=u.id,this._photoPreview=URL.createObjectURL(o))}catch{this._error=r("doc_upload_failed",this.lang)}finally{this._photoUploading=!1}}}_removePhoto(){this._photoPreview&&URL.revokeObjectURL(this._photoPreview),this._photoDocId="",this._photoPreview=""}async _complete(){this._loading=!0,this._error="";try{let e={type:"maintenance_supporter/task/complete",entry_id:this.entryId,task_id:this.taskId};if(this._notes&&(e.notes=this._notes),this._cost){let t=parseFloat(this._cost);!isNaN(t)&&t>=0&&(e.cost=t)}if(this._duration){let t=parseInt(this._duration,10);!isNaN(t)&&t>=0&&(e.duration=t)}if(this.checklist.length>0&&(e.checklist_state=this._checklistState),this.adaptiveEnabled&&(e.feedback=this._feedback),this._photoDocId&&(e.photo_doc_id=this._photoDocId),this._readingValue!==""){let t=parseFloat(this._readingValue);isNaN(t)||(e.reading_value=t)}if(this.restockDefault!==null&&this._restockQty!==""){let t=parseFloat(this._restockQty);!isNaN(t)&&t>=1&&(e.restock_quantity=t)}this.parts.length>0&&(e.used_parts=Object.values(this._usedParts).filter(t=>Number.isFinite(t.quantity)&&t.quantity>0).map(t=>t.entry_id?{part_id:t.part_id,quantity:t.quantity,entry_id:t.entry_id}:{part_id:t.part_id,quantity:t.quantity})),await this.hass.connection.sendMessagePromise(e),this._open=!1,this.dispatchEvent(new CustomEvent("task-completed"))}catch(e){this._error=g(e,this.lang,r("save_error",this.lang))}finally{this._loading=!1}}get _missingRequired(){let e={notes:this._notes.trim()!=="",cost:this._cost.trim()!=="",duration:this._duration.trim()!=="",photo:this._photoDocId!=="",user:!!this.hass?.user};return this.requiredFields.filter(t=>!e[t])}_req(e){return this.requiredFields.includes(e)?a`<span class="req-mark" aria-hidden="true">*</span>`:d}_partsCostSuggestion(){if(this.restockDefault!==null){let o=parseFloat(this._restockQty);return this.restockUnitCost==null||!Number.isFinite(o)||o<=0?null:Math.round(this.restockUnitCost*o*100)/100}if(!this.parts.length)return null;let e=0,t=!1;for(let o of Object.values(this._usedParts)){let c=this.parts.find(p=>_({part_id:p.id,entry_id:p.entry_id})===_(o));c?.cost!=null&&(e+=c.cost*(o.quantity||1),t=!0)}return t?Math.round(e*100)/100:null}_renderCostSuggestion(e){if(this._cost.trim()!=="")return d;let t=this._partsCostSuggestion();if(t==null||t<=0)return d;let o=`${t.toFixed(2)}${this.currencySymbol?` ${this.currencySymbol}`:""}`;return a`<button
|
||||
type="button"
|
||||
class="cost-suggestion"
|
||||
@click=${()=>this._cost=t.toFixed(2)}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZK3W7TF6.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LJXSDCLS.js";import{a as r,b as _,c as l,f as o,g as p,i as d,j as s,n as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var e=class extends p{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return this.hass?.language??navigator.language.split("-")[0]??"en"}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(a,n){this._entryId=a,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(a){this._error=h(a,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(a=>a.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let a=this._lang,n=this._entryId?i("edit_object",a):i("new_object",a);return l`
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-VNISEOIC.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NU5DR7VT.js";import{a as r,b as _,c as l,f as o,g as p,i as d,j as s,n as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var e=class extends p{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return this.hass?.language??navigator.language.split("-")[0]??"en"}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(a,n){this._entryId=a,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(a){this._error=h(a,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(a=>a.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let a=this._lang,n=this._entryId?i("edit_object",a):i("new_object",a);return l`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${n}</div>
|
||||
<div class="content">
|
||||
-143
@@ -1,143 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-BDAGEP22.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as r,b as _,c as l,f as o,g as p,i as d,j as s,n as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var e=class extends p{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return this.hass?.language??navigator.language.split("-")[0]??"en"}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(a,n){this._entryId=a,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(a){this._error=h(a,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(a=>a.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let a=this._lang,n=this._entryId?i("edit_object",a):i("new_object",a);return l`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${n}</div>
|
||||
<div class="content">
|
||||
${this._error?l`<div class="error">${this._error}</div>`:o}
|
||||
<ms-textfield
|
||||
label="${i("name",a)}"
|
||||
required
|
||||
.value=${this._name}
|
||||
@input=${t=>this._name=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("manufacturer_optional",a)}"
|
||||
.value=${this._manufacturer}
|
||||
@input=${t=>this._manufacturer=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("model_optional",a)}"
|
||||
.value=${this._model}
|
||||
@input=${t=>this._model=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("serial_number_optional",a)}"
|
||||
.value=${this._serialNumber}
|
||||
@input=${t=>this._serialNumber=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("documentation_url_optional",a)}"
|
||||
type="url"
|
||||
.value=${this._documentationUrl}
|
||||
@input=${t=>this._documentationUrl=t.target.value}
|
||||
></ms-textfield>
|
||||
<ha-area-picker
|
||||
.hass=${this.hass}
|
||||
label="${i("area_id_optional",a)}"
|
||||
.value=${this._areaId}
|
||||
@value-changed=${t=>this._areaId=t.detail.value||""}
|
||||
></ha-area-picker>
|
||||
<ms-textfield
|
||||
label="${i("installation_date_optional",a)}"
|
||||
type="date"
|
||||
.value=${this._installationDate}
|
||||
@input=${t=>this._installationDate=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("warranty_expiry_optional",a)}"
|
||||
type="date"
|
||||
.value=${this._warrantyExpiry}
|
||||
@input=${t=>this._warrantyExpiry=t.target.value}
|
||||
></ms-textfield>
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${{device:this._haDeviceId||void 0}}
|
||||
.schema=${[{name:"device",selector:{device:{}}}]}
|
||||
.computeLabel=${()=>i("link_device_optional",a)}
|
||||
@value-changed=${t=>this._haDeviceId=t.detail.value?.device||""}
|
||||
></ha-form>
|
||||
${this._parentChoices().length?l`<label class="textarea-field">
|
||||
<span class="textarea-label">${i("parent_object_optional",a)}</span>
|
||||
<select
|
||||
class="parent-select"
|
||||
.value=${this._parentEntryId}
|
||||
@change=${t=>this._parentEntryId=t.target.value}
|
||||
>
|
||||
<option value="" ?selected=${!this._parentEntryId}>
|
||||
${i("parent_none",a)}
|
||||
</option>
|
||||
${this._parentChoices().map(t=>l`<option
|
||||
value=${t.entry_id}
|
||||
?selected=${this._parentEntryId===t.entry_id}
|
||||
>${t.object.name}</option>`)}
|
||||
</select>
|
||||
</label>`:o}
|
||||
<label class="textarea-field">
|
||||
<span class="textarea-label">${i("object_notes_optional",a)}</span>
|
||||
<textarea
|
||||
rows="3"
|
||||
.value=${this._notes}
|
||||
@input=${t=>this._notes=t.target.value}
|
||||
></textarea>
|
||||
</label>
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${i("cancel",this._lang)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._save}
|
||||
.disabled=${this._loading||!this._name.trim()}
|
||||
>
|
||||
${this._loading?i("saving",this._lang):i("save",this._lang)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}};e.styles=_`
|
||||
.dialog-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
min-width: 300px;
|
||||
}
|
||||
.dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
ms-textfield {
|
||||
display: block;
|
||||
}
|
||||
.textarea-field {
|
||||
display: flex; flex-direction: column; gap: 4px;
|
||||
}
|
||||
.textarea-label {
|
||||
font-size: 12px; color: var(--secondary-text-color, #888); font-weight: 500;
|
||||
}
|
||||
.textarea-field textarea {
|
||||
padding: 8px 10px; font-size: 14px; font-family: inherit;
|
||||
background: var(--secondary-background-color, rgba(0,0,0,0.06));
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
resize: vertical;
|
||||
}
|
||||
.textarea-field textarea:focus {
|
||||
outline: none; border-color: var(--primary-color);
|
||||
}
|
||||
.parent-select {
|
||||
padding: 8px 10px; font-size: 14px; font-family: inherit;
|
||||
background: var(--secondary-background-color, rgba(0,0,0,0.06));
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
}
|
||||
.error {
|
||||
color: var(--error-color, #f44336);
|
||||
font-size: 13px;
|
||||
}
|
||||
`,r([d({attribute:!1})],e.prototype,"hass",2),r([d({attribute:!1})],e.prototype,"objects",2),r([s()],e.prototype,"_open",2),r([s()],e.prototype,"_loading",2),r([s()],e.prototype,"_error",2),r([s()],e.prototype,"_name",2),r([s()],e.prototype,"_manufacturer",2),r([s()],e.prototype,"_model",2),r([s()],e.prototype,"_serialNumber",2),r([s()],e.prototype,"_areaId",2),r([s()],e.prototype,"_installationDate",2),r([s()],e.prototype,"_warrantyExpiry",2),r([s()],e.prototype,"_documentationUrl",2),r([s()],e.prototype,"_notes",2),r([s()],e.prototype,"_haDeviceId",2),r([s()],e.prototype,"_parentEntryId",2),r([s()],e.prototype,"_entryId",2);customElements.get("maintenance-object-dialog")||customElements.define("maintenance-object-dialog",e);export{e as MaintenanceObjectDialog};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a,b as v,c as n,f as g,g as b,i as m,j as c,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";function p(l){return l.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function x(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":p(l)}function $(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var r=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,o,s){this._entryId=e,this._taskId=i,this._objectName=o,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let o=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&o.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(o);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let o=i?.code,s=i?.message;this._error=o==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,o=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let h=this.lang||"en",d=p(i),u=p(o),_=!!this._completeResult,f=p(t("qr_action_view",h)),w=p(t("qr_action_complete",h));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{a,b as v,c as n,f as g,g as b,i as m,j as c,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";function p(l){return l.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function x(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":p(l)}function $(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var r=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,o,s){this._entryId=e,this._taskId=i,this._objectName=o,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let o=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&o.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(o);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let o=i?.code,s=i?.message;this._error=o==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,o=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let h=this.lang||"en",d=p(i),u=p(o),_=!!this._completeResult,f=p(t("qr_action_view",h)),w=p(t("qr_action_complete",h));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
<meta name="color-scheme" content="light">
|
||||
<title>${d}</title>
|
||||
<style>
|
||||
@@ -1,213 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{a,b as v,c as n,f as g,g as b,i as m,j as c,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";function p(l){return l.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function x(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":p(l)}function $(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var r=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,o,s){this._entryId=e,this._taskId=i,this._objectName=o,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let o=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&o.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(o);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let o=i?.code,s=i?.message;this._error=o==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,o=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let h=this.lang||"en",d=p(i),u=p(o),_=!!this._completeResult,f=p(t("qr_action_view",h)),w=p(t("qr_action_complete",h));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
<meta name="color-scheme" content="light">
|
||||
<title>${d}</title>
|
||||
<style>
|
||||
/* Printable sheet \u2014 must not inherit the phone's dark theme. The QR images
|
||||
carry their own white quiet zone and stay scannable either way, but the
|
||||
labels below are explicit dark greys and would vanish on a WebView's dark
|
||||
canvas. Same reasoning as helpers/report.ts. */
|
||||
:root{color-scheme:light}
|
||||
body{font-family:sans-serif;text-align:center;padding:20px;background:#fff;color:#1a1a1a}
|
||||
h2{margin:0 0 4px}
|
||||
.sub{color:#666;font-size:14px;margin-bottom:16px}
|
||||
.qr-row{display:flex;justify-content:center;gap:24px;margin:12px 0}
|
||||
.qr-col{display:flex;flex-direction:column;align-items:center;gap:6px}
|
||||
.qr-col img{width:${_?"200px":"280px"}}
|
||||
.qr-label{font-size:13px;font-weight:500;color:#333}
|
||||
.url{font-size:10px;color:#999;word-break:break-all;margin-top:8px;max-width:480px}
|
||||
</style></head><body>
|
||||
<h2>${d}</h2>
|
||||
${u?`<div class="sub">${u}</div>`:""}
|
||||
<div class="qr-row">
|
||||
<div class="qr-col">
|
||||
<img src="${x(this._viewResult.svg_data_uri)}" alt="QR Info" />
|
||||
<div class="qr-label">${f}</div>
|
||||
</div>
|
||||
${_?`<div class="qr-col">
|
||||
<img src="${x(this._completeResult.svg_data_uri)}" alt="QR Complete" />
|
||||
<div class="qr-label">${w}</div>
|
||||
</div>`:""}
|
||||
</div>
|
||||
<div class="url">${p(this._viewResult.url)}</div>
|
||||
<script>setTimeout(()=>window.print(),300)<\/script>
|
||||
</body></html>`),s.document.close()}_downloadSvg(e,i){let o=decodeURIComponent(e.svg_data_uri.replace("data:image/svg+xml,","")),s=new Blob([o],{type:"image/svg+xml"}),h=URL.createObjectURL(s),d=document.createElement("a");d.href=h;let u=this._taskName?`${this._objectName}-${this._taskName}`:this._objectName;d.download=`qr-${$(u)}-${i}.svg`,d.click(),URL.revokeObjectURL(h)}_close(){this._open=!1,this._viewResult=null,this._completeResult=null,this._error="",this._loading=!1}render(){if(!this._open)return n``;let e=this.lang||this.hass?.language||"en",i=this._taskName?`${t("qr_code",e)}: ${this._objectName} \u2014 ${this._taskName}`:`${t("qr_code",e)}: ${this._objectName}`,o=!!this._viewResult;return n`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${i}</div>
|
||||
<div class="content">
|
||||
${this._loading?n`<div class="loading">${t("qr_generating",e)}</div>`:this._error?n`<div class="error">${this._error}</div>`:o?n`
|
||||
<div class="qr-pair">
|
||||
<div class="qr-item">
|
||||
<img
|
||||
class="qr-image ${this._completeResult?"small":""}"
|
||||
src="${this._viewResult.svg_data_uri}"
|
||||
alt="QR Info"
|
||||
/>
|
||||
<div class="qr-item-label">${t("qr_action_view",e)}</div>
|
||||
<button class="dl-btn"
|
||||
@click=${()=>this._downloadSvg(this._viewResult,"info")}>
|
||||
<ha-icon icon="mdi:download"></ha-icon>
|
||||
${t("qr_download",e)}
|
||||
</button>
|
||||
</div>
|
||||
${this._completeResult?n`
|
||||
<div class="qr-item">
|
||||
<img
|
||||
class="qr-image small"
|
||||
src="${this._completeResult.svg_data_uri}"
|
||||
alt="QR Complete"
|
||||
/>
|
||||
<div class="qr-item-label">${t("qr_action_complete",e)}</div>
|
||||
<button class="dl-btn"
|
||||
@click=${()=>this._downloadSvg(this._completeResult,"complete")}>
|
||||
<ha-icon icon="mdi:download"></ha-icon>
|
||||
${t("qr_download",e)}
|
||||
</button>
|
||||
</div>
|
||||
`:g}
|
||||
</div>
|
||||
<div class="url-display">${this._viewResult.url}</div>
|
||||
`:g}
|
||||
<div class="action-row">
|
||||
<label>${t("qr_url_mode",e)}</label>
|
||||
<div class="action-toggle">
|
||||
<button class="toggle-btn ${this._urlMode==="companion"?"active":""}"
|
||||
@click=${()=>this._setUrlMode("companion")}>${t("qr_mode_companion",e)}</button>
|
||||
<button class="toggle-btn ${this._urlMode==="local"?"active":""}"
|
||||
@click=${()=>this._setUrlMode("local")}>${t("qr_mode_local",e)}</button>
|
||||
<button class="toggle-btn ${this._urlMode==="server"?"active":""}"
|
||||
@click=${()=>this._setUrlMode("server")}>${t("qr_mode_server",e)}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${t("cancel",e)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._print}
|
||||
.disabled=${!o}
|
||||
>
|
||||
${t("qr_print",e)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}};r.styles=v`
|
||||
.dialog-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
min-width: 300px;
|
||||
}
|
||||
.dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
.qr-pair {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
.qr-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.qr-image {
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
.qr-image.small {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
}
|
||||
.qr-item-label {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--secondary-text-color);
|
||||
text-align: center;
|
||||
}
|
||||
.dl-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
background: none;
|
||||
border: 1px solid var(--divider-color, #e0e0e0);
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--primary-text-color);
|
||||
padding: 6px 14px;
|
||||
border-radius: 18px;
|
||||
transition: background 0.2s, border-color 0.2s;
|
||||
}
|
||||
.dl-btn:hover {
|
||||
background: var(--secondary-background-color, #f5f5f5);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
.dl-btn ha-icon {
|
||||
--mdc-icon-size: 18px;
|
||||
}
|
||||
.url-display {
|
||||
font-size: 11px;
|
||||
color: var(--secondary-text-color);
|
||||
word-break: break-all;
|
||||
text-align: center;
|
||||
max-width: 400px;
|
||||
}
|
||||
.loading {
|
||||
padding: 40px 0;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.error {
|
||||
padding: 20px 0;
|
||||
color: var(--error-color, #f44336);
|
||||
}
|
||||
.action-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
}
|
||||
.action-row label {
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.action-toggle {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
background: var(--divider-color, #e0e0e0);
|
||||
border-radius: 6px;
|
||||
padding: 3px;
|
||||
}
|
||||
.toggle-btn {
|
||||
flex: 1;
|
||||
padding: 8px 12px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--primary-text-color);
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
transition: all 0.2s;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.toggle-btn:hover {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.toggle-btn.active {
|
||||
background: var(--primary-color);
|
||||
color: var(--text-primary-color, #fff);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
`,a([m({attribute:!1})],r.prototype,"hass",2),a([m()],r.prototype,"lang",2),a([c()],r.prototype,"_open",2),a([c()],r.prototype,"_loading",2),a([c()],r.prototype,"_error",2),a([c()],r.prototype,"_viewResult",2),a([c()],r.prototype,"_completeResult",2),a([c()],r.prototype,"_urlMode",2);customElements.get("maintenance-qr-dialog")||customElements.define("maintenance-qr-dialog",r);export{r as MaintenanceQrDialog};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{a as x,c as $,d as q}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DV4UHMJC.js";import{a as T}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-I7J3AORE.js";import{a as l,b as w,c as r,e as k,f as p,g as E,i as b,j as d,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var S={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},j=m=>(..._)=>({_$litDirective$:m,values:_}),f=class{constructor(_){}get _$AU(){return this._$AM._$AU}_$AT(_,e,s){this._$Ct=_,this._$AM=e,this._$Ci=s}_$AS(_,e){return this.update(_,e)}update(_,e){return this.render(...e)}};var u=class extends f{constructor(_){if(super(_),this.it=p,_.type!==S.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(_){if(_===p||_==null)return this._t=void 0,this.it=_;if(_===k)return _;if(typeof _!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(_===this.it)return this._t;this.it=_;let e=[_];return e.raw=e,this._t={_$litType$:this.constructor.resultType,strings:e,values:[]}}};u.directiveName="unsafeHTML",u.resultType=1;var A=j(u);var H=["EUR","USD","GBP","JPY","CHF","CAD","AUD","NZD","CNY","INR","BRL","CZK","PLN","RUB","SEK","NOK","DKK","UAH"],c=class extends E{constructor(){super(...arguments);this.budget=null;this._settings=null;this._loading=!0;this._importCsv="";this._importLoading=!1;this._includeHistory=!0;this._toast="";this._testingNotification=!1;this._personTargets=[];this._testingUser="";this._users=[];this._savedViews=[];this._vacEnabled=!1;this._vacStart="";this._vacEnd="";this._vacBuffer=3;this._vacExempt=new Set;this._vacIsActive=!1;this._vacWindowEnd=null;this._vacAllTasks=[];this._vacPreview=[];this._vacPreviewLoading=!1;this._vacSaving=!1;this._qrObjects=[];this._qrSelectedEntries=new Set;this._qrActions=new Set(["view"]);this._qrUrlMode="companion";this._qrBatchLoading=!1;this._qrBatchResults=[];this._qrObjectsLoaded=!1;this._exportObjects=[];this._exportSelectedEntries=new Set;this._exportObjectsLoaded=!1;this._docArchiveLoading=!1;this._loaded=!1;this._userService=null;this._sendTestNotification=async e=>{e?this._testingUser=e:this._testingNotification=!0;try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/test_notification",...e?{user_id:e}:{}}),a=s.message||(s.success?t("test_notification_success",this._lang):t("test_notification_failed",this._lang));this._showToast(a)}catch{this._showToast(t("test_notification_failed",this._lang))}finally{e?this._testingUser="":this._testingNotification=!1}};this._allTemplates=[];this._templateCategories={};this._tplOpenGroups=new Set;this._templatesRequested=!1}get _lang(){return this.hass?.language||"en"}updated(e){super.updated(e),e.has("hass")&&this.hass&&!this._loaded?(this._loaded=!0,this._userService=new T(this.hass),this._loadSettings(),this._loadUsers()):e.has("hass")&&this.hass&&this._userService&&this._userService.updateHass(this.hass)}async _loadUsers(){if(this._userService){try{this._users=await this._userService.getUsers()}catch{this._users=[]}this._loadNotifyTargets()}}async _loadNotifyTargets(){try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/notify/user_targets"});this._personTargets=e.targets||[]}catch{this._personTargets=[]}}async _loadSettings(){this._loading=!0;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/settings"});this._settings=e,this._hydrateVacationFromSettings()}catch{}try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/views/list"});this._savedViews=e.views||[]}catch{}this._loading=!1}_hydrateVacationFromSettings(){let e=this._settings?.vacation;e&&(this._vacEnabled=e.enabled,this._vacStart=e.start||"",this._vacEnd=e.end||"",this._vacBuffer=e.buffer_days,this._vacExempt=new Set(e.exempt_task_ids||[]),this._vacIsActive=e.is_active,this._vacWindowEnd=e.window_end)}async _updateSetting(e,s){try{let a=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:{[e]:s}});this._settings=a,this._showToast(t("settings_saved",this._lang)),this.dispatchEvent(new CustomEvent("settings-changed"))}catch{this._showToast(t("action_error",this._lang))}}_showToast(e){this._toast=e,setTimeout(()=>{this._toast=""},3e3)}_downloadFile(e,s,a){q(e,s,a)}render(){let e=this._lang;return this._loading||!this._settings?r`<div class="settings-loading">Loading…</div>`:r`
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{a as x,c as $,d as q}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-T5QK5YQR.js";import{a as T}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GKQ6LXK5.js";import{a as l,b as w,c as r,e as k,f as p,g as E,i as b,j as d,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var S={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},j=m=>(..._)=>({_$litDirective$:m,values:_}),f=class{constructor(_){}get _$AU(){return this._$AM._$AU}_$AT(_,e,s){this._$Ct=_,this._$AM=e,this._$Ci=s}_$AS(_,e){return this.update(_,e)}update(_,e){return this.render(...e)}};var u=class extends f{constructor(_){if(super(_),this.it=p,_.type!==S.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(_){if(_===p||_==null)return this._t=void 0,this.it=_;if(_===k)return _;if(typeof _!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(_===this.it)return this._t;this.it=_;let e=[_];return e.raw=e,this._t={_$litType$:this.constructor.resultType,strings:e,values:[]}}};u.directiveName="unsafeHTML",u.resultType=1;var A=j(u);var H=["EUR","USD","GBP","JPY","CHF","CAD","AUD","NZD","CNY","INR","BRL","CZK","PLN","RUB","SEK","NOK","DKK","UAH"],c=class extends E{constructor(){super(...arguments);this.budget=null;this._settings=null;this._loading=!0;this._importCsv="";this._importLoading=!1;this._includeHistory=!0;this._toast="";this._testingNotification=!1;this._personTargets=[];this._testingUser="";this._users=[];this._savedViews=[];this._vacEnabled=!1;this._vacStart="";this._vacEnd="";this._vacBuffer=3;this._vacExempt=new Set;this._vacIsActive=!1;this._vacWindowEnd=null;this._vacAllTasks=[];this._vacPreview=[];this._vacPreviewLoading=!1;this._vacSaving=!1;this._qrObjects=[];this._qrSelectedEntries=new Set;this._qrActions=new Set(["view"]);this._qrUrlMode="companion";this._qrBatchLoading=!1;this._qrBatchResults=[];this._qrObjectsLoaded=!1;this._exportObjects=[];this._exportSelectedEntries=new Set;this._exportObjectsLoaded=!1;this._docArchiveLoading=!1;this._loaded=!1;this._userService=null;this._sendTestNotification=async e=>{e?this._testingUser=e:this._testingNotification=!0;try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/test_notification",...e?{user_id:e}:{}}),a=s.message||(s.success?t("test_notification_success",this._lang):t("test_notification_failed",this._lang));this._showToast(a)}catch{this._showToast(t("test_notification_failed",this._lang))}finally{e?this._testingUser="":this._testingNotification=!1}};this._allTemplates=[];this._templateCategories={};this._tplOpenGroups=new Set;this._templatesRequested=!1}get _lang(){return this.hass?.language||"en"}updated(e){super.updated(e),e.has("hass")&&this.hass&&!this._loaded?(this._loaded=!0,this._userService=new T(this.hass),this._loadSettings(),this._loadUsers()):e.has("hass")&&this.hass&&this._userService&&this._userService.updateHass(this.hass)}async _loadUsers(){if(this._userService){try{this._users=await this._userService.getUsers()}catch{this._users=[]}this._loadNotifyTargets()}}async _loadNotifyTargets(){try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/notify/user_targets"});this._personTargets=e.targets||[]}catch{this._personTargets=[]}}async _loadSettings(){this._loading=!0;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/settings"});this._settings=e,this._hydrateVacationFromSettings()}catch{}try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/views/list"});this._savedViews=e.views||[]}catch{}this._loading=!1}_hydrateVacationFromSettings(){let e=this._settings?.vacation;e&&(this._vacEnabled=e.enabled,this._vacStart=e.start||"",this._vacEnd=e.end||"",this._vacBuffer=e.buffer_days,this._vacExempt=new Set(e.exempt_task_ids||[]),this._vacIsActive=e.is_active,this._vacWindowEnd=e.window_end)}async _updateSetting(e,s){try{let a=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:{[e]:s}});this._settings=a,this._showToast(t("settings_saved",this._lang)),this.dispatchEvent(new CustomEvent("settings-changed"))}catch{this._showToast(t("action_error",this._lang))}}_showToast(e){this._toast=e,setTimeout(()=>{this._toast=""},3e3)}_downloadFile(e,s,a){q(e,s,a)}render(){let e=this._lang;return this._loading||!this._settings?r`<div class="settings-loading">Loading…</div>`:r`
|
||||
${this._renderFeatures(e)}
|
||||
${this._renderPanelAccess(e)}
|
||||
${this._renderGeneral(e)}
|
||||
-1141
File diff suppressed because it is too large.
Load diff
-146
@@ -1,146 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LJXSDCLS.js";import{a as l,b as m,c as i,f as h,g as v,i as u,j as d,n as p,p as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,f(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||
<div class="title">${p("setups_title",t)}</div>
|
||||
<div class="hint">${p("setups_hint",t)}</div>
|
||||
${this._error?i`<div class="error">${this._error}</div>`:h}
|
||||
|
||||
${this._loading?i`<div class="loading">…</div>`:this._setups.length===0?i`<div class="empty">${p("setups_none",t)}</div>`:i`
|
||||
<div class="list">
|
||||
${this._setups.map(e=>{let r=this._selected.has(e.device_id),c=[e.integration_name,e.area_name].filter(Boolean).join(" \xB7 ");return i`
|
||||
<label class="row">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${r}
|
||||
@change=${()=>this._toggle(e.device_id)}
|
||||
/>
|
||||
<div class="row-main">
|
||||
<div class="row-top">
|
||||
<span class="row-name">${e.device_name}</span>
|
||||
</div>
|
||||
<div class="row-sub">${c}</div>
|
||||
<div class="row-target" @click=${s=>s.preventDefault()}>
|
||||
→
|
||||
${r&&this._objects.length>0?i`
|
||||
<select
|
||||
class="target-select"
|
||||
@change=${s=>{let n=new Map(this._targets),o=s.target.value;o?n.set(e.device_id,o):n.delete(e.device_id),this._targets=n}}
|
||||
>
|
||||
<option value="" ?selected=${!this._targets.get(e.device_id)}>
|
||||
${e.suggested_entry_id?e.suggested_object_name:p("setups_target_new",t).replace("{name}",e.suggested_object_name)}
|
||||
</option>
|
||||
${this._objects.filter(s=>s.entry_id!==e.suggested_entry_id).map(s=>i`<option
|
||||
value=${s.entry_id}
|
||||
?selected=${this._targets.get(e.device_id)===s.entry_id}
|
||||
>
|
||||
${s.name}
|
||||
</option>`)}
|
||||
</select>
|
||||
`:i`${e.suggested_object_name}${e.suggested_entry_id?h:i` <span class="new-tag">${p("adopt_problem_new_object",t)}</span>`}`}
|
||||
</div>
|
||||
<div class="row-tasks">
|
||||
${e.tasks.map(s=>i`<span class="chip" title=${s.entity_ids.join(", ")}>
|
||||
<ha-icon icon="mdi:link-variant"></ha-icon>${s.task_name_localized||s.task_name}
|
||||
</span>`)}
|
||||
</div>
|
||||
${r?e.tasks.filter(s=>s.direction==="usage_delta").map(s=>{let n=`${e.device_id} ${s.task_name}`;return i`
|
||||
<div class="baseline-field" @click=${o=>o.preventDefault()}>
|
||||
<span class="baseline-label"
|
||||
>${s.task_name_localized||s.task_name} —
|
||||
${p("setups_baseline_hint",t)}</span
|
||||
>
|
||||
<input
|
||||
type="number"
|
||||
step="any"
|
||||
min="0"
|
||||
.value=${this._baselines.get(n)??""}
|
||||
@click=${o=>o.preventDefault()}
|
||||
@input=${o=>{let _=new Map(this._baselines);_.set(n,o.target.value),this._baselines=_}}
|
||||
/>
|
||||
</div>
|
||||
`}):h}
|
||||
</div>
|
||||
</label>
|
||||
`})}
|
||||
</div>
|
||||
`}
|
||||
|
||||
<div class="actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${p("cancel",t)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._adopt}
|
||||
.disabled=${this._selected.size===0||this._adopting}
|
||||
>
|
||||
${p("setups_adopt",t)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`}};a.styles=m`
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
min-width: min(360px, calc(100vw - 24px));
|
||||
max-width: 560px;
|
||||
width: 90vw;
|
||||
max-height: 80vh;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.title { font-size: 18px; font-weight: 500; }
|
||||
.hint { color: var(--secondary-text-color); font-size: 13px; }
|
||||
.error { color: var(--error-color, #f44336); font-size: 13px; }
|
||||
.loading, .empty { color: var(--secondary-text-color); font-size: 14px; padding: 12px 0; }
|
||||
.list { display: flex; flex-direction: column; gap: 6px; overflow-y: auto; max-height: 50vh; }
|
||||
.row {
|
||||
display: flex; align-items: flex-start; gap: 10px; padding: 8px;
|
||||
border: 1px solid var(--divider-color); border-radius: 6px; cursor: pointer;
|
||||
}
|
||||
.row input { margin-top: 2px; cursor: pointer; }
|
||||
.row-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
|
||||
.row-name { font-weight: 500; font-size: 13px; }
|
||||
.row-sub, .row-target { color: var(--secondary-text-color); font-size: 12px; }
|
||||
.new-tag { font-style: italic; }
|
||||
.row-tasks { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
|
||||
.chip {
|
||||
display: inline-flex; align-items: center; gap: 4px;
|
||||
font-size: 11px; padding: 2px 8px; border-radius: 10px;
|
||||
background: var(--secondary-background-color, rgba(0, 0, 0, 0.06));
|
||||
color: var(--primary-text-color); white-space: nowrap;
|
||||
}
|
||||
.chip ha-icon { --mdc-icon-size: 12px; color: var(--primary-color); }
|
||||
.target-select {
|
||||
font-size: 12px; padding: 2px 4px; max-width: 100%;
|
||||
border: 1px solid var(--divider-color); border-radius: 4px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.baseline-field {
|
||||
display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
|
||||
margin-top: 4px; font-size: 12px; color: var(--secondary-text-color);
|
||||
}
|
||||
.baseline-field input {
|
||||
width: 110px; padding: 3px 6px; font-size: 12px;
|
||||
border: 1px solid var(--divider-color); border-radius: 4px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 8px; }
|
||||
`,l([u({attribute:!1})],a.prototype,"hass",2),l([d()],a.prototype,"_open",2),l([d()],a.prototype,"_loading",2),l([d()],a.prototype,"_adopting",2),l([d()],a.prototype,"_error",2),l([d()],a.prototype,"_setups",2),l([d()],a.prototype,"_selected",2),l([d()],a.prototype,"_baselines",2),l([d()],a.prototype,"_targets",2),l([d()],a.prototype,"_objects",2);customElements.get("maintenance-suggested-setups-dialog")||customElements.define("maintenance-suggested-setups-dialog",a);export{a as MaintenanceSuggestedSetupsDialog};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as l,b as m,c as i,f as h,g as v,i as u,j as d,n as p,p as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,f(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NU5DR7VT.js";import{a as l,b as m,c as i,f as h,g as v,i as u,j as d,n as p,p as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,f(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||
<div class="title">${p("setups_title",t)}</div>
|
||||
-983
@@ -1,983 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-BDAGEP22.js";import{a as A,b as L}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-7QFSK25W.js";import{a as x}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4HD7ODUX.js";import{a as C}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6RMRSFSY.js";import{a,b as T,c as l,f as u,g as I,i as b,j as o,n as s,r as S,u as $}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var P=["cleaning","inspection","replacement","calibration","service","reading","custom"],N=["low","normal","high"],F=["time_based","weekdays","nth_weekday","day_of_month","sensor_based","one_time","manual"],E=["weekdays","nth_weekday","day_of_month"],H=["threshold","counter","state_change","runtime"],R=[...H,"compound"];function q(){return{entityIds:"",type:"threshold",above:"",below:"",forMinutes:"0",targetValue:"",deltaMode:!1,fromState:"",toState:"",targetChanges:"",runtimeHours:"",onStates:"",carry:{}}}var O=new Set(["entity_id","entity_ids","type","trigger_above","trigger_below","trigger_for_minutes","trigger_target_value","trigger_delta_mode","trigger_from_state","trigger_to_state","trigger_target_changes","trigger_runtime_hours","trigger_on_states"]);function U(p){return{entityIds:(p.entity_ids||(p.entity_id?[p.entity_id]:[])).join(", "),type:p.type||"threshold",above:p.trigger_above?.toString()??"",below:p.trigger_below?.toString()??"",forMinutes:p.trigger_for_minutes?.toString()??"0",targetValue:p.trigger_target_value?.toString()??"",deltaMode:p.trigger_delta_mode||!1,fromState:p.trigger_from_state||"",toState:p.trigger_to_state||"",targetChanges:p.trigger_target_changes?.toString()??"",runtimeHours:p.trigger_runtime_hours?.toString()??"",onStates:(p.trigger_on_states||[]).join(", "),carry:Object.fromEntries(Object.entries(p).filter(([e])=>!O.has(e)&&!e.startsWith("_")))}}function M(p){let y=p.entityIds.split(",").map(i=>i.trim()).filter(Boolean);if(y.length===0)return null;let e={...p.carry||{},entity_id:y[0],entity_ids:y,type:p.type};if(p.type==="threshold"){let i=parseFloat(p.above);isNaN(i)||(e.trigger_above=i);let t=parseFloat(p.below);isNaN(t)||(e.trigger_below=t);let r=parseInt(p.forMinutes,10);isNaN(r)||(e.trigger_for_minutes=r)}else if(p.type==="counter"){let i=parseFloat(p.targetValue);isNaN(i)||(e.trigger_target_value=i),e.trigger_delta_mode=p.deltaMode}else if(p.type==="state_change"){p.fromState&&(e.trigger_from_state=p.fromState),p.toState&&(e.trigger_to_state=p.toState);let i=parseInt(p.targetChanges,10);isNaN(i)||(e.trigger_target_changes=i)}else if(p.type==="runtime"){let i=parseFloat(p.runtimeHours);isNaN(i)||(e.trigger_runtime_hours=i);let t=(p.onStates||"").split(",").map(r=>r.trim()).filter(Boolean);t.length>0&&(e.trigger_on_states=t)}return e}function j(p){return Array.from({length:7},(y,e)=>$(e,p,"short"))}function B(p){let y=new Intl.DateTimeFormat(p||"en",{month:"short"});return Array.from({length:12},(e,i)=>y.format(new Date(2021,i,1)))}var n=class n extends I{constructor(){super(...arguments);this.checklistsEnabled=!1;this.scheduleTimeEnabled=!1;this.completionActionsEnabled=!1;this.defaultWarningDays=7;this.parts=[];this._foreignOwners=[];this._open=!1;this._loading=!1;this._error="";this._entryId="";this._taskId=null;this._objectChoices=[];this._name="";this._type="custom";this._scheduleType="time_based";this._intervalDays="30";this._intervalUnit="days";this._dueDate="";this._warningDays="7";this._earliestCompletionDays="";this._intervalAnchor="completion";this._weekdays=[];this._nth="1";this._nthWeekday="5";this._domDay="1";this._domLastDay=!1;this._domBusiness=!1;this._calOffset="0";this._seasonMonths=[];this._endsMode="never";this._endsCount="";this._endsUntil="";this._schedulePreview=[];this._schedulePreviewEnded=!1;this._previewSeq=0;this._notes="";this._documentationUrl="";this._customIcon="";this._priority="normal";this._labels="";this._enabled=!0;this._triggerEntityId="";this._triggerEntityIds=[];this._triggerEntityLogic="any";this._triggerAttribute="";this._triggerType="threshold";this._triggerAbove="";this._triggerBelow="";this._triggerForMinutes="0";this._triggerTargetValue="";this._triggerDeltaMode=!1;this._triggerBaselineValue="";this._liveBaselineValue=null;this._autoCompleteOnRecovery=!1;this._triggerFromState="";this._triggerToState="";this._triggerTargetChanges="";this._triggerRuntimeHours="";this._triggerOnStates="";this._compoundLogic="AND";this._compoundConditions=[];this._suggestedAttributes=[];this._availableAttributes=[];this._entityDomain="";this._lastPerformed="";this._nfcTagId="";this._readingUnit="";this._consumesParts={};this._partsLoadFailed=!1;this._availableTags=[];this._responsibleUserId=null;this._assigneePool=[];this._rotationStrategy="";this._availableUsers=[];this._checklistText="";this._requiredCompletion=[];this._scheduleTime="";this._actionService="";this._actionTargetEntity="";Line truncated
|
||||
`),this._requiredCompletion=[...i.required_completion_fields||[]],this._scheduleTime=i.schedule_time||"";let _=i.on_complete_action;if(_&&_.service){this._actionService=_.service;let d=_.target?.entity_id;this._actionTargetEntity=Array.isArray(d)?d[0]||"":d||"",this._actionData=_.data&&typeof _.data=="object"?{..._.data}:{},this._actionDataJsonFallback=""}else this._actionService="",this._actionTargetEntity="",this._actionData={},this._actionDataJsonFallback="";let c=i.quick_complete_defaults;this._qcNotes=c?.notes||"",this._qcCost=c?.cost!=null?String(c.cost):"",this._qcDuration=c?.duration!=null?String(c.duration):"",this._qcFeedback=c?.feedback||"";let h=i.adaptive_config||{};if(this._environmentalEntity=h.environmental_entity||"",this._environmentalAttribute=h.environmental_attribute||"",this._environmentalInitial=this._environmentalEntity,this._environmentalAttributeInitial=this._environmentalAttribute,i.trigger_config){let d=i.trigger_config;this._triggerEntityId=d.entity_id||d.entity_ids&&d.entity_ids[0]||"",this._triggerEntityIds=d.entity_ids||(d.entity_id?[d.entity_id]:[]),this._triggerEntityLogic=d.entity_logic||"any",this._triggerAttribute=d.attribute||"",this._triggerType=d.type||"threshold",this._triggerAbove=d.trigger_above?.toString()||"",this._triggerBelow=d.trigger_below?.toString()||"",this._triggerForMinutes=d.trigger_for_minutes?.toString()||"0",this._triggerTargetValue=d.trigger_target_value?.toString()||"",this._triggerDeltaMode=d.trigger_delta_mode||!1,this._triggerBaselineValue=d.trigger_baseline_value?.toString()||"",this._liveBaselineValue=i.trigger_baseline_value??null,this._autoCompleteOnRecovery=d.auto_complete_on_recovery||!1,this._triggerFromState=d.trigger_from_state||"",this._triggerToState=d.trigger_to_state||"",this._triggerTargetChanges=d.trigger_target_changes?.toString()||"",this._triggerRuntimeHours=d.trigger_runtime_hours?.toString()||"",this._triggerOnStates=(d.trigger_on_states||[]).join(", "),d.type==="compound"?(this._compoundLogic=d.compound_logic==="OR"?"OR":"AND",this._compoundConditions=(d.conditions||[]).map(U)):(this._compoundLogic="AND",this._compoundConditions=[])}else this._resetTriggerFields();this._triggerEntityId&&this._fetchEntityAttributes(this._triggerEntityId),await Promise.all([this._loadUsers(),this._loadTags(),this._loadParts(),this._loadForeignPools()]),this._open=!0}_resetFields(){this._name="",this._type="custom",this._scheduleType="time_based",this._intervalDays="30",this._intervalUnit="days",this._dueDate="",this._warningDays=String(this.defaultWarningDays),this._earliestCompletionDays="",this._intervalAnchor="completion",this._weekdays=[],this._nth="1",this._nthWeekday="5",this._domDay="1",this._domLastDay=!1,this._domBusiness=!1,this._calOffset="0",this._seasonMonths=[],this._endsMode="never",this._endsCount="",this._endsUntil="",this._notes="",this._documentationUrl="",this._customIcon="",this._priority="normal",this._labels="",this._enabled=!0,this._lastPerformed="",this._nfcTagId="",this._readingUnit="",this._consumesParts={},this._responsibleUserId=null,this._assigneePool=[],this._rotationStrategy="",this._checklistText="",this._requiredCompletion=[],this._scheduleTime="",this._environmentalEntity="",this._environmentalAttribute="",this._environmentalInitial="",this._environmentalAttributeInitial="",this._actionService="",this._actionTargetEntity="",this._actionData={},this._actionDataJsonFallback="",this._actionTesting=!1,this._actionTestResult="",this._qcNotes="",this._qcCost="",this._qcDuration="",this._qcFeedback="",this._resetTriggerFields()}_resetTriggerFields(){this._triggerEntityId="",this._triggerEntityIds=[],this._triggerEntityLogic="any",this._triggerAttribute="",this._suggestedAttributes=[],this._availableAttributes=[],this._entityDomain="",this._triggerType="threshold",this._triggerAbove="",this._triggerBelow="",this._triggerForMinutes="0",this._triggerTargetValue="",this._triggerDeltaMode=!1,this._triggerBaselineValue="",this._liveBaselineValue=null,this._autoCompleteOnRecovery=!1,this._triggerFromState="",this._triggerToState="",this._triggerTargetChanges="",this._triggerRuntimeHours="",this._triggerOnStates="",this._compoundLogic="AND",this._compoundConditions=[]}async _loadUsers(){this._userService||(this._userService=new k(this.hass));try{this._availableUsers=await this._userService.getUsers()}catch(e){console.error("Failed to load users:",e),this._availableUsers=[]}}_toggleAssignee(e){this._assigneePool=this._assigneePool.includes(e)?this._assigneePool.filter(i=>i!==e):[...this._assigneePool,e]}async _testAction(){let e=this._actionService.trim();if(!e||!/^[a-z][a-z0-9_]*\.[a-z0-9_]+$/.test(e)){this._actionTestResult="error",this._actionTestError="Invalid service format (expected 'domain.service')",setTimeout(()=>{this._actionTestResult="",this._actionTestError=""},5e3);return}let[i,t]=e.split(".");if(!this.hass?.services?.[i]?.[t]){this._actionTestResult="error",this._actionTestError=`Service "${e}" is not registeLine truncated
|
||||
<details class="ca-section">
|
||||
<summary>${s("on_complete_action_title",e)}</summary>
|
||||
<p class="field-help">${s("on_complete_action_desc",e)}</p>
|
||||
<ha-service-picker
|
||||
.hass=${this.hass}
|
||||
.value=${this._actionService}
|
||||
@value-changed=${t=>{this._actionService=t.detail.value||"";let r=this._serviceSchema();if(r){let _=new Set(r.map(c=>c.name));this._actionData=Object.fromEntries(Object.entries(this._actionData).filter(([c])=>_.has(c)))}}}
|
||||
></ha-service-picker>
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.schema=${[{name:"target_entity",selector:{entity:{}}}]}
|
||||
.data=${{target_entity:this._actionTargetEntity}}
|
||||
.computeLabel=${()=>s("on_complete_action_target",e)}
|
||||
@value-changed=${t=>{let r=t.detail.value;this._actionTargetEntity=r.target_entity||""}}
|
||||
></ha-form>
|
||||
<p class="field-help ca-domain-hint">
|
||||
${s("on_complete_action_target_hint",e)}
|
||||
</p>
|
||||
${i?l`
|
||||
<ha-form
|
||||
class="ca-data-form"
|
||||
.hass=${this.hass}
|
||||
.schema=${i}
|
||||
.data=${this._actionData}
|
||||
@value-changed=${t=>{this._actionData={...t.detail.value}}}
|
||||
></ha-form>
|
||||
`:l`
|
||||
<ms-textfield
|
||||
label="${s("on_complete_action_data",e)}"
|
||||
placeholder="{}"
|
||||
.value=${this._actionDataJsonFallback}
|
||||
@input=${t=>{this._actionDataJsonFallback=t.target.value}}
|
||||
></ms-textfield>
|
||||
`}
|
||||
<div class="ca-test-row">
|
||||
<button type="button" ?disabled=${this._actionTesting||!this._actionService}
|
||||
@click=${this._testAction}>
|
||||
${this._actionTesting?"\u2026":s("on_complete_action_test",e)}
|
||||
</button>
|
||||
${this._actionTestResult==="ok"?l`<span class="ca-test-ok">${s("on_complete_action_test_success",e)}</span>`:u}
|
||||
${this._actionTestResult==="error"?l`<div class="ca-test-error-block">
|
||||
<span class="ca-test-error">${s("on_complete_action_test_failed",e)}</span>
|
||||
${this._actionTestError?l`<div class="ca-test-error-detail">${this._actionTestError}</div>`:u}
|
||||
</div>`:u}
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="ca-section">
|
||||
<summary>${s("quick_complete_defaults_title",e)}</summary>
|
||||
<p class="field-help">${s("quick_complete_defaults_desc",e)}</p>
|
||||
<ms-textfield
|
||||
label="${s("quick_complete_defaults_notes",e)}"
|
||||
.value=${this._qcNotes}
|
||||
@input=${t=>{this._qcNotes=t.target.value}}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${s("quick_complete_defaults_cost",e)}"
|
||||
type="number" min="0" step="0.01"
|
||||
.value=${this._qcCost}
|
||||
@input=${t=>{this._qcCost=t.target.value}}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${s("quick_complete_defaults_duration",e)}"
|
||||
type="number" min="0" step="1"
|
||||
.value=${this._qcDuration}
|
||||
@input=${t=>{this._qcDuration=t.target.value}}
|
||||
></ms-textfield>
|
||||
<select class="qc-feedback"
|
||||
.value=${this._qcFeedback}
|
||||
@change=${t=>{this._qcFeedback=t.target.value}}>
|
||||
<option value="">${s("quick_complete_defaults_feedback_none",e)}</option>
|
||||
<option value="needed">${s("quick_complete_defaults_feedback_needed",e)}</option>
|
||||
<option value="not_needed">${s("quick_complete_defaults_feedback_not_needed",e)}</option>
|
||||
</select>
|
||||
</details>
|
||||
`}async _loadParts(){if(this.parts=[],!!this._entryId)try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object",entry_id:this._entryId});this.parts=e.parts||[],this._partsLoadFailed=!1}catch{this.parts=[],this._partsLoadFailed=!0}}async _loadForeignPools(){if(this._foreignOwners=[],!!this._entryId)try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._foreignOwners=(e.objects||[]).filter(i=>i.entry_id!==this._entryId&&(i.parts||[]).length>0).map(i=>({entry_id:i.entry_id,name:i.object?.name||i.entry_id,parts:i.parts||[]})).sort((i,t)=>i.name.localeCompare(t.name))}catch{this._foreignOwners=[]}}async _loadTags(){try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/tags/list"});this._availableTags=e.tags||[]}catch{this._availableTags=[]}}async _fetchEntityAttributes(e){if(!e||!this.hass){this._suggestedAttributes=[],this._availableAttributes=[],this._entityDomain="";return}try{let i=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/entity/attributes",entity_id:e});this._entityDomain=i.domain||"",this._suggestedAttributes=i.suggested_attributes||[],this._availableAttributes=i.available_attributes||[]}catch{this._suggestedAttributes=[],this._availableAttributes=[],this._entityDomain=""}}get _hasForeignPick(){return Object.values(this._consumesParts).some(e=>!!e.entry_id)}_renderConsumesRow(e,i){let t=x({part_id:e.id,entry_id:i}),r=this._consumesParts[t],_=i?{part_id:e.id,quantity:1,entry_id:i}:{part_id:e.id,quantity:1};return l`
|
||||
<div class="consumes-row">
|
||||
<label class="consumes-check">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${r!==void 0}
|
||||
@change=${c=>{let h={...this._consumesParts};c.target.checked?h[t]=h[t]||_:delete h[t],this._consumesParts=h}}
|
||||
/>
|
||||
<span>${e.name}${e.unit?` (${e.unit})`:""}</span>
|
||||
</label>
|
||||
${r!==void 0?l`<input
|
||||
class="consumes-qty"
|
||||
type="number"
|
||||
min="0.01"
|
||||
max="999"
|
||||
step="0.01"
|
||||
.value=${String(r.quantity)}
|
||||
@input=${c=>{let h=parseFloat(c.target.value);this._consumesParts={...this._consumesParts,[t]:{..._,quantity:Number.isFinite(h)&&h>=.01?h:1}}}}
|
||||
/>`:u}
|
||||
</div>
|
||||
`}_toggleRequired(e,i){let t=new Set(this._requiredCompletion);i?t.add(e):t.delete(e),this._requiredCompletion=[...t]}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{let e={type:this._taskId?"maintenance_supporter/task/update":"maintenance_supporter/task/create",entry_id:this._entryId,name:this._name,task_type:this._type,schedule_type:this._scheduleType,warning_days:Number.isNaN(parseInt(this._warningDays,10))?this.defaultWarningDays:Math.max(0,parseInt(this._warningDays,10))},i=this._earliestCompletionDays.trim();if(e.earliest_completion_days=i===""?null:Math.max(0,parseInt(i,10)||0),this._taskId&&(e.task_id=this._taskId),this._scheduleType==="one_time"?(e.due_date=this._dueDate||null,e.interval_days=null):E.includes(this._scheduleType)?(e.schedule={...this._buildSchedule(),...this._recurrenceExtras()},e.interval_days=null,this._taskId&&(e.due_date=null)):(this._taskId&&(e.due_date=null),this._scheduleType!=="manual"&&this._intervalDays?(e.interval_days=parseInt(this._intervalDays,10),e.interval_unit=this._intervalUnit,e.interval_anchor=this._intervalAnchor,this._scheduleType==="time_based"&&(e.schedule={kind:"interval",...this._recurrenceExtras()})):this._taskId&&(e.interval_days=null,e.interval_anchor="completion")),e.notes=this._notes||null,e.documentation_url=this._documentationUrl||null,e.custom_icon=this._customIcon||null,e.priority=this._priority,e.labels=this._labels.split(",").map(c=>c.trim()).filter(Boolean),e.enabled=this._enabled,e.last_performed=this._lastPerformed||null,e.nfc_tag_id=this._nfcTagId||null,e.reading_unit=this._readingUnit.trim()||null,(this.parts.length||this._foreignOwners.length)&&(e.consumes_parts=Object.values(this._consumesParts).map(c=>c.entry_id?{part_id:c.part_id,quantity:c.quantity,entry_id:c.entry_id}:{part_id:c.part_id,quantity:c.quantity})),e.responsible_user_id=this._responsibleUserId,e.assignee_pool=this._assigneePool,e.required_completion_fields=this._requiredCompletion,e.rotation_strategy=this._assigneePool.length>=2&&this._rotationStrategy?this._rotationStrategy:null,this._scheduleType==="sensor_based"&&this._triggerType==="compound"){let c=this._compoundConditions.map(M).filter(h=>h!==null);if(c.length>0){let h={type:"compound",compound_logic:this._compoundLogic,conditions:c};this._autoCompleteOnRecovery&&(h.auto_complete_on_recovery=!0),e.trigger_config=h}else this._taskId&&(e.trigger_config=null)}else if(this._scheduleType==="sensor_based"&&this._triggerEntityId){let c=this._triggerEntityIds.length>0?this._triggerEntityIds:[this._triggerEntityId],h={entity_id:c[0],entity_ids:c,type:this._triggerType};if(this._triggerAttribute&&(h.attribute=this._triggerAttribute),this._autoCompleteOnRecovery&&(h.auto_complete_on_recovery=!0),c.length>1&&(h.entity_logic=this._triggerEntityLogic),this._triggerType==="threshold"){if(this._triggerAbove){let d=parseFloat(this._triggerAbove);isNaN(d)||(h.trigger_above=d)}if(this._triggerBelow){let d=parseFloat(this._triggerBelow);isNaN(d)||(h.trigger_below=d)}if(this._triggerForMinutes){let d=parseInt(this._triggerForMinutes,10);isNaN(d)||(h.trigger_for_minutes=d)}}else if(this._triggerType==="counter"){if(this._triggerTargetValue){let d=parseFloat(this._triggerTargetValue);isNaN(d)||(h.trigger_target_value=d)}if(h.trigger_delta_mode=this._triggerDeltaMode,this._triggerDeltaMode&&this._triggerBaselineValue){let d=parseFloat(this._triggerBaselineValue);!isNaN(d)&&d>=0&&(h.trigger_baseline_value=d)}}else if(this._triggerType==="state_change"){if(this._triggerFromState&&(h.trigger_from_state=this._triggerFromState),this._triggerToState&&(h.trigger_to_state=this._triggerToState),this._triggerTargetChanges){let d=parseInt(this._triggerTargetChanges,10);isNaN(d)||(h.trigger_target_changes=d)}}else if(this._triggerType==="runtime"){if(this._triggerRuntimeHours){let m=parseFloat(this._triggerRuntimeHours);isNaN(m)||(h.trigger_runtime_hours=m)}let d=this._triggerOnStates.split(",").map(m=>m.trim()).filter(Boolean);d.length>0&&(h.trigger_on_states=d)}e.trigger_config=h}else this._taskId&&(e.trigger_config=null);if(this.scheduleTimeEnabled&&this._scheduleType==="time_based"){let c=this._scheduleTime.trim();e.schedule_time=/^([01]\d|2[0-3]):[0-5]\d$/.test(c)?c:null}if(this.checklistsEnabled){let c=this._checklistText.split(`
|
||||
`).map(h=>h.trim()).filter(Boolean).slice(0,100);e.checklist=c.length?c:null}if(this.completionActionsEnabled){let c=this._actionService.trim();if(c&&/^[a-z][a-z0-9_]*\.[a-z0-9_]+$/.test(c)){let v={service:c},g=this._actionTargetEntity.trim();g&&(v.target={entity_id:g});let f=this._buildActionData();Object.keys(f).length>0&&(v.data=f),e.on_complete_action=v}else e.on_complete_action=null;let h={};this._qcNotes.trim()&&(h.notes=this._qcNotes.trim());let d=parseFloat(this._qcCost);!isNaN(d)&&d>=0&&(h.cost=d);let m=parseInt(this._qcDuration,10);!isNaN(m)&&m>=0&&(h.duration=m),this._qcFeedback&&(h.feedback=this._qcFeedback),e.quick_complete_defaults=Object.keys(h).length?h:null}let t=await this.hass.connection.sendMessagePromise(e),r=this._taskId||t?.task_id,_=this._environmentalEntity!==this._environmentalInitial||this._environmentalAttribute!==this._environmentalAttributeInitial;if(r&&this._scheduleType==="sensor_based"&&_)try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/set_environmental_entity",entry_id:this._entryId,task_id:r,environmental_entity:this._environmentalEntity||null,environmental_attribute:this._environmentalAttribute||null}),this._environmentalInitial=this._environmentalEntity,this._environmentalAttributeInitial=this._environmentalAttribute}catch{}this._open=!1,this.dispatchEvent(new CustomEvent("task-saved"))}catch(e){this._error=C(e,this._lang,s("save_error",this._lang))}finally{this._loading=!1}}}_close(){this._open=!1}_renderTriggerFields(){if(this._scheduleType!=="sensor_based")return u;let e=this._lang,i=this._triggerType==="compound";return l`
|
||||
<h3>${s("trigger_configuration",e)}</h3>
|
||||
<div class="select-row">
|
||||
<label>${s("trigger_type",e)}</label>
|
||||
<select
|
||||
.value=${this._triggerType}
|
||||
@change=${t=>this._triggerType=t.target.value}
|
||||
>
|
||||
${R.map(t=>l`<option value=${t} ?selected=${t===this._triggerType}>${s(t,e)}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
${i?this._renderCompoundEditor():l`
|
||||
<ms-textfield
|
||||
label="${s("entity_id",e)} (${s("comma_separated",e)})"
|
||||
.value=${this._triggerEntityIds.length>0?this._triggerEntityIds.join(", "):this._triggerEntityId}
|
||||
@input=${t=>{let _=t.target.value.split(",").map(c=>c.trim()).filter(Boolean);this._triggerEntityId=_[0]||"",this._triggerEntityIds=_,_[0]&&this._fetchEntityAttributes(_[0])}}
|
||||
></ms-textfield>
|
||||
${this._triggerEntityIds.length>1?l`
|
||||
<div class="select-row">
|
||||
<label>${s("entity_logic",e)}</label>
|
||||
<select
|
||||
.value=${this._triggerEntityLogic}
|
||||
@change=${t=>this._triggerEntityLogic=t.target.value}
|
||||
>
|
||||
<option value="any" ?selected=${this._triggerEntityLogic==="any"}>${s("entity_logic_any",e)}</option>
|
||||
<option value="all" ?selected=${this._triggerEntityLogic==="all"}>${s("entity_logic_all",e)}</option>
|
||||
</select>
|
||||
</div>
|
||||
`:u}
|
||||
${this._availableAttributes.length>0?l`
|
||||
<div class="select-row">
|
||||
<label>${s("attribute_optional",e)}</label>
|
||||
<select
|
||||
.value=${this._triggerAttribute}
|
||||
@change=${t=>this._triggerAttribute=t.target.value}
|
||||
>
|
||||
<option value="" ?selected=${!this._triggerAttribute}>${s("use_entity_state",e)}</option>
|
||||
${this._suggestedAttributes.map(t=>l`<option value=${t} ?selected=${t===this._triggerAttribute}>${t} ★</option>`)}
|
||||
${this._availableAttributes.filter(t=>!this._suggestedAttributes.includes(t.name)).map(t=>l`<option value=${t.name} ?selected=${t.name===this._triggerAttribute}>${t.name}${t.numeric?"":" (non-numeric)"}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
`:l`
|
||||
<ms-textfield
|
||||
label="${s("attribute_optional",e)}"
|
||||
.value=${this._triggerAttribute}
|
||||
@input=${t=>this._triggerAttribute=t.target.value}
|
||||
></ms-textfield>
|
||||
`}
|
||||
${this._renderTriggerTypeFields()}
|
||||
${this._renderTriggerLiveHint()}
|
||||
`}
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${this._autoCompleteOnRecovery}
|
||||
@change=${t=>this._autoCompleteOnRecovery=t.target.checked}
|
||||
/>
|
||||
${s("auto_complete_on_recovery",e)}
|
||||
</label>
|
||||
<div class="field-help">${s("auto_complete_on_recovery_help",e)}</div>
|
||||
<ms-textfield
|
||||
label="${s("safety_interval",e)}"
|
||||
type="number"
|
||||
.value=${this._intervalDays}
|
||||
@input=${t=>this._intervalDays=t.target.value}
|
||||
></ms-textfield>
|
||||
${this._intervalDays?this._renderUnitSelect():u}
|
||||
`}_patchCondition(e,i){this._compoundConditions=this._compoundConditions.map((t,r)=>r===e?{...t,...i}:t)}_addCondition(){this._compoundConditions=[...this._compoundConditions,q()]}_removeCondition(e){this._compoundConditions=this._compoundConditions.filter((i,t)=>t!==e)}_renderCompoundEditor(){let e=this._lang;return l`
|
||||
<div class="select-row">
|
||||
<label>${s("compound_logic",e)}</label>
|
||||
<select
|
||||
.value=${this._compoundLogic}
|
||||
@change=${i=>this._compoundLogic=i.target.value}
|
||||
>
|
||||
<option value="AND" ?selected=${this._compoundLogic==="AND"}>${s("compound_logic_and",e)}</option>
|
||||
<option value="OR" ?selected=${this._compoundLogic==="OR"}>${s("compound_logic_or",e)}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field-help">${s("compound_help",e)}</div>
|
||||
${this._compoundConditions.length===0?l`<div class="field-help">${s("compound_no_conditions",e)}</div>`:this._compoundConditions.map((i,t)=>this._renderCondition(i,t))}
|
||||
<button type="button" class="secondary-btn" @click=${()=>this._addCondition()}>
|
||||
+ ${s("compound_add_condition",e)}
|
||||
</button>
|
||||
`}_renderCondition(e,i){let t=this._lang,r=i+1;return l`
|
||||
<div class="compound-condition">
|
||||
<div class="compound-condition-head">
|
||||
<span class="compound-condition-title">${s("compound_condition",t)} ${r}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="icon-btn"
|
||||
title="${s("compound_remove_condition",t)}"
|
||||
@click=${()=>this._removeCondition(i)}
|
||||
>✕</button>
|
||||
</div>
|
||||
<ms-textfield
|
||||
label="${s("entity_id",t)} (${s("comma_separated",t)})"
|
||||
.value=${e.entityIds}
|
||||
@input=${_=>this._patchCondition(i,{entityIds:_.target.value})}
|
||||
></ms-textfield>
|
||||
<div class="select-row">
|
||||
<label>${s("trigger_type",t)}</label>
|
||||
<select
|
||||
.value=${e.type}
|
||||
@change=${_=>this._patchCondition(i,{type:_.target.value})}
|
||||
>
|
||||
${H.map(_=>l`<option value=${_} ?selected=${_===e.type}>${s(_,t)}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
${this._renderConditionTypeFields(e,i)}
|
||||
</div>
|
||||
`}_renderConditionTypeFields(e,i){let t=this._lang;return e.type==="threshold"?l`
|
||||
<ms-textfield label="${s("trigger_above",t)}" type="number" .value=${e.above}
|
||||
@input=${r=>this._patchCondition(i,{above:r.target.value})}></ms-textfield>
|
||||
<ms-textfield label="${s("trigger_below",t)}" type="number" .value=${e.below}
|
||||
@input=${r=>this._patchCondition(i,{below:r.target.value})}></ms-textfield>
|
||||
<ms-textfield label="${s("for_minutes",t)}" type="number" .value=${e.forMinutes}
|
||||
@input=${r=>this._patchCondition(i,{forMinutes:r.target.value})}></ms-textfield>
|
||||
`:e.type==="counter"?l`
|
||||
<ms-textfield label="${s("target_value",t)}" type="number" .value=${e.targetValue}
|
||||
@input=${r=>this._patchCondition(i,{targetValue:r.target.value})}></ms-textfield>
|
||||
<label>
|
||||
<input type="checkbox" .checked=${e.deltaMode}
|
||||
@change=${r=>this._patchCondition(i,{deltaMode:r.target.checked})} />
|
||||
${s("delta_mode",t)}
|
||||
</label>
|
||||
`:e.type==="state_change"?l`
|
||||
<ms-textfield label="${s("from_state_optional",t)}" .value=${e.fromState}
|
||||
@input=${r=>this._patchCondition(i,{fromState:r.target.value})}></ms-textfield>
|
||||
<ms-textfield label="${s("to_state_optional",t)}" .value=${e.toState}
|
||||
@input=${r=>this._patchCondition(i,{toState:r.target.value})}></ms-textfield>
|
||||
<ms-textfield label="${s("target_changes",t)}" type="number" .value=${e.targetChanges}
|
||||
@input=${r=>this._patchCondition(i,{targetChanges:r.target.value})}></ms-textfield>
|
||||
`:e.type==="runtime"?l`
|
||||
<ms-textfield label="${s("runtime_hours",t)}" type="number" .value=${e.runtimeHours}
|
||||
@input=${r=>this._patchCondition(i,{runtimeHours:r.target.value})}></ms-textfield>
|
||||
<ms-textfield label="${s("runtime_on_states",t)}" placeholder="on" .value=${e.onStates}
|
||||
@input=${r=>this._patchCondition(i,{onStates:r.target.value})}></ms-textfield>
|
||||
`:u}_renderUnitSelect(){let e=this._lang;return l`
|
||||
<div class="select-row">
|
||||
<label>${s("interval_unit",e)}</label>
|
||||
<select
|
||||
.value=${this._intervalUnit}
|
||||
@change=${i=>this._intervalUnit=i.target.value}
|
||||
>
|
||||
${["days","weeks","months","years"].map(i=>l`<option value=${i} ?selected=${i===this._intervalUnit}>${s("unit_"+i,e)}</option>`)}
|
||||
</select>
|
||||
</div>`}_toggleWeekday(e){this._weekdays=this._weekdays.includes(e)?this._weekdays.filter(i=>i!==e):[...this._weekdays,e]}_previewScheduleDict(){if(this._scheduleType==="one_time")return this._dueDate?{kind:"one_time",due_date:this._dueDate}:null;if(E.includes(this._scheduleType))return{...this._buildSchedule(),...this._recurrenceExtras()};let e=parseInt(this._intervalDays,10);return this._scheduleType==="manual"||!e||e<=0?null:{kind:"interval",every:e,unit:this._intervalUnit,anchor:this._intervalAnchor,...this._recurrenceExtras()}}updated(e){super.updated?.(e);for(let i of e.keys())if(n._PREVIEW_RELEVANT.has(String(i))){this._schedulePreviewRefresh();return}}_schedulePreviewRefresh(){this._previewTimer&&clearTimeout(this._previewTimer),this._previewTimer=setTimeout(()=>{this._fetchSchedulePreview()},300)}async _fetchSchedulePreview(){let e=this._open?this._previewScheduleDict():null;if(!e){this._schedulePreview=[],this._schedulePreviewEnded=!1;return}let i=++this._previewSeq;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/schedule/preview",schedule:e,...this._lastPerformed?{last_performed:this._lastPerformed}:{}});if(i!==this._previewSeq)return;this._schedulePreview=t.occurrences||[],this._schedulePreviewEnded=!!t.series_ended}catch{}}_renderSchedulePreview(){if(this._schedulePreview.length===0)return u;let e=this._lang,i=this.scheduleTimeEnabled&&this._scheduleTime?` ${this._scheduleTime}`:"",t=this._schedulePreview.map((_,c)=>{let h=new Date(`${_}T12:00:00`).getDay();return`${$(h===0?6:h-1,e,"short")} ${S(_,e)}${c===0?i:""}`}).join(" \xB7 "),r=this._scheduleType==="time_based"&&this._intervalAnchor==="completion"?l`<div class="field-help">${s("schedule_preview_ontime",e)}</div>`:u;return l`
|
||||
<div class="trigger-live-hint schedule-preview">
|
||||
${s("schedule_preview_title",e)}: ${t}${this._schedulePreviewEnded?l` <span class="field-help">${s("schedule_preview_ends",e)}</span>`:u}
|
||||
${r}
|
||||
</div>
|
||||
`}_buildSchedule(){let e=t=>{let r=parseInt(this._calOffset,10)||0;return r&&(t.offset=Math.max(-15,Math.min(r,15))),t};if(this._scheduleType==="weekdays")return e({kind:"weekdays",weekdays:[...this._weekdays].sort((t,r)=>t-r)});if(this._scheduleType==="nth_weekday")return e({kind:"nth_weekday",nth:parseInt(this._nth,10),weekday:parseInt(this._nthWeekday,10)});let i={kind:"day_of_month",day:this._domLastDay?-1:parseInt(this._domDay,10)||1};return this._domBusiness&&(i.business=!0),e(i)}_recurrenceExtras(){let e={};if(this._seasonMonths.length&&(e.season_months=[...this._seasonMonths].sort((i,t)=>i-t)),this._endsMode==="count"){let i=parseInt(this._endsCount,10);i>=1&&(e.ends={count:i})}else this._endsMode==="until"&&this._endsUntil&&(e.ends={until:this._endsUntil});return e}_toggleSeasonMonth(e){this._seasonMonths=this._seasonMonths.includes(e)?this._seasonMonths.filter(i=>i!==e):[...this._seasonMonths,e]}_renderRecurrenceExtras(){let e=this._lang;if(!(this._scheduleType==="time_based"||E.includes(this._scheduleType)))return u;let t=B(e);return l`
|
||||
<label class="field-label">${s("season_window_label",e)}</label>
|
||||
<div class="field-help">${s("season_window_hint",e)}</div>
|
||||
<div class="weekday-chips season-chips">
|
||||
${t.map((r,_)=>l`
|
||||
<button
|
||||
type="button"
|
||||
class="season-chip ${this._seasonMonths.includes(_+1)?"selected":""}"
|
||||
@click=${()=>this._toggleSeasonMonth(_+1)}
|
||||
>${r}</button>`)}
|
||||
</div>
|
||||
|
||||
<label class="field-label">${s("series_end_label",e)}</label>
|
||||
<div class="select-row">
|
||||
<select .value=${this._endsMode}
|
||||
@change=${r=>this._endsMode=r.target.value}>
|
||||
<option value="never" ?selected=${this._endsMode==="never"}>${s("series_end_never",e)}</option>
|
||||
<option value="count" ?selected=${this._endsMode==="count"}>${s("series_end_after_count",e)}</option>
|
||||
<option value="until" ?selected=${this._endsMode==="until"}>${s("series_end_until",e)}</option>
|
||||
</select>
|
||||
</div>
|
||||
${this._endsMode==="count"?l`
|
||||
<ms-textfield
|
||||
label="${s("series_end_count_label",e)}"
|
||||
type="number" min="1"
|
||||
.value=${this._endsCount}
|
||||
@input=${r=>this._endsCount=r.target.value}
|
||||
></ms-textfield>`:u}
|
||||
${this._endsMode==="until"?l`
|
||||
<ms-textfield
|
||||
label="${s("series_end_until_label",e)}"
|
||||
type="date"
|
||||
.value=${this._endsUntil}
|
||||
@input=${r=>this._endsUntil=r.target.value}
|
||||
></ms-textfield>`:u}
|
||||
`}_renderCalendarFields(){let e=this._lang,i=j(e);if(this._scheduleType==="weekdays")return l`
|
||||
<label class="field-label">${s("recurrence_on_days",e)}</label>
|
||||
<div class="weekday-chips">
|
||||
${i.map((t,r)=>l`
|
||||
<button
|
||||
type="button"
|
||||
class="weekday-chip ${this._weekdays.includes(r)?"selected":""}"
|
||||
@click=${()=>this._toggleWeekday(r)}
|
||||
>${t}</button>`)}
|
||||
</div>
|
||||
${this._renderCalOffsetField()}`;if(this._scheduleType==="nth_weekday"){let t=[["1",s("ord_1",e)],["2",s("ord_2",e)],["3",s("ord_3",e)],["4",s("ord_4",e)],["5",s("ord_5",e)],["-1",s("ord_last",e)]];return l`
|
||||
<div class="select-row">
|
||||
<label>${s("recurrence_occurrence",e)}</label>
|
||||
<select .value=${this._nth} @change=${r=>this._nth=r.target.value}>
|
||||
${t.map(([r,_])=>l`<option value=${r} ?selected=${r===this._nth}>${_}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
<div class="select-row">
|
||||
<label>${s("recurrence_weekday",e)}</label>
|
||||
<select .value=${this._nthWeekday} @change=${r=>this._nthWeekday=r.target.value}>
|
||||
${i.map((r,_)=>l`<option value=${String(_)} ?selected=${String(_)===this._nthWeekday}>${r}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
${this._renderCalOffsetField()}`}return this._scheduleType==="day_of_month"?l`
|
||||
${this._domLastDay?u:l`
|
||||
<ms-textfield
|
||||
label="${s("recurrence_day",e)}"
|
||||
type="number"
|
||||
min="1"
|
||||
max="31"
|
||||
.value=${this._domDay}
|
||||
@input=${t=>this._domDay=t.target.value}
|
||||
></ms-textfield>`}
|
||||
<label class="checkbox-row">
|
||||
<input type="checkbox" .checked=${this._domLastDay}
|
||||
@change=${t=>this._domLastDay=t.target.checked} />
|
||||
<span>${s("recurrence_last_day",e)}</span>
|
||||
</label>
|
||||
<label class="checkbox-row">
|
||||
<input type="checkbox" .checked=${this._domBusiness}
|
||||
@change=${t=>this._domBusiness=t.target.checked} />
|
||||
<span>${s("recurrence_business_day",e)}</span>
|
||||
</label>
|
||||
${this._renderCalOffsetField()}`:u}_renderCalOffsetField(){let e=this._lang;return l`
|
||||
<ms-textfield
|
||||
label="${s("recurrence_offset",e)}"
|
||||
helper="${s("recurrence_offset_help",e)}"
|
||||
type="number"
|
||||
min="-15"
|
||||
max="15"
|
||||
.value=${this._calOffset}
|
||||
@input=${i=>this._calOffset=i.target.value}
|
||||
></ms-textfield>`}_renderTriggerLiveHint(){if(this._triggerType==="compound")return u;let e=this._triggerEntityId||this._triggerEntityIds[0];if(!e||!this.hass?.states)return u;let i=this.hass.states[e];if(!i)return u;let t=this._lang,r=i.attributes?.unit_of_measurement,_=typeof r=="string"&&r?` ${r}`:"",c=this._triggerAttribute?i.attributes?.[this._triggerAttribute]:i.state,h=typeof c=="number"?c:parseFloat(String(c)),d=c!=="unknown"&&c!=="unavailable"&&c!=null&&!isNaN(h),m=g=>Number.isInteger(g)?String(g):String(Math.round(g*10)/10),v=[];if(this._triggerType==="threshold"){let g=parseFloat(this._triggerAbove),f=parseFloat(this._triggerBelow);if(isNaN(g)&&isNaN(f))return u;d&&v.push(s("trigger_hint_now",t).replace("{value}",m(h)+_)),isNaN(g)||v.push(s("trigger_hint_above",t).replace("{target}",m(g)+_)),isNaN(f)||v.push(s("trigger_hint_below",t).replace("{target}",m(f)+_))}else if(this._triggerType==="counter"){let g=parseFloat(this._triggerTargetValue);if(isNaN(g))return u;this._triggerDeltaMode?this._taskId?v.push(s("trigger_hint_counter_delta_edit",t).replace("{target}",m(g)+_)):d?v.push(s("trigger_hint_counter_delta",t).replace("{value}",m(h)+_).replace("{due}",m(h+g)+_).replace("{target}",m(g)+_)):v.push(s("trigger_hint_counter_delta_edit",t).replace("{target}",m(g)+_)):(d&&v.push(s("trigger_hint_now",t).replace("{value}",m(h)+_)),v.push(s("trigger_hint_counter_abs",t).replace("{target}",m(g)+_)))}else if(this._triggerType==="runtime"){let g=parseFloat(this._triggerRuntimeHours);if(isNaN(g))return u;v.push(s("trigger_hint_runtime",t).replace("{hours}",m(g))),v.push(s("trigger_hint_state_now",t).replace("{value}",String(i.state)))}else if(this._triggerType==="state_change"){let g=parseInt(this._triggerTargetChanges,10)||1,f=this._triggerToState.trim();v.push((f?s("trigger_hint_state_change_to",t).replace("{state}",f):s("trigger_hint_state_change",t)).replace("{count}",String(g))),v.push(s("trigger_hint_state_now",t).replace("{value}",String(i.state)))}return v.length?l`<div class="trigger-live-hint">${v.join(" ")}</div>`:u}_renderTriggerTypeFields(){let e=this._lang;return this._triggerType==="threshold"?l`
|
||||
<ms-textfield
|
||||
label="${s("trigger_above",e)}"
|
||||
type="number"
|
||||
step="any"
|
||||
.value=${this._triggerAbove}
|
||||
@input=${i=>this._triggerAbove=i.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${s("trigger_below",e)}"
|
||||
type="number"
|
||||
step="any"
|
||||
.value=${this._triggerBelow}
|
||||
@input=${i=>this._triggerBelow=i.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${s("for_at_least_minutes",e)}"
|
||||
type="number"
|
||||
.value=${this._triggerForMinutes}
|
||||
@input=${i=>this._triggerForMinutes=i.target.value}
|
||||
></ms-textfield>
|
||||
`:this._triggerType==="counter"?l`
|
||||
<ms-textfield
|
||||
label="${s("target_value",e)}"
|
||||
type="number"
|
||||
step="any"
|
||||
.value=${this._triggerTargetValue}
|
||||
@input=${i=>this._triggerTargetValue=i.target.value}
|
||||
></ms-textfield>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${this._triggerDeltaMode}
|
||||
@change=${i=>this._triggerDeltaMode=i.target.checked}
|
||||
/>
|
||||
${s("delta_mode",e)}
|
||||
</label>
|
||||
${this._triggerDeltaMode?l`
|
||||
<ms-textfield
|
||||
label="${s("baseline_start_value",e)}"
|
||||
type="number"
|
||||
step="any"
|
||||
.value=${this._triggerBaselineValue}
|
||||
@input=${i=>this._triggerBaselineValue=i.target.value}
|
||||
></ms-textfield>
|
||||
<div class="field-help">
|
||||
${this._taskId?s("baseline_start_help_edit",e):s("baseline_start_help",e)}
|
||||
${this._taskId&&this._liveBaselineValue!=null?l`<div class="baseline-effective">
|
||||
${s("baseline_current_effective",e).replace("{value}",String(this._liveBaselineValue))}
|
||||
</div>`:u}
|
||||
</div>
|
||||
`:u}
|
||||
`:this._triggerType==="state_change"?l`
|
||||
<ms-textfield
|
||||
label="${s("from_state_optional",e)}"
|
||||
.value=${this._triggerFromState}
|
||||
@input=${i=>this._triggerFromState=i.target.value}
|
||||
></ms-textfield>
|
||||
<div class="field-help">${s("state_value_help",e)}</div>
|
||||
<ms-textfield
|
||||
label="${s("to_state_optional",e)}"
|
||||
.value=${this._triggerToState}
|
||||
@input=${i=>this._triggerToState=i.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${s("target_changes",e)}"
|
||||
type="number"
|
||||
min="1"
|
||||
.value=${this._triggerTargetChanges}
|
||||
@input=${i=>this._triggerTargetChanges=i.target.value}
|
||||
></ms-textfield>
|
||||
<div class="field-help">${s("target_changes_help",e)}</div>
|
||||
`:this._triggerType==="runtime"?l`
|
||||
<ms-textfield
|
||||
label="${s("runtime_hours",e)}"
|
||||
type="number"
|
||||
step="1"
|
||||
.value=${this._triggerRuntimeHours}
|
||||
@input=${i=>this._triggerRuntimeHours=i.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${s("runtime_on_states",e)}"
|
||||
placeholder="on"
|
||||
.value=${this._triggerOnStates}
|
||||
@input=${i=>this._triggerOnStates=i.target.value}
|
||||
></ms-textfield>
|
||||
<div class="field-help">${s("runtime_on_states_help",e)}</div>
|
||||
`:u}render(){if(!this._open)return l``;let e=this._lang,i=this._taskId?s("edit_task",e):s("new_task",e);return l`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${i}</div>
|
||||
<div class="content">
|
||||
${this._error?l`<div class="error">${this._error}</div>`:u}
|
||||
${this._objectChoices.length>0?l`
|
||||
<div class="select-row">
|
||||
<label>${s("object",e)}</label>
|
||||
<select
|
||||
.value=${this._entryId}
|
||||
@change=${t=>{this._entryId=t.target.value,this._consumesParts={},this._loadParts(),this._loadForeignPools()}}
|
||||
>
|
||||
${this._objectChoices.map(t=>l`<option value=${t.entry_id} ?selected=${t.entry_id===this._entryId}>${t.name}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
`:u}
|
||||
<ms-textfield
|
||||
label="${s("task_name",e)}"
|
||||
required
|
||||
.value=${this._name}
|
||||
@input=${t=>this._name=t.target.value}
|
||||
></ms-textfield>
|
||||
<div class="select-row">
|
||||
<label>${s("maintenance_type",e)}</label>
|
||||
<select
|
||||
.value=${this._type}
|
||||
@change=${t=>this._type=t.target.value}
|
||||
>
|
||||
${P.map(t=>l`<option value=${t} ?selected=${t===this._type}>${s(t,e)}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
${this._type==="reading"?l`
|
||||
<ms-textfield
|
||||
label="${s("reading_unit_label",e)}"
|
||||
.value=${this._readingUnit}
|
||||
@input=${t=>this._readingUnit=t.target.value}
|
||||
></ms-textfield>
|
||||
<div class="field-help">${s("reading_unit_help",e)}</div>
|
||||
`:u}
|
||||
${this._partsLoadFailed?l`<div class="field-help parts-load-failed">${s("parts_load_failed",e)}</div>`:u}
|
||||
${this.parts.length||this._foreignOwners.length?l`
|
||||
<div class="field">
|
||||
<label>${s("consumes_parts_label",e)}</label>
|
||||
${this.parts.map(t=>this._renderConsumesRow(t))}
|
||||
${this._foreignOwners.length?l`
|
||||
<details class="shared-pools" ?open=${this._hasForeignPick}>
|
||||
<summary>${s("shared_parts_other_objects",e)}</summary>
|
||||
<div class="field-help">${s("shared_parts_help",e)}</div>
|
||||
${this._foreignOwners.map(t=>l`
|
||||
<div class="shared-pool-owner">${t.name}</div>
|
||||
${t.parts.map(r=>this._renderConsumesRow(r,t.entry_id))}
|
||||
`)}
|
||||
</details>
|
||||
`:u}
|
||||
</div>
|
||||
`:u}
|
||||
<div class="select-row">
|
||||
<label>${s("priority",e)}</label>
|
||||
<select
|
||||
.value=${this._priority}
|
||||
@change=${t=>this._priority=t.target.value}
|
||||
>
|
||||
${N.map(t=>l`<option value=${t} ?selected=${t===this._priority}>${s("priority_"+t,e)}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>${s("labels",e)}</label>
|
||||
<input
|
||||
type="text"
|
||||
.value=${this._labels}
|
||||
placeholder="${s("labels_placeholder",e)}"
|
||||
@input=${t=>this._labels=t.target.value}
|
||||
/>
|
||||
<div class="field-help">${s("labels_help",e)}</div>
|
||||
</div>
|
||||
<div class="select-row">
|
||||
<label>${s("schedule_type",e)}</label>
|
||||
<select
|
||||
.value=${this._scheduleType}
|
||||
@change=${t=>this._scheduleType=t.target.value}
|
||||
>
|
||||
${F.map(t=>l`<option value=${t} ?selected=${t===this._scheduleType}>${s(t,e)}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
${this._scheduleType==="time_based"?l`
|
||||
<ms-textfield
|
||||
label="${s("interval_value",e)}"
|
||||
type="number"
|
||||
.value=${this._intervalDays}
|
||||
@input=${t=>this._intervalDays=t.target.value}
|
||||
></ms-textfield>
|
||||
${this._renderUnitSelect()}
|
||||
<div class="select-row">
|
||||
<label>${s("interval_anchor",e)}</label>
|
||||
<select
|
||||
.value=${this._intervalAnchor}
|
||||
@change=${t=>this._intervalAnchor=t.target.value}
|
||||
>
|
||||
<option value="completion" ?selected=${this._intervalAnchor==="completion"}>${s("anchor_completion",e)}</option>
|
||||
<option value="planned" ?selected=${this._intervalAnchor==="planned"}>${s("anchor_planned",e)}</option>
|
||||
</select>
|
||||
</div>
|
||||
${this.scheduleTimeEnabled?l`
|
||||
<ms-textfield
|
||||
label="${s("schedule_time_optional",e)}"
|
||||
type="time"
|
||||
.value=${this._scheduleTime}
|
||||
helper="${s("schedule_time_help",e)}"
|
||||
@input=${t=>this._scheduleTime=t.target.value}
|
||||
></ms-textfield>
|
||||
`:u}
|
||||
`:u}
|
||||
${this._renderCalendarFields()}
|
||||
${this._scheduleType==="one_time"?l`
|
||||
<ms-textfield
|
||||
label="${s("due_date",e)}"
|
||||
type="date"
|
||||
.value=${this._dueDate}
|
||||
@input=${t=>this._dueDate=t.target.value}
|
||||
></ms-textfield>
|
||||
`:u}
|
||||
${this._renderRecurrenceExtras()}
|
||||
${this._renderSchedulePreview()}
|
||||
<ms-textfield
|
||||
label="${s("warning_days",e)}"
|
||||
type="number"
|
||||
min="0"
|
||||
max="365"
|
||||
.value=${this._warningDays}
|
||||
@input=${t=>this._warningDays=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${s("earliest_completion_days",e)}"
|
||||
helper="${s("earliest_completion_days_help",e)}"
|
||||
type="number"
|
||||
.value=${this._earliestCompletionDays}
|
||||
@input=${t=>this._earliestCompletionDays=t.target.value}
|
||||
></ms-textfield>
|
||||
${this.checklistsEnabled?l`
|
||||
<h3>${s("checklist_steps_optional",e)}</h3>
|
||||
<textarea
|
||||
id="checklist-textarea"
|
||||
class="checklist-textarea"
|
||||
rows="5"
|
||||
placeholder="${s("checklist_placeholder",e)}"
|
||||
.value=${this._checklistText}
|
||||
@input=${t=>this._checklistText=t.target.value}
|
||||
></textarea>
|
||||
<div class="field-help">${s("checklist_help",e)}</div>
|
||||
`:u}
|
||||
<h3>${s("require_on_completion",e)}</h3>
|
||||
<div class="required-completion">
|
||||
${A.map(t=>l`
|
||||
<label class="req-option">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${this._requiredCompletion.includes(t)}
|
||||
@change=${r=>this._toggleRequired(t,r.target.checked)}
|
||||
/>
|
||||
<span>${s(L[t],e)}</span>
|
||||
</label>
|
||||
`)}
|
||||
</div>
|
||||
<ms-textfield
|
||||
label="${s("last_performed_optional",e)}"
|
||||
type="date"
|
||||
.value=${this._lastPerformed}
|
||||
@input=${t=>this._lastPerformed=t.target.value}
|
||||
></ms-textfield>
|
||||
<div class="select-row">
|
||||
<label>${s("responsible_user",e)}</label>
|
||||
<select
|
||||
.value=${this._responsibleUserId||""}
|
||||
@change=${t=>{let r=t.target.value;this._responsibleUserId=r||null}}
|
||||
>
|
||||
<option value="" ?selected=${!this._responsibleUserId}>${s("no_user_assigned",e)}</option>
|
||||
${this._availableUsers.map(t=>l`<option value=${t.id} ?selected=${t.id===this._responsibleUserId}>${t.name}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
${this._availableUsers.length>=2?l`
|
||||
<div class="field">
|
||||
<label>${s("shared_with",e)}</label>
|
||||
<div class="field-help">${s("shared_with_help",e)}</div>
|
||||
<div class="assignee-pool">
|
||||
${this._availableUsers.map(t=>l`
|
||||
<label class="pool-item">
|
||||
<input type="checkbox"
|
||||
.checked=${this._assigneePool.includes(t.id)}
|
||||
@change=${()=>this._toggleAssignee(t.id)} />
|
||||
<span>${t.name}</span>
|
||||
</label>`)}
|
||||
</div>
|
||||
</div>
|
||||
${this._assigneePool.length>=2?l`
|
||||
<div class="select-row">
|
||||
<label>${s("rotation_strategy",e)}</label>
|
||||
<select
|
||||
.value=${this._rotationStrategy}
|
||||
@change=${t=>this._rotationStrategy=t.target.value}
|
||||
>
|
||||
<option value="" ?selected=${!this._rotationStrategy}>${s("rotation_none",e)}</option>
|
||||
${["round_robin","least_completed","random"].map(t=>l`<option value=${t} ?selected=${t===this._rotationStrategy}>${s("rotation_"+t,e)}</option>`)}
|
||||
</select>
|
||||
</div>`:u}
|
||||
`:u}
|
||||
${this._renderTriggerFields()}
|
||||
${this._scheduleType==="sensor_based"?l`
|
||||
<ms-textfield
|
||||
label="${s("environmental_entity_optional",e)}"
|
||||
helper="${s("environmental_entity_helper",e)}"
|
||||
.value=${this._environmentalEntity}
|
||||
@input=${t=>this._environmentalEntity=t.target.value.trim()}
|
||||
></ms-textfield>
|
||||
${this._environmentalEntity?l`
|
||||
<ms-textfield
|
||||
label="${s("environmental_attribute_optional",e)}"
|
||||
.value=${this._environmentalAttribute}
|
||||
@input=${t=>this._environmentalAttribute=t.target.value.trim()}
|
||||
></ms-textfield>
|
||||
`:u}
|
||||
`:u}
|
||||
<ms-textfield
|
||||
label="${s("notes_optional",e)}"
|
||||
.value=${this._notes}
|
||||
@input=${t=>this._notes=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${s("documentation_url_optional",e)}"
|
||||
.value=${this._documentationUrl}
|
||||
@input=${t=>this._documentationUrl=t.target.value}
|
||||
></ms-textfield>
|
||||
<ha-icon-picker
|
||||
.hass=${this.hass}
|
||||
label="${s("custom_icon_optional",e)}"
|
||||
.value=${this._customIcon}
|
||||
@value-changed=${t=>this._customIcon=t.detail.value||""}
|
||||
></ha-icon-picker>
|
||||
${this._availableTags.length>0?l`
|
||||
<div class="select-row">
|
||||
<label>${s("nfc_tag_id_optional",e)}</label>
|
||||
<select
|
||||
.value=${this._nfcTagId}
|
||||
@change=${t=>this._nfcTagId=t.target.value}
|
||||
>
|
||||
<option value="" ?selected=${!this._nfcTagId}>${s("no_nfc_tag",e)}</option>
|
||||
${this._availableTags.map(t=>l`<option value=${t.id} ?selected=${t.id===this._nfcTagId}>${t.name}</option>`)}
|
||||
</select>
|
||||
<button type="button" class="link-button" @click=${this._loadTags}
|
||||
title="${s("nfc_tags_refresh",e)}">↻</button>
|
||||
</div>
|
||||
`:l`
|
||||
<ms-textfield
|
||||
label="${s("nfc_tag_id_optional",e)}"
|
||||
.value=${this._nfcTagId}
|
||||
@input=${t=>this._nfcTagId=t.target.value}
|
||||
></ms-textfield>
|
||||
<div class="field-help">
|
||||
${s("nfc_tags_empty_help",e)}
|
||||
<a href="/config/tags">${s("nfc_tags_open_settings",e)}</a>
|
||||
·
|
||||
<button type="button" class="link-button" @click=${this._loadTags}>
|
||||
${s("nfc_tags_refresh",e)}
|
||||
</button>
|
||||
</div>
|
||||
`}
|
||||
<label class="toggle-row">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${this._enabled}
|
||||
@change=${t=>this._enabled=t.target.checked}
|
||||
/>
|
||||
${s("task_enabled",e)}
|
||||
</label>
|
||||
${this._renderCompletionActionsSection(e)}
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>${s("cancel",e)}</ha-button>
|
||||
<ha-button
|
||||
@click=${this._save}
|
||||
.disabled=${this._loading||!this._name.trim()}
|
||||
>
|
||||
${this._loading?s("saving",e):s("save",e)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}};n._PREVIEW_RELEVANT=new Set(["_open","_scheduleType","_intervalDays","_intervalUnit","_intervalAnchor","_dueDate","_weekdays","_nth","_nthWeekday","_domDay","_domLastDay","_domBusiness","_calOffset","_seasonMonths","_endsMode","_endsCount","_endsUntil","_lastPerformed"]),n.styles=T`
|
||||
.dialog-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
/* v1.3.0: completion-action sections */
|
||||
.ca-section {
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 6px;
|
||||
padding: 8px 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.ca-section > summary {
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
}
|
||||
.ca-section ms-textfield,
|
||||
.ca-section ha-entity-picker,
|
||||
.ca-section ha-service-picker,
|
||||
.ca-section ha-form,
|
||||
.ca-section .qc-feedback {
|
||||
width: 100%;
|
||||
margin-top: 8px;
|
||||
display: block;
|
||||
}
|
||||
.ca-section .qc-feedback {
|
||||
padding: 8px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 4px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.ca-test-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.ca-test-ok { color: var(--success-color, #4caf50); font-size: 13px; }
|
||||
.ca-test-error { color: var(--error-color, #f44336); font-size: 13px; font-weight: 500; }
|
||||
.ca-test-error-block { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
|
||||
.ca-test-error-detail {
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
background: rgba(244, 67, 54, 0.08);
|
||||
padding: 6px 8px; border-radius: 4px;
|
||||
line-height: 1.4;
|
||||
word-break: break-word;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
min-width: 350px;
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.content {
|
||||
min-width: 0;
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
.dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
ms-textfield {
|
||||
display: block;
|
||||
}
|
||||
.field-label {
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.checklist-textarea {
|
||||
width: 100%;
|
||||
min-height: 88px;
|
||||
padding: 8px;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 4px;
|
||||
background: var(--card-background-color);
|
||||
color: var(--primary-text-color);
|
||||
resize: vertical;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.consumes-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 2px 0;
|
||||
}
|
||||
.consumes-check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex: 1;
|
||||
}
|
||||
.consumes-qty {
|
||||
width: 64px;
|
||||
padding: 4px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 4px;
|
||||
background: var(--card-background-color);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
/* #111: other objects' pools sit behind a disclosure so the object's OWN
|
||||
parts stay the primary list; each group is headed by the owning object's
|
||||
name, so which pool a checkbox means is never a guess. */
|
||||
.shared-pools {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.shared-pools > summary {
|
||||
cursor: pointer;
|
||||
padding: 2px 0;
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.shared-pool-owner {
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.field-help {
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.baseline-effective {
|
||||
margin-top: 2px;
|
||||
font-weight: 500;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
/* Live computed trigger hint — reads the bound sensor and explains what
|
||||
happens next. Info-accented so it reads as guidance, not an error. */
|
||||
.trigger-live-hint {
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
border-left: 3px solid var(--info-color, #2196f3);
|
||||
background: rgba(33, 150, 243, 0.08);
|
||||
border-radius: 0 6px 6px 0;
|
||||
padding: 6px 10px;
|
||||
margin: 4px 0;
|
||||
}
|
||||
.field-help a,
|
||||
.link-button {
|
||||
background: none;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
color: var(--primary-color);
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.field-help a:hover,
|
||||
.link-button:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
/* Smaller refresh icon-button when shown next to the dropdown. */
|
||||
.select-row .link-button {
|
||||
margin-left: 8px;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
}
|
||||
.select-row .link-button:hover {
|
||||
color: var(--primary-color);
|
||||
opacity: 0.7;
|
||||
}
|
||||
h3 {
|
||||
margin: 8px 0 0;
|
||||
font-size: 14px;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.select-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.assignee-pool {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px 14px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.checkbox-row {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
margin: 2px 0;
|
||||
}
|
||||
.checkbox-row input[type="checkbox"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.pool-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.pool-item input[type="checkbox"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.select-row label {
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.select-row select {
|
||||
padding: 8px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 4px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
font-size: 14px;
|
||||
}
|
||||
.field-label {
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.weekday-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
.weekday-chip {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 16px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.weekday-chip.selected {
|
||||
background: var(--primary-color, #03a9f4);
|
||||
color: var(--text-primary-color, #fff);
|
||||
border-color: var(--primary-color, #03a9f4);
|
||||
}
|
||||
.season-chip {
|
||||
padding: 6px 10px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 16px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.season-chip.selected {
|
||||
background: var(--primary-color, #03a9f4);
|
||||
color: var(--text-primary-color, #fff);
|
||||
border-color: var(--primary-color, #03a9f4);
|
||||
}
|
||||
.error {
|
||||
color: var(--error-color, #f44336);
|
||||
font-size: 13px;
|
||||
}
|
||||
.toggle-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
`,a([b({attribute:!1})],n.prototype,"hass",2),a([b({type:Boolean,attribute:"checklists-enabled"})],n.prototype,"checklistsEnabled",2),a([b({type:Boolean,attribute:"schedule-time-enabled"})],n.prototype,"scheduleTimeEnabled",2),a([b({type:Boolean,attribute:"completion-actions-enabled"})],n.prototype,"completionActionsEnabled",2),a([b({type:Number,attribute:"default-warning-days"})],n.prototype,"defaultWarningDays",2),a([o()],n.prototype,"parts",2),a([o()],n.prototype,"_foreignOwners",2),a([o()],n.prototype,"_open",2),a([o()],n.prototype,"_loading",2),a([o()],n.prototype,"_error",2),a([o()],n.prototype,"_entryId",2),a([o()],n.prototype,"_taskId",2),a([o()],n.prototype,"_objectChoices",2),a([o()],n.prototype,"_name",2),a([o()],n.prototype,"_type",2),a([o()],n.prototype,"_scheduleType",2),a([o()],n.prototype,"_intervalDays",2),a([o()],n.prototype,"_intervalUnit",2),a([o()],n.prototype,"_dueDate",2),a([o()],n.prototype,"_warningDays",2),a([o()],n.prototype,"_earliestCompletionDays",2),a([o()],n.prototype,"_intervalAnchor",2),a([o()],n.prototype,"_weekdays",2),a([o()],n.prototype,"_nth",2),a([o()],n.prototype,"_nthWeekday",2),a([o()],n.prototype,"_domDay",2),a([o()],n.prototype,"_domLastDay",2),a([o()],n.prototype,"_domBusiness",2),a([o()],n.prototype,"_calOffset",2),a([o()],n.prototype,"_seasonMonths",2),a([o()],n.prototype,"_endsMode",2),a([o()],n.prototype,"_endsCount",2),a([o()],n.prototype,"_endsUntil",2),a([o()],n.prototype,"_schedulePreview",2),a([o()],n.prototype,"_schedulePreviewEnded",2),a([o()],n.prototype,"_notes",2),a([o()],n.prototype,"_documentationUrl",2),a([o()],n.prototype,"_customIcon",2),a([o()],n.prototype,"_priority",2),a([o()],n.prototype,"_labels",2),a([o()],n.prototype,"_enabled",2),a([o()],n.prototype,"_triggerEntityId",2),a([o()],n.prototype,"_triggerEntityIds",2),a([o()],n.prototype,"_triggerEntityLogic",2),a([o()],n.prototype,"_triggerAttribute",2),a([o()],n.prototype,"_triggerType",2),a([o()],n.prototype,"_triggerAbove",2),a([o()],n.prototype,"_triggerBelow",2),a([o()],n.prototype,"_triggerForMinutes",2),a([o()],n.prototype,"_triggerTargetValue",2),a([o()],n.prototype,"_triggerDeltaMode",2),a([o()],n.prototype,"_triggerBaselineValue",2),a([o()],n.prototype,"_liveBaselineValue",2),a([o()],n.prototype,"_autoCompleteOnRecovery",2),a([o()],n.prototype,"_triggerFromState",2),a([o()],n.prototype,"_triggerToState",2),a([o()],n.prototype,"_triggerTargetChanges",2),a([o()],n.prototype,"_triggerRuntimeHours",2),a([o()],n.prototype,"_triggerOnStates",2),a([o()],n.prototype,"_compoundLogic",2),a([o()],n.prototype,"_compoundConditions",2),a([o()],n.prototype,"_suggestedAttributes",2),a([o()],n.prototype,"_availableAttributes",2),a([o()],n.prototype,"_entityDomain",2),a([o()],n.prototype,"_lastPerformed",2),a([o()],n.prototype,"_nfcTagId",2),a([o()],n.prototype,"_readingUnit",2),a([o()],n.prototype,"_consumesParts",2),a([o()],n.prototype,"_partsLoadFailed",2),a([o()],n.prototype,"_availableTags",2),a([o()],n.prototype,"_responsibleUserId",2),a([o()],n.prototype,"_assigneePool",2),a([o()],n.prototype,"_rotationStrategy",2),a([o()],n.prototype,"_availableUsers",2),a([o()],n.prototype,"_checklistText",2),a([o()],n.prototype,"_requiredCompletion",2),a([o()],n.prototype,"_scheduleTime",2),a([o()],n.prototype,"_actionService",2),a([o()],n.prototype,"_actionTargetEntity",2),a([o()],n.prototype,"_actionData",2),a([o()],n.prototype,"_actionDataJsonFallback",2),a([o()],n.prototype,"_actionTesting",2),a([o()],n.prototype,"_actionTestResult",2),a([o()],n.prototype,"_actionTestError",2),a([o()],n.prototype,"_qcNotes",2),a([o()],n.prototype,"_qcCost",2),a([o()],n.prototype,"_qcDuration",2),a([o()],n.prototype,"_qcFeedback",2),a([o()],n.prototype,"_environmentalEntity",2),a([o()],n.prototype,"_environmentalAttribute",2);var w=n;customElements.get("maintenance-task-dialog")||customElements.define("maintenance-task-dialog",w);export{w as MaintenanceTaskDialog};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZK3W7TF6.js";import{a as P,b as L}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NGMG4DEY.js";import{a as E}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-SD6IEJBA.js";import{a as C}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LJXSDCLS.js";import{a as A}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-I7J3AORE.js";import{a,b as T,c as o,f as u,g as S,i as b,j as l,n as s,r as k,u as $}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var x=["sensor","binary_sensor","number","input_number","input_boolean","switch","climate","vacuum","cover","fan","light","water_heater","humidifier","media_player","weather","air_quality","valve","lawn_mower","lock"],H=["sensor"],N=["temperature","humidity","pressure"];var F=["cleaning","inspection","replacement","calibration","service","reading","custom"],M=["low","normal","high"],O=["time_based","weekdays","nth_weekday","day_of_month","sensor_based","one_time","manual"],w=["weekdays","nth_weekday","day_of_month"],R=["threshold","counter","state_change","runtime"],q=[...R,"compound"];function U(){return{entityIds:"",type:"threshold",attribute:"",above:"",below:"",forMinutes:"0",targetValue:"",deltaMode:!1,fromState:"",toState:"",targetChanges:"",runtimeHours:"",onStates:"",carry:{}}}var j=new Set(["entity_id","entity_ids","type","attribute","trigger_above","trigger_below","trigger_for_minutes","trigger_target_value","trigger_delta_mode","trigger_from_state","trigger_to_state","trigger_target_changes","trigger_runtime_hours","trigger_on_states"]);function B(p){return{entityIds:(p.entity_ids||(p.entity_id?[p.entity_id]:[])).join(", "),type:p.type||"threshold",attribute:p.attribute||"",above:p.trigger_above?.toString()??"",below:p.trigger_below?.toString()??"",forMinutes:p.trigger_for_minutes?.toString()??"0",targetValue:p.trigger_target_value?.toString()??"",deltaMode:p.trigger_delta_mode||!1,fromState:p.trigger_from_state||"",toState:p.trigger_to_state||"",targetChanges:p.trigger_target_changes?.toString()??"",runtimeHours:p.trigger_runtime_hours?.toString()??"",onStates:(p.trigger_on_states||[]).join(", "),carry:Object.fromEntries(Object.entries(p).filter(([t])=>!j.has(t)&&!t.startsWith("_")))}}function V(p){let y=p.entityIds.split(",").map(i=>i.trim()).filter(Boolean);if(y.length===0)return null;let t={...p.carry||{},entity_id:y[0],entity_ids:y,type:p.type};if(p.attribute&&(t.attribute=p.attribute),p.type==="threshold"){let i=parseFloat(p.above);isNaN(i)||(t.trigger_above=i);let e=parseFloat(p.below);isNaN(e)||(t.trigger_below=e);let r=parseInt(p.forMinutes,10);isNaN(r)||(t.trigger_for_minutes=r)}else if(p.type==="counter"){let i=parseFloat(p.targetValue);isNaN(i)||(t.trigger_target_value=i),t.trigger_delta_mode=p.deltaMode}else if(p.type==="state_change"){p.fromState&&(t.trigger_from_state=p.fromState),p.toState&&(t.trigger_to_state=p.toState);let i=parseInt(p.targetChanges,10);isNaN(i)||(t.trigger_target_changes=i)}else if(p.type==="runtime"){let i=parseFloat(p.runtimeHours);isNaN(i)||(t.trigger_runtime_hours=i);let e=(p.onStates||"").split(",").map(r=>r.trim()).filter(Boolean);e.length>0&&(t.trigger_on_states=e)}return t}function D(p){return Array.from({length:7},(y,t)=>$(t,p,"short"))}function z(p){let y=new Intl.DateTimeFormat(p||"en",{month:"short"});return Array.from({length:12},(t,i)=>y.format(new Date(2021,i,1)))}var n=class n extends S{constructor(){super(...arguments);this.checklistsEnabled=!1;this.scheduleTimeEnabled=!1;this.completionActionsEnabled=!1;this.defaultWarningDays=7;this.parts=[];this._foreignOwners=[];this._open=!1;this._entityPickerFallback=!1;this._pickerProbeStrikes=0;this._loading=!1;this._error="";this._entryId="";this._taskId=null;this._objectChoices=[];this._name="";this._type="custom";this._scheduleType="time_based";this._intervalDays="30";this._intervalUnit="days";this._dueDate="";this._warningDays="7";this._earliestCompletionDays="";this._intervalAnchor="completion";this._weekdays=[];this._nth="1";this._nthWeekday="5";this._domDay="1";this._domLastDay=!1;this._domBusiness=!1;this._calOffset="0";this._seasonMonths=[];this._endsMode="never";this._endsCount="";this._endsUntil="";this._schedulePreview=[];this._schedulePreviewEnded=!1;this._previewSeq=0;this._notes="";this._documentationUrl="";this._customIcon="";this._priority="normal";this._labels="";this._enabled=!0;this._triggerEntityId="";this._triggerEntityIds=[];this._triggerEntityLogic="any";this._triggerAttribute="";this._triggerType="threshold";this._triggerAbove="";this._triggerBelow="";this._triggerForMinutes="0";this._triggerTargetValue="";this._triggerDeltaMode=!1;this._triggerBaselineValue="";this._liveBaselineValue=null;this._autoCompleteOnRecovery=!1;this._triggerFromState="";this._triggerToState="";this._triggerTargetChanges="";this._triggerRuntimeHours="";this._triggerOnStates="";this._compoundLogic="AND";this._compoundConditions=[];this._suggestedAttriLine truncated
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-VNISEOIC.js";import{a as P,b as L}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-RCMO6YCL.js";import{a as E}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-AIMCOREG.js";import{a as C}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NU5DR7VT.js";import{a as A}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GKQ6LXK5.js";import{a,b as T,c as o,f as u,g as S,i as b,j as l,n as s,r as k,u as $}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var x=["sensor","binary_sensor","number","input_number","input_boolean","switch","climate","vacuum","cover","fan","light","water_heater","humidifier","media_player","weather","air_quality","valve","lawn_mower","lock"],H=["sensor"],N=["temperature","humidity","pressure"];var F=["cleaning","inspection","replacement","calibration","service","reading","custom"],M=["low","normal","high"],O=["time_based","weekdays","nth_weekday","day_of_month","sensor_based","one_time","manual"],w=["weekdays","nth_weekday","day_of_month"],R=["threshold","counter","state_change","runtime"],q=[...R,"compound"];function U(){return{entityIds:"",type:"threshold",attribute:"",above:"",below:"",forMinutes:"0",targetValue:"",deltaMode:!1,fromState:"",toState:"",targetChanges:"",runtimeHours:"",onStates:"",carry:{}}}var j=new Set(["entity_id","entity_ids","type","attribute","trigger_above","trigger_below","trigger_for_minutes","trigger_target_value","trigger_delta_mode","trigger_from_state","trigger_to_state","trigger_target_changes","trigger_runtime_hours","trigger_on_states"]);function B(p){return{entityIds:(p.entity_ids||(p.entity_id?[p.entity_id]:[])).join(", "),type:p.type||"threshold",attribute:p.attribute||"",above:p.trigger_above?.toString()??"",below:p.trigger_below?.toString()??"",forMinutes:p.trigger_for_minutes?.toString()??"0",targetValue:p.trigger_target_value?.toString()??"",deltaMode:p.trigger_delta_mode||!1,fromState:p.trigger_from_state||"",toState:p.trigger_to_state||"",targetChanges:p.trigger_target_changes?.toString()??"",runtimeHours:p.trigger_runtime_hours?.toString()??"",onStates:(p.trigger_on_states||[]).join(", "),carry:Object.fromEntries(Object.entries(p).filter(([t])=>!j.has(t)&&!t.startsWith("_")))}}function V(p){let y=p.entityIds.split(",").map(i=>i.trim()).filter(Boolean);if(y.length===0)return null;let t={...p.carry||{},entity_id:y[0],entity_ids:y,type:p.type};if(p.attribute&&(t.attribute=p.attribute),p.type==="threshold"){let i=parseFloat(p.above);isNaN(i)||(t.trigger_above=i);let e=parseFloat(p.below);isNaN(e)||(t.trigger_below=e);let r=parseInt(p.forMinutes,10);isNaN(r)||(t.trigger_for_minutes=r)}else if(p.type==="counter"){let i=parseFloat(p.targetValue);isNaN(i)||(t.trigger_target_value=i),t.trigger_delta_mode=p.deltaMode}else if(p.type==="state_change"){p.fromState&&(t.trigger_from_state=p.fromState),p.toState&&(t.trigger_to_state=p.toState);let i=parseInt(p.targetChanges,10);isNaN(i)||(t.trigger_target_changes=i)}else if(p.type==="runtime"){let i=parseFloat(p.runtimeHours);isNaN(i)||(t.trigger_runtime_hours=i);let e=(p.onStates||"").split(",").map(r=>r.trim()).filter(Boolean);e.length>0&&(t.trigger_on_states=e)}return t}function D(p){return Array.from({length:7},(y,t)=>$(t,p,"short"))}function z(p){let y=new Intl.DateTimeFormat(p||"en",{month:"short"});return Array.from({length:12},(t,i)=>y.format(new Date(2021,i,1)))}var n=class n extends S{constructor(){super(...arguments);this.checklistsEnabled=!1;this.scheduleTimeEnabled=!1;this.completionActionsEnabled=!1;this.defaultWarningDays=7;this.parts=[];this._foreignOwners=[];this._open=!1;this._entityPickerFallback=!1;this._pickerProbeStrikes=0;this._loading=!1;this._error="";this._entryId="";this._taskId=null;this._objectChoices=[];this._name="";this._type="custom";this._scheduleType="time_based";this._intervalDays="30";this._intervalUnit="days";this._dueDate="";this._warningDays="7";this._earliestCompletionDays="";this._intervalAnchor="completion";this._weekdays=[];this._nth="1";this._nthWeekday="5";this._domDay="1";this._domLastDay=!1;this._domBusiness=!1;this._calOffset="0";this._seasonMonths=[];this._endsMode="never";this._endsCount="";this._endsUntil="";this._schedulePreview=[];this._schedulePreviewEnded=!1;this._previewSeq=0;this._notes="";this._documentationUrl="";this._customIcon="";this._priority="normal";this._labels="";this._enabled=!0;this._triggerEntityId="";this._triggerEntityIds=[];this._triggerEntityLogic="any";this._triggerAttribute="";this._triggerType="threshold";this._triggerAbove="";this._triggerBelow="";this._triggerForMinutes="0";this._triggerTargetValue="";this._triggerDeltaMode=!1;this._triggerBaselineValue="";this._liveBaselineValue=null;this._autoCompleteOnRecovery=!1;this._triggerFromState="";this._triggerToState="";this._triggerTargetChanges="";this._triggerRuntimeHours="";this._triggerOnStates="";this._compoundLogic="AND";this._compoundConditions=[];this._suggestedAttriLine truncated
|
||||
`),this._requiredCompletion=[...i.required_completion_fields||[]],this._scheduleTime=i.schedule_time||"";let d=i.on_complete_action;if(d&&d.service){this._actionService=d.service;let h=d.target?.entity_id;this._actionTargetEntity=Array.isArray(h)?h[0]||"":h||"",this._actionData=d.data&&typeof d.data=="object"?{...d.data}:{},this._actionDataJsonFallback=""}else this._actionService="",this._actionTargetEntity="",this._actionData={},this._actionDataJsonFallback="";let _=i.quick_complete_defaults;this._qcNotes=_?.notes||"",this._qcCost=_?.cost!=null?String(_.cost):"",this._qcDuration=_?.duration!=null?String(_.duration):"",this._qcFeedback=_?.feedback||"";let c=i.adaptive_config||{};if(this._environmentalEntity=c.environmental_entity||"",this._environmentalAttribute=c.environmental_attribute||"",this._environmentalInitial=this._environmentalEntity,this._environmentalAttributeInitial=this._environmentalAttribute,this._adaptiveEnabled=!!c.enabled,this._adaptiveAlpha=(c.ewa_alpha??.3).toString(),this._adaptiveMin=(c.min_interval_days??7).toString(),this._adaptiveMax=(c.max_interval_days??365).toString(),this._adaptiveSeasonal=c.seasonal_enabled!==!1,this._adaptivePrediction=c.sensor_prediction_enabled!==!1,this._adaptiveInitial=this._adaptiveSnapshot(),i.trigger_config){let h=i.trigger_config;this._triggerEntityId=h.entity_id||h.entity_ids&&h.entity_ids[0]||"",this._triggerEntityIds=h.entity_ids||(h.entity_id?[h.entity_id]:[]),this._triggerEntityLogic=h.entity_logic||"any",this._triggerAttribute=h.attribute||"",this._triggerType=h.type||"threshold",this._triggerAbove=h.trigger_above?.toString()||"",this._triggerBelow=h.trigger_below?.toString()||"",this._triggerForMinutes=h.trigger_for_minutes?.toString()||"0",this._triggerTargetValue=h.trigger_target_value?.toString()||"",this._triggerDeltaMode=h.trigger_delta_mode||!1,this._triggerBaselineValue=h.trigger_baseline_value?.toString()||"",this._liveBaselineValue=i.trigger_baseline_value??null,this._autoCompleteOnRecovery=h.auto_complete_on_recovery||!1,this._triggerFromState=h.trigger_from_state||"",this._triggerToState=h.trigger_to_state||"",this._triggerTargetChanges=h.trigger_target_changes?.toString()||"",this._triggerRuntimeHours=h.trigger_runtime_hours?.toString()||"",this._triggerOnStates=(h.trigger_on_states||[]).join(", "),h.type==="compound"?(this._compoundLogic=h.compound_logic==="OR"?"OR":"AND",this._compoundConditions=(h.conditions||[]).map(B)):(this._compoundLogic="AND",this._compoundConditions=[])}else this._resetTriggerFields();this._triggerEntityId&&this._fetchEntityAttributes(this._triggerEntityId),await Promise.all([this._loadUsers(),this._loadTags(),this._loadParts(),this._loadForeignPools()]),this._open=!0}_resetFields(){this._name="",this._type="custom",this._scheduleType="time_based",this._intervalDays="30",this._intervalUnit="days",this._dueDate="",this._warningDays=String(this.defaultWarningDays),this._earliestCompletionDays="",this._intervalAnchor="completion",this._weekdays=[],this._nth="1",this._nthWeekday="5",this._domDay="1",this._domLastDay=!1,this._domBusiness=!1,this._calOffset="0",this._seasonMonths=[],this._endsMode="never",this._endsCount="",this._endsUntil="",this._notes="",this._documentationUrl="",this._customIcon="",this._priority="normal",this._labels="",this._enabled=!0,this._lastPerformed="",this._nfcTagId="",this._readingUnit="",this._consumesParts={},this._responsibleUserId=null,this._assigneePool=[],this._rotationStrategy="",this._checklistText="",this._requiredCompletion=[],this._scheduleTime="",this._environmentalEntity="",this._environmentalAttribute="",this._environmentalInitial="",this._environmentalAttributeInitial="",this._adaptiveEnabled=!1,this._adaptiveAlpha="0.3",this._adaptiveMin="7",this._adaptiveMax="365",this._adaptiveSeasonal=!0,this._adaptivePrediction=!0,this._adaptiveInitial=this._adaptiveSnapshot(),this._actionService="",this._actionTargetEntity="",this._actionData={},this._actionDataJsonFallback="",this._actionTesting=!1,this._actionTestResult="",this._qcNotes="",this._qcCost="",this._qcDuration="",this._qcFeedback="",this._resetTriggerFields()}_resetTriggerFields(){this._triggerEntityId="",this._triggerEntityIds=[],this._triggerEntityLogic="any",this._triggerAttribute="",this._suggestedAttributes=[],this._availableAttributes=[],this._entityDomain="",this._triggerType="threshold",this._triggerAbove="",this._triggerBelow="",this._triggerForMinutes="0",this._triggerTargetValue="",this._triggerDeltaMode=!1,this._triggerBaselineValue="",this._liveBaselineValue=null,this._autoCompleteOnRecovery=!1,this._triggerFromState="",this._triggerToState="",this._triggerTargetChanges="",this._triggerRuntimeHours="",this._triggerOnStates="",this._compoundLogic="AND",this._compoundConditions=[]}async _loadUsers(){this._userService||(this._userService=new A(this.hass));try{this._availableUsers=await this._userService.getUsers()}catch(t){console.error("Failed to load users:",t),this._availableUsers=[]}}_toggleAssignee(
Line truncated
|
||||
<details class="ca-section">
|
||||
<summary>${s("on_complete_action_title",t)}</summary>
|
||||
-125
@@ -1,125 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as v}from"./chunk-QCBC6YX3.js";import{a as u,b as o,d as h,e as b,f as y,g as l,h as g,i as r,k as m,t as p}from"./chunk-RNKC43AV.js";import{a as n}from"./chunk-LPNFL3AF.js";var x=80,s=class extends b{constructor(){super(...arguments);this._config={type:""};this._status=null;this._busy=!1;this._error="";this._localMonthly="";this._localYearly="";this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),m(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/budget_status"});this._status=t,this._localMonthly=t.monthly_budget?String(t.monthly_budget):"",this._localYearly=t.yearly_budget?String(t.yearly_budget):"",this._dirty=!1}catch(t){this._error=p(t,this._lang)}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=parseFloat(this._localMonthly),a=parseFloat(this._localYearly),i={};!isNaN(t)&&t>=0&&(i.budget_monthly=t),!isNaN(a)&&a>=0&&(i.budget_yearly=a),await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:i}),await this._load()}catch(t){this._error=p(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_budget"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,a=this._status;if(!a)return o`<ha-card><div class="loading">${r("loading",t)||"Loading\u2026"}</div></ha-card>`;let i=a.currency_symbol||g,_=a.alert_threshold_pct??x,f=[{label:r("budget_monthly",t)||"Monthly",spent:a.monthly_spent||0,budget:a.monthly_budget||0},{label:r("budget_yearly",t)||"Yearly",spent:a.yearly_spent||0,budget:a.yearly_budget||0}];return o`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<span class="emoji">💰</span>
|
||||
<span>${this._config.title||r("settings_budget",t)||"Budget"}</span>
|
||||
</div>
|
||||
<span class="currency">${i}</span>
|
||||
</div>
|
||||
|
||||
${this._error?o`<div class="error">${this._error}</div>`:h}
|
||||
|
||||
${f.map(e=>{if(!(e.budget>0))return o`
|
||||
<div class="track spent-only">
|
||||
<div class="track-label-row">
|
||||
<label>${e.label}</label>
|
||||
<span class="track-numbers ok">${e.spent.toFixed(0)} ${i}</span>
|
||||
</div>
|
||||
</div>
|
||||
`;let d=Math.min(100,Math.max(0,e.spent/e.budget*100)),c=d>=100?"danger":d>=_?"warning":"ok";return o`
|
||||
<div class="track">
|
||||
<div class="track-label-row">
|
||||
<label>${e.label}</label>
|
||||
<span class="track-numbers ${c}">
|
||||
${e.spent.toFixed(0)} / ${e.budget.toFixed(0)} ${i}
|
||||
</span>
|
||||
</div>
|
||||
<div class="bar"><div class="bar-fill ${c}" style="width:${d}%"></div></div>
|
||||
</div>
|
||||
`})}
|
||||
|
||||
${this._isAdmin?o`
|
||||
<div class="inputs-row">
|
||||
<div class="input-field">
|
||||
<label>${r("budget_monthly_set",t)||"Set monthly"}</label>
|
||||
<div class="input-wrap">
|
||||
<input type="number" min="0" step="1"
|
||||
.value=${this._localMonthly}
|
||||
?disabled=${this._busy}
|
||||
@input=${e=>{this._localMonthly=e.target.value,this._dirty=!0}} />
|
||||
<span class="input-suffix">${i}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-field">
|
||||
<label>${r("budget_yearly_set",t)||"Set yearly"}</label>
|
||||
<div class="input-wrap">
|
||||
<input type="number" min="0" step="1"
|
||||
.value=${this._localYearly}
|
||||
?disabled=${this._busy}
|
||||
@input=${e=>{this._localYearly=e.target.value,this._dirty=!0}} />
|
||||
<span class="input-suffix">${i}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="btn ${this._dirty?"primary":"muted"}"
|
||||
@click=${this._save}
|
||||
?disabled=${this._busy||!this._dirty}>
|
||||
<ha-icon icon="${this._dirty?"mdi:content-save":"mdi:check"}"></ha-icon>
|
||||
${this._dirty?r("save",t)||"Save":r("saved",t)||"Saved"}
|
||||
</button>
|
||||
<button class="btn link" @click=${this._onDeepLink}>
|
||||
${r("budget_advanced",t)||"Currency, alerts\u2026"}
|
||||
</button>
|
||||
</div>
|
||||
`:o`
|
||||
<button class="btn link" @click=${this._onDeepLink}>
|
||||
${r("budget_open_panel",t)||"Open in panel"}
|
||||
</button>
|
||||
`}
|
||||
</div>
|
||||
</ha-card>
|
||||
`}};s.styles=[v,u`
|
||||
.currency {
|
||||
font-size: 14px; font-weight: 600;
|
||||
color: var(--secondary-text-color);
|
||||
background: var(--secondary-background-color);
|
||||
padding: 2px 10px; border-radius: 999px;
|
||||
}
|
||||
.track { display: flex; flex-direction: column; gap: 4px; }
|
||||
.track-label-row {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
.track-label-row label {
|
||||
font-size: 12px; color: var(--secondary-text-color);
|
||||
text-transform: uppercase; letter-spacing: 0.5px;
|
||||
}
|
||||
.track-numbers { font-size: 13px; font-weight: 600; }
|
||||
.track-numbers.ok { color: var(--primary-text-color); }
|
||||
.track-numbers.warning { color: #ff9800; }
|
||||
.track-numbers.danger { color: var(--error-color, #f44336); }
|
||||
.bar {
|
||||
height: 6px; background: var(--secondary-background-color);
|
||||
border-radius: 3px; overflow: hidden;
|
||||
}
|
||||
.bar-fill { height: 100%; transition: width 0.3s; border-radius: 3px; }
|
||||
.bar-fill.ok { background: var(--primary-color); }
|
||||
.bar-fill.warning { background: #ff9800; }
|
||||
.bar-fill.danger { background: var(--error-color, #f44336); }
|
||||
.inputs-row {
|
||||
display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
|
||||
padding-top: 4px; border-top: 1px solid var(--divider-color);
|
||||
}
|
||||
.input-field { display: flex; flex-direction: column; gap: 4px; }
|
||||
.input-field label {
|
||||
font-size: 11px; color: var(--secondary-text-color);
|
||||
text-transform: uppercase; letter-spacing: 0.3px;
|
||||
}
|
||||
.input-wrap { position: relative; display: flex; align-items: center; }
|
||||
.input-wrap input {
|
||||
flex: 1; padding: 6px 32px 6px 8px; font-size: 13px;
|
||||
background: var(--secondary-background-color, #2c2c2c);
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
font-family: inherit;
|
||||
}
|
||||
.input-suffix {
|
||||
position: absolute; right: 8px;
|
||||
color: var(--secondary-text-color); font-size: 13px;
|
||||
pointer-events: none;
|
||||
}
|
||||
.actions { display: flex; gap: 8px; align-items: center; }
|
||||
`],n([y({attribute:!1})],s.prototype,"hass",2),n([l()],s.prototype,"_config",2),n([l()],s.prototype,"_status",2),n([l()],s.prototype,"_busy",2),n([l()],s.prototype,"_error",2),n([l()],s.prototype,"_localMonthly",2),n([l()],s.prototype,"_localYearly",2),n([l()],s.prototype,"_dirty",2);customElements.get("maintenance-budget-section-card")||customElements.define("maintenance-budget-section-card",s);window.customCards=window.customCards||[];window.customCards.push({type:"maintenance-budget-section-card",name:"Maintenance Supporter \u2014 Budget",description:"Inline monthly + yearly budget editor",preview:!1});export{s as MaintenanceBudgetSectionCard};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{a as v}from"./chunk-XWMJNIQI.js";import{a as u,b as o,d as h,e as b,f as y,g as l,h as g,i as r,k as m,t as p}from"./chunk-TRW3CRLS.js";import{a as n}from"./chunk-UHANDS57.js";var x=80,s=class extends b{constructor(){super(...arguments);this._config={type:""};this._status=null;this._busy=!1;this._error="";this._localMonthly="";this._localYearly="";this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),m(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/budget_status"});this._status=t,this._localMonthly=t.monthly_budget?String(t.monthly_budget):"",this._localYearly=t.yearly_budget?String(t.yearly_budget):"",this._dirty=!1}catch(t){this._error=p(t,this._lang)}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=parseFloat(this._localMonthly),a=parseFloat(this._localYearly),i={};!isNaN(t)&&t>=0&&(i.budget_monthly=t),!isNaN(a)&&a>=0&&(i.budget_yearly=a),await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:i}),await this._load()}catch(t){this._error=p(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_budget"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,a=this._status;if(!a)return o`<ha-card><div class="loading">${r("loading",t)||"Loading\u2026"}</div></ha-card>`;let i=a.currency_symbol||g,_=a.alert_threshold_pct??x,f=[{label:r("budget_monthly",t)||"Monthly",spent:a.monthly_spent||0,budget:a.monthly_budget||0},{label:r("budget_yearly",t)||"Yearly",spent:a.yearly_spent||0,budget:a.yearly_budget||0}];return o`
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{a as v}from"./chunk-6INP67SU.js";import{a as u,b as o,d as h,e as b,f as y,g as l,h as g,i as r,k as m,t as p}from"./chunk-CWQRMTXS.js";import{a as n}from"./chunk-HQWGP2HE.js";var x=80,s=class extends b{constructor(){super(...arguments);this._config={type:""};this._status=null;this._busy=!1;this._error="";this._localMonthly="";this._localYearly="";this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),m(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/budget_status"});this._status=t,this._localMonthly=t.monthly_budget?String(t.monthly_budget):"",this._localYearly=t.yearly_budget?String(t.yearly_budget):"",this._dirty=!1}catch(t){this._error=p(t,this._lang)}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=parseFloat(this._localMonthly),a=parseFloat(this._localYearly),i={};!isNaN(t)&&t>=0&&(i.budget_monthly=t),!isNaN(a)&&a>=0&&(i.budget_yearly=a),await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:i}),await this._load()}catch(t){this._error=p(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_budget"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,a=this._status;if(!a)return o`<ha-card><div class="loading">${r("loading",t)||"Loading\u2026"}</div></ha-card>`;let i=a.currency_symbol||g,_=a.alert_threshold_pct??x,f=[{label:r("budget_monthly",t)||"Monthly",spent:a.monthly_spent||0,budget:a.monthly_budget||0},{label:r("budget_yearly",t)||"Yearly",spent:a.yearly_spent||0,budget:a.yearly_budget||0}];return o`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<div class="header">
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as r}from"./chunk-RNKC43AV.js";var a=r`
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{a as r}from"./chunk-CWQRMTXS.js";var a=r`
|
||||
ha-card { overflow: hidden; }
|
||||
.card-content {
|
||||
padding: 16px;
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
var L=globalThis,M=L.ShadowRoot&&(L.ShadyCSS===void 0||L.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,W=Symbol(),ae=new WeakMap,$=class{constructor(e,t,r){if(this._$cssResult$=!0,r!==W)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o,t=this.t;if(M&&e===void 0){let r=t!==void 0&&t.length===1;r&&(e=ae.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),r&&ae.set(t,e))}return e}toString(){return this.cssText}},ne=o=>new $(typeof o=="string"?o:o+"",void 0,W),U=(o,...e)=>{let t=o.length===1?o[0]:e.reduce((r,a,n)=>r+(i=>{if(i._$cssResult$===!0)return i.cssText;if(typeof i=="number")return i;throw Error("Value passed to 'css' function must be a 'css' function result: "+i+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(a)+o[n+1],o[0]);return new $(t,o,W)},ie=(o,e)=>{if(M)o.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of e){let r=document.createElement("style"),a=L.litNonce;a!==void 0&&r.setAttribute("nonce",a),r.textContent=t.cssText,o.appendChild(r)}},G=M?o=>o:o=>o instanceof CSSStyleSheet?(e=>{let t="";for(let r of e.cssRules)t+=r.cssText;return ne(t)})(o):o;var{is:Te,defineProperty:je,getOwnPropertyDescriptor:Ne,getOwnPropertyNames:Pe,getOwnPropertySymbols:Re,getPrototypeOf:ze}=Object,q=globalThis,se=q.trustedTypes,Oe=se?se.emptyScript:"",De=q.reactiveElementPolyfillSupport,E=(o,e)=>o,C={toAttribute(o,e){switch(e){case Boolean:o=o?Oe:null;break;case Object:case Array:o=o==null?o:JSON.stringify(o)}return o},fromAttribute(o,e){let t=o;switch(e){case Boolean:t=o!==null;break;case Number:t=o===null?null:Number(o);break;case Object:case Array:try{t=JSON.parse(o)}catch{t=null}}return t}},H=(o,e)=>!Te(o,e),le={attribute:!0,type:String,converter:C,reflect:!1,useDefault:!1,hasChanged:H};Symbol.metadata??=Symbol("metadata"),q.litPropertyMetadata??=new WeakMap;var g=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=le){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){let r=Symbol(),a=this.getPropertyDescriptor(e,r,t);a!==void 0&&je(this.prototype,e,a)}}static getPropertyDescriptor(e,t,r){let{get:a,set:n}=Ne(this.prototype,e)??{get(){return this[t]},set(i){this[t]=i}};return{get:a,set(i){let l=a?.call(this);n?.call(this,i),this.requestUpdate(e,l,r)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??le}static _$Ei(){if(this.hasOwnProperty(E("elementProperties")))return;let e=ze(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(E("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(E("properties"))){let t=this.properties,r=[...Pe(t),...Re(t)];for(let a of r)this.createProperty(a,t[a])}let e=this[Symbol.metadata];if(e!==null){let t=litPropertyMetadata.get(e);if(t!==void 0)for(let[r,a]of t)this.elementProperties.set(r,a)}this._$Eh=new Map;for(let[t,r]of this.elementProperties){let a=this._$Eu(t,r);a!==void 0&&this._$Eh.set(a,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){let t=[];if(Array.isArray(e)){let r=new Set(e.flat(1/0).reverse());for(let a of r)t.unshift(G(a))}else e!==void 0&&t.push(G(e));return t}static _$Eu(e,t){let r=t.attribute;return r===!1?void 0:typeof r=="string"?r:typeof e=="string"?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),this.renderRoot!==void 0&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){let e=new Map,t=this.constructor.elementProperties;for(let r of t.keys())this.hasOwnProperty(r)&&(e.set(r,this[r]),delete this[r]);e.size>0&&(this._$Ep=e)}createRenderRoot(){let e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return ie(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,r){this._$AK(e,r)}_$ET(e,t){let r=this.constructor.elementProperties.get(e),a=this.constructor._$Eu(e,r);if(a!==void 0&&r.reflect===!0){let n=(r.converter?.toAttribute!==void 0?r.converter:C).toAttribute(t,r.type);this._$Em=e,n==null?this.removeAttribute(a):this.setAttribute(a,n),thLine truncated
|
||||
\f\r]`,T=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,pe=/-->/g,_e=/>/g,b=RegExp(`>|${V}(?:([^\\s"'>=/]+)(${V}*=${V}*(?:[^
|
||||
\f\r"'\`<>=]|("|')|))|$)`,"g"),ue=/'/g,he=/"/g,be=/^(?:script|style|textarea|title)$/i,te=o=>(e,...t)=>({_$litType$:o,strings:e,values:t}),ot=te(1),rt=te(2),at=te(3),x=Symbol.for("lit-noChange"),p=Symbol.for("lit-nothing"),ge=new WeakMap,y=v.createTreeWalker(v,129);function ye(o,e){if(!ee(o)||!o.hasOwnProperty("raw"))throw Error("invalid template strings array");return de!==void 0?de.createHTML(e):e}var Ue=(o,e)=>{let t=o.length-1,r=[],a,n=e===2?"<svg>":e===3?"<math>":"",i=T;for(let l=0;l<t;l++){let s=o[l],d,_,c=-1,h=0;for(;h<s.length&&(i.lastIndex=h,_=i.exec(s),_!==null);)h=i.lastIndex,i===T?_[1]==="!--"?i=pe:_[1]!==void 0?i=_e:_[2]!==void 0?(be.test(_[2])&&(a=RegExp("</"+_[2],"g")),i=b):_[3]!==void 0&&(i=b):i===b?_[0]===">"?(i=a??T,c=-1):_[1]===void 0?c=-2:(c=i.lastIndex-_[2].length,d=_[1],i=_[3]===void 0?b:_[3]==='"'?he:ue):i===he||i===ue?i=b:i===pe||i===_e?i=T:(i=b,a=void 0);let m=i===b&&o[l+1].startsWith("/>")?" ":"";n+=i===T?s+Le:c>=0?(r.push(d),s.slice(0,c)+me+s.slice(c)+f+m):s+f+(c===-2?l:m)}return[ye(o,n+(o[t]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),r]},P=class o{constructor({strings:e,_$litType$:t},r){let a;this.parts=[];let n=0,i=0,l=e.length-1,s=this.parts,[d,_]=Ue(e,t);if(this.el=o.createElement(d,r),y.currentNode=this.el.content,t===2||t===3){let c=this.el.content.firstChild;c.replaceWith(...c.childNodes)}for(;(a=y.nextNode())!==null&&s.length<l;){if(a.nodeType===1){if(a.hasAttributes())for(let c of a.getAttributeNames())if(c.endsWith(me)){let h=_[i++],m=a.getAttribute(c).split(f),D=/([.?@])?(.*)/.exec(h);s.push({type:1,index:n,name:D[2],strings:m,ctor:D[1]==="."?Q:D[1]==="?"?Y:D[1]==="@"?J:S}),a.removeAttribute(c)}else c.startsWith(f)&&(s.push({type:6,index:n}),a.removeAttribute(c));if(be.test(a.tagName)){let c=a.textContent.split(f),h=c.length-1;if(h>0){a.textContent=I?I.emptyScript:"";for(let m=0;m<h;m++)a.append(c[m],j()),y.nextNode(),s.push({type:2,index:++n});a.append(c[h],j())}}}else if(a.nodeType===8)if(a.data===fe)s.push({type:2,index:n});else{let c=-1;for(;(c=a.data.indexOf(f,c+1))!==-1;)s.push({type:7,index:n}),c+=f.length-1}n++}}static createElement(e,t){let r=v.createElement("template");return r.innerHTML=e,r}};function k(o,e,t=o,r){if(e===x)return e;let a=r!==void 0?t._$Co?.[r]:t._$Cl,n=N(e)?void 0:e._$litDirective$;return a?.constructor!==n&&(a?._$AO?.(!1),n===void 0?a=void 0:(a=new n(o),a._$AT(o,t,r)),r!==void 0?(t._$Co??=[])[r]=a:t._$Cl=a),a!==void 0&&(e=k(o,a._$AS(o,e.values),a,r)),e}var K=class{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){let{el:{content:t},parts:r}=this._$AD,a=(e?.creationScope??v).importNode(t,!0);y.currentNode=a;let n=y.nextNode(),i=0,l=0,s=r[0];for(;s!==void 0;){if(i===s.index){let d;s.type===2?d=new R(n,n.nextSibling,this,e):s.type===1?d=new s.ctor(n,s.name,s.strings,this,e):s.type===6&&(d=new Z(n,this,e)),this._$AV.push(d),s=r[++l]}i!==s?.index&&(n=y.nextNode(),i++)}return y.currentNode=v,a}p(e){let t=0;for(let r of this._$AV)r!==void 0&&(r.strings!==void 0?(r._$AI(e,r,t),t+=r.strings.length-2):r._$AI(e[t])),t++}},R=class o{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,r,a){this.type=2,this._$AH=p,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=r,this.options=a,this._$Cv=a?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode,t=this._$AM;return t!==void 0&&e?.nodeType===11&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,t=this){e=k(this,e,t),N(e)?e===p||e==null||e===""?(this._$AH!==p&&this._$AR(),this._$AH=p):e!==this._$AH&&e!==x&&this._(e):e._$litType$!==void 0?this.$(e):e.nodeType!==void 0?this.T(e):Me(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==p&&N(this._$AH)?this._$AA.nextSibling.data=e:this.T(v.createTextNode(e)),this._$AH=e}$(e){let{values:t,_$litType$:r}=e,a=typeof r=="number"?this._$AC(e):(r.el===void 0&&(r.el=P.createElement(ye(r.h,r.h[0]),this.options)),r);if(this._$AH?._$AD===a)this._$AH.p(t);else{let n=new K(a,this),i=n.u(this.options);n.p(t),this.T(i),this._$AH=n}}_$AC(e){let t=ge.get(e.strings);return t===void 0&&ge.set(e.strings,t=new P(e)),t}k(e){ee(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,r,a=0;for(let n of e)a===t.length?t.push(r=new o(this.O(j()),this.O(j()),this,this.options)):r=t[a],r._$AI(n),a++;a<t.length&&(this._$AR(r&&r._$AB.nextSibling,a),t.length=a)}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);e!==this._$AB;){let r=ce(e).nextSibling;ce(e).remove(),e=r}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e))}},S=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,r,a,n){this.type=1,this._$AH=p,this._$AN=void 0,this.element=e,this.name=t,this._$AM=a,this.options=n,r.length>2||r[0]!==""||r[1]!==""?(this._$AH=Array(r.length-1).fill(new String),this.strings=r):thisLine truncated
|
||||
Replace seal
|
||||
Test pressure`,checklist_help:"One step per line. Max 100 items.",err_too_long:"{field}: too long (max {n} characters)",err_too_short:"{field}: too short (min {n} characters)",err_value_too_high:"{field}: too large (max {n})",err_value_too_low:"{field}: too small (min {n})",err_required:"{field}: required",err_wrong_type:"{field}: wrong type (expected: {type})",err_invalid_choice:"{field}: not an allowed value",err_invalid_value:"{field}: invalid value",feat_schedule_time:"Time-of-day scheduling",feat_schedule_time_desc:"Tasks become overdue at a specific time of day instead of midnight.",schedule_time_optional:"Due at time (optional, HH:MM)",schedule_time_help:"Empty = midnight (default). HA timezone.",at_time:"at",notes_optional:"Notes (optional)",cost_optional:"Cost (optional)",duration_minutes:"Duration in minutes (optional)",days:"days",day:"day",today:"Today",d_overdue:"d overdue",no_tasks:"No maintenance tasks yet. Create an object to get started.",no_tasks_short:"No tasks",no_history:"No history entries yet.",show_all:"Show all",cost_duration_chart:"Cost & Duration",installed:"Installed",confirm_delete_object:"Delete this object and all its tasks?",confirm_delete_task:"Delete this task?",min:"Min",max:"Max",save:"Save",saving:"Saving\u2026",edit_task:"Edit Task",new_task:"New Maintenance Task",task_name:"Task name",maintenance_type:"Maintenance type",priority:"Priority",labels:"Labels",labels_placeholder:"e.g. safety, seasonal, tenant-visible",labels_help:"Comma-separated tags for filtering and reporting.",priority_low:"Low",priority_normal:"Normal",priority_high:"High",schedule_type:"Schedule type",interval_days:"Interval (days)",warning_days:"Warning days",earliest_completion_days:"Earliest completion (days before due)",earliest_completion_days_help:"Leave empty to allow completing any time. 0 = only on/after the due date.",last_performed_optional:"Last performed (optional)",interval_anchor:"Interval anchor",anchor_completion:"From completion date",anchor_planned:"From planned date (no drift)",edit_object:"Edit Object",name:"Name",manufacturer_optional:"Manufacturer (optional)",model_optional:"Model (optional)",serial_number_optional:"Serial number (optional)",serial_number_label:"S/N",documentation_url_label:"Manual",object_notes_label:"Notes",sort_due_date:"Due date",sort_object:"Object name",sort_type:"Type",sort_task_name:"Task name",all_objects:"All objects",tasks_lower:"tasks",no_tasks_yet:"No tasks yet",add_first_task:"Add first task",trigger_configuration:"Trigger Configuration",entity_id:"Entity ID",comma_separated:"comma-separated",entity_logic:"Entity logic",entity_logic_any:"Any entity triggers",entity_logic_all:"All entities must trigger",entities:"entities",attribute_optional:"Attribute (optional, blank = state)",use_entity_state:"Use entity state (no attribute)",trigger_above:"Trigger above",trigger_below:"Trigger below",for_at_least_minutes:"For at least (minutes)",safety_interval_days:"Safety interval (days, optional)",safety_interval:"Safety interval (optional)",delta_mode:"Delta mode",from_state_optional:"From state (optional)",to_state_optional:"To state (optional)",documentation_url_optional:"Documentation URL (optional)",object_notes_optional:"Notes (optional)",nfc_tag_id_optional:"NFC Tag ID (optional)",nfc_tags_empty_help:"No NFC tags registered in Home Assistant yet.",nfc_tags_open_settings:"Open Tags settings",nfc_tags_refresh:"Refresh",environmental_entity_optional:"Environmental sensor (optional)",environmental_entity_helper:"e.g. sensor.outdoor_temperature \u2014 adjusts the interval based on environmental conditions",adaptive_prediction_enabled:"Enable sensor-driven predictions",adaptive_seasonal_enabled:"Enable seasonal awareness",adaptive_max_interval:"Maximum interval (days)",adaptive_min_interval:"Minimum interval (days)",adaptive_ewa_alpha:"Learning rate (alpha)",adaptive_enabled:"Enable adaptive scheduling",adaptive_section_title:"Adaptive Scheduling",environmental_attribute_optional:"Environmental attribute (optional)",nfc_tag_id:"NFC Tag ID",nfc_linked:"NFC tag linked",nfc_link_hint:"Click to link NFC tag",responsible_user:"Responsible User",shared_with:"Shared with (rotation)",shared_with_help:"Pick multiple people to share this task; the responsible person rotates on each completion.",rotation_strategy:"Rotation",rotation_none:"No rotation",rotation_round_robin:"Round-robin",rotation_least_completed:"Least completed",rotation_random:"Random",no_user_assigned:"(No user assigned)",all_users:"All Users",my_tasks:"My Tasks",tab_calendar:"Calendar",cal_no_events:"No maintenance",cal_window_7:"7 days",cal_window_14:"14 days",cal_window_30:"30 days",cal_window_365:"1 year",cal_every_n_days:"every {n} days",cal_source_time:"Time-based",cal_source_time_adaptive:"Time-based (adaptive)",cal_source_sensor:"Sensor-based",cal_predicted:"predicted",cal_confidence_high:"high confidence",cal_confidence_medium:"medium confidence",cal_confidence_low:"low confidence",budget_mo
Line truncated
|
||||
Test pressure`,checklist_help:"One step per line. Max 100 items.",err_too_long:"{field}: too long (max {n} characters)",err_too_short:"{field}: too short (min {n} characters)",err_value_too_high:"{field}: too large (max {n})",err_value_too_low:"{field}: too small (min {n})",err_required:"{field}: required",err_wrong_type:"{field}: wrong type (expected: {type})",err_invalid_choice:"{field}: not an allowed value",err_invalid_value:"{field}: invalid value",feat_schedule_time:"Time-of-day scheduling",feat_schedule_time_desc:"Tasks become overdue at a specific time of day instead of midnight.",schedule_time_optional:"Due at time (optional, HH:MM)",schedule_time_help:"Empty = midnight (default). HA timezone.",at_time:"at",notes_optional:"Notes (optional)",cost_optional:"Cost (optional)",duration_minutes:"Duration in minutes (optional)",days:"days",day:"day",today:"Today",d_overdue:"d overdue",no_tasks:"No maintenance tasks yet. Create an object to get started.",no_tasks_short:"No tasks",no_history:"No history entries yet.",show_all:"Show all",cost_duration_chart:"Cost & Duration",installed:"Installed",confirm_delete_object:"Delete this object and all its tasks?",confirm_delete_task:"Delete this task?",min:"Min",max:"Max",save:"Save",saving:"Saving\u2026",edit_task:"Edit Task",new_task:"New Maintenance Task",task_name:"Task name",maintenance_type:"Maintenance type",priority:"Priority",labels:"Labels",labels_placeholder:"e.g. safety, seasonal, tenant-visible",labels_help:"Comma-separated tags for filtering and reporting.",priority_low:"Low",priority_normal:"Normal",priority_high:"High",schedule_type:"Schedule type",interval_days:"Interval (days)",warning_days:"Warning days",earliest_completion_days:"Earliest completion (days before due)",earliest_completion_days_help:"Leave empty to allow completing any time. 0 = only on/after the due date.",last_performed_optional:"Last performed (optional)",interval_anchor:"Interval anchor",anchor_completion:"From completion date",anchor_planned:"From planned date (no drift)",edit_object:"Edit Object",name:"Name",manufacturer_optional:"Manufacturer (optional)",model_optional:"Model (optional)",serial_number_optional:"Serial number (optional)",serial_number_label:"S/N",documentation_url_label:"Manual",object_notes_label:"Notes",sort_due_date:"Due date",sort_object:"Object name",sort_type:"Type",sort_task_name:"Task name",all_objects:"All objects",all_parts:"All parts",tasks_lower:"tasks",no_tasks_yet:"No tasks yet",add_first_task:"Add first task",trigger_configuration:"Trigger Configuration",entity_id:"Entity ID",comma_separated:"comma-separated",entity_logic:"Entity logic",entity_logic_any:"Any entity triggers",entity_logic_all:"All entities must trigger",entities:"entities",attribute_optional:"Attribute (optional, blank = state)",use_entity_state:"Use entity state (no attribute)",trigger_above:"Trigger above",trigger_below:"Trigger below",for_at_least_minutes:"For at least (minutes)",safety_interval_days:"Safety interval (days, optional)",safety_interval:"Safety interval (optional)",delta_mode:"Delta mode",from_state_optional:"From state (optional)",to_state_optional:"To state (optional)",documentation_url_optional:"Documentation URL (optional)",object_notes_optional:"Notes (optional)",nfc_tag_id_optional:"NFC Tag ID (optional)",nfc_tags_empty_help:"No NFC tags registered in Home Assistant yet.",nfc_tags_open_settings:"Open Tags settings",nfc_tags_refresh:"Refresh",environmental_entity_optional:"Environmental sensor (optional)",environmental_entity_helper:"e.g. sensor.outdoor_temperature \u2014 adjusts the interval based on environmental conditions",adaptive_prediction_enabled:"Enable sensor-driven predictions",adaptive_seasonal_enabled:"Enable seasonal awareness",adaptive_max_interval:"Maximum interval (days)",adaptive_min_interval:"Minimum interval (days)",adaptive_ewa_alpha:"Learning rate (alpha)",adaptive_enabled:"Enable adaptive scheduling",adaptive_section_title:"Adaptive Scheduling",environmental_attribute_optional:"Environmental attribute (optional)",nfc_tag_id:"NFC Tag ID",nfc_linked:"NFC tag linked",nfc_link_hint:"Click to link NFC tag",responsible_user:"Responsible User",shared_with:"Shared with (rotation)",shared_with_help:"Pick multiple people to share this task; the responsible person rotates on each completion.",rotation_strategy:"Rotation",rotation_none:"No rotation",rotation_round_robin:"Round-robin",rotation_least_completed:"Least completed",rotation_random:"Random",no_user_assigned:"(No user assigned)",all_users:"All Users",my_tasks:"My Tasks",tab_calendar:"Calendar",cal_no_events:"No maintenance",cal_window_7:"7 days",cal_window_14:"14 days",cal_window_30:"30 days",cal_window_365:"1 year",cal_every_n_days:"every {n} days",cal_source_time:"Time-based",cal_source_time_adaptive:"Time-based (adaptive)",cal_source_sensor:"Sensor-based",cal_predicted:"predicted",cal_confidence_high:"high confidence",cal_confidence_medium:"medium confidence",cal_confidence_low:"low
Line truncated
|
||||
.field { display: flex; flex-direction: column; gap: 4px; }
|
||||
.field-label { font-size: 12px; color: var(--secondary-text-color); }
|
||||
.field-input {
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
var s=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var t=(a,r,c,o)=>{for(var e=o>1?void 0:o?l(r,c):r,i=a.length-1,d;i>=0;i--)(d=a[i])&&(e=(o?d(r,c,e):d(e))||e);return o&&e&&s(r,c,e),e};var m={ok:"var(--success-color, #4caf50)",due_soon:"var(--warning-color, #ff9800)",overdue:"var(--error-color, #f44336)",triggered:"var(--deep-orange-color, #ff5722)",archived:"var(--disabled-color, #9e9e9e)",paused:"var(--info-color, #2196f3)"},v={ok:"mdi:check-circle",due_soon:"mdi:alert-circle",overdue:"mdi:alert-octagon",triggered:"mdi:bell-alert",archived:"mdi:archive-outline",paused:"mdi:pause-circle-outline",completed:"mdi:check-circle",skipped:"mdi:skip-next",missed:"mdi:calendar-remove",reset:"mdi:refresh"};export{t as a,m as b,v as c};
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
var s=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var t=(a,r,c,o)=>{for(var e=o>1?void 0:o?l(r,c):r,i=a.length-1,d;i>=0;i--)(d=a[i])&&(e=(o?d(r,c,e):d(e))||e);return o&&e&&s(r,c,e),e};var m={ok:"var(--success-color, #4caf50)",due_soon:"var(--warning-color, #ff9800)",overdue:"var(--error-color, #f44336)",triggered:"var(--deep-orange-color, #ff5722)",archived:"var(--disabled-color, #9e9e9e)",paused:"var(--info-color, #2196f3)"},v={ok:"mdi:check-circle",due_soon:"mdi:alert-circle",overdue:"mdi:alert-octagon",triggered:"mdi:bell-alert",archived:"mdi:archive-outline",paused:"mdi:pause-circle-outline",completed:"mdi:check-circle",skipped:"mdi:skip-next",missed:"mdi:calendar-remove",reset:"mdi:refresh"};export{t as a,m as b,v as c};
|
||||
@@ -1,60 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{a as r}from"./chunk-TRW3CRLS.js";var a=r`
|
||||
ha-card { overflow: hidden; }
|
||||
.card-content {
|
||||
padding: 16px;
|
||||
display: flex; flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.header {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
.title {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
font-size: 16px; font-weight: 500;
|
||||
}
|
||||
.emoji { font-size: 20px; }
|
||||
|
||||
/* Button family — primary action / muted-saved-state / link / icon-with-text */
|
||||
.btn {
|
||||
padding: 6px 12px; font-size: 13px;
|
||||
border-radius: 6px; cursor: pointer;
|
||||
border: 1px solid var(--divider-color);
|
||||
background: var(--secondary-background-color, transparent);
|
||||
color: var(--primary-text-color);
|
||||
font-weight: 500;
|
||||
display: inline-flex; align-items: center; gap: 4px;
|
||||
}
|
||||
.btn:hover { background: var(--state-icon-color, rgba(255,255,255,0.06)); }
|
||||
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
|
||||
.btn.primary {
|
||||
background: var(--primary-color);
|
||||
color: var(--text-primary-color, white);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
.btn.primary[disabled] { opacity: 0.6; }
|
||||
.btn.muted {
|
||||
background: transparent;
|
||||
color: var(--secondary-text-color);
|
||||
border-style: dashed;
|
||||
}
|
||||
.btn.muted[disabled] { opacity: 1; cursor: default; }
|
||||
.btn.muted ha-icon, .btn.primary ha-icon { --mdc-icon-size: 14px; }
|
||||
.btn.link {
|
||||
background: transparent; border: none; padding: 6px 4px;
|
||||
color: var(--primary-color); margin-left: auto;
|
||||
}
|
||||
.btn.link:hover { background: transparent; text-decoration: underline; }
|
||||
|
||||
/* Error + loading states */
|
||||
.error {
|
||||
padding: 8px; border-radius: 6px;
|
||||
background: rgba(211, 47, 47, 0.1);
|
||||
color: var(--error-color, #d32f2f); font-size: 13px;
|
||||
}
|
||||
.loading {
|
||||
padding: 24px; text-align: center;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
`;export{a};
|
||||
+243
-212
File diff suppressed because it is too large.
Load diff
-2453
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{a as m}from"./chunk-XWMJNIQI.js";import{a as u,b as s,d as l,e as h,f as g,g as o,i,k as _,t as p}from"./chunk-TRW3CRLS.js";import{a}from"./chunk-UHANDS57.js";var e=class extends h{constructor(){super(...arguments);this._config={type:""};this._groups={};this._loaded=!1;this._busy=!1;this._error="";this._newName="";this._editingId=null;this._editingName="";this._hasInitiallyLoaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._hasInitiallyLoaded&&(this._hasInitiallyLoaded=!0,this._load(),_(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/groups"});this._groups=t.groups||{},this._loaded=!0}catch(t){this._error=p(t,this._lang)}}async _addGroup(){if(!this._isAdmin)return;let t=this._newName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/create",name:t}),this._newName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}_startEdit(t){this._editingId=t,this._editingName=this._groups[t]?.name||""}async _saveEdit(){if(!this._isAdmin||!this._editingId)return;let t=this._editingName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/update",group_id:this._editingId,name:t}),this._editingId=null,this._editingName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}async _deleteGroup(t,r){if(!this._isAdmin)return;let n=(i("group_delete_confirm",this._lang)||'Delete group "{name}"?').replace("{name}",r);if(window.confirm(n)){this._busy=!0;try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/delete",group_id:t}),await this._load()}catch(d){this._error=p(d,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_groups"),window.dispatchEvent(new CustomEvent("location-changed"))}_onKeyDown(t,r){t.key==="Enter"?(t.preventDefault(),r()):t.key==="Escape"&&(t.preventDefault(),this._editingId=null,this._editingName="")}render(){let t=this._lang;if(!this._loaded)return s`<ha-card><div class="loading">${i("loading",t)||"Loading\u2026"}</div></ha-card>`;let r=Object.keys(this._groups);return s`
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{a as m}from"./chunk-6INP67SU.js";import{a as u,b as s,d as l,e as h,f as g,g as o,i,k as _,t as p}from"./chunk-CWQRMTXS.js";import{a}from"./chunk-HQWGP2HE.js";var e=class extends h{constructor(){super(...arguments);this._config={type:""};this._groups={};this._loaded=!1;this._busy=!1;this._error="";this._newName="";this._editingId=null;this._editingName="";this._hasInitiallyLoaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._hasInitiallyLoaded&&(this._hasInitiallyLoaded=!0,this._load(),_(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/groups"});this._groups=t.groups||{},this._loaded=!0}catch(t){this._error=p(t,this._lang)}}async _addGroup(){if(!this._isAdmin)return;let t=this._newName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/create",name:t}),this._newName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}_startEdit(t){this._editingId=t,this._editingName=this._groups[t]?.name||""}async _saveEdit(){if(!this._isAdmin||!this._editingId)return;let t=this._editingName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/update",group_id:this._editingId,name:t}),this._editingId=null,this._editingName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}async _deleteGroup(t,r){if(!this._isAdmin)return;let n=(i("group_delete_confirm",this._lang)||'Delete group "{name}"?').replace("{name}",r);if(window.confirm(n)){this._busy=!0;try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/delete",group_id:t}),await this._load()}catch(d){this._error=p(d,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_groups"),window.dispatchEvent(new CustomEvent("location-changed"))}_onKeyDown(t,r){t.key==="Enter"?(t.preventDefault(),r()):t.key==="Escape"&&(t.preventDefault(),this._editingId=null,this._editingName="")}render(){let t=this._lang;if(!this._loaded)return s`<ha-card><div class="loading">${i("loading",t)||"Loading\u2026"}</div></ha-card>`;let r=Object.keys(this._groups);return s`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<div class="header">
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as m}from"./chunk-QCBC6YX3.js";import{a as u,b as s,d as l,e as h,f as g,g as o,i,k as _,t as p}from"./chunk-RNKC43AV.js";import{a}from"./chunk-LPNFL3AF.js";var e=class extends h{constructor(){super(...arguments);this._config={type:""};this._groups={};this._loaded=!1;this._busy=!1;this._error="";this._newName="";this._editingId=null;this._editingName="";this._hasInitiallyLoaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._hasInitiallyLoaded&&(this._hasInitiallyLoaded=!0,this._load(),_(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/groups"});this._groups=t.groups||{},this._loaded=!0}catch(t){this._error=p(t,this._lang)}}async _addGroup(){if(!this._isAdmin)return;let t=this._newName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/create",name:t}),this._newName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}_startEdit(t){this._editingId=t,this._editingName=this._groups[t]?.name||""}async _saveEdit(){if(!this._isAdmin||!this._editingId)return;let t=this._editingName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/update",group_id:this._editingId,name:t}),this._editingId=null,this._editingName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}async _deleteGroup(t,r){if(!this._isAdmin)return;let n=(i("group_delete_confirm",this._lang)||'Delete group "{name}"?').replace("{name}",r);if(window.confirm(n)){this._busy=!0;try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/delete",group_id:t}),await this._load()}catch(d){this._error=p(d,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_groups"),window.dispatchEvent(new CustomEvent("location-changed"))}_onKeyDown(t,r){t.key==="Enter"?(t.preventDefault(),r()):t.key==="Escape"&&(t.preventDefault(),this._editingId=null,this._editingName="")}render(){let t=this._lang;if(!this._loaded)return s`<ha-card><div class="loading">${i("loading",t)||"Loading\u2026"}</div></ha-card>`;let r=Object.keys(this._groups);return s`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<span class="emoji">🏷️</span>
|
||||
<span>${this._config.title||i("groups",t)||"Groups"}</span>
|
||||
<span class="count">${r.length}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${this._error?s`<div class="error">${this._error}</div>`:l}
|
||||
|
||||
${r.length===0?s`<div class="empty">${i("groups_empty",t)||"No groups yet."}</div>`:s`
|
||||
<div class="group-list">
|
||||
${r.map(n=>{let d=this._groups[n],v=d.task_refs?.length??0,b=this._editingId===n;return s`
|
||||
<div class="group-row">
|
||||
${b?s`
|
||||
<input class="edit-input" type="text"
|
||||
.value=${this._editingName}
|
||||
?disabled=${this._busy}
|
||||
@input=${c=>{this._editingName=c.target.value}}
|
||||
@keydown=${c=>this._onKeyDown(c,this._saveEdit.bind(this))} />
|
||||
<button class="btn small primary"
|
||||
@click=${this._saveEdit}
|
||||
?disabled=${this._busy||!this._editingName.trim()}>
|
||||
${i("save",t)||"Save"}
|
||||
</button>
|
||||
<button class="btn small"
|
||||
@click=${()=>{this._editingId=null}}>
|
||||
${i("cancel",t)||"Cancel"}
|
||||
</button>
|
||||
`:s`
|
||||
<span class="group-name">${d.name||"Unnamed"}</span>
|
||||
<span class="task-count">${v}</span>
|
||||
${this._isAdmin?s`
|
||||
<button class="icon-btn"
|
||||
title="${i("edit",t)||"Edit"}"
|
||||
@click=${()=>this._startEdit(n)}
|
||||
?disabled=${this._busy}>
|
||||
<ha-icon icon="mdi:pencil"></ha-icon>
|
||||
</button>
|
||||
<button class="icon-btn danger"
|
||||
title="${i("delete",t)||"Delete"}"
|
||||
@click=${()=>this._deleteGroup(n,d.name||"Unnamed")}
|
||||
?disabled=${this._busy}>
|
||||
<ha-icon icon="mdi:delete"></ha-icon>
|
||||
</button>
|
||||
`:l}
|
||||
`}
|
||||
</div>
|
||||
`})}
|
||||
</div>
|
||||
`}
|
||||
|
||||
${this._isAdmin?s`
|
||||
<div class="add-row">
|
||||
<input type="text"
|
||||
placeholder="${i("group_new_placeholder",t)||"Add group\u2026"}"
|
||||
.value=${this._newName}
|
||||
?disabled=${this._busy}
|
||||
@input=${n=>{this._newName=n.target.value}}
|
||||
@keydown=${n=>this._onKeyDown(n,this._addGroup.bind(this))} />
|
||||
<button class="btn primary"
|
||||
@click=${this._addGroup}
|
||||
?disabled=${this._busy||!this._newName.trim()}>
|
||||
<ha-icon icon="mdi:plus"></ha-icon>
|
||||
${i("add",t)||"Add"}
|
||||
</button>
|
||||
</div>
|
||||
<button class="btn link" @click=${this._onDeepLink}>
|
||||
${i("groups_manage_tasks",t)||"Manage task assignments\u2026"}
|
||||
</button>
|
||||
`:s`
|
||||
<button class="btn link" @click=${this._onDeepLink}>
|
||||
${i("groups_open_panel",t)||"Open in panel"}
|
||||
</button>
|
||||
`}
|
||||
</div>
|
||||
</ha-card>
|
||||
`}};e.styles=[m,u`
|
||||
.count {
|
||||
font-size: 12px; color: var(--secondary-text-color);
|
||||
background: var(--secondary-background-color);
|
||||
padding: 2px 8px; border-radius: 999px;
|
||||
}
|
||||
.empty {
|
||||
padding: 16px; text-align: center;
|
||||
color: var(--secondary-text-color); font-style: italic;
|
||||
}
|
||||
.group-list { display: flex; flex-direction: column; gap: 4px; }
|
||||
.group-row {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
padding: 6px 8px; border-radius: 6px;
|
||||
background: var(--secondary-background-color, rgba(255,255,255,0.03));
|
||||
}
|
||||
.group-name { flex: 1; font-size: 14px; }
|
||||
.task-count {
|
||||
font-size: 11px; color: var(--secondary-text-color);
|
||||
background: var(--card-background-color, rgba(0,0,0,0.2));
|
||||
padding: 1px 8px; border-radius: 999px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.edit-input {
|
||||
flex: 1; padding: 4px 8px; font-size: 14px;
|
||||
background: var(--card-background-color, #1c1c1c);
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--primary-color); border-radius: 4px;
|
||||
font-family: inherit;
|
||||
}
|
||||
.icon-btn {
|
||||
background: transparent; border: none; cursor: pointer;
|
||||
color: var(--secondary-text-color); padding: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.icon-btn:hover {
|
||||
background: var(--state-icon-color, rgba(255,255,255,0.06));
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.icon-btn.danger:hover { color: var(--error-color); }
|
||||
.icon-btn ha-icon { --mdc-icon-size: 18px; }
|
||||
.add-row {
|
||||
display: flex; gap: 6px;
|
||||
padding-top: 8px; border-top: 1px solid var(--divider-color);
|
||||
}
|
||||
.add-row input {
|
||||
flex: 1; padding: 6px 8px; font-size: 13px;
|
||||
background: var(--secondary-background-color, #2c2c2c);
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
font-family: inherit;
|
||||
}
|
||||
/* Card-specific overrides on the shared .btn */
|
||||
.btn.small { padding: 4px 8px; font-size: 12px; }
|
||||
.btn ha-icon { --mdc-icon-size: 16px; }
|
||||
`],a([g({attribute:!1})],e.prototype,"hass",2),a([o()],e.prototype,"_config",2),a([o()],e.prototype,"_groups",2),a([o()],e.prototype,"_loaded",2),a([o()],e.prototype,"_busy",2),a([o()],e.prototype,"_error",2),a([o()],e.prototype,"_newName",2),a([o()],e.prototype,"_editingId",2),a([o()],e.prototype,"_editingName",2);customElements.get("maintenance-groups-section-card")||customElements.define("maintenance-groups-section-card",e);window.customCards=window.customCards||[];window.customCards.push({type:"maintenance-groups-section-card",name:"Maintenance Supporter \u2014 Groups",description:"Inline group CRUD",preview:!1});export{e as MaintenanceGroupsSectionCard};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{a as m}from"./chunk-XWMJNIQI.js";import{a as h,b as n,d as c,e as _,f as v,g as r,i as e,k as f,t as l}from"./chunk-TRW3CRLS.js";import{a as i}from"./chunk-UHANDS57.js";var a=class extends _{constructor(){super(...arguments);this._config={type:""};this._state=null;this._busy=!1;this._error="";this._localStart="";this._localEnd="";this._localBuffer=7;this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),f(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/state"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||"",this._localBuffer=t.buffer_days??7,this._dirty=!1}catch(t){this._error=l(t,this._lang)}}async _toggleEnabled(t){this._busy=!0,this._error="";try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",enabled:t});this._state=s}catch(s){this._error=l(s,this._lang)}finally{this._busy=!1}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",start:this._localStart||null,end:this._localEnd||null,buffer_days:this._localBuffer});this._state=t,this._dirty=!1}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}async _endNow(){if(this._isAdmin&&window.confirm(e("vacation_end_now_confirm",this._lang)||"End vacation immediately?")){this._busy=!0;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/end_now"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||""}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_vacation"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,s=this._state;if(!s)return n`<ha-card><div class="loading">${e("loading",t)||"Loading\u2026"}</div></ha-card>`;let p=s.is_active===!0,d=s.enabled===!0,u=s.exempt_task_ids?.length??0,b=p?e("vacation_status_active",t)||"Active now":d?e("vacation_status_scheduled",t)||"Scheduled":e("vacation_status_inactive",t)||"Inactive",g=p?"active":d?"scheduled":"inactive";return n`
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{a as m}from"./chunk-6INP67SU.js";import{a as h,b as n,d as c,e as _,f as v,g as r,i as e,k as f,t as l}from"./chunk-CWQRMTXS.js";import{a as i}from"./chunk-HQWGP2HE.js";var a=class extends _{constructor(){super(...arguments);this._config={type:""};this._state=null;this._busy=!1;this._error="";this._localStart="";this._localEnd="";this._localBuffer=7;this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),f(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/state"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||"",this._localBuffer=t.buffer_days??7,this._dirty=!1}catch(t){this._error=l(t,this._lang)}}async _toggleEnabled(t){this._busy=!0,this._error="";try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",enabled:t});this._state=s}catch(s){this._error=l(s,this._lang)}finally{this._busy=!1}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",start:this._localStart||null,end:this._localEnd||null,buffer_days:this._localBuffer});this._state=t,this._dirty=!1}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}async _endNow(){if(this._isAdmin&&window.confirm(e("vacation_end_now_confirm",this._lang)||"End vacation immediately?")){this._busy=!0;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/end_now"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||""}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_vacation"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,s=this._state;if(!s)return n`<ha-card><div class="loading">${e("loading",t)||"Loading\u2026"}</div></ha-card>`;let p=s.is_active===!0,d=s.enabled===!0,u=s.exempt_task_ids?.length??0,b=p?e("vacation_status_active",t)||"Active now":d?e("vacation_status_scheduled",t)||"Scheduled":e("vacation_status_inactive",t)||"Inactive",g=p?"active":d?"scheduled":"inactive";return n`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<div class="header">
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as m}from"./chunk-QCBC6YX3.js";import{a as h,b as n,d as c,e as _,f as v,g as r,i as e,k as f,t as l}from"./chunk-RNKC43AV.js";import{a as i}from"./chunk-LPNFL3AF.js";var a=class extends _{constructor(){super(...arguments);this._config={type:""};this._state=null;this._busy=!1;this._error="";this._localStart="";this._localEnd="";this._localBuffer=7;this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),f(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/state"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||"",this._localBuffer=t.buffer_days??7,this._dirty=!1}catch(t){this._error=l(t,this._lang)}}async _toggleEnabled(t){this._busy=!0,this._error="";try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",enabled:t});this._state=s}catch(s){this._error=l(s,this._lang)}finally{this._busy=!1}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",start:this._localStart||null,end:this._localEnd||null,buffer_days:this._localBuffer});this._state=t,this._dirty=!1}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}async _endNow(){if(this._isAdmin&&window.confirm(e("vacation_end_now_confirm",this._lang)||"End vacation immediately?")){this._busy=!0;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/end_now"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||""}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_vacation"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,s=this._state;if(!s)return n`<ha-card><div class="loading">${e("loading",t)||"Loading\u2026"}</div></ha-card>`;let p=s.is_active===!0,d=s.enabled===!0,u=s.exempt_task_ids?.length??0,b=p?e("vacation_status_active",t)||"Active now":d?e("vacation_status_scheduled",t)||"Scheduled":e("vacation_status_inactive",t)||"Inactive",g=p?"active":d?"scheduled":"inactive";return n`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<span class="emoji">🏖️</span>
|
||||
<span>${this._config.title||e("vacation_mode",t)||"Vacation mode"}</span>
|
||||
</div>
|
||||
<span class="status-pill ${g}">${b}</span>
|
||||
</div>
|
||||
|
||||
${this._error?n`<div class="error">${this._error}</div>`:c}
|
||||
|
||||
${this._isAdmin?n`
|
||||
<div class="row toggle-row">
|
||||
<label>${e("enable",t)||"Enable"}</label>
|
||||
<ha-switch
|
||||
.checked=${d}
|
||||
.disabled=${this._busy}
|
||||
@change=${o=>this._toggleEnabled(o.target.checked)}
|
||||
></ha-switch>
|
||||
</div>
|
||||
|
||||
<div class="dates-row">
|
||||
<div class="date-field">
|
||||
<label>${e("vacation_start",t)||"Start"}</label>
|
||||
<input type="date" .value=${this._localStart}
|
||||
?disabled=${this._busy}
|
||||
@input=${o=>{this._localStart=o.target.value,this._dirty=!0}} />
|
||||
</div>
|
||||
<div class="date-field">
|
||||
<label>${e("vacation_end",t)||"End"}</label>
|
||||
<input type="date" .value=${this._localEnd}
|
||||
?disabled=${this._busy}
|
||||
@input=${o=>{this._localEnd=o.target.value,this._dirty=!0}} />
|
||||
</div>
|
||||
<div class="date-field buffer">
|
||||
<label>${e("vacation_buffer",t)||"Buffer days"}</label>
|
||||
<input type="number" min="0" max="14"
|
||||
.value=${String(this._localBuffer)}
|
||||
?disabled=${this._busy}
|
||||
@input=${o=>{this._localBuffer=parseInt(o.target.value,10)||0,this._dirty=!0}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button class="btn ${this._dirty?"primary":"muted"}"
|
||||
@click=${this._save}
|
||||
?disabled=${this._busy||!this._dirty}>
|
||||
<ha-icon icon="${this._dirty?"mdi:content-save":"mdi:check"}"></ha-icon>
|
||||
${this._dirty?e("save",t)||"Save":e("saved",t)||"Saved"}
|
||||
</button>
|
||||
${p?n`<button class="btn"
|
||||
@click=${this._endNow}
|
||||
?disabled=${this._busy}>
|
||||
${e("vacation_end_now",t)||"End now"}
|
||||
</button>`:c}
|
||||
${u>0?n`<button class="btn link"
|
||||
@click=${this._onDeepLink}>
|
||||
${u} ${e("vacation_exempt_count",t)||"exempt"}…
|
||||
</button>`:n`<button class="btn link"
|
||||
@click=${this._onDeepLink}>
|
||||
${e("vacation_advanced",t)||"Advanced\u2026"}
|
||||
</button>`}
|
||||
</div>
|
||||
`:n`
|
||||
<div class="readonly">
|
||||
${d&&s.start&&s.end?n`<div>${s.start} → ${s.end}</div>`:c}
|
||||
<button class="btn link" @click=${this._onDeepLink}>
|
||||
${e("vacation_open_panel",t)||"Open in panel"}
|
||||
</button>
|
||||
</div>
|
||||
`}
|
||||
</div>
|
||||
</ha-card>
|
||||
`}};a.styles=[m,h`
|
||||
.status-pill {
|
||||
font-size: 11px; font-weight: 600;
|
||||
padding: 3px 8px; border-radius: 999px;
|
||||
text-transform: uppercase; letter-spacing: 0.5px;
|
||||
}
|
||||
.status-pill.active {
|
||||
background: rgba(76, 175, 80, 0.15);
|
||||
color: #4caf50;
|
||||
}
|
||||
.status-pill.scheduled {
|
||||
background: rgba(255, 152, 0, 0.15);
|
||||
color: #ff9800;
|
||||
}
|
||||
.status-pill.inactive {
|
||||
background: rgba(158, 158, 158, 0.15);
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.row.toggle-row {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
.row.toggle-row label {
|
||||
font-size: 14px; color: var(--primary-text-color);
|
||||
}
|
||||
.dates-row {
|
||||
display: grid; grid-template-columns: 1fr 1fr 100px; gap: 10px;
|
||||
}
|
||||
.date-field.buffer label { white-space: nowrap; }
|
||||
.date-field { display: flex; flex-direction: column; gap: 4px; }
|
||||
.date-field label {
|
||||
font-size: 11px; color: var(--secondary-text-color);
|
||||
text-transform: uppercase; letter-spacing: 0.3px;
|
||||
}
|
||||
.date-field input {
|
||||
padding: 6px 8px; font-size: 13px;
|
||||
background: var(--secondary-background-color, #2c2c2c);
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
font-family: inherit;
|
||||
}
|
||||
.date-field input:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.actions {
|
||||
display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
|
||||
}
|
||||
.readonly { display: flex; flex-direction: column; gap: 8px; }
|
||||
`],i([v({attribute:!1})],a.prototype,"hass",2),i([r()],a.prototype,"_config",2),i([r()],a.prototype,"_state",2),i([r()],a.prototype,"_busy",2),i([r()],a.prototype,"_error",2),i([r()],a.prototype,"_localStart",2),i([r()],a.prototype,"_localEnd",2),i([r()],a.prototype,"_localBuffer",2),i([r()],a.prototype,"_dirty",2);customElements.get("maintenance-vacation-section-card")||customElements.define("maintenance-vacation-section-card",a);window.customCards=window.customCards||[];window.customCards.push({type:"maintenance-vacation-section-card",name:"Maintenance Supporter \u2014 Vacation",description:"Inline vacation mode toggle + dates",preview:!1});export{a as MaintenanceVacationSectionCard};
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.56.0 */
|
||||
import{c as y}from"./chunks/chunk-UHANDS57.js";var L="maintenance-supporter",G=`ll-strategy-dashboard-${L}`,x="hui-maintenance-supporter-strategy-editor",V="NOT_RUNNING",H=[{status:"overdue",title:"Overdue",icon:y.overdue,path:"overdue"},{status:"triggered",title:"Triggered",icon:y.triggered,path:"triggered"},{status:"due_soon",title:"Due Soon",icon:y.due_soon,path:"due-soon"},{status:"ok",title:"OK",icon:y.ok,path:"ok"}],E=[{title:"Overdue",icon:"mdi:alert-circle",path:"overdue",filter:{filter_due_max_days:-1},matches:n=>n<=-1},{title:"Today",icon:"mdi:calendar-today",path:"today",filter:{filter_due_min_days:0,filter_due_max_days:0},matches:n=>n===0},{title:"This Week",icon:"mdi:calendar-week",path:"this-week",filter:{filter_due_min_days:1,filter_due_max_days:7},matches:n=>n>=1&&n<=7},{title:"This Month",icon:"mdi:calendar-month",path:"this-month",filter:{filter_due_min_days:8,filter_due_max_days:30},matches:n=>n>=8&&n<=30},{title:"Later",icon:"mdi:calendar-clock",path:"later",filter:{filter_due_min_days:31},matches:n=>n>=31}];function l(n){return{type:"grid",cards:[n]}}var N={condition:"view_columns",min:2};function _(n,i,e){let s=i[n];if(s)return`{{ states('${s}') }}`;let t=e[n];return t==null?"\u2014":String(t)}function B(n={},i={}){return{type:"markdown",text_only:!0,content:[`\u{1F534} **${_("overdue",n,i)}** overdue`,`\u26A1 **${_("triggered",n,i)}** triggered`,`\u{1F7E1} **${_("due_soon",n,i)}** due soon`,`\u{1F7E2} **${_("ok",n,i)}** ok`].join(" \xB7 ")}}function $(){return{title:"Maintenance",type:"panel",cards:[{type:"empty-state",icon:"mdi:wrench-clock",icon_color:"primary",content_only:!0,title:"No maintenance objects yet",content:"Open the Maintenance panel to add your first object \u2014 pool pump, HVAC filter, vehicle, anything that needs scheduled care.",buttons:[{icon:"mdi:wrench",text:"Open Maintenance panel",appearance:"filled",variant:"brand",tap_action:{action:"navigate",navigation_path:"/maintenance-supporter"}},{icon:"mdi:plus",text:"Add object",appearance:"outlined",variant:"brand",tap_action:{action:"fire-dom-event",ll_custom:{type:"maintenance-supporter:add-object"}}}]}]}}function U(n={},i={}){let e=B(n,i);return{title:"Overview",icon:"mdi:wrench-clock",path:"overview",type:"sections",header:{layout:"responsive",card:e},sidebar:{sections:[{type:"grid",cards:[{type:"heading",heading:"Status",heading_style:"title"},e]}],visibility:[N],content_label:"Tasks",sidebar_label:"Status"},sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_status:["overdue","triggered","due_soon"]})]}}function W(n,i){let e=new Map;for(let a of n){let r=a.object.area_id||null;e.has(r)||e.set(r,[]),e.get(r).push(a)}let s=Array.from(e.keys()).filter(a=>a!==null);s.sort((a,r)=>{let d=i[a]?.name||a,c=i[r]?.name||r;return d.localeCompare(c)});let t=[];for(let a of s){let r=e.get(a);if(r.length===0)continue;let d=i[a];t.push({title:d?.name||a,icon:d?.icon||"mdi:floor-plan",path:`area-${a}`,type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:r.map(c=>c.object.name)})]})}let o=e.get(null);return o&&o.length>0&&t.push({title:"Unassigned",icon:"mdi:help-circle-outline",path:"unassigned",type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:o.map(a=>a.object.name)})]}),t}function Y(n){let i=new Set;for(let s of n)for(let t of s.tasks||[])t.status&&i.add(t.status);let e=[];for(let s of H)i.has(s.status)&&e.push({title:s.title,icon:s.icon,path:s.path,type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_status:[s.status]})]});return e}function F(n,i,e){let s=new Map;for(let r of n){let d=r.object.area_id,c=d&&i[d]?.floor_id||null;s.has(c)||s.set(c,[]),s.get(c).push(r)}let t=Array.from(s.keys()).filter(r=>r!==null);t.sort((r,d)=>{let c=e[r],g=e[d],u=c?.level??0,p=g?.level??0;return u!==p?u-p:(c?.name||r).localeCompare(g?.name||d)});let o=[];for(let r of t){let d=s.get(r);if(d.length===0)continue;let c=e[r];o.push({title:c?.name||r,icon:c?.icon||"mdi:home-floor-1",path:`floor-${r}`,type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:d.map(g=>g.object.name)})]})}let a=s.get(null);return a&&a.length>0&&o.push({title:"Other",icon:"mdi:help-circle-outline",path:"other",type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:a.map(r=>r.object.name)})]}),o}function K(n){return[{title:"Week",icon:"mdi:calendar-week",path:"cal-7",window_days:7},{title:"Fortnight",icon:"mdi:calendar-week-begin",path:"cal-14",window_days:14},{title:"Month",icon:"mdi:calendar-month",path:"cal-30",window_days:30},{title:"Year",icon:"mdi:calendar-clock",path:"cal-365",window_days:365}].map(e=>({title:e.title,icon:e.icon,path:e.path,type:"panel",cards:[{type:"custom:maintenance-supporter-calendar-card",window_days:e.window_days,show_window_chips:!1,show_user_filter:!0}]}))}function q(n){let i=new Set;for(let sLine truncated
|
||||
/*! maintenance_supporter frontend 2.57.0 */
|
||||
import{c as y}from"./chunks/chunk-HQWGP2HE.js";var L="maintenance-supporter",G=`ll-strategy-dashboard-${L}`,x="hui-maintenance-supporter-strategy-editor",V="NOT_RUNNING",H=[{status:"overdue",title:"Overdue",icon:y.overdue,path:"overdue"},{status:"triggered",title:"Triggered",icon:y.triggered,path:"triggered"},{status:"due_soon",title:"Due Soon",icon:y.due_soon,path:"due-soon"},{status:"ok",title:"OK",icon:y.ok,path:"ok"}],E=[{title:"Overdue",icon:"mdi:alert-circle",path:"overdue",filter:{filter_due_max_days:-1},matches:n=>n<=-1},{title:"Today",icon:"mdi:calendar-today",path:"today",filter:{filter_due_min_days:0,filter_due_max_days:0},matches:n=>n===0},{title:"This Week",icon:"mdi:calendar-week",path:"this-week",filter:{filter_due_min_days:1,filter_due_max_days:7},matches:n=>n>=1&&n<=7},{title:"This Month",icon:"mdi:calendar-month",path:"this-month",filter:{filter_due_min_days:8,filter_due_max_days:30},matches:n=>n>=8&&n<=30},{title:"Later",icon:"mdi:calendar-clock",path:"later",filter:{filter_due_min_days:31},matches:n=>n>=31}];function l(n){return{type:"grid",cards:[n]}}var N={condition:"view_columns",min:2};function _(n,i,e){let s=i[n];if(s)return`{{ states('${s}') }}`;let t=e[n];return t==null?"\u2014":String(t)}function B(n={},i={}){return{type:"markdown",text_only:!0,content:[`\u{1F534} **${_("overdue",n,i)}** overdue`,`\u26A1 **${_("triggered",n,i)}** triggered`,`\u{1F7E1} **${_("due_soon",n,i)}** due soon`,`\u{1F7E2} **${_("ok",n,i)}** ok`].join(" \xB7 ")}}function $(){return{title:"Maintenance",type:"panel",cards:[{type:"empty-state",icon:"mdi:wrench-clock",icon_color:"primary",content_only:!0,title:"No maintenance objects yet",content:"Open the Maintenance panel to add your first object \u2014 pool pump, HVAC filter, vehicle, anything that needs scheduled care.",buttons:[{icon:"mdi:wrench",text:"Open Maintenance panel",appearance:"filled",variant:"brand",tap_action:{action:"navigate",navigation_path:"/maintenance-supporter"}},{icon:"mdi:plus",text:"Add object",appearance:"outlined",variant:"brand",tap_action:{action:"fire-dom-event",ll_custom:{type:"maintenance-supporter:add-object"}}}]}]}}function U(n={},i={}){let e=B(n,i);return{title:"Overview",icon:"mdi:wrench-clock",path:"overview",type:"sections",header:{layout:"responsive",card:e},sidebar:{sections:[{type:"grid",cards:[{type:"heading",heading:"Status",heading_style:"title"},e]}],visibility:[N],content_label:"Tasks",sidebar_label:"Status"},sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_status:["overdue","triggered","due_soon"]})]}}function W(n,i){let e=new Map;for(let a of n){let r=a.object.area_id||null;e.has(r)||e.set(r,[]),e.get(r).push(a)}let s=Array.from(e.keys()).filter(a=>a!==null);s.sort((a,r)=>{let d=i[a]?.name||a,c=i[r]?.name||r;return d.localeCompare(c)});let t=[];for(let a of s){let r=e.get(a);if(r.length===0)continue;let d=i[a];t.push({title:d?.name||a,icon:d?.icon||"mdi:floor-plan",path:`area-${a}`,type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:r.map(c=>c.object.name)})]})}let o=e.get(null);return o&&o.length>0&&t.push({title:"Unassigned",icon:"mdi:help-circle-outline",path:"unassigned",type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:o.map(a=>a.object.name)})]}),t}function Y(n){let i=new Set;for(let s of n)for(let t of s.tasks||[])t.status&&i.add(t.status);let e=[];for(let s of H)i.has(s.status)&&e.push({title:s.title,icon:s.icon,path:s.path,type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_status:[s.status]})]});return e}function F(n,i,e){let s=new Map;for(let r of n){let d=r.object.area_id,c=d&&i[d]?.floor_id||null;s.has(c)||s.set(c,[]),s.get(c).push(r)}let t=Array.from(s.keys()).filter(r=>r!==null);t.sort((r,d)=>{let c=e[r],g=e[d],u=c?.level??0,p=g?.level??0;return u!==p?u-p:(c?.name||r).localeCompare(g?.name||d)});let o=[];for(let r of t){let d=s.get(r);if(d.length===0)continue;let c=e[r];o.push({title:c?.name||r,icon:c?.icon||"mdi:home-floor-1",path:`floor-${r}`,type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:d.map(g=>g.object.name)})]})}let a=s.get(null);return a&&a.length>0&&o.push({title:"Other",icon:"mdi:help-circle-outline",path:"other",type:"sections",sections:[l({type:"custom:maintenance-supporter-card",show_header:!1,filter_objects:a.map(r=>r.object.name)})]}),o}function K(n){return[{title:"Week",icon:"mdi:calendar-week",path:"cal-7",window_days:7},{title:"Fortnight",icon:"mdi:calendar-week-begin",path:"cal-14",window_days:14},{title:"Month",icon:"mdi:calendar-month",path:"cal-30",window_days:30},{title:"Year",icon:"mdi:calendar-clock",path:"cal-365",window_days:365}].map(e=>({title:e.title,icon:e.icon,path:e.path,type:"panel",cards:[{type:"custom:maintenance-supporter-calendar-card",window_days:e.window_days,show_window_chips:!1,show_user_filter:!0}]}))}function q(n){let i=new Set;for(let sLine truncated
|
||||
<style>
|
||||
:host, .editor { display: block; padding: 16px 0; }
|
||||
label { display: block; font-weight: 500; margin-bottom: 8px; }
|
||||
@@ -22,4 +22,4 @@ import{c as y}from"./chunks/chunk-UHANDS57.js";var L="maintenance-supporter",G=`
|
||||
The "Overview" view is always first. Empty groups are skipped.
|
||||
</div>
|
||||
</div>
|
||||
`;let t=this.querySelector("#group-by");t?.addEventListener("change",()=>{let o={...this._config,group_by:t.value};this._config=o,this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:o},bubbles:!0,composed:!0}))})}},I="maintenance-supporter-section",Q=`ll-strategy-section-${I}`,v=class extends HTMLElement{static async generate(i,e){let s={type:"custom:maintenance-supporter-card",show_header:!1};i?.filter_status?.length&&(s.filter_status=i.filter_status),i?.max_items&&(s.max_items=i.max_items),i?.filter_due_min_days!==void 0&&(s.filter_due_min_days=i.filter_due_min_days),i?.filter_due_max_days!==void 0&&(s.filter_due_max_days=i.filter_due_max_days);let t=i?.filter_objects;if(i?.area_id&&!t)try{t=((await e.connection.sendMessagePromise({type:"maintenance_supporter/objects"})).objects||[]).filter(r=>r.object.area_id===i.area_id).map(r=>r.object.name)}catch{}t&&t.length>0&&(s.filter_objects=t);let o=[];return i?.title&&o.push({type:"heading",heading:i.title,heading_style:"title"}),o.push(s),{type:"grid",cards:o}}},D="2.3.6",X="[maintenance-supporter]";function M(n,i){try{return customElements.get(n)?"skipped":(customElements.define(n,i),"ok")}catch(e){return`ERROR: ${String(e)}`}}var P={editor:M(x,w),section:M(Q,v)};console.log(`${X} strategy bundle v${D} loaded \u2014 registrations:`,P,"\u2014 run maintenanceSupporterDiagnose() in console for full state");window.maintenanceSupporterDiagnose=async()=>{let n=G,i=[];try{let e=document.querySelector("home-assistant");e?.hass&&(i=(await e.hass.connection.sendMessagePromise({type:"lovelace/resources"})).resources||[])}catch(e){i=[{url:`<error: ${String(e)}>`}]}return{version:D,el_registered:!!customElements.get(n),el_class_excerpt:customElements.get(n)?.toString().slice(0,100)||null,customStrategies_dashboard:window.customStrategies?.filter(e=>e.strategyType==="dashboard").map(e=>e.type)||[],scriptTagsInPage:Array.from(document.querySelectorAll("script[type=module]")).map(e=>e.src).filter(e=>/maint|strateg/i.test(e)),lovelaceResources_matching:i.filter(e=>/maint|strateg/i.test(e.url||"")).map(e=>e.url),registrations:P}};var k=class extends HTMLElement{static async generate(i,e){return await import("./chunks/vacation-section-card-GKIEFNUX.js"),{type:"grid",cards:[{type:"custom:maintenance-vacation-section-card",title:i?.title}]}}},C=class extends HTMLElement{static async generate(i,e){return await import("./chunks/budget-section-card-237GPVDV.js"),{type:"grid",cards:[{type:"custom:maintenance-budget-section-card",title:i?.title}]}}},S=class extends HTMLElement{static async generate(i,e){return await import("./chunks/groups-section-card-HS2WQGRV.js"),{type:"grid",cards:[{type:"custom:maintenance-groups-section-card",title:i?.title}]}}},j="ll-strategy-section-maintenance-supporter-vacation",R="ll-strategy-section-maintenance-supporter-budget",A="ll-strategy-section-maintenance-supporter-groups";customElements.get(j)||customElements.define(j,k);customElements.get(R)||customElements.define(R,C);customElements.get(A)||customElements.define(A,S);var h=null;function J(){return h||(h=import("./chunks/dialog-mount-W7QTL5QF.js").catch(n=>{throw h=null,n})),h}var O="_msSupporterLlCustomBound";function m(n){history.pushState(null,"",n),window.dispatchEvent(new CustomEvent("location-changed"))}function Z(){let n=window;n[O]||(n[O]=!0,document.addEventListener("ll-custom",i=>{let e=i.detail;if(!e||typeof e!="object")return;let s=e.ll_custom,t=s&&typeof s=="object"?s:e;if(!t||typeof t.type!="string"||!t.type.startsWith("maintenance-supporter:"))return;let o=t.type.slice(22);if(o==="deep-link"&&typeof t.path=="string"){m(t.path);return}(async()=>{let a;try{a=await J()}catch{m("/maintenance-supporter");return}if(o==="add-object"){if(a.openCreateObjectDialog())return;m("/maintenance-supporter?ms_action=add_object");return}if(o==="open-task"&&typeof t.entry_id=="string"&&typeof t.task_id=="string"){if(a.openTaskQuickActions(t.entry_id,t.task_id)||a.openEditTaskDialog(t.entry_id,t.task_id))return;m(`/maintenance-supporter?entry_id=${encodeURIComponent(t.entry_id)}&task_id=${encodeURIComponent(t.task_id)}`);return}if(o==="open-object"&&typeof t.entry_id=="string"){if(a.openObjectQuickActions(t.entry_id))return;m(`/maintenance-supporter?entry_id=${encodeURIComponent(t.entry_id)}`);return}if(o==="edit-history"&&typeof t.entry_id=="string"&&typeof t.task_id=="string"&&typeof t.original_timestamp=="string"){let d=document.querySelector("home-assistant")?.hass;if(!d)return;try{let u=(await d.connection.sendMessagePromise({type:"maintenance_supporter/object",entry_id:t.entry_id})).tasks?.find(p=>p.id===t.task_id)?.history?.find(p=>p.timestamp===t.original_timestamp);if(!u)return;a.openHistoryEditDialog({entry_id:t.entry_id,task_id:t.task_id,original_timestamp:t.original_timestamp,type:u.type||"completed",timestamp:u.timestamp||t.original_timestamp,notes:u.notes??null,cost:u.cost??null,duration:u.duration??null,completed_by:u.completed_by??null})}catch{m("/maintenance-suppor
Line truncated
|
||||
`;let t=this.querySelector("#group-by");t?.addEventListener("change",()=>{let o={...this._config,group_by:t.value};this._config=o,this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:o},bubbles:!0,composed:!0}))})}},I="maintenance-supporter-section",Q=`ll-strategy-section-${I}`,v=class extends HTMLElement{static async generate(i,e){let s={type:"custom:maintenance-supporter-card",show_header:!1};i?.filter_status?.length&&(s.filter_status=i.filter_status),i?.max_items&&(s.max_items=i.max_items),i?.filter_due_min_days!==void 0&&(s.filter_due_min_days=i.filter_due_min_days),i?.filter_due_max_days!==void 0&&(s.filter_due_max_days=i.filter_due_max_days);let t=i?.filter_objects;if(i?.area_id&&!t)try{t=((await e.connection.sendMessagePromise({type:"maintenance_supporter/objects"})).objects||[]).filter(r=>r.object.area_id===i.area_id).map(r=>r.object.name)}catch{}t&&t.length>0&&(s.filter_objects=t);let o=[];return i?.title&&o.push({type:"heading",heading:i.title,heading_style:"title"}),o.push(s),{type:"grid",cards:o}}},D="2.3.6",X="[maintenance-supporter]";function M(n,i){try{return customElements.get(n)?"skipped":(customElements.define(n,i),"ok")}catch(e){return`ERROR: ${String(e)}`}}var P={editor:M(x,w),section:M(Q,v)};console.log(`${X} strategy bundle v${D} loaded \u2014 registrations:`,P,"\u2014 run maintenanceSupporterDiagnose() in console for full state");window.maintenanceSupporterDiagnose=async()=>{let n=G,i=[];try{let e=document.querySelector("home-assistant");e?.hass&&(i=(await e.hass.connection.sendMessagePromise({type:"lovelace/resources"})).resources||[])}catch(e){i=[{url:`<error: ${String(e)}>`}]}return{version:D,el_registered:!!customElements.get(n),el_class_excerpt:customElements.get(n)?.toString().slice(0,100)||null,customStrategies_dashboard:window.customStrategies?.filter(e=>e.strategyType==="dashboard").map(e=>e.type)||[],scriptTagsInPage:Array.from(document.querySelectorAll("script[type=module]")).map(e=>e.src).filter(e=>/maint|strateg/i.test(e)),lovelaceResources_matching:i.filter(e=>/maint|strateg/i.test(e.url||"")).map(e=>e.url),registrations:P}};var k=class extends HTMLElement{static async generate(i,e){return await import("./chunks/vacation-section-card-542QWPHZ.js"),{type:"grid",cards:[{type:"custom:maintenance-vacation-section-card",title:i?.title}]}}},C=class extends HTMLElement{static async generate(i,e){return await import("./chunks/budget-section-card-IGYCV4B2.js"),{type:"grid",cards:[{type:"custom:maintenance-budget-section-card",title:i?.title}]}}},S=class extends HTMLElement{static async generate(i,e){return await import("./chunks/groups-section-card-R3BSNA5O.js"),{type:"grid",cards:[{type:"custom:maintenance-groups-section-card",title:i?.title}]}}},j="ll-strategy-section-maintenance-supporter-vacation",R="ll-strategy-section-maintenance-supporter-budget",A="ll-strategy-section-maintenance-supporter-groups";customElements.get(j)||customElements.define(j,k);customElements.get(R)||customElements.define(R,C);customElements.get(A)||customElements.define(A,S);var h=null;function J(){return h||(h=import("./chunks/dialog-mount-NTYI3TJN.js").catch(n=>{throw h=null,n})),h}var O="_msSupporterLlCustomBound";function m(n){history.pushState(null,"",n),window.dispatchEvent(new CustomEvent("location-changed"))}function Z(){let n=window;n[O]||(n[O]=!0,document.addEventListener("ll-custom",i=>{let e=i.detail;if(!e||typeof e!="object")return;let s=e.ll_custom,t=s&&typeof s=="object"?s:e;if(!t||typeof t.type!="string"||!t.type.startsWith("maintenance-supporter:"))return;let o=t.type.slice(22);if(o==="deep-link"&&typeof t.path=="string"){m(t.path);return}(async()=>{let a;try{a=await J()}catch{m("/maintenance-supporter");return}if(o==="add-object"){if(a.openCreateObjectDialog())return;m("/maintenance-supporter?ms_action=add_object");return}if(o==="open-task"&&typeof t.entry_id=="string"&&typeof t.task_id=="string"){if(a.openTaskQuickActions(t.entry_id,t.task_id)||a.openEditTaskDialog(t.entry_id,t.task_id))return;m(`/maintenance-supporter?entry_id=${encodeURIComponent(t.entry_id)}&task_id=${encodeURIComponent(t.task_id)}`);return}if(o==="open-object"&&typeof t.entry_id=="string"){if(a.openObjectQuickActions(t.entry_id))return;m(`/maintenance-supporter?entry_id=${encodeURIComponent(t.entry_id)}`);return}if(o==="edit-history"&&typeof t.entry_id=="string"&&typeof t.task_id=="string"&&typeof t.original_timestamp=="string"){let d=document.querySelector("home-assistant")?.hass;if(!d)return;try{let u=(await d.connection.sendMessagePromise({type:"maintenance_supporter/object",entry_id:t.entry_id})).tasks?.find(p=>p.id===t.task_id)?.history?.find(p=>p.timestamp===t.original_timestamp);if(!u)return;a.openHistoryEditDialog({entry_id:t.entry_id,task_id:t.task_id,original_timestamp:t.original_timestamp,type:u.type||"completed",timestamp:u.timestamp||t.original_timestamp,notes:u.notes??null,cost:u.cost??null,duration:u.duration??null,completed_by:u.completed_by??null,used_parts:u.used_parts??null}
Line truncated
|
||||
@@ -22,5 +22,5 @@
|
||||
"requirements": [
|
||||
"pypdf>=4.3.0"
|
||||
],
|
||||
"version": "2.56.0"
|
||||
"version": "2.57.0"
|
||||
}
|
||||
Loaded 100 of 108 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user