108 files
This commit is contained in:
@@ -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": "下次日期",
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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 one or more lines are too long
+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
File diff suppressed because one or more lines are too long
+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
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
-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
File diff suppressed because one or more lines are too long
+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 one or more lines are too long
@@ -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 one or more lines are too long
-2453
File diff suppressed because one or more lines are too long
+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
File diff suppressed because one or more lines are too long
@@ -22,5 +22,5 @@
|
||||
"requirements": [
|
||||
"pypdf>=4.3.0"
|
||||
],
|
||||
"version": "2.56.0"
|
||||
"version": "2.57.0"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user