142 files

This commit is contained in:
Home Assistant Version Control
2026-08-20 17:17:53 +00:00
parent c987ad41b6
commit c73af9e207
142 changed files with 906 additions and 17859 deletions
+1 -1
View File
@@ -1 +1 @@
{"pid": 71, "version": 1, "ha_version": "2026.8.2", "start_ts": 1787239115.703832} {"pid": 70, "version": 1, "ha_version": "2026.8.2", "start_ts": 1787246176.3005776}
+1 -1
View File
@@ -315,7 +315,7 @@
"type": "module" "type": "module"
}, },
{ {
"id": "8539b8109d044865831c4fd6db9141c3", "id": "ba07e776ada54bb899ab0dfd6f6f2dbd",
"url": "/climate_scheduler/static/climate-scheduler-card.js?v=1.15.1", "url": "/climate_scheduler/static/climate-scheduler-card.js?v=1.15.1",
"type": "module" "type": "module"
} }
@@ -294,6 +294,150 @@ _CAL_STRINGS: dict[str, dict[str, str]] = {
"reading": "Sayaç okuma", "reading": "Sayaç okuma",
"custom": "Özel", "custom": "Özel",
}, },
"cs": {
"type": "Typ",
"interval": "Interval",
"interval_days": "{days} dní",
"cal_last": "Poslední",
"cal_day": "Den",
"last_performed": "Naposledy provedeno",
"never": "Nikdy",
"manually_triggered": "Ručně spuštěná úloha údržby",
"sensor_triggered": "Spuštěno senzorem pro {name}",
"cleaning": "Čištění",
"inspection": "Kontrola",
"replacement": "Výměna",
"calibration": "Kalibrace",
"service": "Servis",
"reading": "Odečet",
"custom": "Vlastní",
},
"da": {
"type": "Type",
"interval": "Interval",
"interval_days": "{days} dage",
"cal_last": "Seneste",
"cal_day": "Dag",
"last_performed": "Senest udført",
"never": "Aldrig",
"manually_triggered": "Manuelt udløst vedligeholdelsesopgave",
"sensor_triggered": "Sensorudløst for {name}",
"cleaning": "Rengøring",
"inspection": "Inspektion",
"replacement": "Udskiftning",
"calibration": "Kalibrering",
"service": "Service",
"reading": "Aflæsning",
"custom": "Brugerdefineret",
},
"fi": {
"type": "Tyyppi",
"interval": "Väli",
"interval_days": "{days} päivää",
"cal_last": "Viimeisin",
"cal_day": "Päivä",
"last_performed": "Viimeksi suoritettu",
"never": "Ei koskaan",
"manually_triggered": "Manuaalisesti käynnistetty huoltotehtävä",
"sensor_triggered": "Anturin laukaisema: {name}",
"cleaning": "Puhdistus",
"inspection": "Tarkastus",
"replacement": "Vaihto",
"calibration": "Kalibrointi",
"service": "Huolto",
"reading": "Lukema",
"custom": "Mukautettu",
},
"hi": {
"type": "प्रकार",
"interval": "अंतराल",
"interval_days": "{days} दिन",
"cal_last": "अंतिम",
"cal_day": "दिन",
"last_performed": "अंतिम बार किया गया",
"never": "कभी नहीं",
"manually_triggered": "मैन्युअल रूप से शुरू किया गया रखरखाव कार्य",
"sensor_triggered": "{name} के लिए सेंसर ट्रिगर",
"cleaning": "सफाई",
"inspection": "निरीक्षण",
"replacement": "बदलना",
"calibration": "अंशांकन",
"service": "सर्विस",
"reading": "रीडिंग",
"custom": "कस्टम",
},
"ja": {
"type": "種類",
"interval": "間隔",
"interval_days": "{days}",
"cal_last": "前回",
"cal_day": "",
"last_performed": "前回実施",
"never": "なし",
"manually_triggered": "手動トリガーのメンテナンスタスク",
"sensor_triggered": "{name} のセンサートリガー",
"cleaning": "清掃",
"inspection": "点検",
"replacement": "交換",
"calibration": "校正",
"service": "サービス",
"reading": "検針",
"custom": "カスタム",
},
"nb": {
"type": "Type",
"interval": "Intervall",
"interval_days": "{days} dager",
"cal_last": "Siste",
"cal_day": "Dag",
"last_performed": "Sist utført",
"never": "Aldri",
"manually_triggered": "Manuelt utløst vedlikeholdsoppgave",
"sensor_triggered": "Sensorutløst for {name}",
"cleaning": "Rengjøring",
"inspection": "Inspeksjon",
"replacement": "Utskifting",
"calibration": "Kalibrering",
"service": "Service",
"reading": "Avlesning",
"custom": "Egendefinert",
},
"pl": {
"type": "Typ",
"interval": "Interwał",
"interval_days": "{days} dni",
"cal_last": "Ostatni",
"cal_day": "Dzień",
"last_performed": "Ostatnio wykonano",
"never": "Nigdy",
"manually_triggered": "Ręcznie wyzwolone zadanie konserwacji",
"sensor_triggered": "Wyzwolone czujnikiem dla {name}",
"cleaning": "Czyszczenie",
"inspection": "Przegląd",
"replacement": "Wymiana",
"calibration": "Kalibracja",
"service": "Serwis",
"reading": "Odczyt",
"custom": "Niestandardowe",
},
"sv": {
"type": "Typ",
"interval": "Intervall",
"interval_days": "{days} dagar",
"cal_last": "Senaste",
"cal_day": "Dag",
"last_performed": "Senast utförd",
"never": "Aldrig",
"manually_triggered": "Manuellt utlöst underhållsuppgift",
"sensor_triggered": "Sensorutlöst för {name}",
"cleaning": "Rengöring",
"inspection": "Inspektion",
"replacement": "Byte",
"calibration": "Kalibrering",
"service": "Service",
"reading": "Avläsning",
"custom": "Anpassad",
},
} }
@@ -244,6 +244,70 @@ _TEST_NOTIFICATION_RESULTS: dict[str, dict[str, str]] = {
"push_message": "🔧 Test bildirimi — bildirim kurulumunuz çalışıyor!", "push_message": "🔧 Test bildirimi — bildirim kurulumunuz çalışıyor!",
"user_no_device": "️ Bu kullanıcıya bağlı bir Companion cihazı yok — hatırlatıcıları ev servisine gider.", "user_no_device": "️ Bu kullanıcıya bağlı bir Companion cihazı yok — hatırlatıcıları ev servisine gider.",
}, },
"cs": {
"success": "✅ Testovací oznámení odesláno — vaše služba funguje. Pokud konkrétní zařízení nic nedostane, zkontrolujte ho ve své notify skupině (a v protokolu HA).",
"no_service": "⚠️ Není nakonfigurována žádná oznamovací služba. Nejprve ji nastavte v Obecných nastaveních.",
"invalid_service": "❌ Formát oznamovací služby je neplatný. Použijte 'notify.nazev_sluzby'.",
"failed": "❌ Testovací oznámení se nepodařilo odeslat. Zkontrolujte prosím svou konfiguraci.",
"push_message": "🔧 Testovací oznámení — vaše nastavení oznámení funguje!",
"user_no_device": "️ Tento uživatel nemá přiřazené žádné Companion zařízení — jeho připomínky půjdou na službu domácnosti.",
},
"da": {
"success": "✅ Testnotifikation sendt — din tjeneste virker. Hvis en bestemt enhed intet modtager, så tjek den enhed i din notify-gruppe (og HA-loggen).",
"no_service": "⚠️ Ingen notifikationstjeneste konfigureret. Opsæt først en tjeneste under Generelle indstillinger.",
"invalid_service": "❌ Notifikationstjenestens format er ugyldigt. Brug 'notify.tjenestenavn'.",
"failed": "❌ Testnotifikationen kunne ikke sendes. Tjek venligst din konfiguration.",
"push_message": "🔧 Testnotifikation — din notifikationsopsætning virker!",
"user_no_device": "️ Denne bruger har ingen tilknyttet Companion-enhed — deres påmindelser går til husstandens tjeneste.",
},
"fi": {
"success": "✅ Testi-ilmoitus lähetetty — palvelusi toimii. Jos jokin laite ei saa mitään, tarkista se notify-ryhmästäsi (ja HA-lokista).",
"no_service": "⚠️ Ilmoituspalvelua ei ole määritetty. Määritä palvelu ensin Yleisissä asetuksissa.",
"invalid_service": "❌ Ilmoituspalvelun muoto on virheellinen. Käytä muotoa 'notify.palvelunnimi'.",
"failed": "❌ Testi-ilmoituksen lähetys epäonnistui. Tarkista määrityksesi.",
"push_message": "🔧 Testi-ilmoitus — ilmoitusasetuksesi toimivat!",
"user_no_device": "️ Tällä käyttäjällä ei ole liitettyä Companion-laitetta — hänen muistutuksensa menevät talouden palveluun.",
},
"hi": {
"success": "✅ परीक्षण सूचना भेजी गई — आपकी सेवा काम कर रही है। यदि किसी विशेष डिवाइस को कुछ नहीं मिलता, तो अपनी notify समूह में उस डिवाइस की जाँच करें (और HA लॉग)।",
"no_service": "⚠️ कोई सूचना सेवा कॉन्फ़िगर नहीं है। कृपया पहले सामान्य सेटिंग्स में एक सेवा सेट करें।",
"invalid_service": "❌ सूचना सेवा का प्रारूप अमान्य है। 'notify.servicename' का उपयोग करें।",
"failed": "❌ परीक्षण सूचना भेजी नहीं जा सकी। कृपया अपनी कॉन्फ़िगरेशन जाँचें।",
"push_message": "🔧 परीक्षण सूचना — आपकी सूचना व्यवस्था काम कर रही है!",
"user_no_device": "ℹ️ इस उपयोगकर्ता से कोई Companion डिवाइस संबद्ध नहीं है — उनकी याद दिलाने वाली सूचनाएँ घरेलू सेवा पर जाएँगी।",
},
"ja": {
"success": "✅ テスト通知を送信しました — サービスは動作しています。特定のデバイスに届かない場合は、notify グループ内のそのデバイス(と HA ログ)を確認してください。",
"no_service": "⚠️ 通知サービスが設定されていません。まず一般設定でサービスを設定してください。",
"invalid_service": "❌ 通知サービスの形式が無効です。'notify.サービス名' を使用してください。",
"failed": "❌ テスト通知を送信できませんでした。設定を確認してください。",
"push_message": "🔧 テスト通知 — 通知の設定は正常に動作しています!",
"user_no_device": "ℹ️ このユーザーには Companion デバイスが関連付けられていません — リマインダーは世帯のサービスに送られます。",
},
"nb": {
"success": "✅ Testvarsel sendt — tjenesten din fungerer. Hvis en bestemt enhet ikke mottar noe, sjekk den enheten i notify-gruppen din (og HA-loggen).",
"no_service": "⚠️ Ingen varslingstjeneste konfigurert. Sett opp en tjeneste under Generelle innstillinger først.",
"invalid_service": "❌ Varslingstjenestens format er ugyldig. Bruk 'notify.tjenestenavn'.",
"failed": "❌ Testvarselet kunne ikke sendes. Sjekk konfigurasjonen din.",
"push_message": "🔧 Testvarsel — varslingsoppsettet ditt fungerer!",
"user_no_device": "️ Denne brukeren har ingen tilknyttet Companion-enhet — påminnelsene deres går til husstandens tjeneste.",
},
"pl": {
"success": "✅ Powiadomienie testowe wysłane — twoja usługa działa. Jeśli konkretne urządzenie nic nie otrzymuje, sprawdź je w swojej grupie notify (i w logu HA).",
"no_service": "⚠️ Nie skonfigurowano usługi powiadomień. Najpierw ustaw usługę w Ustawieniach ogólnych.",
"invalid_service": "❌ Format usługi powiadomień jest nieprawidłowy. Użyj 'notify.nazwa_uslugi'.",
"failed": "❌ Nie udało się wysłać powiadomienia testowego. Sprawdź swoją konfigurację.",
"push_message": "🔧 Powiadomienie testowe — twoja konfiguracja powiadomień działa!",
"user_no_device": "️ Ten użytkownik nie ma przypisanego urządzenia Companion — jego przypomnienia trafią do usługi domowej.",
},
"sv": {
"success": "✅ Testnotis skickad — din tjänst fungerar. Om en viss enhet inte får något, kontrollera den enheten i din notify-grupp (och HA-loggen).",
"no_service": "⚠️ Ingen notistjänst konfigurerad. Konfigurera först en tjänst under Allmänna inställningar.",
"invalid_service": "❌ Notistjänstens format är ogiltigt. Använd 'notify.tjanstnamn'.",
"failed": "❌ Testnotisen kunde inte skickas. Kontrollera din konfiguration.",
"push_message": "🔧 Testnotis — din notiskonfiguration fungerar!",
"user_no_device": "️ Den här användaren har ingen kopplad Companion-enhet — deras påminnelser går till hushållets tjänst.",
},
} }
@@ -342,6 +342,10 @@ CONF_PARTS = "parts"
# and the fleet exclusion all key on them). # and the fleet exclusion all key on them).
BATTERY_FLEET_OBJECT_FLAG = "battery_fleet" BATTERY_FLEET_OBJECT_FLAG = "battery_fleet"
BATTERY_FLEET_EXCLUDED = "battery_fleet_excluded" BATTERY_FLEET_EXCLUDED = "battery_fleet_excluded"
# #135: entity_ids manually ADDED to the fleet — batteries the discovery
# heuristics miss (no device_class, odd naming, self-charging filter). An
# include bypasses the heuristic and #107 filters, never the dedupe.
BATTERY_FLEET_INCLUDED = "battery_fleet_included"
# Task-side link: task["consumes_parts"] = [{"part_id", "quantity"}] — a # Task-side link: task["consumes_parts"] = [{"part_id", "quantity"}] — a
# completion decrements each linked part's stock. # completion decrements each linked part's stock.
CONF_TASK_CONSUMES_PARTS = "consumes_parts" CONF_TASK_CONSUMES_PARTS = "consumes_parts"
@@ -176,6 +176,28 @@ export class MaintenanceBatteryFleetSection extends LitElement {
} }
} }
// #135: manually ADD a battery the discovery heuristics missed. The
// include bypasses the name/% heuristic and the self-charging filter
// server-side; picking an entity acts immediately (no extra button).
private async _addBattery(e: CustomEvent<{ value?: string }>): Promise<void> {
const entityId = e.detail?.value;
if (!entityId || this._marking) return;
this._marking = true;
this._error = "";
try {
await this.hass.connection.sendMessagePromise({
type: "maintenance_supporter/battery_fleet/set_included",
entity_id: entityId,
included: true,
});
await this._load();
} catch (e2) {
this._error = describeWsError(e2, this._lang);
} finally {
this._marking = false;
}
}
/** Lazy: the recorder-backed history is fetched once, when the roster is /** Lazy: the recorder-backed history is fetched once, when the roster is
* first expanded — most panel visits never open it. */ * first expanded — most panel visits never open it. */
private _loadHistory = async (e: Event): Promise<void> => { private _loadHistory = async (e: Event): Promise<void> => {
@@ -485,6 +507,16 @@ export class MaintenanceBatteryFleetSection extends LitElement {
)} )}
</div> </div>
<div class="bf-roster-hint">${t("battery_fleet_all_hint", L)}</div> <div class="bf-roster-hint">${t("battery_fleet_all_hint", L)}</div>
<div class="bf-add">
<span class="bf-label">${t("battery_fleet_add", L)}</span>
<ha-selector
.hass=${this.hass}
.selector=${{ entity: { domain: ["sensor", "binary_sensor"] } }}
.value=${""}
@value-changed=${this._addBattery}
></ha-selector>
<div class="bf-roster-hint">${t("battery_fleet_add_hint", L)}</div>
</div>
</details> </details>
` `
: nothing} : nothing}
@@ -157,6 +157,7 @@
"priority_low": "Nízká", "priority_low": "Nízká",
"priority_normal": "Normální", "priority_normal": "Normální",
"priority_high": "Vysoká", "priority_high": "Vysoká",
"all_priorities": "Všechny priority",
"schedule_type": "Typ rozvrhu", "schedule_type": "Typ rozvrhu",
"interval_days": "Interval (dny)", "interval_days": "Interval (dny)",
"warning_days": "Dny upozornění", "warning_days": "Dny upozornění",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Prázdné = zobrazit všechny objekty.", "card_filter_objects_help": "Prázdné = zobrazit všechny objekty.",
"card_filter_areas": "Filtrovat podle oblastí", "card_filter_areas": "Filtrovat podle oblastí",
"card_filter_areas_help": "Prázdné = zobrazit všechny oblasti.", "card_filter_areas_help": "Prázdné = zobrazit všechny oblasti.",
"card_filter_priority_help": "Prázdné = všechny priority. Úkoly bez explicitní priority se počítají jako Normální.",
"card_filter_entities": "Filtrovat podle entit (entity_ids)", "card_filter_entities": "Filtrovat podle entit (entity_ids)",
"card_filter_entities_help": "Vyberte entity sensor / binary_sensor z této integrace. Prázdné = všechny.", "card_filter_entities_help": "Vyberte entity sensor / binary_sensor z této integrace. Prázdné = všechny.",
"card_loading_objects": "Načítání objektů…", "card_loading_objects": "Načítání objektů…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Znovu sledovat", "battery_fleet_include": "Znovu sledovat",
"battery_fleet_all": "Všechny sledované baterie", "battery_fleet_all": "Všechny sledované baterie",
"battery_fleet_all_hint": "Vylučte zařízení už dřív, než vůbec ohlásí nízkou úroveň — vysavač, který se sám nabíjí, nebo telefon, který varuje sám.", "battery_fleet_all_hint": "Vylučte zařízení už dřív, než vůbec ohlásí nízkou úroveň — vysavač, který se sám nabíjí, nebo telefon, který varuje sám.",
"battery_fleet_add": "Přidat baterii",
"battery_fleet_add_hint": "Vyberte senzor baterie, který automatická detekce přehlédla — okamžitě se objeví v seznamu.",
"battery_fleet_status_low": "Nízká", "battery_fleet_status_low": "Nízká",
"battery_fleet_status_soon": "Brzy", "battery_fleet_status_soon": "Brzy",
"battery_fleet_status_ok": "V pořádku", "battery_fleet_status_ok": "V pořádku",
@@ -158,6 +158,7 @@
"priority_low": "Lav", "priority_low": "Lav",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Høj", "priority_high": "Høj",
"all_priorities": "Alle prioriteter",
"schedule_type": "Planlægningstype", "schedule_type": "Planlægningstype",
"interval_days": "Interval (dage)", "interval_days": "Interval (dage)",
"warning_days": "Advarselsdage", "warning_days": "Advarselsdage",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Tom = vis alle objekter.", "card_filter_objects_help": "Tom = vis alle objekter.",
"card_filter_areas": "Filtrer efter områder", "card_filter_areas": "Filtrer efter områder",
"card_filter_areas_help": "Tom = vis alle områder.", "card_filter_areas_help": "Tom = vis alle områder.",
"card_filter_priority_help": "Tomt = alle prioriteter. Opgaver uden eksplicit prioritet tæller som Normal.",
"card_filter_entities": "Filtrer efter enheder (entity_ids)", "card_filter_entities": "Filtrer efter enheder (entity_ids)",
"card_filter_entities_help": "Vælg sensor- / binary_sensor-enheder fra denne integration. Tom = alle.", "card_filter_entities_help": "Vælg sensor- / binary_sensor-enheder fra denne integration. Tom = alle.",
"card_loading_objects": "Indlæser objekter…", "card_loading_objects": "Indlæser objekter…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Følg igen", "battery_fleet_include": "Følg igen",
"battery_fleet_all": "Alle overvågede batterier", "battery_fleet_all": "Alle overvågede batterier",
"battery_fleet_all_hint": "Udeluk en enhed her, før den overhovedet melder lavt niveau — en støvsuger, der lader sig selv, eller en telefon, der advarer af sig selv.", "battery_fleet_all_hint": "Udeluk en enhed her, før den overhovedet melder lavt niveau — en støvsuger, der lader sig selv, eller en telefon, der advarer af sig selv.",
"battery_fleet_add": "Tilføj et batteri",
"battery_fleet_add_hint": "Vælg en batterisensor, som den automatiske registrering overså — den kommer straks på listen.",
"battery_fleet_status_low": "Lav", "battery_fleet_status_low": "Lav",
"battery_fleet_status_soon": "Snart", "battery_fleet_status_soon": "Snart",
"battery_fleet_status_ok": "I orden", "battery_fleet_status_ok": "I orden",
@@ -158,6 +158,7 @@
"priority_low": "Niedrig", "priority_low": "Niedrig",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Hoch", "priority_high": "Hoch",
"all_priorities": "Alle Prioritäten",
"schedule_type": "Planungsart", "schedule_type": "Planungsart",
"interval_days": "Intervall (Tage)", "interval_days": "Intervall (Tage)",
"warning_days": "Warntage", "warning_days": "Warntage",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Leer = alle Objekte zeigen.", "card_filter_objects_help": "Leer = alle Objekte zeigen.",
"card_filter_areas": "Nach Bereichen filtern", "card_filter_areas": "Nach Bereichen filtern",
"card_filter_areas_help": "Leer = alle Bereiche zeigen.", "card_filter_areas_help": "Leer = alle Bereiche zeigen.",
"card_filter_priority_help": "Leer = alle Prioritäten. Aufgaben ohne explizite Priorität zählen als Normal.",
"card_filter_entities": "Nach Entitäten filtern (entity_ids)", "card_filter_entities": "Nach Entitäten filtern (entity_ids)",
"card_filter_entities_help": "Wähle Sensor-/Binary-Sensor-Entitäten dieser Integration. Leer = alle.", "card_filter_entities_help": "Wähle Sensor-/Binary-Sensor-Entitäten dieser Integration. Leer = alle.",
"card_loading_objects": "Lade Objekte…", "card_loading_objects": "Lade Objekte…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Wieder aufnehmen", "battery_fleet_include": "Wieder aufnehmen",
"battery_fleet_all": "Alle überwachten Batterien", "battery_fleet_all": "Alle überwachten Batterien",
"battery_fleet_all_hint": "Ein Gerät hier ausschließen, bevor es überhaupt schwach meldet — etwa ein Sauger, der sich selbst lädt, oder ein Telefon, das von sich aus warnt.", "battery_fleet_all_hint": "Ein Gerät hier ausschließen, bevor es überhaupt schwach meldet — etwa ein Sauger, der sich selbst lädt, oder ein Telefon, das von sich aus warnt.",
"battery_fleet_add": "Batterie hinzufügen",
"battery_fleet_add_hint": "Einen Batteriesensor wählen, den die automatische Erkennung übersehen hat — er erscheint sofort in der Liste.",
"battery_fleet_status_low": "Schwach", "battery_fleet_status_low": "Schwach",
"battery_fleet_status_soon": "Bald", "battery_fleet_status_soon": "Bald",
"battery_fleet_status_ok": "In Ordnung", "battery_fleet_status_ok": "In Ordnung",
@@ -158,6 +158,7 @@
"priority_low": "Low", "priority_low": "Low",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "High", "priority_high": "High",
"all_priorities": "All priorities",
"schedule_type": "Schedule type", "schedule_type": "Schedule type",
"interval_days": "Interval (days)", "interval_days": "Interval (days)",
"warning_days": "Warning days", "warning_days": "Warning days",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Empty = show all objects.", "card_filter_objects_help": "Empty = show all objects.",
"card_filter_areas": "Filter by areas", "card_filter_areas": "Filter by areas",
"card_filter_areas_help": "Empty = show all areas.", "card_filter_areas_help": "Empty = show all areas.",
"card_filter_priority_help": "Empty = show all priorities. Tasks without an explicit priority count as Normal.",
"card_filter_entities": "Filter by entities (entity_ids)", "card_filter_entities": "Filter by entities (entity_ids)",
"card_filter_entities_help": "Pick sensor / binary_sensor entities from this integration. Empty = all.", "card_filter_entities_help": "Pick sensor / binary_sensor entities from this integration. Empty = all.",
"card_loading_objects": "Loading objects…", "card_loading_objects": "Loading objects…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Track again", "battery_fleet_include": "Track again",
"battery_fleet_all": "All tracked batteries", "battery_fleet_all": "All tracked batteries",
"battery_fleet_all_hint": "Exclude a device here to drop it from the fleet before it ever reports low — a vacuum that recharges itself, or a phone that warns you on its own.", "battery_fleet_all_hint": "Exclude a device here to drop it from the fleet before it ever reports low — a vacuum that recharges itself, or a phone that warns you on its own.",
"battery_fleet_add": "Add a battery",
"battery_fleet_add_hint": "Pick a battery sensor the automatic discovery missed — it joins the roster immediately.",
"battery_fleet_status_low": "Low", "battery_fleet_status_low": "Low",
"battery_fleet_status_soon": "Soon", "battery_fleet_status_soon": "Soon",
"battery_fleet_status_ok": "Healthy", "battery_fleet_status_ok": "Healthy",
@@ -157,6 +157,7 @@
"priority_low": "Baja", "priority_low": "Baja",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
"all_priorities": "Todas las prioridades",
"schedule_type": "Tipo de planificación", "schedule_type": "Tipo de planificación",
"interval_days": "Intervalo (días)", "interval_days": "Intervalo (días)",
"warning_days": "Días de aviso", "warning_days": "Días de aviso",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Vacío = mostrar todos los objetos.", "card_filter_objects_help": "Vacío = mostrar todos los objetos.",
"card_filter_areas": "Filtrar por áreas", "card_filter_areas": "Filtrar por áreas",
"card_filter_areas_help": "Vacío = mostrar todas las áreas.", "card_filter_areas_help": "Vacío = mostrar todas las áreas.",
"card_filter_priority_help": "Vacío = todas las prioridades. Las tareas sin prioridad explícita cuentan como Normal.",
"card_filter_entities": "Filtrar por entidades (entity_ids)", "card_filter_entities": "Filtrar por entidades (entity_ids)",
"card_filter_entities_help": "Selecciona entidades sensor / binary_sensor de esta integración. Vacío = todas.", "card_filter_entities_help": "Selecciona entidades sensor / binary_sensor de esta integración. Vacío = todas.",
"card_loading_objects": "Cargando objetos…", "card_loading_objects": "Cargando objetos…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Seguir de nuevo", "battery_fleet_include": "Seguir de nuevo",
"battery_fleet_all": "Todas las pilas monitorizadas", "battery_fleet_all": "Todas las pilas monitorizadas",
"battery_fleet_all_hint": "Excluye aquí un dispositivo antes de que llegue a avisar de carga baja — un aspirador que se recarga solo o un teléfono que ya avisa por su cuenta.", "battery_fleet_all_hint": "Excluye aquí un dispositivo antes de que llegue a avisar de carga baja — un aspirador que se recarga solo o un teléfono que ya avisa por su cuenta.",
"battery_fleet_add": "Añadir una batería",
"battery_fleet_add_hint": "Elige un sensor de batería que la detección automática pasó por alto — se une a la lista de inmediato.",
"battery_fleet_status_low": "Baja", "battery_fleet_status_low": "Baja",
"battery_fleet_status_soon": "Pronto", "battery_fleet_status_soon": "Pronto",
"battery_fleet_status_ok": "Correcta", "battery_fleet_status_ok": "Correcta",
@@ -158,6 +158,7 @@
"priority_low": "Matala", "priority_low": "Matala",
"priority_normal": "Normaali", "priority_normal": "Normaali",
"priority_high": "Korkea", "priority_high": "Korkea",
"all_priorities": "Kaikki prioriteetit",
"schedule_type": "Ajoitustyyppi", "schedule_type": "Ajoitustyyppi",
"interval_days": "Väli (päivää)", "interval_days": "Väli (päivää)",
"warning_days": "Varoituspäivät", "warning_days": "Varoituspäivät",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Tyhjä = näytä kaikki kohteet.", "card_filter_objects_help": "Tyhjä = näytä kaikki kohteet.",
"card_filter_areas": "Suodata alueiden mukaan", "card_filter_areas": "Suodata alueiden mukaan",
"card_filter_areas_help": "Tyhjä = näytä kaikki alueet.", "card_filter_areas_help": "Tyhjä = näytä kaikki alueet.",
"card_filter_priority_help": "Tyhjä = kaikki prioriteetit. Tehtävät ilman prioriteettia lasketaan Normaaliksi.",
"card_filter_entities": "Suodata entiteettien mukaan (entity_id)", "card_filter_entities": "Suodata entiteettien mukaan (entity_id)",
"card_filter_entities_help": "Valitse sensor- / binary_sensor-entiteetit tästä integraatiosta. Tyhjä = kaikki.", "card_filter_entities_help": "Valitse sensor- / binary_sensor-entiteetit tästä integraatiosta. Tyhjä = kaikki.",
"card_loading_objects": "Ladataan kohteita…", "card_loading_objects": "Ladataan kohteita…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Seuraa uudelleen", "battery_fleet_include": "Seuraa uudelleen",
"battery_fleet_all": "Kaikki seuratut paristot", "battery_fleet_all": "Kaikki seuratut paristot",
"battery_fleet_all_hint": "Sulje laite pois jo ennen kuin se ilmoittaa alhaisesta varauksesta — imuri, joka lataa itsensä, tai puhelin, joka varoittaa itse.", "battery_fleet_all_hint": "Sulje laite pois jo ennen kuin se ilmoittaa alhaisesta varauksesta — imuri, joka lataa itsensä, tai puhelin, joka varoittaa itse.",
"battery_fleet_add": "Lisää paristo",
"battery_fleet_add_hint": "Valitse paristoanturi, jonka automaattinen tunnistus ohitti — se liittyy luetteloon heti.",
"battery_fleet_status_low": "Vähissä", "battery_fleet_status_low": "Vähissä",
"battery_fleet_status_soon": "Pian", "battery_fleet_status_soon": "Pian",
"battery_fleet_status_ok": "Kunnossa", "battery_fleet_status_ok": "Kunnossa",
@@ -157,6 +157,7 @@
"priority_low": "Basse", "priority_low": "Basse",
"priority_normal": "Normale", "priority_normal": "Normale",
"priority_high": "Haute", "priority_high": "Haute",
"all_priorities": "Toutes les priorités",
"schedule_type": "Type de planification", "schedule_type": "Type de planification",
"interval_days": "Intervalle (jours)", "interval_days": "Intervalle (jours)",
"warning_days": "Jours d'avertissement", "warning_days": "Jours d'avertissement",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Vide = afficher tous les objets.", "card_filter_objects_help": "Vide = afficher tous les objets.",
"card_filter_areas": "Filtrer par zones", "card_filter_areas": "Filtrer par zones",
"card_filter_areas_help": "Vide = afficher toutes les zones.", "card_filter_areas_help": "Vide = afficher toutes les zones.",
"card_filter_priority_help": "Vide = toutes les priorités. Les tâches sans priorité explicite comptent comme Normale.",
"card_filter_entities": "Filtrer par entités (entity_ids)", "card_filter_entities": "Filtrer par entités (entity_ids)",
"card_filter_entities_help": "Choisissez des entités sensor / binary_sensor de cette intégration. Vide = toutes.", "card_filter_entities_help": "Choisissez des entités sensor / binary_sensor de cette intégration. Vide = toutes.",
"card_loading_objects": "Chargement des objets…", "card_loading_objects": "Chargement des objets…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Suivre à nouveau", "battery_fleet_include": "Suivre à nouveau",
"battery_fleet_all": "Toutes les piles suivies", "battery_fleet_all": "Toutes les piles suivies",
"battery_fleet_all_hint": "Excluez un appareil ici avant même qu'il ne signale une charge faible — un aspirateur qui se recharge seul, ou un téléphone qui vous prévient lui-même.", "battery_fleet_all_hint": "Excluez un appareil ici avant même qu'il ne signale une charge faible — un aspirateur qui se recharge seul, ou un téléphone qui vous prévient lui-même.",
"battery_fleet_add": "Ajouter une batterie",
"battery_fleet_add_hint": "Choisissez un capteur de batterie que la détection automatique a manqué — il rejoint la liste immédiatement.",
"battery_fleet_status_low": "Faible", "battery_fleet_status_low": "Faible",
"battery_fleet_status_soon": "Bientôt", "battery_fleet_status_soon": "Bientôt",
"battery_fleet_status_ok": "Bon état", "battery_fleet_status_ok": "Bon état",
@@ -158,6 +158,7 @@
"priority_low": "कम", "priority_low": "कम",
"priority_normal": "सामान्य", "priority_normal": "सामान्य",
"priority_high": "उच्च", "priority_high": "उच्च",
"all_priorities": "सभी प्राथमिकताएँ",
"schedule_type": "अनुसूची प्रकार", "schedule_type": "अनुसूची प्रकार",
"interval_days": "अंतराल (दिन)", "interval_days": "अंतराल (दिन)",
"warning_days": "चेतावनी दिन", "warning_days": "चेतावनी दिन",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "खाली = सभी वस्तुएँ दिखाएँ।", "card_filter_objects_help": "खाली = सभी वस्तुएँ दिखाएँ।",
"card_filter_areas": "क्षेत्रों के अनुसार फ़िल्टर करें", "card_filter_areas": "क्षेत्रों के अनुसार फ़िल्टर करें",
"card_filter_areas_help": "खाली = सभी क्षेत्र दिखाएँ।", "card_filter_areas_help": "खाली = सभी क्षेत्र दिखाएँ।",
"card_filter_priority_help": "खाली = सभी प्राथमिकताएँ। स्पष्ट प्राथमिकता के बिना कार्य सामान्य माने जाते हैं।",
"card_filter_entities": "एंटिटी के अनुसार फ़िल्टर करें (entity_ids)", "card_filter_entities": "एंटिटी के अनुसार फ़िल्टर करें (entity_ids)",
"card_filter_entities_help": "इस इंटीग्रेशन से sensor / binary_sensor एंटिटी चुनें। खाली = सभी।", "card_filter_entities_help": "इस इंटीग्रेशन से sensor / binary_sensor एंटिटी चुनें। खाली = सभी।",
"card_loading_objects": "वस्तुएँ लोड हो रही हैं…", "card_loading_objects": "वस्तुएँ लोड हो रही हैं…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "फिर से ट्रैक करें", "battery_fleet_include": "फिर से ट्रैक करें",
"battery_fleet_all": "सभी ट्रैक की गई बैटरियाँ", "battery_fleet_all": "सभी ट्रैक की गई बैटरियाँ",
"battery_fleet_all_hint": "किसी डिवाइस को यहाँ कम बैटरी बताने से पहले ही बाहर रखें — जैसे खुद चार्ज होने वाला वैक्यूम, या खुद ही चेतावनी देने वाला फ़ोन।", "battery_fleet_all_hint": "किसी डिवाइस को यहाँ कम बैटरी बताने से पहले ही बाहर रखें — जैसे खुद चार्ज होने वाला वैक्यूम, या खुद ही चेतावनी देने वाला फ़ोन।",
"battery_fleet_add": "बैटरी जोड़ें",
"battery_fleet_add_hint": "स्वचालित खोज से छूटा बैटरी सेंसर चुनें — यह तुरंत सूची में जुड़ जाएगा।",
"battery_fleet_status_low": "कम", "battery_fleet_status_low": "कम",
"battery_fleet_status_soon": "जल्द", "battery_fleet_status_soon": "जल्द",
"battery_fleet_status_ok": "ठीक", "battery_fleet_status_ok": "ठीक",
@@ -158,6 +158,7 @@
"priority_low": "Alacsony", "priority_low": "Alacsony",
"priority_normal": "Normál", "priority_normal": "Normál",
"priority_high": "Magas", "priority_high": "Magas",
"all_priorities": "Minden prioritás",
"schedule_type": "Ütemezés típusa", "schedule_type": "Ütemezés típusa",
"interval_days": "Intervallum (nap)", "interval_days": "Intervallum (nap)",
"warning_days": "Figyelmeztetési napok", "warning_days": "Figyelmeztetési napok",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Üres = minden objektum megjelenik.", "card_filter_objects_help": "Üres = minden objektum megjelenik.",
"card_filter_areas": "Szűrés területek szerint", "card_filter_areas": "Szűrés területek szerint",
"card_filter_areas_help": "Üres = minden terület megjelenik.", "card_filter_areas_help": "Üres = minden terület megjelenik.",
"card_filter_priority_help": "Üres = minden prioritás. Explicit prioritás nélküli feladatok Normálnak számítanak.",
"card_filter_entities": "Szűrés entitások szerint (entity_id-k)", "card_filter_entities": "Szűrés entitások szerint (entity_id-k)",
"card_filter_entities_help": "Válasszon sensor / binary_sensor entitásokat ebből az integrációból. Üres = mind.", "card_filter_entities_help": "Válasszon sensor / binary_sensor entitásokat ebből az integrációból. Üres = mind.",
"card_loading_objects": "Objektumok betöltése…", "card_loading_objects": "Objektumok betöltése…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Követés újra", "battery_fleet_include": "Követés újra",
"battery_fleet_all": "Minden nyomon követett elem", "battery_fleet_all": "Minden nyomon követett elem",
"battery_fleet_all_hint": "Zárjon ki egy eszközt már azelőtt, hogy alacsony töltöttséget jelezne — például egy magát töltő porszívót vagy egy telefont, amely magától figyelmeztet.", "battery_fleet_all_hint": "Zárjon ki egy eszközt már azelőtt, hogy alacsony töltöttséget jelezne — például egy magát töltő porszívót vagy egy telefont, amely magától figyelmeztet.",
"battery_fleet_add": "Elem hozzáadása",
"battery_fleet_add_hint": "Válassz egy elem-érzékelőt, amelyet az automatikus felismerés kihagyott — azonnal felkerül a listára.",
"battery_fleet_status_low": "Alacsony", "battery_fleet_status_low": "Alacsony",
"battery_fleet_status_soon": "Hamarosan", "battery_fleet_status_soon": "Hamarosan",
"battery_fleet_status_ok": "Rendben", "battery_fleet_status_ok": "Rendben",
@@ -157,6 +157,7 @@
"priority_low": "Bassa", "priority_low": "Bassa",
"priority_normal": "Normale", "priority_normal": "Normale",
"priority_high": "Alta", "priority_high": "Alta",
"all_priorities": "Tutte le priorità",
"schedule_type": "Tipo di pianificazione", "schedule_type": "Tipo di pianificazione",
"interval_days": "Intervallo (giorni)", "interval_days": "Intervallo (giorni)",
"warning_days": "Giorni di avviso", "warning_days": "Giorni di avviso",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Vuoto = mostra tutti gli oggetti.", "card_filter_objects_help": "Vuoto = mostra tutti gli oggetti.",
"card_filter_areas": "Filtra per aree", "card_filter_areas": "Filtra per aree",
"card_filter_areas_help": "Vuoto = mostra tutte le aree.", "card_filter_areas_help": "Vuoto = mostra tutte le aree.",
"card_filter_priority_help": "Vuoto = tutte le priorità. Le attività senza priorità esplicita contano come Normale.",
"card_filter_entities": "Filtra per entità (entity_ids)", "card_filter_entities": "Filtra per entità (entity_ids)",
"card_filter_entities_help": "Seleziona entità sensor / binary_sensor da questa integrazione. Vuoto = tutte.", "card_filter_entities_help": "Seleziona entità sensor / binary_sensor da questa integrazione. Vuoto = tutte.",
"card_loading_objects": "Caricamento oggetti…", "card_loading_objects": "Caricamento oggetti…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Traccia di nuovo", "battery_fleet_include": "Traccia di nuovo",
"battery_fleet_all": "Tutte le batterie monitorate", "battery_fleet_all": "Tutte le batterie monitorate",
"battery_fleet_all_hint": "Escludi qui un dispositivo prima ancora che segnali la batteria scarica — un aspirapolvere che si ricarica da solo o un telefono che avvisa da sé.", "battery_fleet_all_hint": "Escludi qui un dispositivo prima ancora che segnali la batteria scarica — un aspirapolvere che si ricarica da solo o un telefono che avvisa da sé.",
"battery_fleet_add": "Aggiungi una batteria",
"battery_fleet_add_hint": "Scegli un sensore batteria sfuggito al rilevamento automatico — entra subito nell'elenco.",
"battery_fleet_status_low": "Scarica", "battery_fleet_status_low": "Scarica",
"battery_fleet_status_soon": "A breve", "battery_fleet_status_soon": "A breve",
"battery_fleet_status_ok": "A posto", "battery_fleet_status_ok": "A posto",
@@ -158,6 +158,7 @@
"priority_low": "低", "priority_low": "低",
"priority_normal": "標準", "priority_normal": "標準",
"priority_high": "高", "priority_high": "高",
"all_priorities": "すべての優先度",
"schedule_type": "スケジュール種別", "schedule_type": "スケジュール種別",
"interval_days": "間隔(日)", "interval_days": "間隔(日)",
"warning_days": "警告日数", "warning_days": "警告日数",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "空欄=すべての対象を表示。", "card_filter_objects_help": "空欄=すべての対象を表示。",
"card_filter_areas": "エリアで絞り込み", "card_filter_areas": "エリアで絞り込み",
"card_filter_areas_help": "空欄=すべてのエリアを表示。", "card_filter_areas_help": "空欄=すべてのエリアを表示。",
"card_filter_priority_help": "空 = すべての優先度。明示的な優先度のないタスクは「普通」として扱われます。",
"card_filter_entities": "エンティティで絞り込み(entity_ids", "card_filter_entities": "エンティティで絞り込み(entity_ids",
"card_filter_entities_help": "この統合のsensorbinary_sensorエンティティを選択。空欄=すべて。", "card_filter_entities_help": "この統合のsensorbinary_sensorエンティティを選択。空欄=すべて。",
"card_loading_objects": "対象を読み込み中…", "card_loading_objects": "対象を読み込み中…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "再び追跡", "battery_fleet_include": "再び追跡",
"battery_fleet_all": "追跡中のすべての電池", "battery_fleet_all": "追跡中のすべての電池",
"battery_fleet_all_hint": "電池残量が少ないと報告される前に、ここで機器を除外できます — 自動充電するロボット掃除機や、自分で警告するスマートフォンなど。", "battery_fleet_all_hint": "電池残量が少ないと報告される前に、ここで機器を除外できます — 自動充電するロボット掃除機や、自分で警告するスマートフォンなど。",
"battery_fleet_add": "電池を追加",
"battery_fleet_add_hint": "自動検出が見逃した電池センサーを選択すると、すぐに一覧に追加されます。",
"battery_fleet_status_low": "残量低下", "battery_fleet_status_low": "残量低下",
"battery_fleet_status_soon": "まもなく", "battery_fleet_status_soon": "まもなく",
"battery_fleet_status_ok": "良好", "battery_fleet_status_ok": "良好",
@@ -158,6 +158,7 @@
"priority_low": "낮음", "priority_low": "낮음",
"priority_normal": "보통", "priority_normal": "보통",
"priority_high": "높음", "priority_high": "높음",
"all_priorities": "모든 우선순위",
"schedule_type": "일정 유형", "schedule_type": "일정 유형",
"interval_days": "주기 (일)", "interval_days": "주기 (일)",
"warning_days": "경고 일수", "warning_days": "경고 일수",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "비워두면 모든 객체를 표시합니다.", "card_filter_objects_help": "비워두면 모든 객체를 표시합니다.",
"card_filter_areas": "구역으로 필터", "card_filter_areas": "구역으로 필터",
"card_filter_areas_help": "비워두면 모든 구역을 표시합니다.", "card_filter_areas_help": "비워두면 모든 구역을 표시합니다.",
"card_filter_priority_help": "비우면 모든 우선순위를 표시합니다. 명시적 우선순위가 없는 작업은 보통으로 간주됩니다.",
"card_filter_entities": "엔티티로 필터 (entity_ids)", "card_filter_entities": "엔티티로 필터 (entity_ids)",
"card_filter_entities_help": "이 통합구성요소의 sensor / binary_sensor 엔티티를 선택하세요. 비워두면 전체.", "card_filter_entities_help": "이 통합구성요소의 sensor / binary_sensor 엔티티를 선택하세요. 비워두면 전체.",
"card_loading_objects": "객체 불러오는 중…", "card_loading_objects": "객체 불러오는 중…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "다시 추적", "battery_fleet_include": "다시 추적",
"battery_fleet_all": "추적 중인 모든 배터리", "battery_fleet_all": "추적 중인 모든 배터리",
"battery_fleet_all_hint": "배터리 부족을 알리기 전에 여기에서 기기를 제외하세요 — 스스로 충전하는 로봇청소기나 자체적으로 경고하는 휴대폰처럼.", "battery_fleet_all_hint": "배터리 부족을 알리기 전에 여기에서 기기를 제외하세요 — 스스로 충전하는 로봇청소기나 자체적으로 경고하는 휴대폰처럼.",
"battery_fleet_add": "배터리 추가",
"battery_fleet_add_hint": "자동 검색이 놓친 배터리 센서를 선택하면 즉시 목록에 추가됩니다.",
"battery_fleet_status_low": "부족", "battery_fleet_status_low": "부족",
"battery_fleet_status_soon": "곧", "battery_fleet_status_soon": "곧",
"battery_fleet_status_ok": "정상", "battery_fleet_status_ok": "정상",
@@ -158,6 +158,7 @@
"priority_low": "Lav", "priority_low": "Lav",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Høy", "priority_high": "Høy",
"all_priorities": "Alle prioriteter",
"schedule_type": "Planleggingstype", "schedule_type": "Planleggingstype",
"interval_days": "Intervall (dager)", "interval_days": "Intervall (dager)",
"warning_days": "Varslingsdager", "warning_days": "Varslingsdager",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Tom = vis alle objekter.", "card_filter_objects_help": "Tom = vis alle objekter.",
"card_filter_areas": "Filtrer etter områder", "card_filter_areas": "Filtrer etter områder",
"card_filter_areas_help": "Tom = vis alle områder.", "card_filter_areas_help": "Tom = vis alle områder.",
"card_filter_priority_help": "Tomt = alle prioriteter. Oppgaver uten eksplisitt prioritet teller som Normal.",
"card_filter_entities": "Filtrer etter entiteter (entity_ids)", "card_filter_entities": "Filtrer etter entiteter (entity_ids)",
"card_filter_entities_help": "Velg sensor-/binary_sensor-entiteter fra denne integrasjonen. Tom = alle.", "card_filter_entities_help": "Velg sensor-/binary_sensor-entiteter fra denne integrasjonen. Tom = alle.",
"card_loading_objects": "Laster objekter…", "card_loading_objects": "Laster objekter…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Følg igjen", "battery_fleet_include": "Følg igjen",
"battery_fleet_all": "Alle overvåkede batterier", "battery_fleet_all": "Alle overvåkede batterier",
"battery_fleet_all_hint": "Utelukk en enhet her før den i det hele tatt melder lavt nivå — en støvsuger som lader seg selv, eller en telefon som varsler av seg selv.", "battery_fleet_all_hint": "Utelukk en enhet her før den i det hele tatt melder lavt nivå — en støvsuger som lader seg selv, eller en telefon som varsler av seg selv.",
"battery_fleet_add": "Legg til et batteri",
"battery_fleet_add_hint": "Velg en batterisensor som den automatiske gjenkjenningen overså — den blir med i listen umiddelbart.",
"battery_fleet_status_low": "Lav", "battery_fleet_status_low": "Lav",
"battery_fleet_status_soon": "Snart", "battery_fleet_status_soon": "Snart",
"battery_fleet_status_ok": "I orden", "battery_fleet_status_ok": "I orden",
@@ -157,6 +157,7 @@
"priority_low": "Laag", "priority_low": "Laag",
"priority_normal": "Normaal", "priority_normal": "Normaal",
"priority_high": "Hoog", "priority_high": "Hoog",
"all_priorities": "Alle prioriteiten",
"schedule_type": "Planningstype", "schedule_type": "Planningstype",
"interval_days": "Interval (dagen)", "interval_days": "Interval (dagen)",
"warning_days": "Waarschuwingsdagen", "warning_days": "Waarschuwingsdagen",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Leeg = alle objecten tonen.", "card_filter_objects_help": "Leeg = alle objecten tonen.",
"card_filter_areas": "Filteren op gebieden", "card_filter_areas": "Filteren op gebieden",
"card_filter_areas_help": "Leeg = alle gebieden tonen.", "card_filter_areas_help": "Leeg = alle gebieden tonen.",
"card_filter_priority_help": "Leeg = alle prioriteiten. Taken zonder expliciete prioriteit tellen als Normaal.",
"card_filter_entities": "Filteren op entiteiten (entity_ids)", "card_filter_entities": "Filteren op entiteiten (entity_ids)",
"card_filter_entities_help": "Kies sensor/binary_sensor entiteiten van deze integratie. Leeg = alle.", "card_filter_entities_help": "Kies sensor/binary_sensor entiteiten van deze integratie. Leeg = alle.",
"card_loading_objects": "Objecten laden…", "card_loading_objects": "Objecten laden…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Opnieuw volgen", "battery_fleet_include": "Opnieuw volgen",
"battery_fleet_all": "Alle gevolgde batterijen", "battery_fleet_all": "Alle gevolgde batterijen",
"battery_fleet_all_hint": "Sluit een apparaat hier uit voordat het ooit laag meldt — een stofzuiger die zichzelf oplaadt, of een telefoon die zelf waarschuwt.", "battery_fleet_all_hint": "Sluit een apparaat hier uit voordat het ooit laag meldt — een stofzuiger die zichzelf oplaadt, of een telefoon die zelf waarschuwt.",
"battery_fleet_add": "Batterij toevoegen",
"battery_fleet_add_hint": "Kies een batterijsensor die de automatische detectie heeft gemist — hij verschijnt direct in de lijst.",
"battery_fleet_status_low": "Laag", "battery_fleet_status_low": "Laag",
"battery_fleet_status_soon": "Binnenkort", "battery_fleet_status_soon": "Binnenkort",
"battery_fleet_status_ok": "In orde", "battery_fleet_status_ok": "In orde",
@@ -157,6 +157,7 @@
"priority_low": "Niski", "priority_low": "Niski",
"priority_normal": "Normalny", "priority_normal": "Normalny",
"priority_high": "Wysoki", "priority_high": "Wysoki",
"all_priorities": "Wszystkie priorytety",
"schedule_type": "Typ harmonogramu", "schedule_type": "Typ harmonogramu",
"interval_days": "Interwał (dni)", "interval_days": "Interwał (dni)",
"warning_days": "Dni ostrzeżenia", "warning_days": "Dni ostrzeżenia",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Puste = pokaż wszystkie obiekty.", "card_filter_objects_help": "Puste = pokaż wszystkie obiekty.",
"card_filter_areas": "Filtruj wg obszarów", "card_filter_areas": "Filtruj wg obszarów",
"card_filter_areas_help": "Puste = pokaż wszystkie obszary.", "card_filter_areas_help": "Puste = pokaż wszystkie obszary.",
"card_filter_priority_help": "Puste = wszystkie priorytety. Zadania bez jawnego priorytetu liczą się jako Normalny.",
"card_filter_entities": "Filtruj wg encji (entity_ids)", "card_filter_entities": "Filtruj wg encji (entity_ids)",
"card_filter_entities_help": "Wybierz encje sensor / binary_sensor z tej integracji. Puste = wszystkie.", "card_filter_entities_help": "Wybierz encje sensor / binary_sensor z tej integracji. Puste = wszystkie.",
"card_loading_objects": "Ładowanie obiektów…", "card_loading_objects": "Ładowanie obiektów…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Śledź ponownie", "battery_fleet_include": "Śledź ponownie",
"battery_fleet_all": "Wszystkie śledzone baterie", "battery_fleet_all": "Wszystkie śledzone baterie",
"battery_fleet_all_hint": "Wyklucz tutaj urządzenie, zanim w ogóle zgłosi niski poziom — odkurzacz, który sam się ładuje, albo telefon, który ostrzega samodzielnie.", "battery_fleet_all_hint": "Wyklucz tutaj urządzenie, zanim w ogóle zgłosi niski poziom — odkurzacz, który sam się ładuje, albo telefon, który ostrzega samodzielnie.",
"battery_fleet_add": "Dodaj baterię",
"battery_fleet_add_hint": "Wybierz czujnik baterii pominięty przez automatyczne wykrywanie — od razu trafi na listę.",
"battery_fleet_status_low": "Niski", "battery_fleet_status_low": "Niski",
"battery_fleet_status_soon": "Wkrótce", "battery_fleet_status_soon": "Wkrótce",
"battery_fleet_status_ok": "W porządku", "battery_fleet_status_ok": "W porządku",
@@ -158,6 +158,7 @@
"priority_low": "Baixa", "priority_low": "Baixa",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
"all_priorities": "Todas as prioridades",
"schedule_type": "Tipo de agendamento", "schedule_type": "Tipo de agendamento",
"interval_days": "Intervalo (dias)", "interval_days": "Intervalo (dias)",
"warning_days": "Dias de aviso", "warning_days": "Dias de aviso",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Vazio = mostrar todos os objetos.", "card_filter_objects_help": "Vazio = mostrar todos os objetos.",
"card_filter_areas": "Filtrar por áreas", "card_filter_areas": "Filtrar por áreas",
"card_filter_areas_help": "Vazio = mostrar todas as áreas.", "card_filter_areas_help": "Vazio = mostrar todas as áreas.",
"card_filter_priority_help": "Vazio = todas as prioridades. Tarefas sem prioridade explícita contam como Normal.",
"card_filter_entities": "Filtrar por entidades (entity_ids)", "card_filter_entities": "Filtrar por entidades (entity_ids)",
"card_filter_entities_help": "Escolha entidades sensor / binary_sensor desta integração. Vazio = todas.", "card_filter_entities_help": "Escolha entidades sensor / binary_sensor desta integração. Vazio = todas.",
"card_loading_objects": "Carregando objetos…", "card_loading_objects": "Carregando objetos…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Acompanhar novamente", "battery_fleet_include": "Acompanhar novamente",
"battery_fleet_all": "Todas as baterias monitoradas", "battery_fleet_all": "Todas as baterias monitoradas",
"battery_fleet_all_hint": "Exclua aqui um dispositivo antes que ele sequer indique carga baixa — um aspirador que se recarrega sozinho ou um celular que já avisa sozinho.", "battery_fleet_all_hint": "Exclua aqui um dispositivo antes que ele sequer indique carga baixa — um aspirador que se recarrega sozinho ou um celular que já avisa sozinho.",
"battery_fleet_add": "Adicionar uma bateria",
"battery_fleet_add_hint": "Escolha um sensor de bateria que a detecção automática não encontrou — ele entra na lista imediatamente.",
"battery_fleet_status_low": "Fraca", "battery_fleet_status_low": "Fraca",
"battery_fleet_status_soon": "Em breve", "battery_fleet_status_soon": "Em breve",
"battery_fleet_status_ok": "Em bom estado", "battery_fleet_status_ok": "Em bom estado",
@@ -157,6 +157,7 @@
"priority_low": "Baixa", "priority_low": "Baixa",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
"all_priorities": "Todas as prioridades",
"schedule_type": "Tipo de agendamento", "schedule_type": "Tipo de agendamento",
"interval_days": "Intervalo (dias)", "interval_days": "Intervalo (dias)",
"warning_days": "Dias de aviso", "warning_days": "Dias de aviso",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Vazio = mostrar todos os objetos.", "card_filter_objects_help": "Vazio = mostrar todos os objetos.",
"card_filter_areas": "Filtrar por áreas", "card_filter_areas": "Filtrar por áreas",
"card_filter_areas_help": "Vazio = mostrar todas as áreas.", "card_filter_areas_help": "Vazio = mostrar todas as áreas.",
"card_filter_priority_help": "Vazio = todas as prioridades. Tarefas sem prioridade explícita contam como Normal.",
"card_filter_entities": "Filtrar por entidades (entity_ids)", "card_filter_entities": "Filtrar por entidades (entity_ids)",
"card_filter_entities_help": "Selecione entidades sensor / binary_sensor desta integração. Vazio = todas.", "card_filter_entities_help": "Selecione entidades sensor / binary_sensor desta integração. Vazio = todas.",
"card_loading_objects": "A carregar objetos…", "card_loading_objects": "A carregar objetos…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Acompanhar novamente", "battery_fleet_include": "Acompanhar novamente",
"battery_fleet_all": "Todas as pilhas monitorizadas", "battery_fleet_all": "Todas as pilhas monitorizadas",
"battery_fleet_all_hint": "Exclua aqui um dispositivo antes de ele sequer indicar carga fraca — um aspirador que se recarrega sozinho ou um telemóvel que já avisa por si.", "battery_fleet_all_hint": "Exclua aqui um dispositivo antes de ele sequer indicar carga fraca — um aspirador que se recarrega sozinho ou um telemóvel que já avisa por si.",
"battery_fleet_add": "Adicionar uma bateria",
"battery_fleet_add_hint": "Escolha um sensor de bateria que a deteção automática não encontrou — entra de imediato na lista.",
"battery_fleet_status_low": "Fraca", "battery_fleet_status_low": "Fraca",
"battery_fleet_status_soon": "Em breve", "battery_fleet_status_soon": "Em breve",
"battery_fleet_status_ok": "Em bom estado", "battery_fleet_status_ok": "Em bom estado",
@@ -157,6 +157,7 @@
"priority_low": "Низкий", "priority_low": "Низкий",
"priority_normal": "Обычный", "priority_normal": "Обычный",
"priority_high": "Высокий", "priority_high": "Высокий",
"all_priorities": "Все приоритеты",
"schedule_type": "Тип расписания", "schedule_type": "Тип расписания",
"interval_days": "Интервал (дни)", "interval_days": "Интервал (дни)",
"warning_days": "Дни предупреждения", "warning_days": "Дни предупреждения",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Пусто = показать все объекты.", "card_filter_objects_help": "Пусто = показать все объекты.",
"card_filter_areas": "Фильтровать по зонам", "card_filter_areas": "Фильтровать по зонам",
"card_filter_areas_help": "Пусто = показать все зоны.", "card_filter_areas_help": "Пусто = показать все зоны.",
"card_filter_priority_help": "Пусто = все приоритеты. Задачи без явного приоритета считаются обычными.",
"card_filter_entities": "Фильтровать по сущностям (entity_ids)", "card_filter_entities": "Фильтровать по сущностям (entity_ids)",
"card_filter_entities_help": "Выберите сущности sensor / binary_sensor из этой интеграции. Пусто = все.", "card_filter_entities_help": "Выберите сущности sensor / binary_sensor из этой интеграции. Пусто = все.",
"card_loading_objects": "Загрузка объектов…", "card_loading_objects": "Загрузка объектов…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Снова отслеживать", "battery_fleet_include": "Снова отслеживать",
"battery_fleet_all": "Все отслеживаемые батареи", "battery_fleet_all": "Все отслеживаемые батареи",
"battery_fleet_all_hint": "Исключите устройство здесь ещё до того, как оно сообщит о низком заряде — робот-пылесос, который заряжается сам, или телефон, который предупреждает вас сам.", "battery_fleet_all_hint": "Исключите устройство здесь ещё до того, как оно сообщит о низком заряде — робот-пылесос, который заряжается сам, или телефон, который предупреждает вас сам.",
"battery_fleet_add": "Добавить батарею",
"battery_fleet_add_hint": "Выберите датчик батареи, который автоматическое обнаружение пропустило — он сразу появится в списке.",
"battery_fleet_status_low": "Низкий", "battery_fleet_status_low": "Низкий",
"battery_fleet_status_soon": "Скоро", "battery_fleet_status_soon": "Скоро",
"battery_fleet_status_ok": "В норме", "battery_fleet_status_ok": "В норме",
@@ -157,6 +157,7 @@
"priority_low": "Låg", "priority_low": "Låg",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Hög", "priority_high": "Hög",
"all_priorities": "Alla prioriteter",
"schedule_type": "Schematyp", "schedule_type": "Schematyp",
"interval_days": "Intervall (dagar)", "interval_days": "Intervall (dagar)",
"warning_days": "Varningsdagar", "warning_days": "Varningsdagar",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Tomt = visa alla objekt.", "card_filter_objects_help": "Tomt = visa alla objekt.",
"card_filter_areas": "Filtrera efter områden", "card_filter_areas": "Filtrera efter områden",
"card_filter_areas_help": "Tomt = visa alla områden.", "card_filter_areas_help": "Tomt = visa alla områden.",
"card_filter_priority_help": "Tomt = alla prioriteter. Uppgifter utan uttrycklig prioritet räknas som Normal.",
"card_filter_entities": "Filtrera efter entiteter (entity_ids)", "card_filter_entities": "Filtrera efter entiteter (entity_ids)",
"card_filter_entities_help": "Välj sensor- / binary_sensor-entiteter från denna integration. Tomt = alla.", "card_filter_entities_help": "Välj sensor- / binary_sensor-entiteter från denna integration. Tomt = alla.",
"card_loading_objects": "Laddar objekt…", "card_loading_objects": "Laddar objekt…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Spåra igen", "battery_fleet_include": "Spåra igen",
"battery_fleet_all": "Alla bevakade batterier", "battery_fleet_all": "Alla bevakade batterier",
"battery_fleet_all_hint": "Uteslut en enhet här redan innan den rapporterar låg nivå — en dammsugare som laddar sig själv, eller en telefon som varnar på egen hand.", "battery_fleet_all_hint": "Uteslut en enhet här redan innan den rapporterar låg nivå — en dammsugare som laddar sig själv, eller en telefon som varnar på egen hand.",
"battery_fleet_add": "Lägg till ett batteri",
"battery_fleet_add_hint": "Välj en batterisensor som den automatiska identifieringen missade — den läggs till i listan direkt.",
"battery_fleet_status_low": "Låg", "battery_fleet_status_low": "Låg",
"battery_fleet_status_soon": "Snart", "battery_fleet_status_soon": "Snart",
"battery_fleet_status_ok": "I ordning", "battery_fleet_status_ok": "I ordning",
@@ -158,6 +158,7 @@
"priority_low": "Düşük", "priority_low": "Düşük",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Yüksek", "priority_high": "Yüksek",
"all_priorities": "Tüm öncelikler",
"schedule_type": "Zamanlama türü", "schedule_type": "Zamanlama türü",
"interval_days": "Aralık (gün)", "interval_days": "Aralık (gün)",
"warning_days": "Uyarı günleri", "warning_days": "Uyarı günleri",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Boş = tüm nesneleri göster.", "card_filter_objects_help": "Boş = tüm nesneleri göster.",
"card_filter_areas": "Alanlara göre filtrele", "card_filter_areas": "Alanlara göre filtrele",
"card_filter_areas_help": "Boş = tüm alanları göster.", "card_filter_areas_help": "Boş = tüm alanları göster.",
"card_filter_priority_help": "Boş = tüm öncelikler. Açık önceliği olmayan görevler Normal sayılır.",
"card_filter_entities": "Varlıklara göre filtrele (entity_id)", "card_filter_entities": "Varlıklara göre filtrele (entity_id)",
"card_filter_entities_help": "Bu entegrasyonun sensor / binary_sensor varlıklarını seçin. Boş = tümü.", "card_filter_entities_help": "Bu entegrasyonun sensor / binary_sensor varlıklarını seçin. Boş = tümü.",
"card_loading_objects": "Nesneler yükleniyor…", "card_loading_objects": "Nesneler yükleniyor…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Yeniden takip et", "battery_fleet_include": "Yeniden takip et",
"battery_fleet_all": "İzlenen tüm piller", "battery_fleet_all": "İzlenen tüm piller",
"battery_fleet_all_hint": "Bir cihazı, daha düşük şarj bildirmeden burada hariç tutun — kendi kendine şarj olan bir süpürge ya da zaten kendisi uyaran bir telefon gibi.", "battery_fleet_all_hint": "Bir cihazı, daha düşük şarj bildirmeden burada hariç tutun — kendi kendine şarj olan bir süpürge ya da zaten kendisi uyaran bir telefon gibi.",
"battery_fleet_add": "Pil ekle",
"battery_fleet_add_hint": "Otomatik keşfin atladığı bir pil sensörü seçin — hemen listeye katılır.",
"battery_fleet_status_low": "Düşük", "battery_fleet_status_low": "Düşük",
"battery_fleet_status_soon": "Yakında", "battery_fleet_status_soon": "Yakında",
"battery_fleet_status_ok": "İyi durumda", "battery_fleet_status_ok": "İyi durumda",
@@ -157,6 +157,7 @@
"priority_low": "Низький", "priority_low": "Низький",
"priority_normal": "Звичайний", "priority_normal": "Звичайний",
"priority_high": "Високий", "priority_high": "Високий",
"all_priorities": "Усі пріоритети",
"schedule_type": "Тип розкладу", "schedule_type": "Тип розкладу",
"interval_days": "Інтервал (дні)", "interval_days": "Інтервал (дні)",
"warning_days": "Днів попередження", "warning_days": "Днів попередження",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Порожньо = показати всі об'єкти.", "card_filter_objects_help": "Порожньо = показати всі об'єкти.",
"card_filter_areas": "Фільтрувати за зонами", "card_filter_areas": "Фільтрувати за зонами",
"card_filter_areas_help": "Порожньо = показати всі зони.", "card_filter_areas_help": "Порожньо = показати всі зони.",
"card_filter_priority_help": "Порожньо = усі пріоритети. Завдання без явного пріоритету вважаються звичайними.",
"card_filter_entities": "Фільтрувати за сутностями (entity_ids)", "card_filter_entities": "Фільтрувати за сутностями (entity_ids)",
"card_filter_entities_help": "Виберіть сутності sensor / binary_sensor з цієї інтеграції. Порожньо = всі.", "card_filter_entities_help": "Виберіть сутності sensor / binary_sensor з цієї інтеграції. Порожньо = всі.",
"card_loading_objects": "Завантаження об'єктів…", "card_loading_objects": "Завантаження об'єктів…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Знову відстежувати", "battery_fleet_include": "Знову відстежувати",
"battery_fleet_all": "Усі відстежувані батареї", "battery_fleet_all": "Усі відстежувані батареї",
"battery_fleet_all_hint": "Вилучіть пристрій тут ще до того, як він повідомить про низький заряд — робот-пилосос, що заряджається сам, або телефон, який попереджає сам.", "battery_fleet_all_hint": "Вилучіть пристрій тут ще до того, як він повідомить про низький заряд — робот-пилосос, що заряджається сам, або телефон, який попереджає сам.",
"battery_fleet_add": "Додати батарею",
"battery_fleet_add_hint": "Виберіть датчик батареї, який автоматичне виявлення пропустило — він одразу з'явиться у списку.",
"battery_fleet_status_low": "Низький", "battery_fleet_status_low": "Низький",
"battery_fleet_status_soon": "Незабаром", "battery_fleet_status_soon": "Незабаром",
"battery_fleet_status_ok": "У нормі", "battery_fleet_status_ok": "У нормі",
@@ -158,6 +158,7 @@
"priority_low": "低", "priority_low": "低",
"priority_normal": "普通", "priority_normal": "普通",
"priority_high": "高", "priority_high": "高",
"all_priorities": "所有优先级",
"schedule_type": "计划类型", "schedule_type": "计划类型",
"interval_days": "间隔 (天)", "interval_days": "间隔 (天)",
"warning_days": "预警天数", "warning_days": "预警天数",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "留空则显示所有维护项。", "card_filter_objects_help": "留空则显示所有维护项。",
"card_filter_areas": "按区域过滤", "card_filter_areas": "按区域过滤",
"card_filter_areas_help": "留空则显示所有区域。", "card_filter_areas_help": "留空则显示所有区域。",
"card_filter_priority_help": "留空 = 显示所有优先级。没有明确优先级的任务视为普通。",
"card_filter_entities": "按实体过滤 (entity_ids)", "card_filter_entities": "按实体过滤 (entity_ids)",
"card_filter_entities_help": "选择该集成的传感器或二进制传感器实体。留空则显示全部。", "card_filter_entities_help": "选择该集成的传感器或二进制传感器实体。留空则显示全部。",
"card_loading_objects": "正在加载维护项…", "card_loading_objects": "正在加载维护项…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "重新跟踪", "battery_fleet_include": "重新跟踪",
"battery_fleet_all": "所有跟踪的电池", "battery_fleet_all": "所有跟踪的电池",
"battery_fleet_all_hint": "在设备报告电量不足之前就可以在这里将其排除——例如会自行充电的扫地机器人,或本身就会提醒你的手机。", "battery_fleet_all_hint": "在设备报告电量不足之前就可以在这里将其排除——例如会自行充电的扫地机器人,或本身就会提醒你的手机。",
"battery_fleet_add": "添加电池",
"battery_fleet_add_hint": "选择自动发现遗漏的电池传感器——它会立即加入列表。",
"battery_fleet_status_low": "电量低", "battery_fleet_status_low": "电量低",
"battery_fleet_status_soon": "即将", "battery_fleet_status_soon": "即将",
"battery_fleet_status_ok": "正常", "battery_fleet_status_ok": "正常",
@@ -93,6 +93,12 @@ export class MaintenanceSupporterCardEditor extends LitElement {
this._valueChanged("filter_areas", [...current]); this._valueChanged("filter_areas", [...current]);
} }
private _togglePriority(priority: string, on: boolean): void {
const current = new Set(this._config.filter_priority || []);
if (on) current.add(priority); else current.delete(priority);
this._valueChanged("filter_priority", [...current]);
}
private _onEntitiesChanged = (e: CustomEvent<{ value: string[] }>): void => { private _onEntitiesChanged = (e: CustomEvent<{ value: string[] }>): void => {
this._valueChanged("entity_ids", e.detail.value || []); this._valueChanged("entity_ids", e.detail.value || []);
}; };
@@ -123,6 +129,7 @@ export class MaintenanceSupporterCardEditor extends LitElement {
.map((id) => ({ id, name: areaName(id) })) .map((id) => ({ id, name: areaName(id) }))
.sort((a, b) => a.name.localeCompare(b.name)); .sort((a, b) => a.name.localeCompare(b.name));
const selectedLabels = new Set(this._config.filter_labels || []); const selectedLabels = new Set(this._config.filter_labels || []);
const selectedPriorities = new Set(this._config.filter_priority || []);
// Labels are free-form per task, so the picker offers exactly the ones in // Labels are free-form per task, so the picker offers exactly the ones in
// use — an empty list simply hides the section. // use — an empty list simply hides the section.
const labelNames = [ const labelNames = [
@@ -220,6 +227,20 @@ export class MaintenanceSupporterCardEditor extends LitElement {
`)} `)}
</div> </div>
</div>` : nothing} </div>` : nothing}
<div class="field">
<div class="field-label">${t("priority", L)}</div>
<div class="object-list">
${["high", "normal", "low"].map((pr) => html`
<label class="object-row">
<input type="checkbox"
.checked=${selectedPriorities.has(pr)}
@change=${(e: Event) => this._togglePriority(pr, (e.target as HTMLInputElement).checked)} />
<span>${t(`priority_${pr}`, L)}</span>
</label>
`)}
</div>
<div class="field-help">${t("card_filter_priority_help", L)}</div>
</div>
<!-- Entity-id filter (HA-native pattern). Limited to our integration's <!-- Entity-id filter (HA-native pattern). Limited to our integration's
sensor + binary_sensor entities via includeEntities so the picker sensor + binary_sensor entities via includeEntities so the picker
@@ -302,6 +302,7 @@ export class MaintenanceSupporterCard extends LitElement {
filter_due_min_days, filter_due_min_days,
filter_due_max_days, filter_due_max_days,
filter_labels, filter_labels,
filter_priority,
filter_areas, filter_areas,
max_items, max_items,
} = this._config; } = this._config;
@@ -335,6 +336,9 @@ export class MaintenanceSupporterCard extends LitElement {
if (filter_status?.length && !filter_status.includes(task.status)) continue; if (filter_status?.length && !filter_status.includes(task.status)) continue;
// Labels: a task passes when it carries at least one configured label. // Labels: a task passes when it carries at least one configured label.
if (filter_labels?.length && !(task.labels || []).some((lb) => filter_labels.includes(lb))) continue; if (filter_labels?.length && !(task.labels || []).some((lb) => filter_labels.includes(lb))) continue;
// Priority (#134): OR over the configured levels; no explicit
// priority on the task means "normal" (the model default).
if (filter_priority?.length && !filter_priority.includes(task.priority || "normal")) continue;
// entity_ids: HA-native filter — match the task's sensor or // entity_ids: HA-native filter — match the task's sensor or
// binary_sensor entity_id. Both fields come pre-resolved from the // binary_sensor entity_id. Both fields come pre-resolved from the
// backend WS response (see _build_task_summary in websocket/__init__.py). // backend WS response (see _build_task_summary in websocket/__init__.py).
@@ -355,6 +359,7 @@ export class MaintenanceSupporterCard extends LitElement {
if (vf) { if (vf) {
if (vf.status && task.status !== vf.status) continue; if (vf.status && task.status !== vf.status) continue;
if (vf.label && !(task.labels || []).includes(vf.label)) continue; if (vf.label && !(task.labels || []).includes(vf.label)) continue;
if (vf.priority && (task.priority || "normal") !== vf.priority) continue;
if (viewUser && task.responsible_user_id !== viewUser) continue; if (viewUser && task.responsible_user_id !== viewUser) continue;
} }
tasks.push({ entry_id: obj.entry_id, object_name: obj.object.name, task }); tasks.push({ entry_id: obj.entry_id, object_name: obj.object.name, task });
@@ -128,6 +128,8 @@ export class MaintenanceSupporterPanel extends LitElement {
@state() private _filterStatus = ""; @state() private _filterStatus = "";
@state() private _filterUser: string | null = null; @state() private _filterUser: string | null = null;
@state() private _filterLabel: string | null = null; @state() private _filterLabel: string | null = null;
/** #134: only tasks of this priority (low|normal|high); "" = no filter. */
@state() private _filterPriority = "";
// v2.24: shared saved filter views + the id of the one currently applied ("" = // v2.24: shared saved filter views + the id of the one currently applied ("" =
// none; cleared the moment the user hand-edits any filter control). // none; cleared the moment the user hand-edits any filter control).
@state() private _savedViews: SavedView[] = []; @state() private _savedViews: SavedView[] = [];
@@ -738,6 +740,10 @@ export class MaintenanceSupporterPanel extends LitElement {
// Label filter (v2.26 — also captured by saved views) // Label filter (v2.26 — also captured by saved views)
if (this._filterLabel && !(task.labels || []).includes(this._filterLabel)) continue; if (this._filterLabel && !(task.labels || []).includes(this._filterLabel)) continue;
// Priority filter (#134 — also captured by saved views). Tasks
// without an explicit priority are "normal", the model default.
if (this._filterPriority && (task.priority || "normal") !== this._filterPriority) continue;
// Collect groups that contain this task // Collect groups that contain this task
const groupNames: string[] = []; const groupNames: string[] = [];
for (const group of Object.values(this._groups)) { for (const group of Object.values(this._groups)) {
@@ -926,6 +932,7 @@ export class MaintenanceSupporterPanel extends LitElement {
status: this._filterStatus, status: this._filterStatus,
user_id: this._filterUser, user_id: this._filterUser,
label: this._filterLabel, label: this._filterLabel,
priority: this._filterPriority,
archived: this._showArchived, archived: this._showArchived,
sort_mode: this._sortMode, sort_mode: this._sortMode,
group_by: this._groupByMode, group_by: this._groupByMode,
@@ -942,6 +949,7 @@ export class MaintenanceSupporterPanel extends LitElement {
this._filterStatus = f.status || ""; this._filterStatus = f.status || "";
this._filterUser = f.user_id || null; this._filterUser = f.user_id || null;
this._filterLabel = f.label || null; this._filterLabel = f.label || null;
this._filterPriority = f.priority || "";
this._showArchived = !!f.archived; this._showArchived = !!f.archived;
// Validate against the current enums before assigning — a view saved by an // Validate against the current enums before assigning — a view saved by an
// older/renamed build could carry a mode no longer valid, which would then // older/renamed build could carry a mode no longer valid, which would then
@@ -2266,6 +2274,7 @@ export class MaintenanceSupporterPanel extends LitElement {
(this._filterStatus ? 1 : 0) + (this._filterStatus ? 1 : 0) +
(this._filterUser ? 1 : 0) + (this._filterUser ? 1 : 0) +
(this._filterLabel ? 1 : 0) + (this._filterLabel ? 1 : 0) +
(this._filterPriority ? 1 : 0) +
(this._activeViewId ? 1 : 0); (this._activeViewId ? 1 : 0);
return html` return html`
@@ -2350,6 +2359,21 @@ export class MaintenanceSupporterPanel extends LitElement {
</select> </select>
</label> </label>
` : nothing} ` : nothing}
<label class="filter-field">
<span class="filter-label">${t("priority", L)}</span>
<select
.value=${this._filterPriority}
@change=${(e: Event) => {
this._filterPriority = (e.target as HTMLSelectElement).value;
this._activeViewId = "";
}}
>
<option value="">${t("all_priorities", L)}</option>
${["high", "normal", "low"].map(
(pr) => html`<option value=${pr} ?selected=${this._filterPriority === pr}>${t(`priority_${pr}`, L)}</option>`
)}
</select>
</label>
<label class="filter-field"> <label class="filter-field">
<span class="filter-label">${t("sort_label", L)}</span> <span class="filter-label">${t("sort_label", L)}</span>
<select <select
@@ -333,6 +333,8 @@ export interface SavedViewFilters {
user_id: string | null; user_id: string | null;
/** Only tasks carrying this label (v2.26); null = no label filter. */ /** Only tasks carrying this label (v2.26); null = no label filter. */
label?: string | null; label?: string | null;
/** Only tasks of this priority (#134): low|normal|high; "" = no filter. */
priority?: string;
archived: boolean; archived: boolean;
sort_mode: string; sort_mode: string;
group_by: string; group_by: string;
@@ -375,6 +377,9 @@ export interface CardConfig {
// Labels to limit the card to (v2.44). A task passes when it carries at // Labels to limit the card to (v2.44). A task passes when it carries at
// least one of them — same OR semantics as filter_status / filter_objects. // least one of them — same OR semantics as filter_status / filter_objects.
filter_labels?: string[]; filter_labels?: string[];
// Priorities to limit the card to (#134): low|normal|high. Same OR
// semantics; a task without an explicit priority counts as "normal".
filter_priority?: string[];
// HA area ids to limit the card to (C8). A task passes when its parent // HA area ids to limit the card to (C8). A task passes when its parent
// OBJECT sits in one of these areas — same OR semantics as filter_objects, // OBJECT sits in one of these areas — same OR semantics as filter_objects,
// and ANDed with every other filter. Objects without an area never match a // and ANDed with every other filter. Objects without an area never match a
@@ -157,6 +157,7 @@
"priority_low": "Nízká", "priority_low": "Nízká",
"priority_normal": "Normální", "priority_normal": "Normální",
"priority_high": "Vysoká", "priority_high": "Vysoká",
"all_priorities": "Všechny priority",
"schedule_type": "Typ rozvrhu", "schedule_type": "Typ rozvrhu",
"interval_days": "Interval (dny)", "interval_days": "Interval (dny)",
"warning_days": "Dny upozornění", "warning_days": "Dny upozornění",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Prázdné = zobrazit všechny objekty.", "card_filter_objects_help": "Prázdné = zobrazit všechny objekty.",
"card_filter_areas": "Filtrovat podle oblastí", "card_filter_areas": "Filtrovat podle oblastí",
"card_filter_areas_help": "Prázdné = zobrazit všechny oblasti.", "card_filter_areas_help": "Prázdné = zobrazit všechny oblasti.",
"card_filter_priority_help": "Prázdné = všechny priority. Úkoly bez explicitní priority se počítají jako Normální.",
"card_filter_entities": "Filtrovat podle entit (entity_ids)", "card_filter_entities": "Filtrovat podle entit (entity_ids)",
"card_filter_entities_help": "Vyberte entity sensor / binary_sensor z této integrace. Prázdné = všechny.", "card_filter_entities_help": "Vyberte entity sensor / binary_sensor z této integrace. Prázdné = všechny.",
"card_loading_objects": "Načítání objektů…", "card_loading_objects": "Načítání objektů…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Znovu sledovat", "battery_fleet_include": "Znovu sledovat",
"battery_fleet_all": "Všechny sledované baterie", "battery_fleet_all": "Všechny sledované baterie",
"battery_fleet_all_hint": "Vylučte zařízení už dřív, než vůbec ohlásí nízkou úroveň — vysavač, který se sám nabíjí, nebo telefon, který varuje sám.", "battery_fleet_all_hint": "Vylučte zařízení už dřív, než vůbec ohlásí nízkou úroveň — vysavač, který se sám nabíjí, nebo telefon, který varuje sám.",
"battery_fleet_add": "Přidat baterii",
"battery_fleet_add_hint": "Vyberte senzor baterie, který automatická detekce přehlédla — okamžitě se objeví v seznamu.",
"battery_fleet_status_low": "Nízká", "battery_fleet_status_low": "Nízká",
"battery_fleet_status_soon": "Brzy", "battery_fleet_status_soon": "Brzy",
"battery_fleet_status_ok": "V pořádku", "battery_fleet_status_ok": "V pořádku",
@@ -158,6 +158,7 @@
"priority_low": "Lav", "priority_low": "Lav",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Høj", "priority_high": "Høj",
"all_priorities": "Alle prioriteter",
"schedule_type": "Planlægningstype", "schedule_type": "Planlægningstype",
"interval_days": "Interval (dage)", "interval_days": "Interval (dage)",
"warning_days": "Advarselsdage", "warning_days": "Advarselsdage",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Tom = vis alle objekter.", "card_filter_objects_help": "Tom = vis alle objekter.",
"card_filter_areas": "Filtrer efter områder", "card_filter_areas": "Filtrer efter områder",
"card_filter_areas_help": "Tom = vis alle områder.", "card_filter_areas_help": "Tom = vis alle områder.",
"card_filter_priority_help": "Tomt = alle prioriteter. Opgaver uden eksplicit prioritet tæller som Normal.",
"card_filter_entities": "Filtrer efter enheder (entity_ids)", "card_filter_entities": "Filtrer efter enheder (entity_ids)",
"card_filter_entities_help": "Vælg sensor- / binary_sensor-enheder fra denne integration. Tom = alle.", "card_filter_entities_help": "Vælg sensor- / binary_sensor-enheder fra denne integration. Tom = alle.",
"card_loading_objects": "Indlæser objekter…", "card_loading_objects": "Indlæser objekter…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Følg igen", "battery_fleet_include": "Følg igen",
"battery_fleet_all": "Alle overvågede batterier", "battery_fleet_all": "Alle overvågede batterier",
"battery_fleet_all_hint": "Udeluk en enhed her, før den overhovedet melder lavt niveau — en støvsuger, der lader sig selv, eller en telefon, der advarer af sig selv.", "battery_fleet_all_hint": "Udeluk en enhed her, før den overhovedet melder lavt niveau — en støvsuger, der lader sig selv, eller en telefon, der advarer af sig selv.",
"battery_fleet_add": "Tilføj et batteri",
"battery_fleet_add_hint": "Vælg en batterisensor, som den automatiske registrering overså — den kommer straks på listen.",
"battery_fleet_status_low": "Lav", "battery_fleet_status_low": "Lav",
"battery_fleet_status_soon": "Snart", "battery_fleet_status_soon": "Snart",
"battery_fleet_status_ok": "I orden", "battery_fleet_status_ok": "I orden",
@@ -158,6 +158,7 @@
"priority_low": "Niedrig", "priority_low": "Niedrig",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Hoch", "priority_high": "Hoch",
"all_priorities": "Alle Prioritäten",
"schedule_type": "Planungsart", "schedule_type": "Planungsart",
"interval_days": "Intervall (Tage)", "interval_days": "Intervall (Tage)",
"warning_days": "Warntage", "warning_days": "Warntage",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Leer = alle Objekte zeigen.", "card_filter_objects_help": "Leer = alle Objekte zeigen.",
"card_filter_areas": "Nach Bereichen filtern", "card_filter_areas": "Nach Bereichen filtern",
"card_filter_areas_help": "Leer = alle Bereiche zeigen.", "card_filter_areas_help": "Leer = alle Bereiche zeigen.",
"card_filter_priority_help": "Leer = alle Prioritäten. Aufgaben ohne explizite Priorität zählen als Normal.",
"card_filter_entities": "Nach Entitäten filtern (entity_ids)", "card_filter_entities": "Nach Entitäten filtern (entity_ids)",
"card_filter_entities_help": "Wähle Sensor-/Binary-Sensor-Entitäten dieser Integration. Leer = alle.", "card_filter_entities_help": "Wähle Sensor-/Binary-Sensor-Entitäten dieser Integration. Leer = alle.",
"card_loading_objects": "Lade Objekte…", "card_loading_objects": "Lade Objekte…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Wieder aufnehmen", "battery_fleet_include": "Wieder aufnehmen",
"battery_fleet_all": "Alle überwachten Batterien", "battery_fleet_all": "Alle überwachten Batterien",
"battery_fleet_all_hint": "Ein Gerät hier ausschließen, bevor es überhaupt schwach meldet — etwa ein Sauger, der sich selbst lädt, oder ein Telefon, das von sich aus warnt.", "battery_fleet_all_hint": "Ein Gerät hier ausschließen, bevor es überhaupt schwach meldet — etwa ein Sauger, der sich selbst lädt, oder ein Telefon, das von sich aus warnt.",
"battery_fleet_add": "Batterie hinzufügen",
"battery_fleet_add_hint": "Einen Batteriesensor wählen, den die automatische Erkennung übersehen hat — er erscheint sofort in der Liste.",
"battery_fleet_status_low": "Schwach", "battery_fleet_status_low": "Schwach",
"battery_fleet_status_soon": "Bald", "battery_fleet_status_soon": "Bald",
"battery_fleet_status_ok": "In Ordnung", "battery_fleet_status_ok": "In Ordnung",
@@ -158,6 +158,7 @@
"priority_low": "Low", "priority_low": "Low",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "High", "priority_high": "High",
"all_priorities": "All priorities",
"schedule_type": "Schedule type", "schedule_type": "Schedule type",
"interval_days": "Interval (days)", "interval_days": "Interval (days)",
"warning_days": "Warning days", "warning_days": "Warning days",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Empty = show all objects.", "card_filter_objects_help": "Empty = show all objects.",
"card_filter_areas": "Filter by areas", "card_filter_areas": "Filter by areas",
"card_filter_areas_help": "Empty = show all areas.", "card_filter_areas_help": "Empty = show all areas.",
"card_filter_priority_help": "Empty = show all priorities. Tasks without an explicit priority count as Normal.",
"card_filter_entities": "Filter by entities (entity_ids)", "card_filter_entities": "Filter by entities (entity_ids)",
"card_filter_entities_help": "Pick sensor / binary_sensor entities from this integration. Empty = all.", "card_filter_entities_help": "Pick sensor / binary_sensor entities from this integration. Empty = all.",
"card_loading_objects": "Loading objects…", "card_loading_objects": "Loading objects…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Track again", "battery_fleet_include": "Track again",
"battery_fleet_all": "All tracked batteries", "battery_fleet_all": "All tracked batteries",
"battery_fleet_all_hint": "Exclude a device here to drop it from the fleet before it ever reports low — a vacuum that recharges itself, or a phone that warns you on its own.", "battery_fleet_all_hint": "Exclude a device here to drop it from the fleet before it ever reports low — a vacuum that recharges itself, or a phone that warns you on its own.",
"battery_fleet_add": "Add a battery",
"battery_fleet_add_hint": "Pick a battery sensor the automatic discovery missed — it joins the roster immediately.",
"battery_fleet_status_low": "Low", "battery_fleet_status_low": "Low",
"battery_fleet_status_soon": "Soon", "battery_fleet_status_soon": "Soon",
"battery_fleet_status_ok": "Healthy", "battery_fleet_status_ok": "Healthy",
@@ -157,6 +157,7 @@
"priority_low": "Baja", "priority_low": "Baja",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
"all_priorities": "Todas las prioridades",
"schedule_type": "Tipo de planificación", "schedule_type": "Tipo de planificación",
"interval_days": "Intervalo (días)", "interval_days": "Intervalo (días)",
"warning_days": "Días de aviso", "warning_days": "Días de aviso",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Vacío = mostrar todos los objetos.", "card_filter_objects_help": "Vacío = mostrar todos los objetos.",
"card_filter_areas": "Filtrar por áreas", "card_filter_areas": "Filtrar por áreas",
"card_filter_areas_help": "Vacío = mostrar todas las áreas.", "card_filter_areas_help": "Vacío = mostrar todas las áreas.",
"card_filter_priority_help": "Vacío = todas las prioridades. Las tareas sin prioridad explícita cuentan como Normal.",
"card_filter_entities": "Filtrar por entidades (entity_ids)", "card_filter_entities": "Filtrar por entidades (entity_ids)",
"card_filter_entities_help": "Selecciona entidades sensor / binary_sensor de esta integración. Vacío = todas.", "card_filter_entities_help": "Selecciona entidades sensor / binary_sensor de esta integración. Vacío = todas.",
"card_loading_objects": "Cargando objetos…", "card_loading_objects": "Cargando objetos…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Seguir de nuevo", "battery_fleet_include": "Seguir de nuevo",
"battery_fleet_all": "Todas las pilas monitorizadas", "battery_fleet_all": "Todas las pilas monitorizadas",
"battery_fleet_all_hint": "Excluye aquí un dispositivo antes de que llegue a avisar de carga baja — un aspirador que se recarga solo o un teléfono que ya avisa por su cuenta.", "battery_fleet_all_hint": "Excluye aquí un dispositivo antes de que llegue a avisar de carga baja — un aspirador que se recarga solo o un teléfono que ya avisa por su cuenta.",
"battery_fleet_add": "Añadir una batería",
"battery_fleet_add_hint": "Elige un sensor de batería que la detección automática pasó por alto — se une a la lista de inmediato.",
"battery_fleet_status_low": "Baja", "battery_fleet_status_low": "Baja",
"battery_fleet_status_soon": "Pronto", "battery_fleet_status_soon": "Pronto",
"battery_fleet_status_ok": "Correcta", "battery_fleet_status_ok": "Correcta",
@@ -158,6 +158,7 @@
"priority_low": "Matala", "priority_low": "Matala",
"priority_normal": "Normaali", "priority_normal": "Normaali",
"priority_high": "Korkea", "priority_high": "Korkea",
"all_priorities": "Kaikki prioriteetit",
"schedule_type": "Ajoitustyyppi", "schedule_type": "Ajoitustyyppi",
"interval_days": "Väli (päivää)", "interval_days": "Väli (päivää)",
"warning_days": "Varoituspäivät", "warning_days": "Varoituspäivät",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Tyhjä = näytä kaikki kohteet.", "card_filter_objects_help": "Tyhjä = näytä kaikki kohteet.",
"card_filter_areas": "Suodata alueiden mukaan", "card_filter_areas": "Suodata alueiden mukaan",
"card_filter_areas_help": "Tyhjä = näytä kaikki alueet.", "card_filter_areas_help": "Tyhjä = näytä kaikki alueet.",
"card_filter_priority_help": "Tyhjä = kaikki prioriteetit. Tehtävät ilman prioriteettia lasketaan Normaaliksi.",
"card_filter_entities": "Suodata entiteettien mukaan (entity_id)", "card_filter_entities": "Suodata entiteettien mukaan (entity_id)",
"card_filter_entities_help": "Valitse sensor- / binary_sensor-entiteetit tästä integraatiosta. Tyhjä = kaikki.", "card_filter_entities_help": "Valitse sensor- / binary_sensor-entiteetit tästä integraatiosta. Tyhjä = kaikki.",
"card_loading_objects": "Ladataan kohteita…", "card_loading_objects": "Ladataan kohteita…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Seuraa uudelleen", "battery_fleet_include": "Seuraa uudelleen",
"battery_fleet_all": "Kaikki seuratut paristot", "battery_fleet_all": "Kaikki seuratut paristot",
"battery_fleet_all_hint": "Sulje laite pois jo ennen kuin se ilmoittaa alhaisesta varauksesta — imuri, joka lataa itsensä, tai puhelin, joka varoittaa itse.", "battery_fleet_all_hint": "Sulje laite pois jo ennen kuin se ilmoittaa alhaisesta varauksesta — imuri, joka lataa itsensä, tai puhelin, joka varoittaa itse.",
"battery_fleet_add": "Lisää paristo",
"battery_fleet_add_hint": "Valitse paristoanturi, jonka automaattinen tunnistus ohitti — se liittyy luetteloon heti.",
"battery_fleet_status_low": "Vähissä", "battery_fleet_status_low": "Vähissä",
"battery_fleet_status_soon": "Pian", "battery_fleet_status_soon": "Pian",
"battery_fleet_status_ok": "Kunnossa", "battery_fleet_status_ok": "Kunnossa",
@@ -157,6 +157,7 @@
"priority_low": "Basse", "priority_low": "Basse",
"priority_normal": "Normale", "priority_normal": "Normale",
"priority_high": "Haute", "priority_high": "Haute",
"all_priorities": "Toutes les priorités",
"schedule_type": "Type de planification", "schedule_type": "Type de planification",
"interval_days": "Intervalle (jours)", "interval_days": "Intervalle (jours)",
"warning_days": "Jours d'avertissement", "warning_days": "Jours d'avertissement",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Vide = afficher tous les objets.", "card_filter_objects_help": "Vide = afficher tous les objets.",
"card_filter_areas": "Filtrer par zones", "card_filter_areas": "Filtrer par zones",
"card_filter_areas_help": "Vide = afficher toutes les zones.", "card_filter_areas_help": "Vide = afficher toutes les zones.",
"card_filter_priority_help": "Vide = toutes les priorités. Les tâches sans priorité explicite comptent comme Normale.",
"card_filter_entities": "Filtrer par entités (entity_ids)", "card_filter_entities": "Filtrer par entités (entity_ids)",
"card_filter_entities_help": "Choisissez des entités sensor / binary_sensor de cette intégration. Vide = toutes.", "card_filter_entities_help": "Choisissez des entités sensor / binary_sensor de cette intégration. Vide = toutes.",
"card_loading_objects": "Chargement des objets…", "card_loading_objects": "Chargement des objets…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Suivre à nouveau", "battery_fleet_include": "Suivre à nouveau",
"battery_fleet_all": "Toutes les piles suivies", "battery_fleet_all": "Toutes les piles suivies",
"battery_fleet_all_hint": "Excluez un appareil ici avant même qu'il ne signale une charge faible — un aspirateur qui se recharge seul, ou un téléphone qui vous prévient lui-même.", "battery_fleet_all_hint": "Excluez un appareil ici avant même qu'il ne signale une charge faible — un aspirateur qui se recharge seul, ou un téléphone qui vous prévient lui-même.",
"battery_fleet_add": "Ajouter une batterie",
"battery_fleet_add_hint": "Choisissez un capteur de batterie que la détection automatique a manqué — il rejoint la liste immédiatement.",
"battery_fleet_status_low": "Faible", "battery_fleet_status_low": "Faible",
"battery_fleet_status_soon": "Bientôt", "battery_fleet_status_soon": "Bientôt",
"battery_fleet_status_ok": "Bon état", "battery_fleet_status_ok": "Bon état",
@@ -158,6 +158,7 @@
"priority_low": "कम", "priority_low": "कम",
"priority_normal": "सामान्य", "priority_normal": "सामान्य",
"priority_high": "उच्च", "priority_high": "उच्च",
"all_priorities": "सभी प्राथमिकताएँ",
"schedule_type": "अनुसूची प्रकार", "schedule_type": "अनुसूची प्रकार",
"interval_days": "अंतराल (दिन)", "interval_days": "अंतराल (दिन)",
"warning_days": "चेतावनी दिन", "warning_days": "चेतावनी दिन",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "खाली = सभी वस्तुएँ दिखाएँ।", "card_filter_objects_help": "खाली = सभी वस्तुएँ दिखाएँ।",
"card_filter_areas": "क्षेत्रों के अनुसार फ़िल्टर करें", "card_filter_areas": "क्षेत्रों के अनुसार फ़िल्टर करें",
"card_filter_areas_help": "खाली = सभी क्षेत्र दिखाएँ।", "card_filter_areas_help": "खाली = सभी क्षेत्र दिखाएँ।",
"card_filter_priority_help": "खाली = सभी प्राथमिकताएँ। स्पष्ट प्राथमिकता के बिना कार्य सामान्य माने जाते हैं।",
"card_filter_entities": "एंटिटी के अनुसार फ़िल्टर करें (entity_ids)", "card_filter_entities": "एंटिटी के अनुसार फ़िल्टर करें (entity_ids)",
"card_filter_entities_help": "इस इंटीग्रेशन से sensor / binary_sensor एंटिटी चुनें। खाली = सभी।", "card_filter_entities_help": "इस इंटीग्रेशन से sensor / binary_sensor एंटिटी चुनें। खाली = सभी।",
"card_loading_objects": "वस्तुएँ लोड हो रही हैं…", "card_loading_objects": "वस्तुएँ लोड हो रही हैं…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "फिर से ट्रैक करें", "battery_fleet_include": "फिर से ट्रैक करें",
"battery_fleet_all": "सभी ट्रैक की गई बैटरियाँ", "battery_fleet_all": "सभी ट्रैक की गई बैटरियाँ",
"battery_fleet_all_hint": "किसी डिवाइस को यहाँ कम बैटरी बताने से पहले ही बाहर रखें — जैसे खुद चार्ज होने वाला वैक्यूम, या खुद ही चेतावनी देने वाला फ़ोन।", "battery_fleet_all_hint": "किसी डिवाइस को यहाँ कम बैटरी बताने से पहले ही बाहर रखें — जैसे खुद चार्ज होने वाला वैक्यूम, या खुद ही चेतावनी देने वाला फ़ोन।",
"battery_fleet_add": "बैटरी जोड़ें",
"battery_fleet_add_hint": "स्वचालित खोज से छूटा बैटरी सेंसर चुनें — यह तुरंत सूची में जुड़ जाएगा।",
"battery_fleet_status_low": "कम", "battery_fleet_status_low": "कम",
"battery_fleet_status_soon": "जल्द", "battery_fleet_status_soon": "जल्द",
"battery_fleet_status_ok": "ठीक", "battery_fleet_status_ok": "ठीक",
@@ -158,6 +158,7 @@
"priority_low": "Alacsony", "priority_low": "Alacsony",
"priority_normal": "Normál", "priority_normal": "Normál",
"priority_high": "Magas", "priority_high": "Magas",
"all_priorities": "Minden prioritás",
"schedule_type": "Ütemezés típusa", "schedule_type": "Ütemezés típusa",
"interval_days": "Intervallum (nap)", "interval_days": "Intervallum (nap)",
"warning_days": "Figyelmeztetési napok", "warning_days": "Figyelmeztetési napok",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Üres = minden objektum megjelenik.", "card_filter_objects_help": "Üres = minden objektum megjelenik.",
"card_filter_areas": "Szűrés területek szerint", "card_filter_areas": "Szűrés területek szerint",
"card_filter_areas_help": "Üres = minden terület megjelenik.", "card_filter_areas_help": "Üres = minden terület megjelenik.",
"card_filter_priority_help": "Üres = minden prioritás. Explicit prioritás nélküli feladatok Normálnak számítanak.",
"card_filter_entities": "Szűrés entitások szerint (entity_id-k)", "card_filter_entities": "Szűrés entitások szerint (entity_id-k)",
"card_filter_entities_help": "Válasszon sensor / binary_sensor entitásokat ebből az integrációból. Üres = mind.", "card_filter_entities_help": "Válasszon sensor / binary_sensor entitásokat ebből az integrációból. Üres = mind.",
"card_loading_objects": "Objektumok betöltése…", "card_loading_objects": "Objektumok betöltése…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Követés újra", "battery_fleet_include": "Követés újra",
"battery_fleet_all": "Minden nyomon követett elem", "battery_fleet_all": "Minden nyomon követett elem",
"battery_fleet_all_hint": "Zárjon ki egy eszközt már azelőtt, hogy alacsony töltöttséget jelezne — például egy magát töltő porszívót vagy egy telefont, amely magától figyelmeztet.", "battery_fleet_all_hint": "Zárjon ki egy eszközt már azelőtt, hogy alacsony töltöttséget jelezne — például egy magát töltő porszívót vagy egy telefont, amely magától figyelmeztet.",
"battery_fleet_add": "Elem hozzáadása",
"battery_fleet_add_hint": "Válassz egy elem-érzékelőt, amelyet az automatikus felismerés kihagyott — azonnal felkerül a listára.",
"battery_fleet_status_low": "Alacsony", "battery_fleet_status_low": "Alacsony",
"battery_fleet_status_soon": "Hamarosan", "battery_fleet_status_soon": "Hamarosan",
"battery_fleet_status_ok": "Rendben", "battery_fleet_status_ok": "Rendben",
@@ -157,6 +157,7 @@
"priority_low": "Bassa", "priority_low": "Bassa",
"priority_normal": "Normale", "priority_normal": "Normale",
"priority_high": "Alta", "priority_high": "Alta",
"all_priorities": "Tutte le priorità",
"schedule_type": "Tipo di pianificazione", "schedule_type": "Tipo di pianificazione",
"interval_days": "Intervallo (giorni)", "interval_days": "Intervallo (giorni)",
"warning_days": "Giorni di avviso", "warning_days": "Giorni di avviso",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Vuoto = mostra tutti gli oggetti.", "card_filter_objects_help": "Vuoto = mostra tutti gli oggetti.",
"card_filter_areas": "Filtra per aree", "card_filter_areas": "Filtra per aree",
"card_filter_areas_help": "Vuoto = mostra tutte le aree.", "card_filter_areas_help": "Vuoto = mostra tutte le aree.",
"card_filter_priority_help": "Vuoto = tutte le priorità. Le attività senza priorità esplicita contano come Normale.",
"card_filter_entities": "Filtra per entità (entity_ids)", "card_filter_entities": "Filtra per entità (entity_ids)",
"card_filter_entities_help": "Seleziona entità sensor / binary_sensor da questa integrazione. Vuoto = tutte.", "card_filter_entities_help": "Seleziona entità sensor / binary_sensor da questa integrazione. Vuoto = tutte.",
"card_loading_objects": "Caricamento oggetti…", "card_loading_objects": "Caricamento oggetti…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Traccia di nuovo", "battery_fleet_include": "Traccia di nuovo",
"battery_fleet_all": "Tutte le batterie monitorate", "battery_fleet_all": "Tutte le batterie monitorate",
"battery_fleet_all_hint": "Escludi qui un dispositivo prima ancora che segnali la batteria scarica — un aspirapolvere che si ricarica da solo o un telefono che avvisa da sé.", "battery_fleet_all_hint": "Escludi qui un dispositivo prima ancora che segnali la batteria scarica — un aspirapolvere che si ricarica da solo o un telefono che avvisa da sé.",
"battery_fleet_add": "Aggiungi una batteria",
"battery_fleet_add_hint": "Scegli un sensore batteria sfuggito al rilevamento automatico — entra subito nell'elenco.",
"battery_fleet_status_low": "Scarica", "battery_fleet_status_low": "Scarica",
"battery_fleet_status_soon": "A breve", "battery_fleet_status_soon": "A breve",
"battery_fleet_status_ok": "A posto", "battery_fleet_status_ok": "A posto",
@@ -158,6 +158,7 @@
"priority_low": "低", "priority_low": "低",
"priority_normal": "標準", "priority_normal": "標準",
"priority_high": "高", "priority_high": "高",
"all_priorities": "すべての優先度",
"schedule_type": "スケジュール種別", "schedule_type": "スケジュール種別",
"interval_days": "間隔(日)", "interval_days": "間隔(日)",
"warning_days": "警告日数", "warning_days": "警告日数",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "空欄=すべての対象を表示。", "card_filter_objects_help": "空欄=すべての対象を表示。",
"card_filter_areas": "エリアで絞り込み", "card_filter_areas": "エリアで絞り込み",
"card_filter_areas_help": "空欄=すべてのエリアを表示。", "card_filter_areas_help": "空欄=すべてのエリアを表示。",
"card_filter_priority_help": "空 = すべての優先度。明示的な優先度のないタスクは「普通」として扱われます。",
"card_filter_entities": "エンティティで絞り込み(entity_ids", "card_filter_entities": "エンティティで絞り込み(entity_ids",
"card_filter_entities_help": "この統合のsensorbinary_sensorエンティティを選択。空欄=すべて。", "card_filter_entities_help": "この統合のsensorbinary_sensorエンティティを選択。空欄=すべて。",
"card_loading_objects": "対象を読み込み中…", "card_loading_objects": "対象を読み込み中…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "再び追跡", "battery_fleet_include": "再び追跡",
"battery_fleet_all": "追跡中のすべての電池", "battery_fleet_all": "追跡中のすべての電池",
"battery_fleet_all_hint": "電池残量が少ないと報告される前に、ここで機器を除外できます — 自動充電するロボット掃除機や、自分で警告するスマートフォンなど。", "battery_fleet_all_hint": "電池残量が少ないと報告される前に、ここで機器を除外できます — 自動充電するロボット掃除機や、自分で警告するスマートフォンなど。",
"battery_fleet_add": "電池を追加",
"battery_fleet_add_hint": "自動検出が見逃した電池センサーを選択すると、すぐに一覧に追加されます。",
"battery_fleet_status_low": "残量低下", "battery_fleet_status_low": "残量低下",
"battery_fleet_status_soon": "まもなく", "battery_fleet_status_soon": "まもなく",
"battery_fleet_status_ok": "良好", "battery_fleet_status_ok": "良好",
@@ -158,6 +158,7 @@
"priority_low": "낮음", "priority_low": "낮음",
"priority_normal": "보통", "priority_normal": "보통",
"priority_high": "높음", "priority_high": "높음",
"all_priorities": "모든 우선순위",
"schedule_type": "일정 유형", "schedule_type": "일정 유형",
"interval_days": "주기 (일)", "interval_days": "주기 (일)",
"warning_days": "경고 일수", "warning_days": "경고 일수",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "비워두면 모든 객체를 표시합니다.", "card_filter_objects_help": "비워두면 모든 객체를 표시합니다.",
"card_filter_areas": "구역으로 필터", "card_filter_areas": "구역으로 필터",
"card_filter_areas_help": "비워두면 모든 구역을 표시합니다.", "card_filter_areas_help": "비워두면 모든 구역을 표시합니다.",
"card_filter_priority_help": "비우면 모든 우선순위를 표시합니다. 명시적 우선순위가 없는 작업은 보통으로 간주됩니다.",
"card_filter_entities": "엔티티로 필터 (entity_ids)", "card_filter_entities": "엔티티로 필터 (entity_ids)",
"card_filter_entities_help": "이 통합구성요소의 sensor / binary_sensor 엔티티를 선택하세요. 비워두면 전체.", "card_filter_entities_help": "이 통합구성요소의 sensor / binary_sensor 엔티티를 선택하세요. 비워두면 전체.",
"card_loading_objects": "객체 불러오는 중…", "card_loading_objects": "객체 불러오는 중…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "다시 추적", "battery_fleet_include": "다시 추적",
"battery_fleet_all": "추적 중인 모든 배터리", "battery_fleet_all": "추적 중인 모든 배터리",
"battery_fleet_all_hint": "배터리 부족을 알리기 전에 여기에서 기기를 제외하세요 — 스스로 충전하는 로봇청소기나 자체적으로 경고하는 휴대폰처럼.", "battery_fleet_all_hint": "배터리 부족을 알리기 전에 여기에서 기기를 제외하세요 — 스스로 충전하는 로봇청소기나 자체적으로 경고하는 휴대폰처럼.",
"battery_fleet_add": "배터리 추가",
"battery_fleet_add_hint": "자동 검색이 놓친 배터리 센서를 선택하면 즉시 목록에 추가됩니다.",
"battery_fleet_status_low": "부족", "battery_fleet_status_low": "부족",
"battery_fleet_status_soon": "곧", "battery_fleet_status_soon": "곧",
"battery_fleet_status_ok": "정상", "battery_fleet_status_ok": "정상",
@@ -158,6 +158,7 @@
"priority_low": "Lav", "priority_low": "Lav",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Høy", "priority_high": "Høy",
"all_priorities": "Alle prioriteter",
"schedule_type": "Planleggingstype", "schedule_type": "Planleggingstype",
"interval_days": "Intervall (dager)", "interval_days": "Intervall (dager)",
"warning_days": "Varslingsdager", "warning_days": "Varslingsdager",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Tom = vis alle objekter.", "card_filter_objects_help": "Tom = vis alle objekter.",
"card_filter_areas": "Filtrer etter områder", "card_filter_areas": "Filtrer etter områder",
"card_filter_areas_help": "Tom = vis alle områder.", "card_filter_areas_help": "Tom = vis alle områder.",
"card_filter_priority_help": "Tomt = alle prioriteter. Oppgaver uten eksplisitt prioritet teller som Normal.",
"card_filter_entities": "Filtrer etter entiteter (entity_ids)", "card_filter_entities": "Filtrer etter entiteter (entity_ids)",
"card_filter_entities_help": "Velg sensor-/binary_sensor-entiteter fra denne integrasjonen. Tom = alle.", "card_filter_entities_help": "Velg sensor-/binary_sensor-entiteter fra denne integrasjonen. Tom = alle.",
"card_loading_objects": "Laster objekter…", "card_loading_objects": "Laster objekter…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Følg igjen", "battery_fleet_include": "Følg igjen",
"battery_fleet_all": "Alle overvåkede batterier", "battery_fleet_all": "Alle overvåkede batterier",
"battery_fleet_all_hint": "Utelukk en enhet her før den i det hele tatt melder lavt nivå — en støvsuger som lader seg selv, eller en telefon som varsler av seg selv.", "battery_fleet_all_hint": "Utelukk en enhet her før den i det hele tatt melder lavt nivå — en støvsuger som lader seg selv, eller en telefon som varsler av seg selv.",
"battery_fleet_add": "Legg til et batteri",
"battery_fleet_add_hint": "Velg en batterisensor som den automatiske gjenkjenningen overså — den blir med i listen umiddelbart.",
"battery_fleet_status_low": "Lav", "battery_fleet_status_low": "Lav",
"battery_fleet_status_soon": "Snart", "battery_fleet_status_soon": "Snart",
"battery_fleet_status_ok": "I orden", "battery_fleet_status_ok": "I orden",
@@ -157,6 +157,7 @@
"priority_low": "Laag", "priority_low": "Laag",
"priority_normal": "Normaal", "priority_normal": "Normaal",
"priority_high": "Hoog", "priority_high": "Hoog",
"all_priorities": "Alle prioriteiten",
"schedule_type": "Planningstype", "schedule_type": "Planningstype",
"interval_days": "Interval (dagen)", "interval_days": "Interval (dagen)",
"warning_days": "Waarschuwingsdagen", "warning_days": "Waarschuwingsdagen",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Leeg = alle objecten tonen.", "card_filter_objects_help": "Leeg = alle objecten tonen.",
"card_filter_areas": "Filteren op gebieden", "card_filter_areas": "Filteren op gebieden",
"card_filter_areas_help": "Leeg = alle gebieden tonen.", "card_filter_areas_help": "Leeg = alle gebieden tonen.",
"card_filter_priority_help": "Leeg = alle prioriteiten. Taken zonder expliciete prioriteit tellen als Normaal.",
"card_filter_entities": "Filteren op entiteiten (entity_ids)", "card_filter_entities": "Filteren op entiteiten (entity_ids)",
"card_filter_entities_help": "Kies sensor/binary_sensor entiteiten van deze integratie. Leeg = alle.", "card_filter_entities_help": "Kies sensor/binary_sensor entiteiten van deze integratie. Leeg = alle.",
"card_loading_objects": "Objecten laden…", "card_loading_objects": "Objecten laden…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Opnieuw volgen", "battery_fleet_include": "Opnieuw volgen",
"battery_fleet_all": "Alle gevolgde batterijen", "battery_fleet_all": "Alle gevolgde batterijen",
"battery_fleet_all_hint": "Sluit een apparaat hier uit voordat het ooit laag meldt — een stofzuiger die zichzelf oplaadt, of een telefoon die zelf waarschuwt.", "battery_fleet_all_hint": "Sluit een apparaat hier uit voordat het ooit laag meldt — een stofzuiger die zichzelf oplaadt, of een telefoon die zelf waarschuwt.",
"battery_fleet_add": "Batterij toevoegen",
"battery_fleet_add_hint": "Kies een batterijsensor die de automatische detectie heeft gemist — hij verschijnt direct in de lijst.",
"battery_fleet_status_low": "Laag", "battery_fleet_status_low": "Laag",
"battery_fleet_status_soon": "Binnenkort", "battery_fleet_status_soon": "Binnenkort",
"battery_fleet_status_ok": "In orde", "battery_fleet_status_ok": "In orde",
@@ -157,6 +157,7 @@
"priority_low": "Niski", "priority_low": "Niski",
"priority_normal": "Normalny", "priority_normal": "Normalny",
"priority_high": "Wysoki", "priority_high": "Wysoki",
"all_priorities": "Wszystkie priorytety",
"schedule_type": "Typ harmonogramu", "schedule_type": "Typ harmonogramu",
"interval_days": "Interwał (dni)", "interval_days": "Interwał (dni)",
"warning_days": "Dni ostrzeżenia", "warning_days": "Dni ostrzeżenia",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Puste = pokaż wszystkie obiekty.", "card_filter_objects_help": "Puste = pokaż wszystkie obiekty.",
"card_filter_areas": "Filtruj wg obszarów", "card_filter_areas": "Filtruj wg obszarów",
"card_filter_areas_help": "Puste = pokaż wszystkie obszary.", "card_filter_areas_help": "Puste = pokaż wszystkie obszary.",
"card_filter_priority_help": "Puste = wszystkie priorytety. Zadania bez jawnego priorytetu liczą się jako Normalny.",
"card_filter_entities": "Filtruj wg encji (entity_ids)", "card_filter_entities": "Filtruj wg encji (entity_ids)",
"card_filter_entities_help": "Wybierz encje sensor / binary_sensor z tej integracji. Puste = wszystkie.", "card_filter_entities_help": "Wybierz encje sensor / binary_sensor z tej integracji. Puste = wszystkie.",
"card_loading_objects": "Ładowanie obiektów…", "card_loading_objects": "Ładowanie obiektów…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Śledź ponownie", "battery_fleet_include": "Śledź ponownie",
"battery_fleet_all": "Wszystkie śledzone baterie", "battery_fleet_all": "Wszystkie śledzone baterie",
"battery_fleet_all_hint": "Wyklucz tutaj urządzenie, zanim w ogóle zgłosi niski poziom — odkurzacz, który sam się ładuje, albo telefon, który ostrzega samodzielnie.", "battery_fleet_all_hint": "Wyklucz tutaj urządzenie, zanim w ogóle zgłosi niski poziom — odkurzacz, który sam się ładuje, albo telefon, który ostrzega samodzielnie.",
"battery_fleet_add": "Dodaj baterię",
"battery_fleet_add_hint": "Wybierz czujnik baterii pominięty przez automatyczne wykrywanie — od razu trafi na listę.",
"battery_fleet_status_low": "Niski", "battery_fleet_status_low": "Niski",
"battery_fleet_status_soon": "Wkrótce", "battery_fleet_status_soon": "Wkrótce",
"battery_fleet_status_ok": "W porządku", "battery_fleet_status_ok": "W porządku",
@@ -158,6 +158,7 @@
"priority_low": "Baixa", "priority_low": "Baixa",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
"all_priorities": "Todas as prioridades",
"schedule_type": "Tipo de agendamento", "schedule_type": "Tipo de agendamento",
"interval_days": "Intervalo (dias)", "interval_days": "Intervalo (dias)",
"warning_days": "Dias de aviso", "warning_days": "Dias de aviso",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Vazio = mostrar todos os objetos.", "card_filter_objects_help": "Vazio = mostrar todos os objetos.",
"card_filter_areas": "Filtrar por áreas", "card_filter_areas": "Filtrar por áreas",
"card_filter_areas_help": "Vazio = mostrar todas as áreas.", "card_filter_areas_help": "Vazio = mostrar todas as áreas.",
"card_filter_priority_help": "Vazio = todas as prioridades. Tarefas sem prioridade explícita contam como Normal.",
"card_filter_entities": "Filtrar por entidades (entity_ids)", "card_filter_entities": "Filtrar por entidades (entity_ids)",
"card_filter_entities_help": "Escolha entidades sensor / binary_sensor desta integração. Vazio = todas.", "card_filter_entities_help": "Escolha entidades sensor / binary_sensor desta integração. Vazio = todas.",
"card_loading_objects": "Carregando objetos…", "card_loading_objects": "Carregando objetos…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Acompanhar novamente", "battery_fleet_include": "Acompanhar novamente",
"battery_fleet_all": "Todas as baterias monitoradas", "battery_fleet_all": "Todas as baterias monitoradas",
"battery_fleet_all_hint": "Exclua aqui um dispositivo antes que ele sequer indique carga baixa — um aspirador que se recarrega sozinho ou um celular que já avisa sozinho.", "battery_fleet_all_hint": "Exclua aqui um dispositivo antes que ele sequer indique carga baixa — um aspirador que se recarrega sozinho ou um celular que já avisa sozinho.",
"battery_fleet_add": "Adicionar uma bateria",
"battery_fleet_add_hint": "Escolha um sensor de bateria que a detecção automática não encontrou — ele entra na lista imediatamente.",
"battery_fleet_status_low": "Fraca", "battery_fleet_status_low": "Fraca",
"battery_fleet_status_soon": "Em breve", "battery_fleet_status_soon": "Em breve",
"battery_fleet_status_ok": "Em bom estado", "battery_fleet_status_ok": "Em bom estado",
@@ -157,6 +157,7 @@
"priority_low": "Baixa", "priority_low": "Baixa",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Alta", "priority_high": "Alta",
"all_priorities": "Todas as prioridades",
"schedule_type": "Tipo de agendamento", "schedule_type": "Tipo de agendamento",
"interval_days": "Intervalo (dias)", "interval_days": "Intervalo (dias)",
"warning_days": "Dias de aviso", "warning_days": "Dias de aviso",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Vazio = mostrar todos os objetos.", "card_filter_objects_help": "Vazio = mostrar todos os objetos.",
"card_filter_areas": "Filtrar por áreas", "card_filter_areas": "Filtrar por áreas",
"card_filter_areas_help": "Vazio = mostrar todas as áreas.", "card_filter_areas_help": "Vazio = mostrar todas as áreas.",
"card_filter_priority_help": "Vazio = todas as prioridades. Tarefas sem prioridade explícita contam como Normal.",
"card_filter_entities": "Filtrar por entidades (entity_ids)", "card_filter_entities": "Filtrar por entidades (entity_ids)",
"card_filter_entities_help": "Selecione entidades sensor / binary_sensor desta integração. Vazio = todas.", "card_filter_entities_help": "Selecione entidades sensor / binary_sensor desta integração. Vazio = todas.",
"card_loading_objects": "A carregar objetos…", "card_loading_objects": "A carregar objetos…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Acompanhar novamente", "battery_fleet_include": "Acompanhar novamente",
"battery_fleet_all": "Todas as pilhas monitorizadas", "battery_fleet_all": "Todas as pilhas monitorizadas",
"battery_fleet_all_hint": "Exclua aqui um dispositivo antes de ele sequer indicar carga fraca — um aspirador que se recarrega sozinho ou um telemóvel que já avisa por si.", "battery_fleet_all_hint": "Exclua aqui um dispositivo antes de ele sequer indicar carga fraca — um aspirador que se recarrega sozinho ou um telemóvel que já avisa por si.",
"battery_fleet_add": "Adicionar uma bateria",
"battery_fleet_add_hint": "Escolha um sensor de bateria que a deteção automática não encontrou — entra de imediato na lista.",
"battery_fleet_status_low": "Fraca", "battery_fleet_status_low": "Fraca",
"battery_fleet_status_soon": "Em breve", "battery_fleet_status_soon": "Em breve",
"battery_fleet_status_ok": "Em bom estado", "battery_fleet_status_ok": "Em bom estado",
@@ -157,6 +157,7 @@
"priority_low": "Низкий", "priority_low": "Низкий",
"priority_normal": "Обычный", "priority_normal": "Обычный",
"priority_high": "Высокий", "priority_high": "Высокий",
"all_priorities": "Все приоритеты",
"schedule_type": "Тип расписания", "schedule_type": "Тип расписания",
"interval_days": "Интервал (дни)", "interval_days": "Интервал (дни)",
"warning_days": "Дни предупреждения", "warning_days": "Дни предупреждения",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Пусто = показать все объекты.", "card_filter_objects_help": "Пусто = показать все объекты.",
"card_filter_areas": "Фильтровать по зонам", "card_filter_areas": "Фильтровать по зонам",
"card_filter_areas_help": "Пусто = показать все зоны.", "card_filter_areas_help": "Пусто = показать все зоны.",
"card_filter_priority_help": "Пусто = все приоритеты. Задачи без явного приоритета считаются обычными.",
"card_filter_entities": "Фильтровать по сущностям (entity_ids)", "card_filter_entities": "Фильтровать по сущностям (entity_ids)",
"card_filter_entities_help": "Выберите сущности sensor / binary_sensor из этой интеграции. Пусто = все.", "card_filter_entities_help": "Выберите сущности sensor / binary_sensor из этой интеграции. Пусто = все.",
"card_loading_objects": "Загрузка объектов…", "card_loading_objects": "Загрузка объектов…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Снова отслеживать", "battery_fleet_include": "Снова отслеживать",
"battery_fleet_all": "Все отслеживаемые батареи", "battery_fleet_all": "Все отслеживаемые батареи",
"battery_fleet_all_hint": "Исключите устройство здесь ещё до того, как оно сообщит о низком заряде — робот-пылесос, который заряжается сам, или телефон, который предупреждает вас сам.", "battery_fleet_all_hint": "Исключите устройство здесь ещё до того, как оно сообщит о низком заряде — робот-пылесос, который заряжается сам, или телефон, который предупреждает вас сам.",
"battery_fleet_add": "Добавить батарею",
"battery_fleet_add_hint": "Выберите датчик батареи, который автоматическое обнаружение пропустило — он сразу появится в списке.",
"battery_fleet_status_low": "Низкий", "battery_fleet_status_low": "Низкий",
"battery_fleet_status_soon": "Скоро", "battery_fleet_status_soon": "Скоро",
"battery_fleet_status_ok": "В норме", "battery_fleet_status_ok": "В норме",
@@ -157,6 +157,7 @@
"priority_low": "Låg", "priority_low": "Låg",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Hög", "priority_high": "Hög",
"all_priorities": "Alla prioriteter",
"schedule_type": "Schematyp", "schedule_type": "Schematyp",
"interval_days": "Intervall (dagar)", "interval_days": "Intervall (dagar)",
"warning_days": "Varningsdagar", "warning_days": "Varningsdagar",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Tomt = visa alla objekt.", "card_filter_objects_help": "Tomt = visa alla objekt.",
"card_filter_areas": "Filtrera efter områden", "card_filter_areas": "Filtrera efter områden",
"card_filter_areas_help": "Tomt = visa alla områden.", "card_filter_areas_help": "Tomt = visa alla områden.",
"card_filter_priority_help": "Tomt = alla prioriteter. Uppgifter utan uttrycklig prioritet räknas som Normal.",
"card_filter_entities": "Filtrera efter entiteter (entity_ids)", "card_filter_entities": "Filtrera efter entiteter (entity_ids)",
"card_filter_entities_help": "Välj sensor- / binary_sensor-entiteter från denna integration. Tomt = alla.", "card_filter_entities_help": "Välj sensor- / binary_sensor-entiteter från denna integration. Tomt = alla.",
"card_loading_objects": "Laddar objekt…", "card_loading_objects": "Laddar objekt…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Spåra igen", "battery_fleet_include": "Spåra igen",
"battery_fleet_all": "Alla bevakade batterier", "battery_fleet_all": "Alla bevakade batterier",
"battery_fleet_all_hint": "Uteslut en enhet här redan innan den rapporterar låg nivå — en dammsugare som laddar sig själv, eller en telefon som varnar på egen hand.", "battery_fleet_all_hint": "Uteslut en enhet här redan innan den rapporterar låg nivå — en dammsugare som laddar sig själv, eller en telefon som varnar på egen hand.",
"battery_fleet_add": "Lägg till ett batteri",
"battery_fleet_add_hint": "Välj en batterisensor som den automatiska identifieringen missade — den läggs till i listan direkt.",
"battery_fleet_status_low": "Låg", "battery_fleet_status_low": "Låg",
"battery_fleet_status_soon": "Snart", "battery_fleet_status_soon": "Snart",
"battery_fleet_status_ok": "I ordning", "battery_fleet_status_ok": "I ordning",
@@ -158,6 +158,7 @@
"priority_low": "Düşük", "priority_low": "Düşük",
"priority_normal": "Normal", "priority_normal": "Normal",
"priority_high": "Yüksek", "priority_high": "Yüksek",
"all_priorities": "Tüm öncelikler",
"schedule_type": "Zamanlama türü", "schedule_type": "Zamanlama türü",
"interval_days": "Aralık (gün)", "interval_days": "Aralık (gün)",
"warning_days": "Uyarı günleri", "warning_days": "Uyarı günleri",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "Boş = tüm nesneleri göster.", "card_filter_objects_help": "Boş = tüm nesneleri göster.",
"card_filter_areas": "Alanlara göre filtrele", "card_filter_areas": "Alanlara göre filtrele",
"card_filter_areas_help": "Boş = tüm alanları göster.", "card_filter_areas_help": "Boş = tüm alanları göster.",
"card_filter_priority_help": "Boş = tüm öncelikler. Açık önceliği olmayan görevler Normal sayılır.",
"card_filter_entities": "Varlıklara göre filtrele (entity_id)", "card_filter_entities": "Varlıklara göre filtrele (entity_id)",
"card_filter_entities_help": "Bu entegrasyonun sensor / binary_sensor varlıklarını seçin. Boş = tümü.", "card_filter_entities_help": "Bu entegrasyonun sensor / binary_sensor varlıklarını seçin. Boş = tümü.",
"card_loading_objects": "Nesneler yükleniyor…", "card_loading_objects": "Nesneler yükleniyor…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Yeniden takip et", "battery_fleet_include": "Yeniden takip et",
"battery_fleet_all": "İzlenen tüm piller", "battery_fleet_all": "İzlenen tüm piller",
"battery_fleet_all_hint": "Bir cihazı, daha düşük şarj bildirmeden burada hariç tutun — kendi kendine şarj olan bir süpürge ya da zaten kendisi uyaran bir telefon gibi.", "battery_fleet_all_hint": "Bir cihazı, daha düşük şarj bildirmeden burada hariç tutun — kendi kendine şarj olan bir süpürge ya da zaten kendisi uyaran bir telefon gibi.",
"battery_fleet_add": "Pil ekle",
"battery_fleet_add_hint": "Otomatik keşfin atladığı bir pil sensörü seçin — hemen listeye katılır.",
"battery_fleet_status_low": "Düşük", "battery_fleet_status_low": "Düşük",
"battery_fleet_status_soon": "Yakında", "battery_fleet_status_soon": "Yakında",
"battery_fleet_status_ok": "İyi durumda", "battery_fleet_status_ok": "İyi durumda",
@@ -157,6 +157,7 @@
"priority_low": "Низький", "priority_low": "Низький",
"priority_normal": "Звичайний", "priority_normal": "Звичайний",
"priority_high": "Високий", "priority_high": "Високий",
"all_priorities": "Усі пріоритети",
"schedule_type": "Тип розкладу", "schedule_type": "Тип розкладу",
"interval_days": "Інтервал (дні)", "interval_days": "Інтервал (дні)",
"warning_days": "Днів попередження", "warning_days": "Днів попередження",
@@ -380,6 +381,7 @@
"card_filter_objects_help": "Порожньо = показати всі об'єкти.", "card_filter_objects_help": "Порожньо = показати всі об'єкти.",
"card_filter_areas": "Фільтрувати за зонами", "card_filter_areas": "Фільтрувати за зонами",
"card_filter_areas_help": "Порожньо = показати всі зони.", "card_filter_areas_help": "Порожньо = показати всі зони.",
"card_filter_priority_help": "Порожньо = усі пріоритети. Завдання без явного пріоритету вважаються звичайними.",
"card_filter_entities": "Фільтрувати за сутностями (entity_ids)", "card_filter_entities": "Фільтрувати за сутностями (entity_ids)",
"card_filter_entities_help": "Виберіть сутності sensor / binary_sensor з цієї інтеграції. Порожньо = всі.", "card_filter_entities_help": "Виберіть сутності sensor / binary_sensor з цієї інтеграції. Порожньо = всі.",
"card_loading_objects": "Завантаження об'єктів…", "card_loading_objects": "Завантаження об'єктів…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "Знову відстежувати", "battery_fleet_include": "Знову відстежувати",
"battery_fleet_all": "Усі відстежувані батареї", "battery_fleet_all": "Усі відстежувані батареї",
"battery_fleet_all_hint": "Вилучіть пристрій тут ще до того, як він повідомить про низький заряд — робот-пилосос, що заряджається сам, або телефон, який попереджає сам.", "battery_fleet_all_hint": "Вилучіть пристрій тут ще до того, як він повідомить про низький заряд — робот-пилосос, що заряджається сам, або телефон, який попереджає сам.",
"battery_fleet_add": "Додати батарею",
"battery_fleet_add_hint": "Виберіть датчик батареї, який автоматичне виявлення пропустило — він одразу з'явиться у списку.",
"battery_fleet_status_low": "Низький", "battery_fleet_status_low": "Низький",
"battery_fleet_status_soon": "Незабаром", "battery_fleet_status_soon": "Незабаром",
"battery_fleet_status_ok": "У нормі", "battery_fleet_status_ok": "У нормі",
@@ -158,6 +158,7 @@
"priority_low": "低", "priority_low": "低",
"priority_normal": "普通", "priority_normal": "普通",
"priority_high": "高", "priority_high": "高",
"all_priorities": "所有优先级",
"schedule_type": "计划类型", "schedule_type": "计划类型",
"interval_days": "间隔 (天)", "interval_days": "间隔 (天)",
"warning_days": "预警天数", "warning_days": "预警天数",
@@ -381,6 +382,7 @@
"card_filter_objects_help": "留空则显示所有维护项。", "card_filter_objects_help": "留空则显示所有维护项。",
"card_filter_areas": "按区域过滤", "card_filter_areas": "按区域过滤",
"card_filter_areas_help": "留空则显示所有区域。", "card_filter_areas_help": "留空则显示所有区域。",
"card_filter_priority_help": "留空 = 显示所有优先级。没有明确优先级的任务视为普通。",
"card_filter_entities": "按实体过滤 (entity_ids)", "card_filter_entities": "按实体过滤 (entity_ids)",
"card_filter_entities_help": "选择该集成的传感器或二进制传感器实体。留空则显示全部。", "card_filter_entities_help": "选择该集成的传感器或二进制传感器实体。留空则显示全部。",
"card_loading_objects": "正在加载维护项…", "card_loading_objects": "正在加载维护项…",
@@ -834,6 +836,8 @@
"battery_fleet_include": "重新跟踪", "battery_fleet_include": "重新跟踪",
"battery_fleet_all": "所有跟踪的电池", "battery_fleet_all": "所有跟踪的电池",
"battery_fleet_all_hint": "在设备报告电量不足之前就可以在这里将其排除——例如会自行充电的扫地机器人,或本身就会提醒你的手机。", "battery_fleet_all_hint": "在设备报告电量不足之前就可以在这里将其排除——例如会自行充电的扫地机器人,或本身就会提醒你的手机。",
"battery_fleet_add": "添加电池",
"battery_fleet_add_hint": "选择自动发现遗漏的电池传感器——它会立即加入列表。",
"battery_fleet_status_low": "电量低", "battery_fleet_status_low": "电量低",
"battery_fleet_status_soon": "即将", "battery_fleet_status_soon": "即将",
"battery_fleet_status_ok": "正常", "battery_fleet_status_ok": "正常",
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.59.0 */ /*! maintenance_supporter frontend 2.61.0 */
var S="2.59.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{}})(); var S="2.61.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{}})();
@@ -1,222 +0,0 @@
/*! 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>
<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,5 +1,5 @@
/*! maintenance_supporter frontend 2.59.0 */ /*! maintenance_supporter frontend 2.61.0 */
import{a as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DZAYWHWN.js";import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-7ZFDRUH2.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,o as v,q as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DD2OCRNH.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 v(this.hass)}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,u(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 m(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` import{a as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TGQTH4TY.js";import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-JPOJFRHB.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,o as v,q as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4JER2GPD.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 v(this.hass)}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,u(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 m(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="overlay" @click=${this._close}>
<div class="card" @click=${e=>e.stopPropagation()}> <div class="card" @click=${e=>e.stopPropagation()}>
<div class="title">${i("adopt_problem_title",s)}</div> <div class="title">${i("adopt_problem_title",s)}</div>
@@ -1,222 +0,0 @@
/*! maintenance_supporter frontend 2.58.0 */
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-F567KB5W.js";import{a as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-2TYYX7JG.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,o as v,q as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-5LZFNUMR.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 v(this.hass)}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,u(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 m(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 f=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=${f}
@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.58.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,5 +1,5 @@
/*! maintenance_supporter frontend 2.59.0 */ /*! maintenance_supporter frontend 2.61.0 */
import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-7ZFDRUH2.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,o as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DD2OCRNH.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 h(this.hass)}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=u(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` import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-JPOJFRHB.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,o as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4JER2GPD.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 h(this.hass)}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=u(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}> <ha-dialog open @closed=${this._close}>
<div class="dialog-title">${n}</div> <div class="dialog-title">${n}</div>
<div class="content"> <div class="content">
@@ -1,2 +1,2 @@
/*! maintenance_supporter frontend 2.59.0 */ /*! maintenance_supporter frontend 2.61.0 */
import{n as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DD2OCRNH.js";function u(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let n=!!e.entry_id&&e.entry_id!==r,o=n?e.entry_id:r,a=s.find(p=>p.entry_id===o),t=(a?.parts||[]).find(p=>p.id===e.part_id)||null,d=n&&a?.object?.name||"",i=t?.name||_("shared_part_unknown",c);return{part:t,foreign:n,ownerName:d,label:d?`${i} (${d})`:i}}function P(e,r,s,c){let{part:n,label:o}=l(e,r,s,c),a=n&&n.stock!==null&&n.stock!==void 0?` (${n.stock}${n.unit?" "+n.unit:""})`:"",t=n?.storage_location?` \u2014 ${n.storage_location}`:"";return`${e.quantity}\xD7 ${o}${a}${t}`}function g(e,r,s,c){let o=(s.find(t=>t.entry_id===r)?.parts||[]).map(t=>({...t})),a=new Set(o.map(t=>u({part_id:t.id})));for(let t of e?.consumes_parts||[]){if(!t.entry_id||t.entry_id===r)continue;let d=u(t);if(a.has(d))continue;a.add(d);let{part:i,ownerName:p}=l(t,r,s,c);o.push({id:t.part_id,name:i?.name||_("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:t.entry_id,owner_name:p})}return o}var f=["notes","cost","duration","photo","user"],m={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};export{u as a,P as b,g as c,f as d,m as e}; import{n as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4JER2GPD.js";function u(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let n=!!e.entry_id&&e.entry_id!==r,o=n?e.entry_id:r,a=s.find(p=>p.entry_id===o),t=(a?.parts||[]).find(p=>p.id===e.part_id)||null,d=n&&a?.object?.name||"",i=t?.name||_("shared_part_unknown",c);return{part:t,foreign:n,ownerName:d,label:d?`${i} (${d})`:i}}function P(e,r,s,c){let{part:n,label:o}=l(e,r,s,c),a=n&&n.stock!==null&&n.stock!==void 0?` (${n.stock}${n.unit?" "+n.unit:""})`:"",t=n?.storage_location?` \u2014 ${n.storage_location}`:"";return`${e.quantity}\xD7 ${o}${a}${t}`}function g(e,r,s,c){let o=(s.find(t=>t.entry_id===r)?.parts||[]).map(t=>({...t})),a=new Set(o.map(t=>u({part_id:t.id})));for(let t of e?.consumes_parts||[]){if(!t.entry_id||t.entry_id===r)continue;let d=u(t);if(a.has(d))continue;a.add(d);let{part:i,ownerName:p}=l(t,r,s,c);o.push({id:t.part_id,name:i?.name||_("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:t.entry_id,owner_name:p})}return o}var f=["notes","cost","duration","photo","user"],m={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};export{u as a,P as b,g as c,f as d,m as e};
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
/*! maintenance_supporter frontend 2.58.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,2 +0,0 @@
/*! maintenance_supporter frontend 2.58.0 */
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-5LZFNUMR.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 +1,2 @@
/*! maintenance_supporter frontend 2.58.0 */ /*! maintenance_supporter frontend 2.61.0 */
function m(n,t,e){let o=new Blob([n],{type:e}),r=URL.createObjectURL(o),a=document.createElement("a");a.href=r,a.download=t,a.target="_blank",a.rel="noopener",a.style.display="none",document.body.appendChild(a),a.dispatchEvent(new MouseEvent("click")),document.body.removeChild(a),setTimeout(()=>URL.revokeObjectURL(r),6e4)}function i(n,t){let e=document.createElement("a");e.href=n,e.download=t,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}async function c(n,t,e=300){return(await n.connection.sendMessagePromise({type:"auth/sign_path",path:t,expires:e})).path}async function s(n,t,e=300){return c(n,`/api/maintenance_supporter/document/${t}`,e)}async function b(n,t,e=""){let o=window.open("about:blank","_blank");try{let r=await s(n,t);o&&(o.location.href=new URL(r+e,window.location.origin).href)}catch(r){throw o&&o.close(),r}}async function g(n,t,e){i(await s(n,t,30),e)}var d=[{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"}],u=d.map(n=>n.key),l=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function _(n){if(!Array.isArray(n))return[...l];let t=new Set,e=[];for(let o of n)typeof o=="string"&&u.includes(o)&&!t.has(o)&&(t.add(o),e.push(o));return e.length?(e.includes("name")||e.unshift("name"),e):[...l]}export{m as a,i as b,c,s as d,b as e,g as f,d as g,l as h,_ as i}; function m(n,t,e){let o=new Blob([n],{type:e}),r=URL.createObjectURL(o),a=document.createElement("a");a.href=r,a.download=t,a.target="_blank",a.rel="noopener",a.style.display="none",document.body.appendChild(a),a.dispatchEvent(new MouseEvent("click")),document.body.removeChild(a),setTimeout(()=>URL.revokeObjectURL(r),6e4)}function i(n,t){let e=document.createElement("a");e.href=n,e.download=t,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}async function c(n,t,e=300){return(await n.connection.sendMessagePromise({type:"auth/sign_path",path:t,expires:e})).path}async function s(n,t,e=300){return c(n,`/api/maintenance_supporter/document/${t}`,e)}async function b(n,t,e=""){let o=window.open("about:blank","_blank");try{let r=await s(n,t);o&&(o.location.href=new URL(r+e,window.location.origin).href)}catch(r){throw o&&o.close(),r}}async function g(n,t,e){i(await s(n,t,30),e)}var d=[{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"}],u=d.map(n=>n.key),l=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function _(n){if(!Array.isArray(n))return[...l];let t=new Set,e=[];for(let o of n)typeof o=="string"&&u.includes(o)&&!t.has(o)&&(t.add(o),e.push(o));return e.length?(e.includes("name")||e.unshift("name"),e):[...l]}export{m as a,i as b,c,s as d,b as e,g as f,d as g,l as h,_ as i};
@@ -1,2 +0,0 @@
/*! 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,5 +1,5 @@
/*! maintenance_supporter frontend 2.58.0 */ /*! maintenance_supporter frontend 2.61.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-5LZFNUMR.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` 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-4JER2GPD.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"> <label class="field">
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:l}</span>`:l} ${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:l}</span>`:l}
<input <input
@@ -1,2 +0,0 @@
/*! maintenance_supporter frontend 2.58.0 */
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-5LZFNUMR.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,54 +0,0 @@
/*! maintenance_supporter frontend 2.59.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-DD2OCRNH.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);
@@ -1,2 +0,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 +1,2 @@
/*! maintenance_supporter frontend 2.59.0 */ /*! maintenance_supporter frontend 2.61.0 */
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DD2OCRNH.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_equals:"trigger_equals",trigger_not_equals:"trigger_not_equals",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}; import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4JER2GPD.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_equals:"trigger_equals",trigger_not_equals:"trigger_not_equals",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.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,5 +1,5 @@
/*! maintenance_supporter frontend 2.59.0 */ /*! maintenance_supporter frontend 2.61.0 */
import{a as _,e as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-FMV3K4OT.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-7ZFDRUH2.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,z as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DD2OCRNH.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._completedAt="";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._completedAt="",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._completedAt){if(new Date(this._completedAt).getTime()>Date.now()){this._error=r("completed_at_future_error",this.lang),this._loading=!1;return}e.completed_at=this._completedAt.length===16?`${this._completedAt}:00`:this._completedAt}if(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 import{a as _,e as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4Q4MHZO7.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-JPOJFRHB.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,z as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4JER2GPD.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._completedAt="";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._completedAt="",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._completedAt){if(new Date(this._completedAt).getTime()>Date.now()){this._error=r("completed_at_future_error",this.lang),this._loading=!1;return}e.completed_at=this._completedAt.length===16?`${this._completedAt}:00`:this._completedAt}if(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" type="button"
class="cost-suggestion" class="cost-suggestion"
@click=${()=>this._cost=t.toFixed(2)} @click=${()=>this._cost=t.toFixed(2)}
@@ -1,2 +0,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,2 +0,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};
@@ -1,2 +1,2 @@
/*! maintenance_supporter frontend 2.59.0 */ /*! maintenance_supporter frontend 2.61.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}; 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,5 +1,5 @@
/*! maintenance_supporter frontend 2.59.0 */ /*! maintenance_supporter frontend 2.61.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-DD2OCRNH.js";function p(l){return l.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}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"> 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-4JER2GPD.js";function p(l){return l.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}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"> <meta name="color-scheme" content="light">
<title>${d}</title> <title>${d}</title>
<style> <style>
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
/*! maintenance_supporter frontend 2.59.0 */
function m(n,t,e){let o=new Blob([n],{type:e}),r=URL.createObjectURL(o),a=document.createElement("a");a.href=r,a.download=t,a.target="_blank",a.rel="noopener",a.style.display="none",document.body.appendChild(a),a.dispatchEvent(new MouseEvent("click")),document.body.removeChild(a),setTimeout(()=>URL.revokeObjectURL(r),6e4)}function i(n,t){let e=document.createElement("a");e.href=n,e.download=t,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}async function c(n,t,e=300){return(await n.connection.sendMessagePromise({type:"auth/sign_path",path:t,expires:e})).path}async function s(n,t,e=300){return c(n,`/api/maintenance_supporter/document/${t}`,e)}async function b(n,t,e=""){let o=window.open("about:blank","_blank");try{let r=await s(n,t);o&&(o.location.href=new URL(r+e,window.location.origin).href)}catch(r){throw o&&o.close(),r}}async function g(n,t,e){i(await s(n,t,30),e)}var d=[{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"}],u=d.map(n=>n.key),l=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function _(n){if(!Array.isArray(n))return[...l];let t=new Set,e=[];for(let o of n)typeof o=="string"&&u.includes(o)&&!t.has(o)&&(t.add(o),e.push(o));return e.length?(e.includes("name")||e.unshift("name"),e):[...l]}export{m as a,i as b,c,s as d,b as e,g as f,d as g,l as h,_ as i};
@@ -1,54 +0,0 @@
/*! 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
.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);
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.61.0 */
import{a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-P4GKDOK3.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4Q4MHZO7.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-JPOJFRHB.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4JER2GPD.js";export{a as MaintenanceCompleteDialog};
@@ -1,292 +0,0 @@
/*! 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)}
>${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};
@@ -1,2 +0,0 @@
/*! maintenance_supporter frontend 2.59.0 */
import{a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-CWIVA4GR.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-FMV3K4OT.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-7ZFDRUH2.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-DD2OCRNH.js";export{a as MaintenanceCompleteDialog};
@@ -1,292 +0,0 @@
/*! maintenance_supporter frontend 2.58.0 */
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6HOHOTKU.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6LSK7BBU.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-F567KB5W.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,y as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-5LZFNUMR.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};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.61.0 */
import{g as a,h as b,i as c,j as d,k as e,l as f,m as g,n as h,o as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LVFV6HYC.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4LG4SJUR.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-H5KOKMZN.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-EW357W3K.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-P4GKDOK3.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4Q4MHZO7.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-TRENHXOS.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-TGQTH4TY.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-JPOJFRHB.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4JER2GPD.js";export{f as openCompleteDialog,a as openCreateObjectDialog,c as openCreateTaskDialog,b as openEditObjectDialog,d as openEditTaskDialog,e as openHistoryEditDialog,i as openObjectQuickActions,g as openQrDialog,h as openTaskQuickActions};
@@ -1,2 +0,0 @@
/*! maintenance_supporter frontend 2.59.0 */
import{g as a,h as b,i as c,j as d,k as e,l as f,m as g,n as h,o as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NJUM55WH.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-GF2CJ2A7.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-WP2TGE7S.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-FBSXXMGM.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-CWIVA4GR.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-FMV3K4OT.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-EIEW3O3I.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-DZAYWHWN.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-7ZFDRUH2.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-DD2OCRNH.js";export{f as openCompleteDialog,a as openCreateObjectDialog,c as openCreateTaskDialog,b as openEditObjectDialog,d as openEditTaskDialog,e as openHistoryEditDialog,i as openObjectQuickActions,g as openQrDialog,h as openTaskQuickActions};
@@ -1,143 +0,0 @@
/*! 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">
${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};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.61.0 */
import{a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4LG4SJUR.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-EW357W3K.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-JPOJFRHB.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4JER2GPD.js";export{a as MaintenanceObjectDialog};
@@ -1,143 +0,0 @@
/*! maintenance_supporter frontend 2.58.0 */
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-7UOPU2CL.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-F567KB5W.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,o as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-5LZFNUMR.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 h(this.hass)}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=u(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};
@@ -1,2 +0,0 @@
/*! maintenance_supporter frontend 2.59.0 */
import{a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GF2CJ2A7.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-FBSXXMGM.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-7ZFDRUH2.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-DD2OCRNH.js";export{a as MaintenanceObjectDialog};
@@ -0,0 +1,2 @@
/*! maintenance_supporter frontend 2.61.0 */
import{a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TRENHXOS.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4JER2GPD.js";export{a as MaintenanceQrDialog};
@@ -1,2 +0,0 @@
/*! maintenance_supporter frontend 2.59.0 */
import{a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-EIEW3O3I.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-DD2OCRNH.js";export{a as MaintenanceQrDialog};
@@ -1,213 +0,0 @@
/*! 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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}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};
@@ -1,213 +0,0 @@
/*! maintenance_supporter frontend 2.58.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-5LZFNUMR.js";function p(l){return l.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}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};

Some files were not shown because too many files have changed in this diff Show More