126 files
This commit is contained in:
@@ -196,7 +196,7 @@
|
||||
},
|
||||
{
|
||||
"id": "e92ef0caff41454e9f49ea966ed99e41",
|
||||
"url": "/hacsfiles/lovelace-multiple-entity-row/multiple-entity-row.js?hacstag=178921037490",
|
||||
"url": "/hacsfiles/lovelace-multiple-entity-row/multiple-entity-row.js?hacstag=1789210374100",
|
||||
"type": "module"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -430,6 +430,11 @@ class AlarmoCoordinator(DataUpdateCoordinator):
|
||||
)
|
||||
return
|
||||
|
||||
if action == const.EVENT_ACTION_DISARM:
|
||||
_LOGGER.info("Received request for disarming")
|
||||
await alarm_entity.async_alarm_disarm(None, skip_code=True)
|
||||
return
|
||||
|
||||
arm_mode = (
|
||||
alarm_entity._revert_state
|
||||
if alarm_entity._revert_state in const.ARM_MODES
|
||||
@@ -452,9 +457,6 @@ class AlarmoCoordinator(DataUpdateCoordinator):
|
||||
elif action == const.EVENT_ACTION_RETRY_ARM:
|
||||
_LOGGER.info("Received request for retry arming")
|
||||
await alarm_entity.async_handle_arm_request(arm_mode, skip_code=True)
|
||||
elif action == const.EVENT_ACTION_DISARM:
|
||||
_LOGGER.info("Received request for disarming")
|
||||
await alarm_entity.async_alarm_disarm(None, skip_code=True)
|
||||
else:
|
||||
_LOGGER.info(
|
||||
"Received request for arming with mode %s",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -323,8 +323,11 @@ class AlarmoBaseEntity(AlarmControlPanelEntity, RestoreEntity):
|
||||
async def _validate_code(self, code, to_state): # noqa PLR0911
|
||||
"""Validate code and user permissions for a requested state change.
|
||||
|
||||
Returns a (success, error_event) tuple. When success is True,
|
||||
error_event is None.
|
||||
Returns a (success, info) tuple.
|
||||
When validation is successful, success is True, otherwise False.
|
||||
When success is True, info is the user data
|
||||
(or None if no user/code was needed).
|
||||
When success is False, info is the error event.
|
||||
"""
|
||||
# check bypass rules
|
||||
if (
|
||||
@@ -404,7 +407,7 @@ class AlarmoBaseEntity(AlarmControlPanelEntity, RestoreEntity):
|
||||
|
||||
# success
|
||||
self._changed_by = user[ATTR_NAME]
|
||||
return True, None
|
||||
return True, user
|
||||
|
||||
async def async_service_disarm_handler(self, code, context_id=None):
|
||||
"""Handle external disarm request from alarmo.disarm service."""
|
||||
|
||||
@@ -44,6 +44,8 @@ def validate_area(trigger, area_id, hass):
|
||||
return False
|
||||
elif trigger[const.ATTR_AREA]:
|
||||
return trigger[const.ATTR_AREA] == area_id
|
||||
elif area_id and hass.data[const.DOMAIN].get("master"):
|
||||
return False
|
||||
elif len(hass.data[const.DOMAIN]["areas"]) == 1:
|
||||
return True
|
||||
else:
|
||||
|
||||
@@ -15,7 +15,7 @@ from homeassistant.components.alarm_control_panel import (
|
||||
AlarmControlPanelEntityFeature,
|
||||
)
|
||||
|
||||
VERSION = "1.10.18"
|
||||
VERSION = "1.10.19"
|
||||
NAME = "Alarmo"
|
||||
MANUFACTURER = "@nielsfaber"
|
||||
|
||||
|
||||
+448
-448
File diff suppressed because one or more lines are too long
@@ -17,5 +17,5 @@
|
||||
"iot_class": "local_push",
|
||||
"issue_tracker": "https://github.com/nielsfaber/alarmo/issues",
|
||||
"requirements": [],
|
||||
"version": "1.10.18"
|
||||
"version": "1.10.19"
|
||||
}
|
||||
@@ -130,7 +130,11 @@ class SensorHandler:
|
||||
|
||||
def __init__(self, hass: HomeAssistant):
|
||||
"""Initialize the sensor handler."""
|
||||
self._config = None
|
||||
# The sensor config is only loaded once HA has finished starting (see
|
||||
# _setup_sensor_listeners below). Until then this must be an empty dict
|
||||
# rather than None: restoring a persisted alarm state can call into
|
||||
# active_sensors_for_alarm_state() before that point.
|
||||
self._config = {}
|
||||
self.hass = hass
|
||||
self._state_listener = None
|
||||
self._subscriptions = []
|
||||
@@ -144,9 +148,10 @@ class SensorHandler:
|
||||
@callback
|
||||
def async_update_sensor_config():
|
||||
"""Sensor config updated, reload the configuration."""
|
||||
self._config = self.hass.data[const.DOMAIN][
|
||||
"coordinator"
|
||||
].store.async_get_sensors()
|
||||
self._config = (
|
||||
self.hass.data[const.DOMAIN]["coordinator"].store.async_get_sensors()
|
||||
or {}
|
||||
)
|
||||
self._groups = self.hass.data[const.DOMAIN][
|
||||
"coordinator"
|
||||
].store.async_get_sensor_groups()
|
||||
@@ -377,15 +382,28 @@ class SensorHandler:
|
||||
new_state = parse_sensor_state(event.data["new_state"])
|
||||
sensor_config = self._config[entity]
|
||||
if old_state == STATE_UNKNOWN:
|
||||
# sensor is unknown at startup,
|
||||
# state which comes after is considered as initial state
|
||||
_LOGGER.debug(
|
||||
"Initial state for %s is %s",
|
||||
entity,
|
||||
new_state,
|
||||
)
|
||||
self.update_ready_to_arm_status(sensor_config["area"])
|
||||
return
|
||||
if new_state not in (STATE_OPEN, STATE_UNAVAILABLE) or (
|
||||
sensor_config[ATTR_ALLOW_OPEN] and new_state == STATE_OPEN
|
||||
):
|
||||
# transition to a safe state, or to open while the sensor is
|
||||
# allowed to be open — treat as initial state
|
||||
_LOGGER.debug(
|
||||
"Initial state for %s is %s",
|
||||
entity,
|
||||
new_state,
|
||||
)
|
||||
self.update_ready_to_arm_status(sensor_config["area"])
|
||||
return
|
||||
else:
|
||||
# transition to a violation state — do not treat as initial,
|
||||
# proceed through normal trigger evaluation
|
||||
_LOGGER.debug(
|
||||
"Sensor %s recovered from unknown to %s while alarm is %s, "
|
||||
"evaluating as live state change",
|
||||
entity,
|
||||
new_state,
|
||||
self.hass.data[const.DOMAIN]["areas"][sensor_config["area"]].state,
|
||||
)
|
||||
if old_state == new_state:
|
||||
# not a state change - ignore
|
||||
return
|
||||
@@ -740,6 +758,13 @@ class SensorHandler:
|
||||
# Skip unknown sensors - they'll be handled when they become known
|
||||
continue
|
||||
|
||||
if sensor_config[ATTR_ALLOW_OPEN] and sensor_state == STATE_OPEN:
|
||||
_LOGGER.debug(
|
||||
"Sensor %s is open with allow_open, skipping startup eval",
|
||||
entity_id,
|
||||
)
|
||||
continue
|
||||
|
||||
# Check if sensor state is allowed in current alarm state
|
||||
res = sensor_state_allowed(sensor_state, sensor_config, alarm_entity.state)
|
||||
|
||||
|
||||
@@ -381,10 +381,10 @@ class AlarmoStorage:
|
||||
for area in data["areas"]:
|
||||
modes = {
|
||||
mode: ModeEntry(
|
||||
enabled=config["enabled"],
|
||||
exit_time=config["exit_time"],
|
||||
entry_time=config["entry_time"],
|
||||
trigger_time=config["trigger_time"],
|
||||
enabled=config.get("enabled", False),
|
||||
exit_time=config.get("exit_time", None),
|
||||
entry_time=config.get("entry_time", None),
|
||||
trigger_time=config.get("trigger_time", None),
|
||||
)
|
||||
for (mode, config) in area["modes"].items()
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ from homeassistant.helpers.start import async_at_started
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import (
|
||||
BATTERY_FLEET_OBJECT_FLAG,
|
||||
CONF_ADMIN_PANEL_USER_IDS,
|
||||
CONF_ADVANCED_ADAPTIVE,
|
||||
CONF_ADVANCED_BUDGET,
|
||||
@@ -1322,7 +1323,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: MaintenanceSupporterConf
|
||||
# a different UI language) keeps English notes forever while every
|
||||
# runtime string around them is translated. Rewrite the ones the user
|
||||
# never touched into the instance's language; edited texts stay.
|
||||
if obj_data.get("battery_fleet"):
|
||||
if obj_data.get(BATTERY_FLEET_OBJECT_FLAG):
|
||||
from .helpers.battery_fleet_setup import retranslate_seeded_texts
|
||||
from .helpers.i18n import normalize_language
|
||||
|
||||
|
||||
@@ -323,6 +323,11 @@ CONF_OBJECT_NOTES = "notes"
|
||||
# Static part definitions live in entry.data["parts"] (like tasks); the
|
||||
# mutable stock count lives in the per-entry Store. See helpers/parts.py.
|
||||
CONF_PARTS = "parts"
|
||||
# Battery-fleet markers on the OBJECT dict (DRY audit 2026-08: these were
|
||||
# string literals in four files; find_fleet_entry, setup, the WS response
|
||||
# and the fleet exclusion all key on them).
|
||||
BATTERY_FLEET_OBJECT_FLAG = "battery_fleet"
|
||||
BATTERY_FLEET_EXCLUDED = "battery_fleet_excluded"
|
||||
# Task-side link: task["consumes_parts"] = [{"part_id", "quantity"}] — a
|
||||
# completion decrements each linked part's stock.
|
||||
CONF_TASK_CONSUMES_PARTS = "consumes_parts"
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Načíst znovu",
|
||||
"battery_fleet_forecast_overdue": "Předpovězené datum uplynulo — baterie stále hlásí dobrý stav. Pokud jste ji vyměnili, zaznamenejte výměnu; jinak byla předpověď mylná.",
|
||||
"cost_from_parts": "Použít ≈ {amount} z dílů",
|
||||
"new_menu": "Nový",
|
||||
"dismiss": "Skrýt",
|
||||
"gs_label": "Začínáme — tyto tipy zmizí, jak vaše nastavení poroste",
|
||||
"gs_setups_chip": "Navrhovaná nastavení: nalezeno {n} zařízení s předpřipravenými spouštěči",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Genindlæs",
|
||||
"battery_fleet_forecast_overdue": "Forudsagt dato er overskredet — batteriet melder stadig god tilstand. Hvis du har skiftet det, registrér udskiftningen; ellers ramte prognosen forbi.",
|
||||
"cost_from_parts": "Brug ≈ {amount} fra dele",
|
||||
"new_menu": "Ny",
|
||||
"dismiss": "Afvis",
|
||||
"gs_label": "Kom godt i gang — disse tips forsvinder, efterhånden som opsætningen vokser",
|
||||
"gs_setups_chip": "Foreslåede opsætninger fandt {n} enheder med forudindstillede udløsere",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Neu laden",
|
||||
"battery_fleet_forecast_overdue": "Prognosedatum überschritten — die Batterie meldet sich weiterhin gesund. Falls du sie gewechselt hast, trage den Wechsel nach; andernfalls lag die Prognose daneben.",
|
||||
"cost_from_parts": "≈ {amount} aus Teilen übernehmen",
|
||||
"new_menu": "Neu",
|
||||
"dismiss": "Ausblenden",
|
||||
"gs_label": "Erste Schritte — diese Hinweise verschwinden, wenn dein Setup wächst",
|
||||
"gs_setups_chip": "Vorgeschlagene Setups: {n} Geräte mit vorverdrahteten Auslösern gefunden",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Reload",
|
||||
"battery_fleet_forecast_overdue": "Predicted date passed — the battery still reports healthy. If you swapped it, record the replacement; otherwise the forecast was off.",
|
||||
"cost_from_parts": "Use ≈ {amount} from parts",
|
||||
"new_menu": "New",
|
||||
"dismiss": "Dismiss",
|
||||
"gs_label": "Getting started — these hints retire as your setup grows",
|
||||
"gs_setups_chip": "Suggested setups found {n} devices with pre-wired triggers",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Recargar",
|
||||
"battery_fleet_forecast_overdue": "Fecha prevista superada: la batería sigue informando buen estado. Si la cambiaste, registra el reemplazo; si no, la previsión falló.",
|
||||
"cost_from_parts": "Usar ≈ {amount} de las piezas",
|
||||
"new_menu": "Nuevo",
|
||||
"dismiss": "Descartar",
|
||||
"gs_label": "Primeros pasos: estas sugerencias desaparecen a medida que crece tu configuración",
|
||||
"gs_setups_chip": "Configuraciones sugeridas: {n} dispositivos con disparadores preconfigurados",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Lataa uudelleen",
|
||||
"battery_fleet_forecast_overdue": "Ennustettu päivä on ohitettu — akku ilmoittaa yhä hyvästä kunnosta. Jos vaihdoit sen, kirjaa vaihto; muuten ennuste oli pielessä.",
|
||||
"cost_from_parts": "Käytä ≈ {amount} osista",
|
||||
"new_menu": "Uusi",
|
||||
"dismiss": "Hylkää",
|
||||
"gs_label": "Aloitus — nämä vihjeet poistuvat asennuksen kasvaessa",
|
||||
"gs_setups_chip": "Ehdotetut asetukset löysivät {n} laitetta valmiilla laukaisimilla",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Recharger",
|
||||
"battery_fleet_forecast_overdue": "Date prévue dépassée — la batterie se signale toujours en bon état. Si vous l'avez remplacée, enregistrez le remplacement ; sinon la prévision était erronée.",
|
||||
"cost_from_parts": "Reprendre ≈ {amount} des pièces",
|
||||
"new_menu": "Nouveau",
|
||||
"dismiss": "Ignorer",
|
||||
"gs_label": "Premiers pas — ces conseils disparaissent à mesure que votre configuration grandit",
|
||||
"gs_setups_chip": "Configurations suggérées : {n} appareils avec déclencheurs pré-câblés trouvés",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "पुनः लोड करें",
|
||||
"battery_fleet_forecast_overdue": "अनुमानित तिथि बीत गई — बैटरी अब भी अच्छी स्थिति बता रही है। यदि आपने इसे बदला है, तो बदलाव दर्ज करें; अन्यथा पूर्वानुमान गलत था।",
|
||||
"cost_from_parts": "पुर्ज़ों से ≈ {amount} लें",
|
||||
"new_menu": "नया",
|
||||
"dismiss": "हटाएँ",
|
||||
"gs_label": "शुरुआत — सेटअप बढ़ने पर ये संकेत हट जाते हैं",
|
||||
"gs_setups_chip": "सुझाए गए सेटअप: पूर्व-निर्धारित ट्रिगर वाले {n} उपकरण मिले",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Újratöltés",
|
||||
"battery_fleet_forecast_overdue": "Az előrejelzett dátum elmúlt — az elem továbbra is jó állapotot jelez. Ha kicserélted, rögzítsd a cserét; különben az előrejelzés tévedett.",
|
||||
"cost_from_parts": "≈ {amount} átvétele az alkatrészekből",
|
||||
"new_menu": "Új",
|
||||
"dismiss": "Elrejtés",
|
||||
"gs_label": "Első lépések — a tippek eltűnnek, ahogy a beállítás bővül",
|
||||
"gs_setups_chip": "Javasolt beállítások: {n} eszköz előre bekötött triggerekkel",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Ricarica",
|
||||
"battery_fleet_forecast_overdue": "Data prevista superata — la batteria risulta ancora in buono stato. Se l'hai sostituita, registra la sostituzione; altrimenti la previsione era errata.",
|
||||
"cost_from_parts": "Usa ≈ {amount} dai ricambi",
|
||||
"new_menu": "Nuovo",
|
||||
"dismiss": "Ignora",
|
||||
"gs_label": "Primi passi — questi suggerimenti scompaiono man mano che la configurazione cresce",
|
||||
"gs_setups_chip": "Configurazioni suggerite: trovati {n} dispositivi con trigger preconfigurati",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "再読み込み",
|
||||
"battery_fleet_forecast_overdue": "予測日を過ぎましたが、電池はまだ正常と報告しています。交換済みなら交換を記録してください。そうでなければ予測が外れています。",
|
||||
"cost_from_parts": "部品から ≈ {amount} を適用",
|
||||
"new_menu": "新規",
|
||||
"dismiss": "閉じる",
|
||||
"gs_label": "はじめに — セットアップが進むとこれらのヒントは消えます",
|
||||
"gs_setups_chip": "推奨セットアップ:トリガー設定済みのデバイスを{n}台検出",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "새로 고침",
|
||||
"battery_fleet_forecast_overdue": "예측 날짜가 지났지만 배터리는 여전히 정상으로 보고됩니다. 교체했다면 교체를 기록하세요. 아니라면 예측이 빗나간 것입니다.",
|
||||
"cost_from_parts": "부품에서 ≈ {amount} 적용",
|
||||
"new_menu": "새로 만들기",
|
||||
"dismiss": "닫기",
|
||||
"gs_label": "시작하기 — 설정이 늘어나면 이 힌트는 사라집니다",
|
||||
"gs_setups_chip": "추천 설정: 트리거가 준비된 기기 {n}대 발견",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Last inn på nytt",
|
||||
"battery_fleet_forecast_overdue": "Forutsagt dato er passert — batteriet melder fortsatt god tilstand. Hvis du byttet det, registrer byttet; ellers bommet prognosen.",
|
||||
"cost_from_parts": "Bruk ≈ {amount} fra deler",
|
||||
"new_menu": "Ny",
|
||||
"dismiss": "Avvis",
|
||||
"gs_label": "Kom i gang — tipsene forsvinner etter hvert som oppsettet vokser",
|
||||
"gs_setups_chip": "Foreslåtte oppsett fant {n} enheter med ferdigkoblede utløsere",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Herladen",
|
||||
"battery_fleet_forecast_overdue": "Voorspelde datum verstreken — de batterij meldt zich nog steeds gezond. Heb je hem vervangen, registreer dan de vervanging; anders zat de voorspelling ernaast.",
|
||||
"cost_from_parts": "≈ {amount} uit onderdelen overnemen",
|
||||
"new_menu": "Nieuw",
|
||||
"dismiss": "Verbergen",
|
||||
"gs_label": "Aan de slag — deze tips verdwijnen naarmate je installatie groeit",
|
||||
"gs_setups_chip": "Voorgestelde setups: {n} apparaten met vooraf ingestelde triggers gevonden",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Załaduj ponownie",
|
||||
"battery_fleet_forecast_overdue": "Przewidywana data minęła — bateria nadal zgłasza dobry stan. Jeśli ją wymieniono, zapisz wymianę; w przeciwnym razie prognoza była błędna.",
|
||||
"cost_from_parts": "Użyj ≈ {amount} z części",
|
||||
"new_menu": "Nowy",
|
||||
"dismiss": "Odrzuć",
|
||||
"gs_label": "Pierwsze kroki — te wskazówki znikają wraz z rozwojem konfiguracji",
|
||||
"gs_setups_chip": "Sugerowane konfiguracje: znaleziono {n} urządzeń z gotowymi wyzwalaczami",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Recarregar",
|
||||
"battery_fleet_forecast_overdue": "Data prevista ultrapassada — a bateria ainda reporta bom estado. Se você a trocou, registre a troca; caso contrário, a previsão errou.",
|
||||
"cost_from_parts": "Usar ≈ {amount} das peças",
|
||||
"new_menu": "Novo",
|
||||
"dismiss": "Dispensar",
|
||||
"gs_label": "Primeiros passos — estas dicas somem conforme a configuração cresce",
|
||||
"gs_setups_chip": "Configurações sugeridas: {n} dispositivos com gatilhos pré-configurados",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Recarregar",
|
||||
"battery_fleet_forecast_overdue": "Data prevista ultrapassada — a bateria continua a reportar bom estado. Se a substituiu, registe a substituição; caso contrário, a previsão falhou.",
|
||||
"cost_from_parts": "Usar ≈ {amount} das peças",
|
||||
"new_menu": "Novo",
|
||||
"dismiss": "Dispensar",
|
||||
"gs_label": "Primeiros passos — estas dicas desaparecem à medida que a configuração cresce",
|
||||
"gs_setups_chip": "Configurações sugeridas: {n} dispositivos com gatilhos pré-configurados",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Перезагрузить",
|
||||
"battery_fleet_forecast_overdue": "Прогнозируемая дата прошла — батарея по-прежнему сообщает о хорошем состоянии. Если вы её заменили, зафиксируйте замену; иначе прогноз оказался неверным.",
|
||||
"cost_from_parts": "Взять ≈ {amount} из запчастей",
|
||||
"new_menu": "Создать",
|
||||
"dismiss": "Скрыть",
|
||||
"gs_label": "Первые шаги — эти подсказки исчезнут по мере роста настройки",
|
||||
"gs_setups_chip": "Рекомендуемые настройки: найдено {n} устройств с готовыми триггерами",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Ladda om",
|
||||
"battery_fleet_forecast_overdue": "Förutsagt datum har passerat — batteriet rapporterar fortfarande god status. Om du bytte det, registrera bytet; annars slog prognosen fel.",
|
||||
"cost_from_parts": "Använd ≈ {amount} från delar",
|
||||
"new_menu": "Ny",
|
||||
"dismiss": "Avfärda",
|
||||
"gs_label": "Kom igång — tipsen försvinner när din installation växer",
|
||||
"gs_setups_chip": "Föreslagna uppsättningar hittade {n} enheter med förkopplade utlösare",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Yeniden yükle",
|
||||
"battery_fleet_forecast_overdue": "Öngörülen tarih geçti — pil hâlâ sağlıklı görünüyor. Değiştirdiyseniz değişimi kaydedin; aksi halde tahmin yanılmış demektir.",
|
||||
"cost_from_parts": "Parçalardan ≈ {amount} kullan",
|
||||
"new_menu": "Yeni",
|
||||
"dismiss": "Kapat",
|
||||
"gs_label": "Başlarken — kurulumunuz büyüdükçe bu ipuçları kaybolur",
|
||||
"gs_setups_chip": "Önerilen kurulumlar {n} cihaz buldu (hazır tetikleyicilerle)",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Перезавантажити",
|
||||
"battery_fleet_forecast_overdue": "Прогнозована дата минула — батарея й далі повідомляє про добрий стан. Якщо ви її замінили, зафіксуйте заміну; інакше прогноз не справдився.",
|
||||
"cost_from_parts": "Узяти ≈ {amount} із запчастин",
|
||||
"new_menu": "Створити",
|
||||
"dismiss": "Приховати",
|
||||
"gs_label": "Перші кроки — ці підказки зникнуть у міру зростання налаштування",
|
||||
"gs_setups_chip": "Рекомендовані налаштування: знайдено {n} пристроїв із готовими тригерами",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "重新加载",
|
||||
"battery_fleet_forecast_overdue": "预测日期已过——电池仍报告状态良好。如果您已更换电池,请记录更换;否则说明预测有误。",
|
||||
"cost_from_parts": "采用配件合计 ≈ {amount}",
|
||||
"new_menu": "新建",
|
||||
"dismiss": "忽略",
|
||||
"gs_label": "入门提示——随着配置的完善,这些提示会自动消失",
|
||||
"gs_setups_chip": "推荐配置发现 {n} 台设备(含预设触发器)",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** Maintenance Supporter Lovelace Card. */
|
||||
|
||||
import { LitElement, html, css, nothing } from "lit";
|
||||
import { mergeSubscriptionEvent, type SubscriptionEvent } from "./helpers/subscription-merge";
|
||||
import { applySubscriptionEvent, type SubscriptionEvent } from "./helpers/subscription-merge";
|
||||
import { hydrateObjects } from "./helpers/hydrate-objects";
|
||||
import { property, state } from "lit/decorators.js";
|
||||
import { sharedStyles, STATUS_COLORS, t, ensureLocale, isLocaleLoaded, setDateTimePrefs, formatDueDays } from "./styles";
|
||||
@@ -276,11 +276,10 @@ export class MaintenanceSupporterCard extends LitElement {
|
||||
try {
|
||||
const unsub = await this.hass.connection.subscribeMessage(
|
||||
(msg: unknown) => {
|
||||
const ev = msg as SubscriptionEvent<MaintenanceObjectResponse>;
|
||||
// Compact payloads: hydrate before merging (helpers/hydrate-objects).
|
||||
if (ev.objects) hydrateObjects(ev.objects);
|
||||
if (ev.delta) hydrateObjects(ev.delta);
|
||||
const next = mergeSubscriptionEvent(this._objects, ev);
|
||||
const next = applySubscriptionEvent(
|
||||
this._objects,
|
||||
msg as SubscriptionEvent<MaintenanceObjectResponse>,
|
||||
);
|
||||
if (next !== null) this._objects = next;
|
||||
},
|
||||
// deltas: only changed entries arrive — see helpers/subscription-merge.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { LitElement, html, nothing } from "lit";
|
||||
import { isSafeHttpUrl } from "./helpers/url";
|
||||
import { mergeSubscriptionEvent, type SubscriptionEvent } from "./helpers/subscription-merge";
|
||||
import { applySubscriptionEvent, type SubscriptionEvent } from "./helpers/subscription-merge";
|
||||
import { isStaleBundle } from "./helpers/bundle-version";
|
||||
import { customElement, property, state } from "lit/decorators.js";
|
||||
import { sharedStyles, STATUS_COLORS, STATUS_ICONS, DEFAULT_CURRENCY_SYMBOL, t, ensureLocale, isLocaleLoaded, formatDate, formatDueDays, formatInterval, formatRecurrence, setDateTimePrefs } from "./styles";
|
||||
@@ -657,11 +657,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
const unsub = await this.hass.connection.subscribeMessage(
|
||||
(msg: unknown) => {
|
||||
const ev = msg as SubscriptionEvent<MaintenanceObjectResponse>;
|
||||
// Compact payloads: hydrate incoming entries before merging so
|
||||
// everything downstream keeps seeing the full shape.
|
||||
if (ev.objects) hydrateObjects(ev.objects);
|
||||
if (ev.delta) hydrateObjects(ev.delta);
|
||||
const next = mergeSubscriptionEvent(this._objects, ev);
|
||||
const next = applySubscriptionEvent(this._objects, ev);
|
||||
if (next !== null) {
|
||||
this._objects = next;
|
||||
// Full snapshots are rare (subscribe start) — keep the skeleton
|
||||
@@ -3284,7 +3280,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
<div class="new-menu-wrapper">
|
||||
<ha-button appearance="filled" class="new-menu-button"
|
||||
@click=${(e: Event) => { e.stopPropagation(); this._toggleNewMenu(); }}>
|
||||
<ha-icon icon="mdi:plus"></ha-icon> ${t("new_menu", L)}
|
||||
<ha-icon icon="mdi:plus"></ha-icon> ${t("add", L)}
|
||||
<ha-icon icon="mdi:menu-down"></ha-icon>
|
||||
</ha-button>
|
||||
${this._newMenuOpen ? html`
|
||||
@@ -3316,16 +3312,25 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _toggleNewMenu(): void {
|
||||
this._newMenuOpen = !this._newMenuOpen;
|
||||
if (this._newMenuOpen) {
|
||||
/** Shared popup mechanic (DRY audit 2026-08: this closer was copy-pasted
|
||||
* three times): flip the flag, and while open arm a one-shot document
|
||||
* click that closes it again. The setTimeout defers past the click that
|
||||
* opened the menu. */
|
||||
private _togglePopup(get: () => boolean, set: (v: boolean) => void): void {
|
||||
const open = !get();
|
||||
set(open);
|
||||
if (open) {
|
||||
setTimeout(() => {
|
||||
const handler = () => { this._newMenuOpen = false; document.removeEventListener("click", handler); };
|
||||
const handler = () => { set(false); document.removeEventListener("click", handler); };
|
||||
document.addEventListener("click", handler);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private _toggleNewMenu(): void {
|
||||
this._togglePopup(() => this._newMenuOpen, (v) => { this._newMenuOpen = v; });
|
||||
}
|
||||
|
||||
private _closeNewMenu(): void {
|
||||
this._newMenuOpen = false;
|
||||
}
|
||||
@@ -3421,13 +3426,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
}
|
||||
|
||||
private _toggleObjMenu(): void {
|
||||
this._objMenuOpen = !this._objMenuOpen;
|
||||
if (this._objMenuOpen) {
|
||||
setTimeout(() => {
|
||||
const handler = () => { this._objMenuOpen = false; document.removeEventListener("click", handler); };
|
||||
document.addEventListener("click", handler);
|
||||
}, 0);
|
||||
}
|
||||
this._togglePopup(() => this._objMenuOpen, (v) => { this._objMenuOpen = v; });
|
||||
}
|
||||
|
||||
private _closeObjMenu(): void {
|
||||
@@ -3435,12 +3434,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
}
|
||||
|
||||
private _toggleMoreMenu(): void {
|
||||
this._moreMenuOpen = !this._moreMenuOpen;
|
||||
if (this._moreMenuOpen) {
|
||||
// Close menu on next outside click
|
||||
const handler = () => { this._moreMenuOpen = false; document.removeEventListener("click", handler); };
|
||||
setTimeout(() => document.addEventListener("click", handler, { once: true }), 0);
|
||||
}
|
||||
this._togglePopup(() => this._moreMenuOpen, (v) => { this._moreMenuOpen = v; });
|
||||
}
|
||||
|
||||
private _closeMoreMenu(): void {
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Načíst znovu",
|
||||
"battery_fleet_forecast_overdue": "Předpovězené datum uplynulo — baterie stále hlásí dobrý stav. Pokud jste ji vyměnili, zaznamenejte výměnu; jinak byla předpověď mylná.",
|
||||
"cost_from_parts": "Použít ≈ {amount} z dílů",
|
||||
"new_menu": "Nový",
|
||||
"dismiss": "Skrýt",
|
||||
"gs_label": "Začínáme — tyto tipy zmizí, jak vaše nastavení poroste",
|
||||
"gs_setups_chip": "Navrhovaná nastavení: nalezeno {n} zařízení s předpřipravenými spouštěči",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Genindlæs",
|
||||
"battery_fleet_forecast_overdue": "Forudsagt dato er overskredet — batteriet melder stadig god tilstand. Hvis du har skiftet det, registrér udskiftningen; ellers ramte prognosen forbi.",
|
||||
"cost_from_parts": "Brug ≈ {amount} fra dele",
|
||||
"new_menu": "Ny",
|
||||
"dismiss": "Afvis",
|
||||
"gs_label": "Kom godt i gang — disse tips forsvinder, efterhånden som opsætningen vokser",
|
||||
"gs_setups_chip": "Foreslåede opsætninger fandt {n} enheder med forudindstillede udløsere",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Neu laden",
|
||||
"battery_fleet_forecast_overdue": "Prognosedatum überschritten — die Batterie meldet sich weiterhin gesund. Falls du sie gewechselt hast, trage den Wechsel nach; andernfalls lag die Prognose daneben.",
|
||||
"cost_from_parts": "≈ {amount} aus Teilen übernehmen",
|
||||
"new_menu": "Neu",
|
||||
"dismiss": "Ausblenden",
|
||||
"gs_label": "Erste Schritte — diese Hinweise verschwinden, wenn dein Setup wächst",
|
||||
"gs_setups_chip": "Vorgeschlagene Setups: {n} Geräte mit vorverdrahteten Auslösern gefunden",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Reload",
|
||||
"battery_fleet_forecast_overdue": "Predicted date passed — the battery still reports healthy. If you swapped it, record the replacement; otherwise the forecast was off.",
|
||||
"cost_from_parts": "Use ≈ {amount} from parts",
|
||||
"new_menu": "New",
|
||||
"dismiss": "Dismiss",
|
||||
"gs_label": "Getting started — these hints retire as your setup grows",
|
||||
"gs_setups_chip": "Suggested setups found {n} devices with pre-wired triggers",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Recargar",
|
||||
"battery_fleet_forecast_overdue": "Fecha prevista superada: la batería sigue informando buen estado. Si la cambiaste, registra el reemplazo; si no, la previsión falló.",
|
||||
"cost_from_parts": "Usar ≈ {amount} de las piezas",
|
||||
"new_menu": "Nuevo",
|
||||
"dismiss": "Descartar",
|
||||
"gs_label": "Primeros pasos: estas sugerencias desaparecen a medida que crece tu configuración",
|
||||
"gs_setups_chip": "Configuraciones sugeridas: {n} dispositivos con disparadores preconfigurados",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Lataa uudelleen",
|
||||
"battery_fleet_forecast_overdue": "Ennustettu päivä on ohitettu — akku ilmoittaa yhä hyvästä kunnosta. Jos vaihdoit sen, kirjaa vaihto; muuten ennuste oli pielessä.",
|
||||
"cost_from_parts": "Käytä ≈ {amount} osista",
|
||||
"new_menu": "Uusi",
|
||||
"dismiss": "Hylkää",
|
||||
"gs_label": "Aloitus — nämä vihjeet poistuvat asennuksen kasvaessa",
|
||||
"gs_setups_chip": "Ehdotetut asetukset löysivät {n} laitetta valmiilla laukaisimilla",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Recharger",
|
||||
"battery_fleet_forecast_overdue": "Date prévue dépassée — la batterie se signale toujours en bon état. Si vous l'avez remplacée, enregistrez le remplacement ; sinon la prévision était erronée.",
|
||||
"cost_from_parts": "Reprendre ≈ {amount} des pièces",
|
||||
"new_menu": "Nouveau",
|
||||
"dismiss": "Ignorer",
|
||||
"gs_label": "Premiers pas — ces conseils disparaissent à mesure que votre configuration grandit",
|
||||
"gs_setups_chip": "Configurations suggérées : {n} appareils avec déclencheurs pré-câblés trouvés",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "पुनः लोड करें",
|
||||
"battery_fleet_forecast_overdue": "अनुमानित तिथि बीत गई — बैटरी अब भी अच्छी स्थिति बता रही है। यदि आपने इसे बदला है, तो बदलाव दर्ज करें; अन्यथा पूर्वानुमान गलत था।",
|
||||
"cost_from_parts": "पुर्ज़ों से ≈ {amount} लें",
|
||||
"new_menu": "नया",
|
||||
"dismiss": "हटाएँ",
|
||||
"gs_label": "शुरुआत — सेटअप बढ़ने पर ये संकेत हट जाते हैं",
|
||||
"gs_setups_chip": "सुझाए गए सेटअप: पूर्व-निर्धारित ट्रिगर वाले {n} उपकरण मिले",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Újratöltés",
|
||||
"battery_fleet_forecast_overdue": "Az előrejelzett dátum elmúlt — az elem továbbra is jó állapotot jelez. Ha kicserélted, rögzítsd a cserét; különben az előrejelzés tévedett.",
|
||||
"cost_from_parts": "≈ {amount} átvétele az alkatrészekből",
|
||||
"new_menu": "Új",
|
||||
"dismiss": "Elrejtés",
|
||||
"gs_label": "Első lépések — a tippek eltűnnek, ahogy a beállítás bővül",
|
||||
"gs_setups_chip": "Javasolt beállítások: {n} eszköz előre bekötött triggerekkel",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Ricarica",
|
||||
"battery_fleet_forecast_overdue": "Data prevista superata — la batteria risulta ancora in buono stato. Se l'hai sostituita, registra la sostituzione; altrimenti la previsione era errata.",
|
||||
"cost_from_parts": "Usa ≈ {amount} dai ricambi",
|
||||
"new_menu": "Nuovo",
|
||||
"dismiss": "Ignora",
|
||||
"gs_label": "Primi passi — questi suggerimenti scompaiono man mano che la configurazione cresce",
|
||||
"gs_setups_chip": "Configurazioni suggerite: trovati {n} dispositivi con trigger preconfigurati",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "再読み込み",
|
||||
"battery_fleet_forecast_overdue": "予測日を過ぎましたが、電池はまだ正常と報告しています。交換済みなら交換を記録してください。そうでなければ予測が外れています。",
|
||||
"cost_from_parts": "部品から ≈ {amount} を適用",
|
||||
"new_menu": "新規",
|
||||
"dismiss": "閉じる",
|
||||
"gs_label": "はじめに — セットアップが進むとこれらのヒントは消えます",
|
||||
"gs_setups_chip": "推奨セットアップ:トリガー設定済みのデバイスを{n}台検出",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "새로 고침",
|
||||
"battery_fleet_forecast_overdue": "예측 날짜가 지났지만 배터리는 여전히 정상으로 보고됩니다. 교체했다면 교체를 기록하세요. 아니라면 예측이 빗나간 것입니다.",
|
||||
"cost_from_parts": "부품에서 ≈ {amount} 적용",
|
||||
"new_menu": "새로 만들기",
|
||||
"dismiss": "닫기",
|
||||
"gs_label": "시작하기 — 설정이 늘어나면 이 힌트는 사라집니다",
|
||||
"gs_setups_chip": "추천 설정: 트리거가 준비된 기기 {n}대 발견",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Last inn på nytt",
|
||||
"battery_fleet_forecast_overdue": "Forutsagt dato er passert — batteriet melder fortsatt god tilstand. Hvis du byttet det, registrer byttet; ellers bommet prognosen.",
|
||||
"cost_from_parts": "Bruk ≈ {amount} fra deler",
|
||||
"new_menu": "Ny",
|
||||
"dismiss": "Avvis",
|
||||
"gs_label": "Kom i gang — tipsene forsvinner etter hvert som oppsettet vokser",
|
||||
"gs_setups_chip": "Foreslåtte oppsett fant {n} enheter med ferdigkoblede utløsere",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Herladen",
|
||||
"battery_fleet_forecast_overdue": "Voorspelde datum verstreken — de batterij meldt zich nog steeds gezond. Heb je hem vervangen, registreer dan de vervanging; anders zat de voorspelling ernaast.",
|
||||
"cost_from_parts": "≈ {amount} uit onderdelen overnemen",
|
||||
"new_menu": "Nieuw",
|
||||
"dismiss": "Verbergen",
|
||||
"gs_label": "Aan de slag — deze tips verdwijnen naarmate je installatie groeit",
|
||||
"gs_setups_chip": "Voorgestelde setups: {n} apparaten met vooraf ingestelde triggers gevonden",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Załaduj ponownie",
|
||||
"battery_fleet_forecast_overdue": "Przewidywana data minęła — bateria nadal zgłasza dobry stan. Jeśli ją wymieniono, zapisz wymianę; w przeciwnym razie prognoza była błędna.",
|
||||
"cost_from_parts": "Użyj ≈ {amount} z części",
|
||||
"new_menu": "Nowy",
|
||||
"dismiss": "Odrzuć",
|
||||
"gs_label": "Pierwsze kroki — te wskazówki znikają wraz z rozwojem konfiguracji",
|
||||
"gs_setups_chip": "Sugerowane konfiguracje: znaleziono {n} urządzeń z gotowymi wyzwalaczami",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Recarregar",
|
||||
"battery_fleet_forecast_overdue": "Data prevista ultrapassada — a bateria ainda reporta bom estado. Se você a trocou, registre a troca; caso contrário, a previsão errou.",
|
||||
"cost_from_parts": "Usar ≈ {amount} das peças",
|
||||
"new_menu": "Novo",
|
||||
"dismiss": "Dispensar",
|
||||
"gs_label": "Primeiros passos — estas dicas somem conforme a configuração cresce",
|
||||
"gs_setups_chip": "Configurações sugeridas: {n} dispositivos com gatilhos pré-configurados",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Recarregar",
|
||||
"battery_fleet_forecast_overdue": "Data prevista ultrapassada — a bateria continua a reportar bom estado. Se a substituiu, registe a substituição; caso contrário, a previsão falhou.",
|
||||
"cost_from_parts": "Usar ≈ {amount} das peças",
|
||||
"new_menu": "Novo",
|
||||
"dismiss": "Dispensar",
|
||||
"gs_label": "Primeiros passos — estas dicas desaparecem à medida que a configuração cresce",
|
||||
"gs_setups_chip": "Configurações sugeridas: {n} dispositivos com gatilhos pré-configurados",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Перезагрузить",
|
||||
"battery_fleet_forecast_overdue": "Прогнозируемая дата прошла — батарея по-прежнему сообщает о хорошем состоянии. Если вы её заменили, зафиксируйте замену; иначе прогноз оказался неверным.",
|
||||
"cost_from_parts": "Взять ≈ {amount} из запчастей",
|
||||
"new_menu": "Создать",
|
||||
"dismiss": "Скрыть",
|
||||
"gs_label": "Первые шаги — эти подсказки исчезнут по мере роста настройки",
|
||||
"gs_setups_chip": "Рекомендуемые настройки: найдено {n} устройств с готовыми триггерами",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Ladda om",
|
||||
"battery_fleet_forecast_overdue": "Förutsagt datum har passerat — batteriet rapporterar fortfarande god status. Om du bytte det, registrera bytet; annars slog prognosen fel.",
|
||||
"cost_from_parts": "Använd ≈ {amount} från delar",
|
||||
"new_menu": "Ny",
|
||||
"dismiss": "Avfärda",
|
||||
"gs_label": "Kom igång — tipsen försvinner när din installation växer",
|
||||
"gs_setups_chip": "Föreslagna uppsättningar hittade {n} enheter med förkopplade utlösare",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Yeniden yükle",
|
||||
"battery_fleet_forecast_overdue": "Öngörülen tarih geçti — pil hâlâ sağlıklı görünüyor. Değiştirdiyseniz değişimi kaydedin; aksi halde tahmin yanılmış demektir.",
|
||||
"cost_from_parts": "Parçalardan ≈ {amount} kullan",
|
||||
"new_menu": "Yeni",
|
||||
"dismiss": "Kapat",
|
||||
"gs_label": "Başlarken — kurulumunuz büyüdükçe bu ipuçları kaybolur",
|
||||
"gs_setups_chip": "Önerilen kurulumlar {n} cihaz buldu (hazır tetikleyicilerle)",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "Перезавантажити",
|
||||
"battery_fleet_forecast_overdue": "Прогнозована дата минула — батарея й далі повідомляє про добрий стан. Якщо ви її замінили, зафіксуйте заміну; інакше прогноз не справдився.",
|
||||
"cost_from_parts": "Узяти ≈ {amount} із запчастин",
|
||||
"new_menu": "Створити",
|
||||
"dismiss": "Приховати",
|
||||
"gs_label": "Перші кроки — ці підказки зникнуть у міру зростання налаштування",
|
||||
"gs_setups_chip": "Рекомендовані налаштування: знайдено {n} пристроїв із готовими тригерами",
|
||||
|
||||
@@ -836,7 +836,6 @@
|
||||
"update_reload": "重新加载",
|
||||
"battery_fleet_forecast_overdue": "预测日期已过——电池仍报告状态良好。如果您已更换电池,请记录更换;否则说明预测有误。",
|
||||
"cost_from_parts": "采用配件合计 ≈ {amount}",
|
||||
"new_menu": "新建",
|
||||
"dismiss": "忽略",
|
||||
"gs_label": "入门提示——随着配置的完善,这些提示会自动消失",
|
||||
"gs_setups_chip": "推荐配置发现 {n} 台设备(含预设触发器)",
|
||||
|
||||
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.54.0 */
|
||||
var S="2.54.0";var l="maintenance-supporter",T=`ll-strategy-dashboard-${l}`,D="hui-maintenance-supporter-strategy-editor",C=`/maintenance_supporter_strategy/maintenance-dashboard-strategy.js?v=${S}`,m=null;function v(){return m||(m=import(C)),m}async function I(){let r=await v();if(!r.MaintenanceDashboardStrategy)throw new Error("[maintenance-supporter] strategy bundle loaded but did not export MaintenanceDashboardStrategy");return r.MaintenanceDashboardStrategy}var p=class extends HTMLElement{static getCreateSuggestions(c){return{title:"Maintenance Supporter",icon:"mdi:wrench-clock"}}static async getConfigElement(){return await v(),document.createElement(D)}static async generate(c,f){return(await I()).generate(c,f)}};function M(){try{customElements.define(T,p)}catch{}}M();var w=window;w.customStrategies=w.customStrategies||[];w.customStrategies.some(r=>r.type===l&&r.strategyType==="dashboard")||w.customStrategies.push({type:l,strategyType:"dashboard",name:"Maintenance Supporter",description:"Auto-generated dashboard. Group views by area, status, floor, or due date \u2014 picked from the strategy editor or YAML.",documentationURL:"https://github.com/iluebbe/maintenance_supporter#dashboard-strategy"});(()=>{let r=window;if(r.__msStrategyHealActive)return;r.__msStrategyHealActive=!0;let c=/^\/(auth|config|developer-tools|profile|hassio|history|logbook|map|media-browser|energy|todo|calendar)\b/,f=/Timeout waiting for strategy element ll-strategy-(dashboard-)?maintenance-supporter/i,g=`custom:${l}`;function R(a){let t=[document.documentElement],n=0;for(;t.length&&n<9e3;){let o=t.pop();if(n++,!o)continue;let e=o;if(e.nodeType===1&&e.tagName&&e.tagName.toLowerCase()===a)return e;e.shadowRoot&&t.push(e.shadowRoot);let i=o.children;if(i)for(let d of Array.from(i))t.push(d)}return null}function k(a){let t=a?.views;if(!Array.isArray(t)||!t.length)return null;let n=window.location.pathname.split("/").filter(Boolean).pop()||"",o=t.find(i=>i?.path===n);if(o)return o;let e=Number(n);return Number.isInteger(e)&&t[e]?t[e]:t[0]}function b(){try{let t=R("ha-panel-lovelace")?.lovelace;if(!t)return!1;let n=o=>o?.type;for(let o of[t.config,t.rawConfig]){if(!o)continue;if(n(o.strategy)===g)return!0;let e=k(o);if(e&&n(e.strategy)===g)return!0}return!1}catch{return!1}}function A(){let a=!1,t=0,n=!1,o=!1,e=[document.documentElement],i=0;for(;e.length&&i<9e3;){let d=e.pop();if(i++,!d)continue;let u=d;if(u.nodeType===1&&u.tagName){let s=u.tagName.toLowerCase();(s==="hui-view"||s==="hui-sections-view")&&(a=!0),(s==="ha-card"||s==="hui-card")&&t++,s==="hui-empty-state-card"&&(o=!0),s==="hui-error-card"&&f.test(u.textContent||"")&&(n=!0)}u.shadowRoot&&e.push(u.shadowRoot);let E=d.children;if(E)for(let s of Array.from(E))e.push(s)}return n?!0:o?!1:a&&t<3&&b()}let N="/maintenance_supporter_strategy_shim.js",y=0,_=0;function L(){let a=Date.now();a-_<5e3||y>=3||(_=a,y+=1,import(`${N}?heal=${a}`).catch(()=>{}).finally(()=>{let t=window.location.pathname+window.location.search;history.pushState(null,"","/lovelace"),window.dispatchEvent(new CustomEvent("location-changed")),window.setTimeout(()=>{history.pushState(null,"",t),window.dispatchEvent(new CustomEvent("location-changed"))},200)}))}function h(){if(c.test(window.location.pathname))return;let a=0,t=Date.now(),n=window.setInterval(()=>{a++;try{if(Date.now()-t<6e3)return;if(c.test(window.location.pathname)){window.clearInterval(n);return}A()?L():window.clearInterval(n),a>=30&&window.clearInterval(n)}catch{window.clearInterval(n)}},500)}try{document.readyState==="loading"?window.addEventListener("DOMContentLoaded",h):h(),window.addEventListener("location-changed",()=>{c.test(window.location.pathname)||h()})}catch{}})();
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
var S="2.55.0";var l="maintenance-supporter",T=`ll-strategy-dashboard-${l}`,D="hui-maintenance-supporter-strategy-editor",C=`/maintenance_supporter_strategy/maintenance-dashboard-strategy.js?v=${S}`,m=null;function v(){return m||(m=import(C)),m}async function I(){let r=await v();if(!r.MaintenanceDashboardStrategy)throw new Error("[maintenance-supporter] strategy bundle loaded but did not export MaintenanceDashboardStrategy");return r.MaintenanceDashboardStrategy}var p=class extends HTMLElement{static getCreateSuggestions(c){return{title:"Maintenance Supporter",icon:"mdi:wrench-clock"}}static async getConfigElement(){return await v(),document.createElement(D)}static async generate(c,f){return(await I()).generate(c,f)}};function M(){try{customElements.define(T,p)}catch{}}M();var w=window;w.customStrategies=w.customStrategies||[];w.customStrategies.some(r=>r.type===l&&r.strategyType==="dashboard")||w.customStrategies.push({type:l,strategyType:"dashboard",name:"Maintenance Supporter",description:"Auto-generated dashboard. Group views by area, status, floor, or due date \u2014 picked from the strategy editor or YAML.",documentationURL:"https://github.com/iluebbe/maintenance_supporter#dashboard-strategy"});(()=>{let r=window;if(r.__msStrategyHealActive)return;r.__msStrategyHealActive=!0;let c=/^\/(auth|config|developer-tools|profile|hassio|history|logbook|map|media-browser|energy|todo|calendar)\b/,f=/Timeout waiting for strategy element ll-strategy-(dashboard-)?maintenance-supporter/i,g=`custom:${l}`;function R(a){let t=[document.documentElement],n=0;for(;t.length&&n<9e3;){let o=t.pop();if(n++,!o)continue;let e=o;if(e.nodeType===1&&e.tagName&&e.tagName.toLowerCase()===a)return e;e.shadowRoot&&t.push(e.shadowRoot);let i=o.children;if(i)for(let d of Array.from(i))t.push(d)}return null}function k(a){let t=a?.views;if(!Array.isArray(t)||!t.length)return null;let n=window.location.pathname.split("/").filter(Boolean).pop()||"",o=t.find(i=>i?.path===n);if(o)return o;let e=Number(n);return Number.isInteger(e)&&t[e]?t[e]:t[0]}function b(){try{let t=R("ha-panel-lovelace")?.lovelace;if(!t)return!1;let n=o=>o?.type;for(let o of[t.config,t.rawConfig]){if(!o)continue;if(n(o.strategy)===g)return!0;let e=k(o);if(e&&n(e.strategy)===g)return!0}return!1}catch{return!1}}function A(){let a=!1,t=0,n=!1,o=!1,e=[document.documentElement],i=0;for(;e.length&&i<9e3;){let d=e.pop();if(i++,!d)continue;let u=d;if(u.nodeType===1&&u.tagName){let s=u.tagName.toLowerCase();(s==="hui-view"||s==="hui-sections-view")&&(a=!0),(s==="ha-card"||s==="hui-card")&&t++,s==="hui-empty-state-card"&&(o=!0),s==="hui-error-card"&&f.test(u.textContent||"")&&(n=!0)}u.shadowRoot&&e.push(u.shadowRoot);let E=d.children;if(E)for(let s of Array.from(E))e.push(s)}return n?!0:o?!1:a&&t<3&&b()}let N="/maintenance_supporter_strategy_shim.js",y=0,_=0;function L(){let a=Date.now();a-_<5e3||y>=3||(_=a,y+=1,import(`${N}?heal=${a}`).catch(()=>{}).finally(()=>{let t=window.location.pathname+window.location.search;history.pushState(null,"","/lovelace"),window.dispatchEvent(new CustomEvent("location-changed")),window.setTimeout(()=>{history.pushState(null,"",t),window.dispatchEvent(new CustomEvent("location-changed"))},200)}))}function h(){if(c.test(window.location.pathname))return;let a=0,t=Date.now(),n=window.setInterval(()=>{a++;try{if(Date.now()-t<6e3)return;if(c.test(window.location.pathname)){window.clearInterval(n);return}A()?L():window.clearInterval(n),a>=30&&window.clearInterval(n)}catch{window.clearInterval(n)}},500)}try{document.readyState==="loading"?window.addEventListener("DOMContentLoaded",h):h(),window.addEventListener("location-changed",()=>{c.test(window.location.pathname)||h()})}catch{}})();
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.53.0 */
|
||||
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-MEKM6THN.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-URNT5464.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-4MVSRJ3Y.js";var r=class extends h{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._users=[];this._responsible="";this._localeReady=!1;this._userService=null;this._toggle=s=>{let o=new Set(this._selected);o.has(s)?o.delete(s):o.add(s),this._selected=o};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(s=>s.entity_id))};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let s=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:e.suggested_entry_id??void 0,object_name:e.suggested_object_name,device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0})),o=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/adopt",selections:s});this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:o})),this._open=!1}catch(s){this._error=d(s,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,v(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._sensors=[],this._selected=new Set,this._responsible="";try{this._userService?this._userService.updateHass(this.hass):this._userService=new u(this.hass);let[s,o]=await Promise.all([this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/discover"}),this._userService.getUsers().catch(()=>[])]);this._sensors=s.sensors||[],this._selected=new Set(this._sensors.map(e=>e.entity_id)),this._users=o}catch(s){this._error=d(s,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return t``;let s=this._lang,o=this._sensors.length>0&&this._selected.size===this._sensors.length;return t`
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6RMRSFSY.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,p as v}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var r=class extends h{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._users=[];this._responsible="";this._localeReady=!1;this._userService=null;this._toggle=s=>{let o=new Set(this._selected);o.has(s)?o.delete(s):o.add(s),this._selected=o};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(s=>s.entity_id))};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let s=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:e.suggested_entry_id??void 0,object_name:e.suggested_object_name,device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0})),o=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/adopt",selections:s});this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:o})),this._open=!1}catch(s){this._error=d(s,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,v(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._sensors=[],this._selected=new Set,this._responsible="";try{this._userService?this._userService.updateHass(this.hass):this._userService=new u(this.hass);let[s,o]=await Promise.all([this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/discover"}),this._userService.getUsers().catch(()=>[])]);this._sensors=s.sensors||[],this._selected=new Set(this._sensors.map(e=>e.entity_id)),this._users=o}catch(s){this._error=d(s,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return t``;let s=this._lang,o=this._sensors.length>0&&this._selected.size===this._sensors.length;return t`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||
<div class="title">${i("adopt_problem_title",s)}</div>
|
||||
-222
@@ -1,222 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.54.0 */
|
||||
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-WZ6RLKNK.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-A7WM72WE.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-C2ERU424.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};
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.53.0 */
|
||||
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4MVSRJ3Y.js";function _(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let t=!!e.entry_id&&e.entry_id!==r,a=t?e.entry_id:r,o=s.find(p=>p.entry_id===a),n=(o?.parts||[]).find(p=>p.id===e.part_id)||null,d=t&&o?.object?.name||"",i=n?.name||u("shared_part_unknown",c);return{part:n,foreign:t,ownerName:d,label:d?`${i} (${d})`:i}}function f(e,r,s,c){let{part:t,label:a}=l(e,r,s,c),o=t&&t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:"",n=t?.storage_location?` \u2014 ${t.storage_location}`:"";return`${e.quantity}\xD7 ${a}${o}${n}`}function g(e,r,s,c){let a=(s.find(n=>n.entry_id===r)?.parts||[]).map(n=>({...n})),o=new Set(a.map(n=>_({part_id:n.id})));for(let n of e?.consumes_parts||[]){if(!n.entry_id||n.entry_id===r)continue;let d=_(n);if(o.has(d))continue;o.add(d);let{part:i,ownerName:p}=l(n,r,s,c);a.push({id:n.part_id,name:i?.name||u("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:n.entry_id,owner_name:p})}return a}export{_ as a,f as b,g as c};
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";function _(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let t=!!e.entry_id&&e.entry_id!==r,a=t?e.entry_id:r,o=s.find(p=>p.entry_id===a),n=(o?.parts||[]).find(p=>p.id===e.part_id)||null,d=t&&o?.object?.name||"",i=n?.name||u("shared_part_unknown",c);return{part:n,foreign:t,ownerName:d,label:d?`${i} (${d})`:i}}function f(e,r,s,c){let{part:t,label:a}=l(e,r,s,c),o=t&&t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:"",n=t?.storage_location?` \u2014 ${t.storage_location}`:"";return`${e.quantity}\xD7 ${a}${o}${n}`}function g(e,r,s,c){let a=(s.find(n=>n.entry_id===r)?.parts||[]).map(n=>({...n})),o=new Set(a.map(n=>_({part_id:n.id})));for(let n of e?.consumes_parts||[]){if(!n.entry_id||n.entry_id===r)continue;let d=_(n);if(o.has(d))continue;o.add(d);let{part:i,ownerName:p}=l(n,r,s,c);a.push({id:n.part_id,name:i?.name||u("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:n.entry_id,owner_name:p})}return a}export{_ as a,f as b,g as c};
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.54.0 */
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
var r=class{constructor(s){this.usersCache=null;this.cacheTimestamp=0;this.CACHE_TTL_MS=6e4;this.hass=s}updateHass(s){this.hass=s}async getUsers(s=!1){let e=Date.now();if(!s&&this.usersCache&&e-this.cacheTimestamp<this.CACHE_TTL_MS)return this.usersCache;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/users/list"});return this.usersCache=t.users,this.cacheTimestamp=e,this.usersCache}catch(t){return console.error("Failed to fetch users:",t),this.usersCache||[]}}async assignUser(s,e,t){await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/assign_user",entry_id:s,task_id:e,user_id:t})}async getTasksByUser(s){return(await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/tasks/by_user",user_id:s})).tasks}getUserName(s){return!s||!this.usersCache?null:this.usersCache.find(t=>t.id===s)?.name||null}getUser(s){return!s||!this.usersCache?null:this.usersCache.find(e=>e.id===s)||null}getCurrentUserId(){return this.hass.user?.id||null}isCurrentUser(s){return s?s===this.getCurrentUserId():!1}clearCache(){this.usersCache=null,this.cacheTimestamp=0}};export{r as a};
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.53.0 */
|
||||
/*! maintenance_supporter frontend 2.55.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,54 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.54.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-C2ERU424.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);
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.53.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-4MVSRJ3Y.js";var e=class extends p{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1}_onInput(n){let o=n.target.value;this.value=o,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:o}}))}render(){return i`
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as t,b as a,c as i,f as l,g as p,i as r}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var e=class extends p{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1}_onInput(n){let o=n.target.value;this.value=o,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:o}}))}render(){return i`
|
||||
<label class="field">
|
||||
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:l}</span>`:l}
|
||||
<input
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.54.0 */
|
||||
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C2ERU424.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};
|
||||
+2
-2
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.54.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 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.54.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.53.0 */
|
||||
var r=class{constructor(s){this.usersCache=null;this.cacheTimestamp=0;this.CACHE_TTL_MS=6e4;this.hass=s}updateHass(s){this.hass=s}async getUsers(s=!1){let e=Date.now();if(!s&&this.usersCache&&e-this.cacheTimestamp<this.CACHE_TTL_MS)return this.usersCache;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/users/list"});return this.usersCache=t.users,this.cacheTimestamp=e,this.usersCache}catch(t){return console.error("Failed to fetch users:",t),this.usersCache||[]}}async assignUser(s,e,t){await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/assign_user",entry_id:s,task_id:e,user_id:t})}async getTasksByUser(s){return(await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/tasks/by_user",user_id:s})).tasks}getUserName(s){return!s||!this.usersCache?null:this.usersCache.find(t=>t.id===s)?.name||null}getUser(s){return!s||!this.usersCache?null:this.usersCache.find(e=>e.id===s)||null}getCurrentUserId(){return this.hass.user?.id||null}isCurrentUser(s){return s?s===this.getCurrentUserId():!1}clearCache(){this.usersCache=null,this.cacheTimestamp=0}};export{r as a};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.54.0 */
|
||||
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C2ERU424.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};
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.53.0 */
|
||||
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4MVSRJ3Y.js";var s={name:"name",task_type:"maintenance_type",schedule_type:"schedule_type",interval_days:"interval_days",interval_anchor:"interval_anchor",warning_days:"warning_days",last_performed:"last_performed_optional",notes:"notes_optional",documentation_url:"documentation_url_optional",custom_icon:"custom_icon_optional",nfc_tag_id:"nfc_tag_id_optional",responsible_user_id:"responsible_user",entity_slug:"entity_slug",entity_id:"entity_id",area_id:"area_id_optional",manufacturer:"manufacturer_optional",model:"model_optional",serial_number:"serial_number_optional",installation_date:"installation_date_optional",warranty_expiry:"warranty_expiry_optional",checklist:"checklist_steps_optional",reason:"reason",feedback:"feedback",cost:"cost",duration:"duration",description:"description_optional",group_name:"name",group_description:"description_optional",environmental_entity:"environmental_entity_optional",environmental_attribute:"environmental_attribute_optional",trigger_above:"trigger_above",trigger_below:"trigger_below",trigger_for_minutes:"trigger_for_minutes"};function c(r,o){let e=s[r];if(!e)return r;let t=a(e,o);return t&&t!==e?t:r}function d(r){let e=r.match(/data\['([^']+)'\]/)?.[1],t;return(t=r.match(/length of value must be at most (\d+)/))?{field:e,rule:"too_long",param:t[1]}:(t=r.match(/length of value must be at least (\d+)/))?{field:e,rule:"too_short",param:t[1]}:(t=r.match(/value must be at most (\S+)/))?{field:e,rule:"value_too_high",param:t[1]}:(t=r.match(/value must be at least (\S+)/))?{field:e,rule:"value_too_low",param:t[1]}:/required key not provided/.test(r)?{field:e,rule:"required"}:(t=r.match(/expected (\w+)/))?{field:e,rule:"wrong_type",param:t[1]}:/value must be one of/.test(r)?{field:e,rule:"invalid_choice"}:/not a valid value/.test(r)?{field:e,rule:"invalid_value"}:{field:e,rule:"unknown"}}function g(r,o,e){if(e=e??a("action_error",o),typeof r=="string")return r;if(typeof r!="object"||r===null)return e;let t=r,_=t.message||t.error?.message||"";if(!_)return e;let i=d(_),l=i.field?c(i.field,o):"",n=u=>a(u,o).replace("{field}",l).replace("{n}",i.param??"");switch(i.rule){case"too_long":return n("err_too_long");case"too_short":return n("err_too_short");case"value_too_high":return n("err_value_too_high");case"value_too_low":return n("err_value_too_low");case"required":return n("err_required");case"wrong_type":return n("err_wrong_type").replace("{type}",i.param??"");case"invalid_choice":return n("err_invalid_choice");case"invalid_value":return n("err_invalid_value");default:return _||e}}export{g as a};
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var s={name:"name",task_type:"maintenance_type",schedule_type:"schedule_type",interval_days:"interval_days",interval_anchor:"interval_anchor",warning_days:"warning_days",last_performed:"last_performed_optional",notes:"notes_optional",documentation_url:"documentation_url_optional",custom_icon:"custom_icon_optional",nfc_tag_id:"nfc_tag_id_optional",responsible_user_id:"responsible_user",entity_slug:"entity_slug",entity_id:"entity_id",area_id:"area_id_optional",manufacturer:"manufacturer_optional",model:"model_optional",serial_number:"serial_number_optional",installation_date:"installation_date_optional",warranty_expiry:"warranty_expiry_optional",checklist:"checklist_steps_optional",reason:"reason",feedback:"feedback",cost:"cost",duration:"duration",description:"description_optional",group_name:"name",group_description:"description_optional",environmental_entity:"environmental_entity_optional",environmental_attribute:"environmental_attribute_optional",trigger_above:"trigger_above",trigger_below:"trigger_below",trigger_for_minutes:"trigger_for_minutes"};function c(r,o){let e=s[r];if(!e)return r;let t=a(e,o);return t&&t!==e?t:r}function d(r){let e=r.match(/data\['([^']+)'\]/)?.[1],t;return(t=r.match(/length of value must be at most (\d+)/))?{field:e,rule:"too_long",param:t[1]}:(t=r.match(/length of value must be at least (\d+)/))?{field:e,rule:"too_short",param:t[1]}:(t=r.match(/value must be at most (\S+)/))?{field:e,rule:"value_too_high",param:t[1]}:(t=r.match(/value must be at least (\S+)/))?{field:e,rule:"value_too_low",param:t[1]}:/required key not provided/.test(r)?{field:e,rule:"required"}:(t=r.match(/expected (\w+)/))?{field:e,rule:"wrong_type",param:t[1]}:/value must be one of/.test(r)?{field:e,rule:"invalid_choice"}:/not a valid value/.test(r)?{field:e,rule:"invalid_value"}:{field:e,rule:"unknown"}}function g(r,o,e){if(e=e??a("action_error",o),typeof r=="string")return r;if(typeof r!="object"||r===null)return e;let t=r,_=t.message||t.error?.message||"";if(!_)return e;let i=d(_),l=i.field?c(i.field,o):"",n=u=>a(u,o).replace("{field}",l).replace("{n}",i.param??"");switch(i.rule){case"too_long":return n("err_too_long");case"too_short":return n("err_too_short");case"value_too_high":return n("err_value_too_high");case"value_too_low":return n("err_value_too_low");case"required":return n("err_required");case"wrong_type":return n("err_wrong_type").replace("{type}",i.param??"");case"invalid_choice":return n("err_invalid_choice");case"invalid_value":return n("err_invalid_value");default:return _||e}}export{g as a};
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.53.0 */
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
var i=[{key:"name",labelKey:"name",required:!0},{key:"manufacturer",labelKey:"manufacturer"},{key:"model",labelKey:"model"},{key:"serial_number",labelKey:"serial_number_label"},{key:"installation_date",labelKey:"installed"},{key:"warranty_expiry",labelKey:"warranty"},{key:"area_id",labelKey:"area"},{key:"documentation_url",labelKey:"documentation_url_label"},{key:"notes",labelKey:"object_notes_label"},{key:"task_count",labelKey:"tasks"},{key:"actions",labelKey:"actions"}],s=i.map(n=>n.key),l=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function c(n){if(!Array.isArray(n))return[...l];let o=new Set,e=[];for(let a of n)typeof a=="string"&&s.includes(a)&&!o.has(a)&&(o.add(a),e.push(a));return e.length?(e.includes("name")||e.unshift("name"),e):[...l]}function u(n,o,e){let a=new Blob([n],{type:e}),r=URL.createObjectURL(a),t=document.createElement("a");t.href=r,t.download=o,t.target="_blank",t.rel="noopener",t.style.display="none",document.body.appendChild(t),t.dispatchEvent(new MouseEvent("click")),document.body.removeChild(t),setTimeout(()=>URL.revokeObjectURL(r),6e4)}function y(n,o){let e=document.createElement("a");e.href=n,e.download=o,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}export{i as a,l as b,c,u as d,y as e};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.54.0 */
|
||||
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TLH3CQAL.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-KH7UXWPC.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-WZ6RLKNK.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-C2ERU424.js";var i=class extends v{constructor(){super(...arguments);this.entryId="";this.taskId="";this.taskName="";this.lang="en";this.checklist=[];this.adaptiveEnabled=!1;this.taskType="";this.readingUnit="";this.restockDefault=null;this.restockUnitCost=null;this.currencySymbol="";this.parts=[];this.consumesParts=[];this.consumesInfo=[];this.requiredFields=[];this._open=!1;this._notes="";this._cost="";this._duration="";this._loading=!1;this._error="";this._checklistState={};this._feedback="needed";this._photoDocId="";this._photoPreview="";this._photoUploading=!1;this._readingValue="";this._restockQty="";this._usedParts={};this.checklistPrefill={}}open(){this._open||(this._open=!0,this._notes="",this._cost="",this._duration="",this._error="",this._checklistState=Object.fromEntries(this.checklist.map((e,t)=>[String(t),!!this.checklistPrefill[e]]).filter(([,e])=>e)),this._feedback="needed",this._photoDocId="",this._photoPreview="",this._photoUploading=!1,this._readingValue="",this._restockQty=this.restockDefault!==null?String(this.restockDefault):"",this._usedParts=Object.fromEntries(this.consumesParts.map(e=>[_(e),{...e}])))}_toggleCheck(e){let t=String(e);this._checklistState={...this._checklistState,[t]:!this._checklistState[t]}}_setFeedback(e){this._feedback=e}async _onPhotoInput(e){let t=e.target,o=t.files?.[0];if(t.value="",!!o){this._photoUploading=!0,this._error="";try{let c=new FormData;c.append("entry_id",this.entryId),c.append("tags","photo"),c.append("file",o,o.name);let p=await fetch("/api/maintenance_supporter/document/upload",{method:"POST",headers:{Authorization:`Bearer ${this.hass.auth?.data?.access_token??""}`},body:c});if(!p.ok){this._error=p.status===413?r("doc_too_large",this.lang):r("doc_upload_failed",this.lang);return}let u=await p.json();u.id&&(this._photoDocId=u.id,this._photoPreview=URL.createObjectURL(o))}catch{this._error=r("doc_upload_failed",this.lang)}finally{this._photoUploading=!1}}}_removePhoto(){this._photoPreview&&URL.revokeObjectURL(this._photoPreview),this._photoDocId="",this._photoPreview=""}async _complete(){this._loading=!0,this._error="";try{let e={type:"maintenance_supporter/task/complete",entry_id:this.entryId,task_id:this.taskId};if(this._notes&&(e.notes=this._notes),this._cost){let t=parseFloat(this._cost);!isNaN(t)&&t>=0&&(e.cost=t)}if(this._duration){let t=parseInt(this._duration,10);!isNaN(t)&&t>=0&&(e.duration=t)}if(this.checklist.length>0&&(e.checklist_state=this._checklistState),this.adaptiveEnabled&&(e.feedback=this._feedback),this._photoDocId&&(e.photo_doc_id=this._photoDocId),this._readingValue!==""){let t=parseFloat(this._readingValue);isNaN(t)||(e.reading_value=t)}if(this.restockDefault!==null&&this._restockQty!==""){let t=parseFloat(this._restockQty);!isNaN(t)&&t>=1&&(e.restock_quantity=t)}this.parts.length>0&&(e.used_parts=Object.values(this._usedParts).filter(t=>Number.isFinite(t.quantity)&&t.quantity>0).map(t=>t.entry_id?{part_id:t.part_id,quantity:t.quantity,entry_id:t.entry_id}:{part_id:t.part_id,quantity:t.quantity})),await this.hass.connection.sendMessagePromise(e),this._open=!1,this.dispatchEvent(new CustomEvent("task-completed"))}catch(e){this._error=g(e,this.lang,r("save_error",this.lang))}finally{this._loading=!1}}get _missingRequired(){let e={notes:this._notes.trim()!=="",cost:this._cost.trim()!=="",duration:this._duration.trim()!=="",photo:this._photoDocId!=="",user:!!this.hass?.user};return this.requiredFields.filter(t=>!e[t])}_req(e){return this.requiredFields.includes(e)?a`<span class="req-mark" aria-hidden="true">*</span>`:d}_partsCostSuggestion(){if(this.restockDefault!==null){let o=parseFloat(this._restockQty);return this.restockUnitCost==null||!Number.isFinite(o)||o<=0?null:Math.round(this.restockUnitCost*o*100)/100}if(!this.parts.length)return null;let e=0,t=!1;for(let o of Object.values(this._usedParts)){let c=this.parts.find(p=>_({part_id:p.id,entry_id:p.entry_id})===_(o));c?.cost!=null&&(e+=c.cost*(o.quantity||1),t=!0)}return t?Math.round(e*100)/100:null}_renderCostSuggestion(e){if(this._cost.trim()!=="")return d;let t=this._partsCostSuggestion();if(t==null||t<=0)return d;let o=`${t.toFixed(2)}${this.currencySymbol?` ${this.currencySymbol}`:""}`;return a`<button
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-7QFSK25W.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4HD7ODUX.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,x as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var i=class extends v{constructor(){super(...arguments);this.entryId="";this.taskId="";this.taskName="";this.lang="en";this.checklist=[];this.adaptiveEnabled=!1;this.taskType="";this.readingUnit="";this.restockDefault=null;this.restockUnitCost=null;this.currencySymbol="";this.parts=[];this.consumesParts=[];this.consumesInfo=[];this.requiredFields=[];this._open=!1;this._notes="";this._cost="";this._duration="";this._loading=!1;this._error="";this._checklistState={};this._feedback="needed";this._photoDocId="";this._photoPreview="";this._photoUploading=!1;this._readingValue="";this._restockQty="";this._usedParts={};this.checklistPrefill={}}open(){this._open||(this._open=!0,this._notes="",this._cost="",this._duration="",this._error="",this._checklistState=Object.fromEntries(this.checklist.map((e,t)=>[String(t),!!this.checklistPrefill[e]]).filter(([,e])=>e)),this._feedback="needed",this._photoDocId="",this._photoPreview="",this._photoUploading=!1,this._readingValue="",this._restockQty=this.restockDefault!==null?String(this.restockDefault):"",this._usedParts=Object.fromEntries(this.consumesParts.map(e=>[_(e),{...e}])))}_toggleCheck(e){let t=String(e);this._checklistState={...this._checklistState,[t]:!this._checklistState[t]}}_setFeedback(e){this._feedback=e}async _onPhotoInput(e){let t=e.target,o=t.files?.[0];if(t.value="",!!o){this._photoUploading=!0,this._error="";try{let c=new FormData;c.append("entry_id",this.entryId),c.append("tags","photo"),c.append("file",o,o.name);let p=await fetch("/api/maintenance_supporter/document/upload",{method:"POST",headers:{Authorization:`Bearer ${this.hass.auth?.data?.access_token??""}`},body:c});if(!p.ok){this._error=p.status===413?r("doc_too_large",this.lang):r("doc_upload_failed",this.lang);return}let u=await p.json();u.id&&(this._photoDocId=u.id,this._photoPreview=URL.createObjectURL(o))}catch{this._error=r("doc_upload_failed",this.lang)}finally{this._photoUploading=!1}}}_removePhoto(){this._photoPreview&&URL.revokeObjectURL(this._photoPreview),this._photoDocId="",this._photoPreview=""}async _complete(){this._loading=!0,this._error="";try{let e={type:"maintenance_supporter/task/complete",entry_id:this.entryId,task_id:this.taskId};if(this._notes&&(e.notes=this._notes),this._cost){let t=parseFloat(this._cost);!isNaN(t)&&t>=0&&(e.cost=t)}if(this._duration){let t=parseInt(this._duration,10);!isNaN(t)&&t>=0&&(e.duration=t)}if(this.checklist.length>0&&(e.checklist_state=this._checklistState),this.adaptiveEnabled&&(e.feedback=this._feedback),this._photoDocId&&(e.photo_doc_id=this._photoDocId),this._readingValue!==""){let t=parseFloat(this._readingValue);isNaN(t)||(e.reading_value=t)}if(this.restockDefault!==null&&this._restockQty!==""){let t=parseFloat(this._restockQty);!isNaN(t)&&t>=1&&(e.restock_quantity=t)}this.parts.length>0&&(e.used_parts=Object.values(this._usedParts).filter(t=>Number.isFinite(t.quantity)&&t.quantity>0).map(t=>t.entry_id?{part_id:t.part_id,quantity:t.quantity,entry_id:t.entry_id}:{part_id:t.part_id,quantity:t.quantity})),await this.hass.connection.sendMessagePromise(e),this._open=!1,this.dispatchEvent(new CustomEvent("task-completed"))}catch(e){this._error=g(e,this.lang,r("save_error",this.lang))}finally{this._loading=!1}}get _missingRequired(){let e={notes:this._notes.trim()!=="",cost:this._cost.trim()!=="",duration:this._duration.trim()!=="",photo:this._photoDocId!=="",user:!!this.hass?.user};return this.requiredFields.filter(t=>!e[t])}_req(e){return this.requiredFields.includes(e)?a`<span class="req-mark" aria-hidden="true">*</span>`:d}_partsCostSuggestion(){if(this.restockDefault!==null){let o=parseFloat(this._restockQty);return this.restockUnitCost==null||!Number.isFinite(o)||o<=0?null:Math.round(this.restockUnitCost*o*100)/100}if(!this.parts.length)return null;let e=0,t=!1;for(let o of Object.values(this._usedParts)){let c=this.parts.find(p=>_({part_id:p.id,entry_id:p.entry_id})===_(o));c?.cost!=null&&(e+=c.cost*(o.quantity||1),t=!0)}return t?Math.round(e*100)/100:null}_renderCostSuggestion(e){if(this._cost.trim()!=="")return d;let t=this._partsCostSuggestion();if(t==null||t<=0)return d;let o=`${t.toFixed(2)}${this.currencySymbol?` ${this.currencySymbol}`:""}`;return a`<button
|
||||
type="button"
|
||||
class="cost-suggestion"
|
||||
@click=${()=>this._cost=t.toFixed(2)}
|
||||
-292
@@ -1,292 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.53.0 */
|
||||
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4AV2K4W7.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-3FYWLAW5.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-MEKM6THN.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-4MVSRJ3Y.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};
|
||||
-143
@@ -1,143 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.54.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-AEF5ZY4E.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-WZ6RLKNK.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-C2ERU424.js";var e=class extends p{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return this.hass?.language??navigator.language.split("-")[0]??"en"}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(a,n){this._entryId=a,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(a){this._error=h(a,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(a=>a.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let a=this._lang,n=this._entryId?i("edit_object",a):i("new_object",a);return l`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${n}</div>
|
||||
<div class="content">
|
||||
${this._error?l`<div class="error">${this._error}</div>`:o}
|
||||
<ms-textfield
|
||||
label="${i("name",a)}"
|
||||
required
|
||||
.value=${this._name}
|
||||
@input=${t=>this._name=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("manufacturer_optional",a)}"
|
||||
.value=${this._manufacturer}
|
||||
@input=${t=>this._manufacturer=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("model_optional",a)}"
|
||||
.value=${this._model}
|
||||
@input=${t=>this._model=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("serial_number_optional",a)}"
|
||||
.value=${this._serialNumber}
|
||||
@input=${t=>this._serialNumber=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("documentation_url_optional",a)}"
|
||||
type="url"
|
||||
.value=${this._documentationUrl}
|
||||
@input=${t=>this._documentationUrl=t.target.value}
|
||||
></ms-textfield>
|
||||
<ha-area-picker
|
||||
.hass=${this.hass}
|
||||
label="${i("area_id_optional",a)}"
|
||||
.value=${this._areaId}
|
||||
@value-changed=${t=>this._areaId=t.detail.value||""}
|
||||
></ha-area-picker>
|
||||
<ms-textfield
|
||||
label="${i("installation_date_optional",a)}"
|
||||
type="date"
|
||||
.value=${this._installationDate}
|
||||
@input=${t=>this._installationDate=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("warranty_expiry_optional",a)}"
|
||||
type="date"
|
||||
.value=${this._warrantyExpiry}
|
||||
@input=${t=>this._warrantyExpiry=t.target.value}
|
||||
></ms-textfield>
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${{device:this._haDeviceId||void 0}}
|
||||
.schema=${[{name:"device",selector:{device:{}}}]}
|
||||
.computeLabel=${()=>i("link_device_optional",a)}
|
||||
@value-changed=${t=>this._haDeviceId=t.detail.value?.device||""}
|
||||
></ha-form>
|
||||
${this._parentChoices().length?l`<label class="textarea-field">
|
||||
<span class="textarea-label">${i("parent_object_optional",a)}</span>
|
||||
<select
|
||||
class="parent-select"
|
||||
.value=${this._parentEntryId}
|
||||
@change=${t=>this._parentEntryId=t.target.value}
|
||||
>
|
||||
<option value="" ?selected=${!this._parentEntryId}>
|
||||
${i("parent_none",a)}
|
||||
</option>
|
||||
${this._parentChoices().map(t=>l`<option
|
||||
value=${t.entry_id}
|
||||
?selected=${this._parentEntryId===t.entry_id}
|
||||
>${t.object.name}</option>`)}
|
||||
</select>
|
||||
</label>`:o}
|
||||
<label class="textarea-field">
|
||||
<span class="textarea-label">${i("object_notes_optional",a)}</span>
|
||||
<textarea
|
||||
rows="3"
|
||||
.value=${this._notes}
|
||||
@input=${t=>this._notes=t.target.value}
|
||||
></textarea>
|
||||
</label>
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${i("cancel",this._lang)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._save}
|
||||
.disabled=${this._loading||!this._name.trim()}
|
||||
>
|
||||
${this._loading?i("saving",this._lang):i("save",this._lang)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}};e.styles=_`
|
||||
.dialog-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
min-width: 300px;
|
||||
}
|
||||
.dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
ms-textfield {
|
||||
display: block;
|
||||
}
|
||||
.textarea-field {
|
||||
display: flex; flex-direction: column; gap: 4px;
|
||||
}
|
||||
.textarea-label {
|
||||
font-size: 12px; color: var(--secondary-text-color, #888); font-weight: 500;
|
||||
}
|
||||
.textarea-field textarea {
|
||||
padding: 8px 10px; font-size: 14px; font-family: inherit;
|
||||
background: var(--secondary-background-color, rgba(0,0,0,0.06));
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
resize: vertical;
|
||||
}
|
||||
.textarea-field textarea:focus {
|
||||
outline: none; border-color: var(--primary-color);
|
||||
}
|
||||
.parent-select {
|
||||
padding: 8px 10px; font-size: 14px; font-family: inherit;
|
||||
background: var(--secondary-background-color, rgba(0,0,0,0.06));
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
}
|
||||
.error {
|
||||
color: var(--error-color, #f44336);
|
||||
font-size: 13px;
|
||||
}
|
||||
`,r([d({attribute:!1})],e.prototype,"hass",2),r([d({attribute:!1})],e.prototype,"objects",2),r([s()],e.prototype,"_open",2),r([s()],e.prototype,"_loading",2),r([s()],e.prototype,"_error",2),r([s()],e.prototype,"_name",2),r([s()],e.prototype,"_manufacturer",2),r([s()],e.prototype,"_model",2),r([s()],e.prototype,"_serialNumber",2),r([s()],e.prototype,"_areaId",2),r([s()],e.prototype,"_installationDate",2),r([s()],e.prototype,"_warrantyExpiry",2),r([s()],e.prototype,"_documentationUrl",2),r([s()],e.prototype,"_notes",2),r([s()],e.prototype,"_haDeviceId",2),r([s()],e.prototype,"_parentEntryId",2),r([s()],e.prototype,"_entryId",2);customElements.get("maintenance-object-dialog")||customElements.define("maintenance-object-dialog",e);export{e as MaintenanceObjectDialog};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.53.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-6CM3ZIHM.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-MEKM6THN.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-4MVSRJ3Y.js";var e=class extends p{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return this.hass?.language??navigator.language.split("-")[0]??"en"}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(a,n){this._entryId=a,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(a){this._error=h(a,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(a=>a.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let a=this._lang,n=this._entryId?i("edit_object",a):i("new_object",a);return l`
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-BDAGEP22.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as r,b as _,c as l,f as o,g as p,i as d,j as s,n as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var e=class extends p{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return this.hass?.language??navigator.language.split("-")[0]??"en"}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(a,n){this._entryId=a,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(a){this._error=h(a,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(a=>a.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let a=this._lang,n=this._entryId?i("edit_object",a):i("new_object",a);return l`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${n}</div>
|
||||
<div class="content">
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.54.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-C2ERU424.js";function p(l){return l.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function x(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":p(l)}function $(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var r=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,o,s){this._entryId=e,this._taskId=i,this._objectName=o,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let o=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&o.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(o);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let o=i?.code,s=i?.message;this._error=o==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,o=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let h=this.lang||"en",d=p(i),u=p(o),_=!!this._completeResult,f=p(t("qr_action_view",h)),w=p(t("qr_action_complete",h));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a,b as v,c as n,f as g,g as b,i as m,j as c,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";function p(l){return l.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function x(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":p(l)}function $(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var r=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,o,s){this._entryId=e,this._taskId=i,this._objectName=o,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let o=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&o.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(o);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let o=i?.code,s=i?.message;this._error=o==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,o=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let h=this.lang||"en",d=p(i),u=p(o),_=!!this._completeResult,f=p(t("qr_action_view",h)),w=p(t("qr_action_complete",h));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
<meta name="color-scheme" content="light">
|
||||
<title>${d}</title>
|
||||
<style>
|
||||
@@ -1,213 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.53.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-4MVSRJ3Y.js";function p(l){return l.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function x(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":p(l)}function $(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var r=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,o,s){this._entryId=e,this._taskId=i,this._objectName=o,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let o=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&o.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(o);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let o=i?.code,s=i?.message;this._error=o==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,o=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let h=this.lang||"en",d=p(i),u=p(o),_=!!this._completeResult,f=p(t("qr_action_view",h)),w=p(t("qr_action_complete",h));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
<meta name="color-scheme" content="light">
|
||||
<title>${d}</title>
|
||||
<style>
|
||||
/* Printable sheet \u2014 must not inherit the phone's dark theme. The QR images
|
||||
carry their own white quiet zone and stay scannable either way, but the
|
||||
labels below are explicit dark greys and would vanish on a WebView's dark
|
||||
canvas. Same reasoning as helpers/report.ts. */
|
||||
:root{color-scheme:light}
|
||||
body{font-family:sans-serif;text-align:center;padding:20px;background:#fff;color:#1a1a1a}
|
||||
h2{margin:0 0 4px}
|
||||
.sub{color:#666;font-size:14px;margin-bottom:16px}
|
||||
.qr-row{display:flex;justify-content:center;gap:24px;margin:12px 0}
|
||||
.qr-col{display:flex;flex-direction:column;align-items:center;gap:6px}
|
||||
.qr-col img{width:${_?"200px":"280px"}}
|
||||
.qr-label{font-size:13px;font-weight:500;color:#333}
|
||||
.url{font-size:10px;color:#999;word-break:break-all;margin-top:8px;max-width:480px}
|
||||
</style></head><body>
|
||||
<h2>${d}</h2>
|
||||
${u?`<div class="sub">${u}</div>`:""}
|
||||
<div class="qr-row">
|
||||
<div class="qr-col">
|
||||
<img src="${x(this._viewResult.svg_data_uri)}" alt="QR Info" />
|
||||
<div class="qr-label">${f}</div>
|
||||
</div>
|
||||
${_?`<div class="qr-col">
|
||||
<img src="${x(this._completeResult.svg_data_uri)}" alt="QR Complete" />
|
||||
<div class="qr-label">${w}</div>
|
||||
</div>`:""}
|
||||
</div>
|
||||
<div class="url">${p(this._viewResult.url)}</div>
|
||||
<script>setTimeout(()=>window.print(),300)<\/script>
|
||||
</body></html>`),s.document.close()}_downloadSvg(e,i){let o=decodeURIComponent(e.svg_data_uri.replace("data:image/svg+xml,","")),s=new Blob([o],{type:"image/svg+xml"}),h=URL.createObjectURL(s),d=document.createElement("a");d.href=h;let u=this._taskName?`${this._objectName}-${this._taskName}`:this._objectName;d.download=`qr-${$(u)}-${i}.svg`,d.click(),URL.revokeObjectURL(h)}_close(){this._open=!1,this._viewResult=null,this._completeResult=null,this._error="",this._loading=!1}render(){if(!this._open)return n``;let e=this.lang||this.hass?.language||"en",i=this._taskName?`${t("qr_code",e)}: ${this._objectName} \u2014 ${this._taskName}`:`${t("qr_code",e)}: ${this._objectName}`,o=!!this._viewResult;return n`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${i}</div>
|
||||
<div class="content">
|
||||
${this._loading?n`<div class="loading">${t("qr_generating",e)}</div>`:this._error?n`<div class="error">${this._error}</div>`:o?n`
|
||||
<div class="qr-pair">
|
||||
<div class="qr-item">
|
||||
<img
|
||||
class="qr-image ${this._completeResult?"small":""}"
|
||||
src="${this._viewResult.svg_data_uri}"
|
||||
alt="QR Info"
|
||||
/>
|
||||
<div class="qr-item-label">${t("qr_action_view",e)}</div>
|
||||
<button class="dl-btn"
|
||||
@click=${()=>this._downloadSvg(this._viewResult,"info")}>
|
||||
<ha-icon icon="mdi:download"></ha-icon>
|
||||
${t("qr_download",e)}
|
||||
</button>
|
||||
</div>
|
||||
${this._completeResult?n`
|
||||
<div class="qr-item">
|
||||
<img
|
||||
class="qr-image small"
|
||||
src="${this._completeResult.svg_data_uri}"
|
||||
alt="QR Complete"
|
||||
/>
|
||||
<div class="qr-item-label">${t("qr_action_complete",e)}</div>
|
||||
<button class="dl-btn"
|
||||
@click=${()=>this._downloadSvg(this._completeResult,"complete")}>
|
||||
<ha-icon icon="mdi:download"></ha-icon>
|
||||
${t("qr_download",e)}
|
||||
</button>
|
||||
</div>
|
||||
`:g}
|
||||
</div>
|
||||
<div class="url-display">${this._viewResult.url}</div>
|
||||
`:g}
|
||||
<div class="action-row">
|
||||
<label>${t("qr_url_mode",e)}</label>
|
||||
<div class="action-toggle">
|
||||
<button class="toggle-btn ${this._urlMode==="companion"?"active":""}"
|
||||
@click=${()=>this._setUrlMode("companion")}>${t("qr_mode_companion",e)}</button>
|
||||
<button class="toggle-btn ${this._urlMode==="local"?"active":""}"
|
||||
@click=${()=>this._setUrlMode("local")}>${t("qr_mode_local",e)}</button>
|
||||
<button class="toggle-btn ${this._urlMode==="server"?"active":""}"
|
||||
@click=${()=>this._setUrlMode("server")}>${t("qr_mode_server",e)}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${t("cancel",e)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._print}
|
||||
.disabled=${!o}
|
||||
>
|
||||
${t("qr_print",e)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}};r.styles=v`
|
||||
.dialog-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
min-width: 300px;
|
||||
}
|
||||
.dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
.qr-pair {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
.qr-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.qr-image {
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
.qr-image.small {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
}
|
||||
.qr-item-label {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--secondary-text-color);
|
||||
text-align: center;
|
||||
}
|
||||
.dl-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
background: none;
|
||||
border: 1px solid var(--divider-color, #e0e0e0);
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--primary-text-color);
|
||||
padding: 6px 14px;
|
||||
border-radius: 18px;
|
||||
transition: background 0.2s, border-color 0.2s;
|
||||
}
|
||||
.dl-btn:hover {
|
||||
background: var(--secondary-background-color, #f5f5f5);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
.dl-btn ha-icon {
|
||||
--mdc-icon-size: 18px;
|
||||
}
|
||||
.url-display {
|
||||
font-size: 11px;
|
||||
color: var(--secondary-text-color);
|
||||
word-break: break-all;
|
||||
text-align: center;
|
||||
max-width: 400px;
|
||||
}
|
||||
.loading {
|
||||
padding: 40px 0;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.error {
|
||||
padding: 20px 0;
|
||||
color: var(--error-color, #f44336);
|
||||
}
|
||||
.action-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
}
|
||||
.action-row label {
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.action-toggle {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
background: var(--divider-color, #e0e0e0);
|
||||
border-radius: 6px;
|
||||
padding: 3px;
|
||||
}
|
||||
.toggle-btn {
|
||||
flex: 1;
|
||||
padding: 8px 12px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--primary-text-color);
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
transition: all 0.2s;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.toggle-btn:hover {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.toggle-btn.active {
|
||||
background: var(--primary-color);
|
||||
color: var(--text-primary-color, #fff);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
`,a([m({attribute:!1})],r.prototype,"hass",2),a([m()],r.prototype,"lang",2),a([c()],r.prototype,"_open",2),a([c()],r.prototype,"_loading",2),a([c()],r.prototype,"_error",2),a([c()],r.prototype,"_viewResult",2),a([c()],r.prototype,"_completeResult",2),a([c()],r.prototype,"_urlMode",2);customElements.get("maintenance-qr-dialog")||customElements.define("maintenance-qr-dialog",r);export{r as MaintenanceQrDialog};
|
||||
-1141
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.53.0 */
|
||||
import{a as x,c as $,d as q}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-JBZVB6GP.js";import{a as T}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-URNT5464.js";import{a as l,b as w,c as r,e as k,f as p,g as E,i as b,j as d,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4MVSRJ3Y.js";var S={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},j=m=>(..._)=>({_$litDirective$:m,values:_}),f=class{constructor(_){}get _$AU(){return this._$AM._$AU}_$AT(_,e,s){this._$Ct=_,this._$AM=e,this._$Ci=s}_$AS(_,e){return this.update(_,e)}update(_,e){return this.render(...e)}};var u=class extends f{constructor(_){if(super(_),this.it=p,_.type!==S.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(_){if(_===p||_==null)return this._t=void 0,this.it=_;if(_===k)return _;if(typeof _!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(_===this.it)return this._t;this.it=_;let e=[_];return e.raw=e,this._t={_$litType$:this.constructor.resultType,strings:e,values:[]}}};u.directiveName="unsafeHTML",u.resultType=1;var A=j(u);var H=["EUR","USD","GBP","JPY","CHF","CAD","AUD","NZD","CNY","INR","BRL","CZK","PLN","RUB","SEK","NOK","DKK","UAH"],c=class extends E{constructor(){super(...arguments);this.budget=null;this._settings=null;this._loading=!0;this._importCsv="";this._importLoading=!1;this._includeHistory=!0;this._toast="";this._testingNotification=!1;this._personTargets=[];this._testingUser="";this._users=[];this._savedViews=[];this._vacEnabled=!1;this._vacStart="";this._vacEnd="";this._vacBuffer=3;this._vacExempt=new Set;this._vacIsActive=!1;this._vacWindowEnd=null;this._vacAllTasks=[];this._vacPreview=[];this._vacPreviewLoading=!1;this._vacSaving=!1;this._qrObjects=[];this._qrSelectedEntries=new Set;this._qrActions=new Set(["view"]);this._qrUrlMode="companion";this._qrBatchLoading=!1;this._qrBatchResults=[];this._qrObjectsLoaded=!1;this._exportObjects=[];this._exportSelectedEntries=new Set;this._exportObjectsLoaded=!1;this._docArchiveLoading=!1;this._loaded=!1;this._userService=null;this._sendTestNotification=async e=>{e?this._testingUser=e:this._testingNotification=!0;try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/test_notification",...e?{user_id:e}:{}}),a=s.message||(s.success?t("test_notification_success",this._lang):t("test_notification_failed",this._lang));this._showToast(a)}catch{this._showToast(t("test_notification_failed",this._lang))}finally{e?this._testingUser="":this._testingNotification=!1}};this._allTemplates=[];this._templateCategories={};this._tplOpenGroups=new Set;this._templatesRequested=!1}get _lang(){return this.hass?.language||"en"}updated(e){super.updated(e),e.has("hass")&&this.hass&&!this._loaded?(this._loaded=!0,this._userService=new T(this.hass),this._loadSettings(),this._loadUsers()):e.has("hass")&&this.hass&&this._userService&&this._userService.updateHass(this.hass)}async _loadUsers(){if(this._userService){try{this._users=await this._userService.getUsers()}catch{this._users=[]}this._loadNotifyTargets()}}async _loadNotifyTargets(){try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/notify/user_targets"});this._personTargets=e.targets||[]}catch{this._personTargets=[]}}async _loadSettings(){this._loading=!0;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/settings"});this._settings=e,this._hydrateVacationFromSettings()}catch{}try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/views/list"});this._savedViews=e.views||[]}catch{}this._loading=!1}_hydrateVacationFromSettings(){let e=this._settings?.vacation;e&&(this._vacEnabled=e.enabled,this._vacStart=e.start||"",this._vacEnd=e.end||"",this._vacBuffer=e.buffer_days,this._vacExempt=new Set(e.exempt_task_ids||[]),this._vacIsActive=e.is_active,this._vacWindowEnd=e.window_end)}async _updateSetting(e,s){try{let a=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:{[e]:s}});this._settings=a,this._showToast(t("settings_saved",this._lang)),this.dispatchEvent(new CustomEvent("settings-changed"))}catch{this._showToast(t("action_error",this._lang))}}_showToast(e){this._toast=e,setTimeout(()=>{this._toast=""},3e3)}_downloadFile(e,s,a){q(e,s,a)}render(){let e=this._lang;return this._loading||!this._settings?r`<div class="settings-loading">Loading…</div>`:r`
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as x,c as $,d as q}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZIQ7JY7R.js";import{a as T}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6RMRSFSY.js";import{a as l,b as w,c as r,e as k,f as p,g as E,i as b,j as d,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var S={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},j=m=>(..._)=>({_$litDirective$:m,values:_}),f=class{constructor(_){}get _$AU(){return this._$AM._$AU}_$AT(_,e,s){this._$Ct=_,this._$AM=e,this._$Ci=s}_$AS(_,e){return this.update(_,e)}update(_,e){return this.render(...e)}};var u=class extends f{constructor(_){if(super(_),this.it=p,_.type!==S.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(_){if(_===p||_==null)return this._t=void 0,this.it=_;if(_===k)return _;if(typeof _!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(_===this.it)return this._t;this.it=_;let e=[_];return e.raw=e,this._t={_$litType$:this.constructor.resultType,strings:e,values:[]}}};u.directiveName="unsafeHTML",u.resultType=1;var A=j(u);var H=["EUR","USD","GBP","JPY","CHF","CAD","AUD","NZD","CNY","INR","BRL","CZK","PLN","RUB","SEK","NOK","DKK","UAH"],c=class extends E{constructor(){super(...arguments);this.budget=null;this._settings=null;this._loading=!0;this._importCsv="";this._importLoading=!1;this._includeHistory=!0;this._toast="";this._testingNotification=!1;this._personTargets=[];this._testingUser="";this._users=[];this._savedViews=[];this._vacEnabled=!1;this._vacStart="";this._vacEnd="";this._vacBuffer=3;this._vacExempt=new Set;this._vacIsActive=!1;this._vacWindowEnd=null;this._vacAllTasks=[];this._vacPreview=[];this._vacPreviewLoading=!1;this._vacSaving=!1;this._qrObjects=[];this._qrSelectedEntries=new Set;this._qrActions=new Set(["view"]);this._qrUrlMode="companion";this._qrBatchLoading=!1;this._qrBatchResults=[];this._qrObjectsLoaded=!1;this._exportObjects=[];this._exportSelectedEntries=new Set;this._exportObjectsLoaded=!1;this._docArchiveLoading=!1;this._loaded=!1;this._userService=null;this._sendTestNotification=async e=>{e?this._testingUser=e:this._testingNotification=!0;try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/test_notification",...e?{user_id:e}:{}}),a=s.message||(s.success?t("test_notification_success",this._lang):t("test_notification_failed",this._lang));this._showToast(a)}catch{this._showToast(t("test_notification_failed",this._lang))}finally{e?this._testingUser="":this._testingNotification=!1}};this._allTemplates=[];this._templateCategories={};this._tplOpenGroups=new Set;this._templatesRequested=!1}get _lang(){return this.hass?.language||"en"}updated(e){super.updated(e),e.has("hass")&&this.hass&&!this._loaded?(this._loaded=!0,this._userService=new T(this.hass),this._loadSettings(),this._loadUsers()):e.has("hass")&&this.hass&&this._userService&&this._userService.updateHass(this.hass)}async _loadUsers(){if(this._userService){try{this._users=await this._userService.getUsers()}catch{this._users=[]}this._loadNotifyTargets()}}async _loadNotifyTargets(){try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/notify/user_targets"});this._personTargets=e.targets||[]}catch{this._personTargets=[]}}async _loadSettings(){this._loading=!0;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/settings"});this._settings=e,this._hydrateVacationFromSettings()}catch{}try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/views/list"});this._savedViews=e.views||[]}catch{}this._loading=!1}_hydrateVacationFromSettings(){let e=this._settings?.vacation;e&&(this._vacEnabled=e.enabled,this._vacStart=e.start||"",this._vacEnd=e.end||"",this._vacBuffer=e.buffer_days,this._vacExempt=new Set(e.exempt_task_ids||[]),this._vacIsActive=e.is_active,this._vacWindowEnd=e.window_end)}async _updateSetting(e,s){try{let a=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:{[e]:s}});this._settings=a,this._showToast(t("settings_saved",this._lang)),this.dispatchEvent(new CustomEvent("settings-changed"))}catch{this._showToast(t("action_error",this._lang))}}_showToast(e){this._toast=e,setTimeout(()=>{this._toast=""},3e3)}_downloadFile(e,s,a){q(e,s,a)}render(){let e=this._lang;return this._loading||!this._settings?r`<div class="settings-loading">Loading…</div>`:r`
|
||||
${this._renderFeatures(e)}
|
||||
${this._renderPanelAccess(e)}
|
||||
${this._renderGeneral(e)}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.54.0 */
|
||||
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-WZ6RLKNK.js";import{a as l,b as m,c as i,f as h,g as v,i as u,j as d,n as p,p as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C2ERU424.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,f(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
|
||||
/*! maintenance_supporter frontend 2.55.0 */
|
||||
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as l,b as m,c as i,f as h,g as v,i as u,j as d,n as p,p as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,f(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||
<div class="title">${p("setups_title",t)}</div>
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.53.0 */
|
||||
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-MEKM6THN.js";import{a as l,b as m,c as i,f as h,g as v,i as u,j as d,n as p,p as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4MVSRJ3Y.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,f(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||
<div class="title">${p("setups_title",t)}</div>
|
||||
<div class="hint">${p("setups_hint",t)}</div>
|
||||
${this._error?i`<div class="error">${this._error}</div>`:h}
|
||||
|
||||
${this._loading?i`<div class="loading">…</div>`:this._setups.length===0?i`<div class="empty">${p("setups_none",t)}</div>`:i`
|
||||
<div class="list">
|
||||
${this._setups.map(e=>{let r=this._selected.has(e.device_id),c=[e.integration_name,e.area_name].filter(Boolean).join(" \xB7 ");return i`
|
||||
<label class="row">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${r}
|
||||
@change=${()=>this._toggle(e.device_id)}
|
||||
/>
|
||||
<div class="row-main">
|
||||
<div class="row-top">
|
||||
<span class="row-name">${e.device_name}</span>
|
||||
</div>
|
||||
<div class="row-sub">${c}</div>
|
||||
<div class="row-target" @click=${s=>s.preventDefault()}>
|
||||
→
|
||||
${r&&this._objects.length>0?i`
|
||||
<select
|
||||
class="target-select"
|
||||
@change=${s=>{let n=new Map(this._targets),o=s.target.value;o?n.set(e.device_id,o):n.delete(e.device_id),this._targets=n}}
|
||||
>
|
||||
<option value="" ?selected=${!this._targets.get(e.device_id)}>
|
||||
${e.suggested_entry_id?e.suggested_object_name:p("setups_target_new",t).replace("{name}",e.suggested_object_name)}
|
||||
</option>
|
||||
${this._objects.filter(s=>s.entry_id!==e.suggested_entry_id).map(s=>i`<option
|
||||
value=${s.entry_id}
|
||||
?selected=${this._targets.get(e.device_id)===s.entry_id}
|
||||
>
|
||||
${s.name}
|
||||
</option>`)}
|
||||
</select>
|
||||
`:i`${e.suggested_object_name}${e.suggested_entry_id?h:i` <span class="new-tag">${p("adopt_problem_new_object",t)}</span>`}`}
|
||||
</div>
|
||||
<div class="row-tasks">
|
||||
${e.tasks.map(s=>i`<span class="chip" title=${s.entity_ids.join(", ")}>
|
||||
<ha-icon icon="mdi:link-variant"></ha-icon>${s.task_name_localized||s.task_name}
|
||||
</span>`)}
|
||||
</div>
|
||||
${r?e.tasks.filter(s=>s.direction==="usage_delta").map(s=>{let n=`${e.device_id} ${s.task_name}`;return i`
|
||||
<div class="baseline-field" @click=${o=>o.preventDefault()}>
|
||||
<span class="baseline-label"
|
||||
>${s.task_name_localized||s.task_name} —
|
||||
${p("setups_baseline_hint",t)}</span
|
||||
>
|
||||
<input
|
||||
type="number"
|
||||
step="any"
|
||||
min="0"
|
||||
.value=${this._baselines.get(n)??""}
|
||||
@click=${o=>o.preventDefault()}
|
||||
@input=${o=>{let _=new Map(this._baselines);_.set(n,o.target.value),this._baselines=_}}
|
||||
/>
|
||||
</div>
|
||||
`}):h}
|
||||
</div>
|
||||
</label>
|
||||
`})}
|
||||
</div>
|
||||
`}
|
||||
|
||||
<div class="actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${p("cancel",t)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._adopt}
|
||||
.disabled=${this._selected.size===0||this._adopting}
|
||||
>
|
||||
${p("setups_adopt",t)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`}};a.styles=m`
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
min-width: min(360px, calc(100vw - 24px));
|
||||
max-width: 560px;
|
||||
width: 90vw;
|
||||
max-height: 80vh;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.title { font-size: 18px; font-weight: 500; }
|
||||
.hint { color: var(--secondary-text-color); font-size: 13px; }
|
||||
.error { color: var(--error-color, #f44336); font-size: 13px; }
|
||||
.loading, .empty { color: var(--secondary-text-color); font-size: 14px; padding: 12px 0; }
|
||||
.list { display: flex; flex-direction: column; gap: 6px; overflow-y: auto; max-height: 50vh; }
|
||||
.row {
|
||||
display: flex; align-items: flex-start; gap: 10px; padding: 8px;
|
||||
border: 1px solid var(--divider-color); border-radius: 6px; cursor: pointer;
|
||||
}
|
||||
.row input { margin-top: 2px; cursor: pointer; }
|
||||
.row-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
|
||||
.row-name { font-weight: 500; font-size: 13px; }
|
||||
.row-sub, .row-target { color: var(--secondary-text-color); font-size: 12px; }
|
||||
.new-tag { font-style: italic; }
|
||||
.row-tasks { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
|
||||
.chip {
|
||||
display: inline-flex; align-items: center; gap: 4px;
|
||||
font-size: 11px; padding: 2px 8px; border-radius: 10px;
|
||||
background: var(--secondary-background-color, rgba(0, 0, 0, 0.06));
|
||||
color: var(--primary-text-color); white-space: nowrap;
|
||||
}
|
||||
.chip ha-icon { --mdc-icon-size: 12px; color: var(--primary-color); }
|
||||
.target-select {
|
||||
font-size: 12px; padding: 2px 4px; max-width: 100%;
|
||||
border: 1px solid var(--divider-color); border-radius: 4px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.baseline-field {
|
||||
display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
|
||||
margin-top: 4px; font-size: 12px; color: var(--secondary-text-color);
|
||||
}
|
||||
.baseline-field input {
|
||||
width: 110px; padding: 3px 6px; font-size: 12px;
|
||||
border: 1px solid var(--divider-color); border-radius: 4px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 8px; }
|
||||
`,l([u({attribute:!1})],a.prototype,"hass",2),l([d()],a.prototype,"_open",2),l([d()],a.prototype,"_loading",2),l([d()],a.prototype,"_adopting",2),l([d()],a.prototype,"_error",2),l([d()],a.prototype,"_setups",2),l([d()],a.prototype,"_selected",2),l([d()],a.prototype,"_baselines",2),l([d()],a.prototype,"_targets",2),l([d()],a.prototype,"_objects",2);customElements.get("maintenance-suggested-setups-dialog")||customElements.define("maintenance-suggested-setups-dialog",a);export{a as MaintenanceSuggestedSetupsDialog};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user