209 files
This commit is contained in:
@@ -84,6 +84,7 @@ from .const import (
|
||||
SERVICE_RESET,
|
||||
SERVICE_SKIP,
|
||||
SERVICE_UPDATE_TASK,
|
||||
SIGNAL_BATTERY_FLEET_CHANGED,
|
||||
SIGNAL_NEW_OBJECT_ENTRY,
|
||||
SIGNAL_OBJECT_ENTRY_REMOVED,
|
||||
STORES_CACHE_KEY,
|
||||
@@ -1735,6 +1736,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: MaintenanceSupporterConf
|
||||
|
||||
coordinator = MaintenanceCoordinator(hass, entry, store)
|
||||
entry.runtime_data = MaintenanceSupporterData(coordinator=coordinator, store=store)
|
||||
if obj_data.get(BATTERY_FLEET_OBJECT_FLAG):
|
||||
# The hub counts this fleet's batteries now (its Store, with the
|
||||
# low latch, is reachable through runtime_data from here on), so
|
||||
# the first refresh and the trigger of the fleet task read the
|
||||
# real count, not the hub's count from before this fleet loaded.
|
||||
# A stale 0 there was taken for a recovery, and the count catching
|
||||
# up announced the same low battery again (2026-10-05).
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
||||
async_dispatcher_send(hass, SIGNAL_BATTERY_FLEET_CHANGED)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
# A shopping-list row checked while this object was not loaded (a
|
||||
@@ -1991,6 +2002,11 @@ async def _async_global_options_updated(hass: HomeAssistant, entry: ConfigEntry)
|
||||
from .shopping_sync import schedule_resync
|
||||
|
||||
schedule_resync(hass)
|
||||
# The low/recovered battery percentages may have changed: the hub counts
|
||||
# now, not at its next poll.
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
||||
async_dispatcher_send(hass, SIGNAL_BATTERY_FLEET_CHANGED)
|
||||
|
||||
|
||||
_ORPHAN_ISSUE_PREFIX = "orphan_admin_panel_user_"
|
||||
|
||||
@@ -92,6 +92,8 @@ TRIGGER_ENTITY_DOMAINS = [
|
||||
"valve",
|
||||
"lawn_mower",
|
||||
"lock",
|
||||
# #204: Plant Monitor (HACS) sums a plant up as ok / problem.
|
||||
"plant",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -842,6 +842,10 @@ SIGNAL_OBJECT_ENTRY_REMOVED = f"{DOMAIN}_object_entry_removed"
|
||||
# Fired by the DocumentStore after any metadata/blob change so the storage
|
||||
# sensor (and any other listener) can refresh without polling.
|
||||
SIGNAL_DOCUMENTS_UPDATED = f"{DOMAIN}_documents_updated"
|
||||
# The battery fleet's inputs changed outside the hub's own count (a fleet
|
||||
# object loaded its Store, the low/recovered percentages changed): the hub's
|
||||
# low-count sensor recounts now instead of at its next 30-s poll.
|
||||
SIGNAL_BATTERY_FLEET_CHANGED = f"{DOMAIN}_battery_fleet_changed"
|
||||
|
||||
# --- Trigger Completion Cooldown ---
|
||||
TRIGGER_COMPLETION_COOLDOWN_SECONDS = 600 # 10 minutes
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Interval",
|
||||
"warning": "Upozornění",
|
||||
"last_performed": "Naposledy provedeno",
|
||||
"last_done_days_ago": "hotovo před {n} d",
|
||||
"last_done_today": "hotovo dnes",
|
||||
"next_due": "Další termín",
|
||||
"days_until_due": "Dnů do termínu",
|
||||
"avg_duration": "Prům. trvání",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Interval",
|
||||
"warning": "Advarsel",
|
||||
"last_performed": "Senest udført",
|
||||
"last_done_days_ago": "udført for {n} d siden",
|
||||
"last_done_today": "udført i dag",
|
||||
"next_due": "Næste forfald",
|
||||
"days_until_due": "Dage til forfald",
|
||||
"avg_duration": "Gns. varighed",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Intervall",
|
||||
"warning": "Vorwarnung",
|
||||
"last_performed": "Zuletzt durchgeführt",
|
||||
"last_done_days_ago": "vor {n} T erledigt",
|
||||
"last_done_today": "heute erledigt",
|
||||
"next_due": "Nächste Fälligkeit",
|
||||
"days_until_due": "Tage bis fällig",
|
||||
"avg_duration": "Ø Dauer",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Interval",
|
||||
"warning": "Warning",
|
||||
"last_performed": "Last performed",
|
||||
"last_done_days_ago": "done {n} d ago",
|
||||
"last_done_today": "done today",
|
||||
"next_due": "Next due",
|
||||
"days_until_due": "Days until due",
|
||||
"avg_duration": "Avg duration",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervalo",
|
||||
"warning": "Aviso",
|
||||
"last_performed": "Última ejecución",
|
||||
"last_done_days_ago": "hecho hace {n} d",
|
||||
"last_done_today": "hecho hoy",
|
||||
"next_due": "Próximo vencimiento",
|
||||
"days_until_due": "Días hasta vencimiento",
|
||||
"avg_duration": "Ø Duración",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Väli",
|
||||
"warning": "Varoitus",
|
||||
"last_performed": "Viimeksi suoritettu",
|
||||
"last_done_days_ago": "tehty {n} pv sitten",
|
||||
"last_done_today": "tehty tänään",
|
||||
"next_due": "Seuraava eräpäivä",
|
||||
"days_until_due": "Päiviä eräpäivään",
|
||||
"avg_duration": "Keskim. kesto",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervalle",
|
||||
"warning": "Avertissement",
|
||||
"last_performed": "Dernière exécution",
|
||||
"last_done_days_ago": "fait il y a {n} j",
|
||||
"last_done_today": "fait aujourd’hui",
|
||||
"next_due": "Prochaine échéance",
|
||||
"days_until_due": "Jours restants",
|
||||
"avg_duration": "Ø Durée",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "अंतराल",
|
||||
"warning": "चेतावनी",
|
||||
"last_performed": "अंतिम बार किया गया",
|
||||
"last_done_days_ago": "{n} दिन पहले किया",
|
||||
"last_done_today": "आज किया",
|
||||
"next_due": "अगली देय",
|
||||
"days_until_due": "देय तक दिन",
|
||||
"avg_duration": "औसत अवधि",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Intervallum",
|
||||
"warning": "Figyelmeztetés",
|
||||
"last_performed": "Utoljára elvégezve",
|
||||
"last_done_days_ago": "{n} napja elvégezve",
|
||||
"last_done_today": "ma elvégezve",
|
||||
"next_due": "Következő esedékesség",
|
||||
"days_until_due": "Napok az esedékességig",
|
||||
"avg_duration": "Átl. időtartam",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervallo",
|
||||
"warning": "Avviso",
|
||||
"last_performed": "Ultima esecuzione",
|
||||
"last_done_days_ago": "fatto {n} g fa",
|
||||
"last_done_today": "fatto oggi",
|
||||
"next_due": "Prossima scadenza",
|
||||
"days_until_due": "Giorni alla scadenza",
|
||||
"avg_duration": "Ø Durata",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "間隔",
|
||||
"warning": "警告",
|
||||
"last_performed": "最終実施",
|
||||
"last_done_days_ago": "{n}日前に実施",
|
||||
"last_done_today": "今日実施",
|
||||
"next_due": "次回期限",
|
||||
"days_until_due": "期限までの日数",
|
||||
"avg_duration": "平均所要時間",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "주기",
|
||||
"warning": "경고",
|
||||
"last_performed": "마지막 수행일",
|
||||
"last_done_days_ago": "{n}일 전 완료",
|
||||
"last_done_today": "오늘 완료",
|
||||
"next_due": "다음 예정일",
|
||||
"days_until_due": "남은 일수",
|
||||
"avg_duration": "평균 소요 시간",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Intervall",
|
||||
"warning": "Advarsel",
|
||||
"last_performed": "Sist utført",
|
||||
"last_done_days_ago": "utført for {n} d siden",
|
||||
"last_done_today": "utført i dag",
|
||||
"next_due": "Neste forfall",
|
||||
"days_until_due": "Dager til forfall",
|
||||
"avg_duration": "Gj.snittlig varighet",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Interval",
|
||||
"warning": "Waarschuwing",
|
||||
"last_performed": "Laatst uitgevoerd",
|
||||
"last_done_days_ago": "{n} d geleden gedaan",
|
||||
"last_done_today": "vandaag gedaan",
|
||||
"next_due": "Volgende keer",
|
||||
"days_until_due": "Dagen tot vervaldatum",
|
||||
"avg_duration": "Ø Duur",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Interwał",
|
||||
"warning": "Ostrzeżenie",
|
||||
"last_performed": "Ostatnio wykonane",
|
||||
"last_done_days_ago": "wykonano {n} d temu",
|
||||
"last_done_today": "wykonano dziś",
|
||||
"next_due": "Następny termin",
|
||||
"days_until_due": "Dni do terminu",
|
||||
"avg_duration": "Śr. czas trwania",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Intervalo",
|
||||
"warning": "Aviso",
|
||||
"last_performed": "Última execução",
|
||||
"last_done_days_ago": "feito há {n} d",
|
||||
"last_done_today": "feito hoje",
|
||||
"next_due": "Próximo vencimento",
|
||||
"days_until_due": "Dias até o vencimento",
|
||||
"avg_duration": "Duração média",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervalo",
|
||||
"warning": "Aviso",
|
||||
"last_performed": "Última execução",
|
||||
"last_done_days_ago": "feito há {n} d",
|
||||
"last_done_today": "feito hoje",
|
||||
"next_due": "Próximo vencimento",
|
||||
"days_until_due": "Dias até vencimento",
|
||||
"avg_duration": "Ø Duração",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Интервал",
|
||||
"warning": "Предупреждение",
|
||||
"last_performed": "Последнее выполнение",
|
||||
"last_done_days_ago": "выполнено {n} дн. назад",
|
||||
"last_done_today": "выполнено сегодня",
|
||||
"next_due": "Следующий срок",
|
||||
"days_until_due": "Дней до срока",
|
||||
"avg_duration": "Ср. длительность",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervall",
|
||||
"warning": "Varning",
|
||||
"last_performed": "Senast utförd",
|
||||
"last_done_days_ago": "klar för {n} d sedan",
|
||||
"last_done_today": "klar i dag",
|
||||
"next_due": "Nästa förfallodatum",
|
||||
"days_until_due": "Dagar till förfallodatum",
|
||||
"avg_duration": "Snittlig varaktighet",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Aralık",
|
||||
"warning": "Uyarı",
|
||||
"last_performed": "Son yapılma",
|
||||
"last_done_days_ago": "{n} g önce yapıldı",
|
||||
"last_done_today": "bugün yapıldı",
|
||||
"next_due": "Sonraki vade",
|
||||
"days_until_due": "Vadeye kalan gün",
|
||||
"avg_duration": "Ort. süre",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Інтервал",
|
||||
"warning": "Попередження",
|
||||
"last_performed": "Останнє виконання",
|
||||
"last_done_days_ago": "виконано {n} д тому",
|
||||
"last_done_today": "виконано сьогодні",
|
||||
"next_due": "Наступний термін",
|
||||
"days_until_due": "Днів до терміну",
|
||||
"avg_duration": "Сер. тривалість",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "间隔",
|
||||
"warning": "预警",
|
||||
"last_performed": "上次执行",
|
||||
"last_done_days_ago": "{n} 天前完成",
|
||||
"last_done_today": "今天完成",
|
||||
"next_due": "下次到期",
|
||||
"days_until_due": "距离到期天数",
|
||||
"avg_duration": "平均耗时",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { LitElement, html, css, nothing } from "lit";
|
||||
import { applySubscriptionEvent, type SubscriptionEvent } from "./helpers/subscription-merge";
|
||||
import { hydrateObjects } from "./helpers/hydrate-objects";
|
||||
import { property, state } from "lit/decorators.js";
|
||||
import { syncLocaleFromHass, sharedStyles, STATUS_COLORS, t, ensureLocale, isLocaleLoaded, setProfilePrefs, formatDueDays, langOf, currencySymbolOf, syncCurrencyDecimals} from "./styles";
|
||||
import { syncLocaleFromHass, sharedStyles, STATUS_COLORS, t, ensureLocale, isLocaleLoaded, setProfilePrefs, formatDueDays, formatLastDone, formatDate, langOf, currencySymbolOf, syncCurrencyDecimals} from "./styles";
|
||||
import { openSignedDocument } from "./helpers/document-url";
|
||||
import { isPhotoDocument } from "./helpers/document-categories";
|
||||
import { isSafeHttpUrl } from "./helpers/url";
|
||||
@@ -207,6 +207,15 @@ export class MaintenanceSupporterCard extends LitElement {
|
||||
this._firstLoadDone = true;
|
||||
}
|
||||
|
||||
/** A task without a due date (manual, sensor-only, paused): when it was
|
||||
* last done, "done 23 d ago" (D#203) — a dash only when never done. */
|
||||
private _lastDone(task: MaintenanceTask, L: string) {
|
||||
const done = formatLastDone(task.last_performed, L);
|
||||
return done
|
||||
? html`<span class="last-done" title="${t("last_performed", L)}: ${formatDate(task.last_performed, L)}">${done}</span>`
|
||||
: "—";
|
||||
}
|
||||
|
||||
/** Display name of the task's responsible user, or "" when the badge must
|
||||
* stay hidden (feature off, nobody assigned, or the name not resolved).
|
||||
* With a rotation this is whoever is up next — the pointer the engine
|
||||
@@ -603,7 +612,7 @@ export class MaintenanceSupporterCard extends LitElement {
|
||||
: formatDueDays(task.days_until_due, L)
|
||||
: task.trigger_active
|
||||
? "⚡"
|
||||
: "—"}
|
||||
: this._lastDone(task, L)}
|
||||
</div>
|
||||
${showActions && useButtons
|
||||
? html`
|
||||
|
||||
@@ -116,7 +116,7 @@ import type { MaintenanceSavedViewsDialog } from "./components/saved-views-dialo
|
||||
import { type SparklineContext } from "./renderers/sparkline";
|
||||
import { buildCalendarBuckets, type CalendarEvent } from "./helpers/calendar-bucket";
|
||||
import { haToday } from "./helpers/ha-time";
|
||||
import { renderTriggerProgress, renderMiniSparkline, computeTrend } from "./renderers/progress";
|
||||
import { renderTriggerProgress, renderMiniSparkline, computeTrend, renderDueText } from "./renderers/progress";
|
||||
import { type HistoryContext } from "./renderers/history";
|
||||
import { renderUserBadge, type TaskDetailContext } from "./renderers/task-detail";
|
||||
import { renderPersonChip, type PersonDisplay } from "./helpers/person";
|
||||
@@ -1248,6 +1248,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
status: task.status,
|
||||
days_until_due: task.days_until_due ?? null,
|
||||
next_due: task.next_due ?? null,
|
||||
last_performed: task.last_performed ?? null,
|
||||
next_event_titles: task.next_event_titles ?? [],
|
||||
trigger_active: task.trigger_active,
|
||||
trigger_current_value: task.trigger_current_value ?? null,
|
||||
@@ -4615,7 +4616,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
</span>
|
||||
<span class="cell type">${t(row.type, L)}</span>
|
||||
<span class="due-cell" @click=${() => this._showTask(row.entry_id, row.task_id)}>
|
||||
<span class="due-text">${formatDueDays(row.days_until_due, L)}</span>
|
||||
${renderDueText(row.days_until_due, row.last_performed, L)}
|
||||
${hasDaysBar
|
||||
? html`<div class="days-bar"><div class="days-bar-fill${daysOverflow ? " overflow" : ""}" style="width:${pct}%;background:${barColor}"></div></div>`
|
||||
: nothing}
|
||||
@@ -4845,7 +4846,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
||||
<span class="task-sub${task.responsible_user_id ? '' : ' task-sub-empty'}">${renderUserBadge(task, (id) => this._userService?.getUserName(id) ?? null, (id) => this._userService?.getPerson(id) ?? null)}</span>
|
||||
<span class="cell type">${t(task.type, L)}</span>
|
||||
<span class="due-cell" @click=${() => this._showTask(obj.entry_id, task.id)}>
|
||||
<span class="due-text">${formatDueDays(task.days_until_due, L)}</span>
|
||||
${renderDueText(task.days_until_due, task.last_performed, L)}
|
||||
${task.trigger_config
|
||||
? renderTriggerProgress(task, { trend: computeTrend(task, this._miniStatsData), lang: L })
|
||||
: nothing}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
import { html, nothing } from "lit";
|
||||
import { t, formatDate, formatDueDays, formatNumber } from "../styles";
|
||||
import { t, formatDate, formatDueDays, formatLastDone, formatNumber } from "../styles";
|
||||
import { px } from "./chart-utils";
|
||||
import { daysProgress } from "../helpers/interval";
|
||||
import { stampMs } from "../helpers/ha-time";
|
||||
@@ -296,6 +296,24 @@ export function renderMiniSparkline(
|
||||
`;
|
||||
}
|
||||
|
||||
/** The due column's text: days until due, or, for a task without a due date
|
||||
* (manual, sensor-only, paused), when it was last done (D#203) — muted, so
|
||||
* it never reads as a status. A bare dash only for a task never done. */
|
||||
export function renderDueText(
|
||||
days: number | null | undefined,
|
||||
lastPerformed: string | null | undefined,
|
||||
lang: string,
|
||||
cls = "due-text",
|
||||
) {
|
||||
if (days == null) {
|
||||
const done = formatLastDone(lastPerformed, lang);
|
||||
if (done) {
|
||||
return html`<span class="${cls} last-done" title="${t("last_performed", lang)}: ${formatDate(lastPerformed, lang)}">${done}</span>`;
|
||||
}
|
||||
}
|
||||
return html`<span class="${cls}">${formatDueDays(days, lang)}</span>`;
|
||||
}
|
||||
|
||||
/** A detailed days-progress bar (last performed → next due) for the detail view. */
|
||||
export function renderDaysProgress(task: MaintenanceTask, lang: string) {
|
||||
const L = lang;
|
||||
|
||||
@@ -33,7 +33,7 @@ export { STATUS_COLORS, STATUS_ICONS } from "./status-constants";
|
||||
// `from "./styles"` import keeps working.
|
||||
import { ensureLocale, isLocaleLoaded, normLang, seedEnglish, t, type Translations } from "./helpers/locale-core";
|
||||
import { primeBackendErrors } from "./helpers/backend-errors";
|
||||
import { displayTimeZone, haTimeZone, minuteIn, stampMs, ymdIn } from "./helpers/ha-time";
|
||||
import { daysBetweenIso, displayTimeZone, haTimeZone, haToday, minuteIn, stampDate, stampMs, ymdIn } from "./helpers/ha-time";
|
||||
export { ensureLocale, isLocaleLoaded, seedEnglish, setLocale, t } from "./helpers/locale-core";
|
||||
seedEnglish(EN as Translations);
|
||||
|
||||
@@ -316,6 +316,18 @@ export function formatDueDays(days: number | null | undefined, lang?: string): s
|
||||
return `${days} ${days === 1 ? t("day", l) : t("days", l)}`;
|
||||
}
|
||||
|
||||
/** "done 23 d ago" / "done today" on HA's calendar — what the due column
|
||||
* shows for a task without a due date (manual, sensor-only, paused) instead
|
||||
* of a bare dash (D#203). null when the task was never done. */
|
||||
export function formatLastDone(lastPerformed: string | null | undefined, lang?: string): string | null {
|
||||
const day = stampDate(lastPerformed);
|
||||
if (!day) return null;
|
||||
const days = daysBetweenIso(day, haToday());
|
||||
if (!Number.isFinite(days)) return null;
|
||||
if (days <= 0) return t("last_done_today", lang || "en");
|
||||
return t("last_done_days_ago", lang || "en").replace("{n}", String(days));
|
||||
}
|
||||
|
||||
/** Localized interval label, e.g. "3 Months" / "7 Days" (issue #59 — was
|
||||
* hard-coded to days). Uses the unit_* keys from the schedule dialog. */
|
||||
export function formatInterval(
|
||||
@@ -1045,6 +1057,9 @@ export const sharedStyles = css`
|
||||
}
|
||||
|
||||
.due-text { font-size: 13px; }
|
||||
/* D#203: a task without a due date shows when it was last done — muted,
|
||||
so it never reads as a status. */
|
||||
.due-text.last-done { color: var(--secondary-text-color); }
|
||||
|
||||
.days-bar {
|
||||
width: 100%;
|
||||
|
||||
@@ -599,6 +599,8 @@ export interface TaskRow {
|
||||
status: string;
|
||||
days_until_due: number | null;
|
||||
next_due: string | null;
|
||||
/** D#203: shown as "done N d ago" when the task has no due date. */
|
||||
last_performed?: string | null;
|
||||
trigger_active: boolean;
|
||||
trigger_current_value: number | null;
|
||||
trigger_current_delta: number | null;
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Interval",
|
||||
"warning": "Upozornění",
|
||||
"last_performed": "Naposledy provedeno",
|
||||
"last_done_days_ago": "hotovo před {n} d",
|
||||
"last_done_today": "hotovo dnes",
|
||||
"next_due": "Další termín",
|
||||
"days_until_due": "Dnů do termínu",
|
||||
"avg_duration": "Prům. trvání",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Interval",
|
||||
"warning": "Advarsel",
|
||||
"last_performed": "Senest udført",
|
||||
"last_done_days_ago": "udført for {n} d siden",
|
||||
"last_done_today": "udført i dag",
|
||||
"next_due": "Næste forfald",
|
||||
"days_until_due": "Dage til forfald",
|
||||
"avg_duration": "Gns. varighed",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Intervall",
|
||||
"warning": "Vorwarnung",
|
||||
"last_performed": "Zuletzt durchgeführt",
|
||||
"last_done_days_ago": "vor {n} T erledigt",
|
||||
"last_done_today": "heute erledigt",
|
||||
"next_due": "Nächste Fälligkeit",
|
||||
"days_until_due": "Tage bis fällig",
|
||||
"avg_duration": "Ø Dauer",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Interval",
|
||||
"warning": "Warning",
|
||||
"last_performed": "Last performed",
|
||||
"last_done_days_ago": "done {n} d ago",
|
||||
"last_done_today": "done today",
|
||||
"next_due": "Next due",
|
||||
"days_until_due": "Days until due",
|
||||
"avg_duration": "Avg duration",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervalo",
|
||||
"warning": "Aviso",
|
||||
"last_performed": "Última ejecución",
|
||||
"last_done_days_ago": "hecho hace {n} d",
|
||||
"last_done_today": "hecho hoy",
|
||||
"next_due": "Próximo vencimiento",
|
||||
"days_until_due": "Días hasta vencimiento",
|
||||
"avg_duration": "Ø Duración",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Väli",
|
||||
"warning": "Varoitus",
|
||||
"last_performed": "Viimeksi suoritettu",
|
||||
"last_done_days_ago": "tehty {n} pv sitten",
|
||||
"last_done_today": "tehty tänään",
|
||||
"next_due": "Seuraava eräpäivä",
|
||||
"days_until_due": "Päiviä eräpäivään",
|
||||
"avg_duration": "Keskim. kesto",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervalle",
|
||||
"warning": "Avertissement",
|
||||
"last_performed": "Dernière exécution",
|
||||
"last_done_days_ago": "fait il y a {n} j",
|
||||
"last_done_today": "fait aujourd’hui",
|
||||
"next_due": "Prochaine échéance",
|
||||
"days_until_due": "Jours restants",
|
||||
"avg_duration": "Ø Durée",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "अंतराल",
|
||||
"warning": "चेतावनी",
|
||||
"last_performed": "अंतिम बार किया गया",
|
||||
"last_done_days_ago": "{n} दिन पहले किया",
|
||||
"last_done_today": "आज किया",
|
||||
"next_due": "अगली देय",
|
||||
"days_until_due": "देय तक दिन",
|
||||
"avg_duration": "औसत अवधि",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Intervallum",
|
||||
"warning": "Figyelmeztetés",
|
||||
"last_performed": "Utoljára elvégezve",
|
||||
"last_done_days_ago": "{n} napja elvégezve",
|
||||
"last_done_today": "ma elvégezve",
|
||||
"next_due": "Következő esedékesség",
|
||||
"days_until_due": "Napok az esedékességig",
|
||||
"avg_duration": "Átl. időtartam",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervallo",
|
||||
"warning": "Avviso",
|
||||
"last_performed": "Ultima esecuzione",
|
||||
"last_done_days_ago": "fatto {n} g fa",
|
||||
"last_done_today": "fatto oggi",
|
||||
"next_due": "Prossima scadenza",
|
||||
"days_until_due": "Giorni alla scadenza",
|
||||
"avg_duration": "Ø Durata",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "間隔",
|
||||
"warning": "警告",
|
||||
"last_performed": "最終実施",
|
||||
"last_done_days_ago": "{n}日前に実施",
|
||||
"last_done_today": "今日実施",
|
||||
"next_due": "次回期限",
|
||||
"days_until_due": "期限までの日数",
|
||||
"avg_duration": "平均所要時間",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "주기",
|
||||
"warning": "경고",
|
||||
"last_performed": "마지막 수행일",
|
||||
"last_done_days_ago": "{n}일 전 완료",
|
||||
"last_done_today": "오늘 완료",
|
||||
"next_due": "다음 예정일",
|
||||
"days_until_due": "남은 일수",
|
||||
"avg_duration": "평균 소요 시간",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Intervall",
|
||||
"warning": "Advarsel",
|
||||
"last_performed": "Sist utført",
|
||||
"last_done_days_ago": "utført for {n} d siden",
|
||||
"last_done_today": "utført i dag",
|
||||
"next_due": "Neste forfall",
|
||||
"days_until_due": "Dager til forfall",
|
||||
"avg_duration": "Gj.snittlig varighet",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Interval",
|
||||
"warning": "Waarschuwing",
|
||||
"last_performed": "Laatst uitgevoerd",
|
||||
"last_done_days_ago": "{n} d geleden gedaan",
|
||||
"last_done_today": "vandaag gedaan",
|
||||
"next_due": "Volgende keer",
|
||||
"days_until_due": "Dagen tot vervaldatum",
|
||||
"avg_duration": "Ø Duur",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Interwał",
|
||||
"warning": "Ostrzeżenie",
|
||||
"last_performed": "Ostatnio wykonane",
|
||||
"last_done_days_ago": "wykonano {n} d temu",
|
||||
"last_done_today": "wykonano dziś",
|
||||
"next_due": "Następny termin",
|
||||
"days_until_due": "Dni do terminu",
|
||||
"avg_duration": "Śr. czas trwania",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Intervalo",
|
||||
"warning": "Aviso",
|
||||
"last_performed": "Última execução",
|
||||
"last_done_days_ago": "feito há {n} d",
|
||||
"last_done_today": "feito hoje",
|
||||
"next_due": "Próximo vencimento",
|
||||
"days_until_due": "Dias até o vencimento",
|
||||
"avg_duration": "Duração média",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervalo",
|
||||
"warning": "Aviso",
|
||||
"last_performed": "Última execução",
|
||||
"last_done_days_ago": "feito há {n} d",
|
||||
"last_done_today": "feito hoje",
|
||||
"next_due": "Próximo vencimento",
|
||||
"days_until_due": "Dias até vencimento",
|
||||
"avg_duration": "Ø Duração",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Интервал",
|
||||
"warning": "Предупреждение",
|
||||
"last_performed": "Последнее выполнение",
|
||||
"last_done_days_ago": "выполнено {n} дн. назад",
|
||||
"last_done_today": "выполнено сегодня",
|
||||
"next_due": "Следующий срок",
|
||||
"days_until_due": "Дней до срока",
|
||||
"avg_duration": "Ср. длительность",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Intervall",
|
||||
"warning": "Varning",
|
||||
"last_performed": "Senast utförd",
|
||||
"last_done_days_ago": "klar för {n} d sedan",
|
||||
"last_done_today": "klar i dag",
|
||||
"next_due": "Nästa förfallodatum",
|
||||
"days_until_due": "Dagar till förfallodatum",
|
||||
"avg_duration": "Snittlig varaktighet",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "Aralık",
|
||||
"warning": "Uyarı",
|
||||
"last_performed": "Son yapılma",
|
||||
"last_done_days_ago": "{n} g önce yapıldı",
|
||||
"last_done_today": "bugün yapıldı",
|
||||
"next_due": "Sonraki vade",
|
||||
"days_until_due": "Vadeye kalan gün",
|
||||
"avg_duration": "Ort. süre",
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
"interval": "Інтервал",
|
||||
"warning": "Попередження",
|
||||
"last_performed": "Останнє виконання",
|
||||
"last_done_days_ago": "виконано {n} д тому",
|
||||
"last_done_today": "виконано сьогодні",
|
||||
"next_due": "Наступний термін",
|
||||
"days_until_due": "Днів до терміну",
|
||||
"avg_duration": "Сер. тривалість",
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"interval": "间隔",
|
||||
"warning": "预警",
|
||||
"last_performed": "上次执行",
|
||||
"last_done_days_ago": "{n} 天前完成",
|
||||
"last_done_today": "今天完成",
|
||||
"next_due": "下次到期",
|
||||
"days_until_due": "距离到期天数",
|
||||
"avg_duration": "平均耗时",
|
||||
|
||||
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
File diff suppressed because one or more lines are too long
-301
@@ -1,301 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import{e as y}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-D4KM62SJ.js";import{d as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GSRF4WCQ.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GVLO7RZ4.js";import{a as o,b as u,c as n,f as l,h as v,l as g,m as d,s as r,u as f,y as b}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._objectNames={};this._objects=[];this._covered={};this._users=[];this._responsible="";this._forMinutes="0";this._localeReady=!1;this._userService=null;this._toggle=t=>{let i=new Set(this._selected);i.has(t)?i.delete(t):i.add(t),this._selected=i};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(t=>t.entity_id))};this._adopt=async()=>{if(this._selected.size===0||this._adopting)return;this._error="";let t=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:this._existingEntryFor(e)??void 0,object_name:this._effectiveName(e),device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0,for_minutes:parseInt(this._forMinutes,10)>0?parseInt(this._forMinutes,10):void 0})),i=await h(this,{type:"maintenance_supporter/problem_sensors/adopt",selections:t},{busy:e=>{this._adopting=e},onError:e=>{this._error=e}});i!==void 0&&(this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:i})),this._open=!1)}}get _lang(){return b(this.hass)}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._sensors=[],this._selected=new Set,this._objectNames={},this._responsible="",this._forMinutes="0",this._userService?this._userService.updateHass(this.hass):this._userService=new y(this.hass);let[t,i,e]=await Promise.all([h(this,{type:"maintenance_supporter/problem_sensors/discover"},{onError:s=>{this._error=s}}),this._userService.getUsers().catch(()=>[]),this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"}).catch(()=>({objects:[]}))]);this._loading=!1,t!==void 0&&(this._objects=(e?.objects||[]).filter(s=>!s.object.archived_at).map(s=>({entry_id:s.entry_id,name:s.object.name,tasks:(s.tasks||[]).length})),this._sensors=t?.sensors||[],this._covered=Object.fromEntries(this._sensors.map(s=>[s.entity_id,s.covered_by??null])),this._selected=new Set(this._sensors.filter(s=>!s.covered_by).map(s=>s.entity_id)),this._users=i)}_defaultName(t){return t.suggested_entry_id?t.suggested_object_name:t.candidate?.name??t.suggested_object_name}_effectiveName(t){return(this._objectNames[t.entity_id]??"").trim()||this._defaultName(t)}_existingEntryFor(t){let i=this._effectiveName(t),e=t.suggested_entry_id||t.target_entry_id||null;if(i===this._defaultName(t)&&e)return e;let s=this._objects.find(c=>c.name.trim().toLowerCase()===i.toLowerCase());return s?s.entry_id:null}_schedulePreview(){clearTimeout(this._previewTimer),this._previewTimer=setTimeout(()=>{this._preview()},350)}async _preview(){let t=this._sensors.map(e=>({entity_id:e.entity_id,name:e.name,entry_id:this._existingEntryFor(e)})),i=await h(this,{type:"maintenance_supporter/problem_sensors/preview",selections:t},{onError:()=>{}});i?.covered&&(this._covered={...this._covered,...i.covered})}_summary(t){let i=new Map;for(let e of this._sensors){if(!this._selected.has(e.entity_id))continue;let s=this._existingEntryFor(e),c=this._effectiveName(e),_=s??`new:${c.toLowerCase()}`,p=i.get(_)??{name:c,entry:s,adding:0};p.adding+=1,i.set(_,p)}return i.size===0?l:n`
|
||||
<div class="summary">
|
||||
<div class="summary-title">${r("adopt_summary_title",t)}</div>
|
||||
${[...i.values()].map(e=>{if(!e.entry)return n`<div class="summary-line new">
|
||||
${r("setups_new_object_count",t).replace("{name}",e.name).replace("{count}",String(e.adding))}
|
||||
</div>`;let s=this._objects.find(c=>c.entry_id===e.entry)?.tasks??0;return n`<div class="summary-line">
|
||||
${r("adopt_summary_existing",t).replace("{name}",e.name).replace("{before}",String(s)).replace("{after}",String(s+e.adding))}
|
||||
</div>`})}
|
||||
</div>
|
||||
`}_close(){clearTimeout(this._previewTimer),this._open=!1}_targetLabel(t,i){if(t.candidate&&this._existingEntryFor(t)===t.candidate.entry_id){let e=t.candidate.reasons.map(s=>r(`setups_reason_${s}`,i)).join(", ");return r("setups_target_match",i).replace("{name}",t.candidate.name).replace("{reasons}",e)}return this._effectiveName(t)}render(){if(!this._open)return n``;let t=this._lang,i=this._sensors.length>0&&this._selected.size===this._sensors.length;return n`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||
<div class="title">${r("adopt_problem_title",t)}</div>
|
||||
<div class="hint">${r("adopt_problem_hint",t)}</div>
|
||||
${this._error?n`<div class="error">${this._error}</div>`:l}
|
||||
|
||||
${this._loading?n`<div class="loading">…</div>`:this._sensors.length===0?n`<div class="empty">${r("adopt_problem_none",t)}</div>`:n`
|
||||
<label class="select-all">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${i}
|
||||
@change=${this._toggleAll}
|
||||
/>
|
||||
<span>${r("selected",t)}: ${this._selected.size} / ${this._sensors.length}</span>
|
||||
</label>
|
||||
<div class="row-sub adopt-object-hint">${r("adopt_object_hint",t)}</div>
|
||||
<datalist id="adopt-object-names">
|
||||
${this._objects.map(e=>n`<option value=${e.name}></option>`)}
|
||||
</datalist>
|
||||
<div class="list">
|
||||
${this._sensors.map(e=>{let s=this._selected.has(e.entity_id),c=e.state==="on",_=[e.device_name,e.area_name].filter(Boolean).join(" \xB7 ");return n`
|
||||
<label class="row">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${s}
|
||||
@change=${()=>this._toggle(e.entity_id)}
|
||||
/>
|
||||
<div class="row-main">
|
||||
<div class="row-top">
|
||||
<span class="row-name">${e.name}</span>
|
||||
<span class="chip ${c?"chip-active":"chip-ok"}">
|
||||
${c?r("adopt_problem_active",t):r("adopt_problem_ok",t)}
|
||||
</span>
|
||||
</div>
|
||||
${_?n`<div class="row-sub">${_}</div>`:l}
|
||||
${s?n`<div class="row-object" @click=${p=>p.stopPropagation()}>
|
||||
<input
|
||||
class="adopt-object"
|
||||
list="adopt-object-names"
|
||||
aria-label=${r("object",t)}
|
||||
placeholder=${this._defaultName(e)}
|
||||
.value=${this._objectNames[e.entity_id]??this._defaultName(e)}
|
||||
@input=${p=>{this._objectNames={...this._objectNames,[e.entity_id]:p.target.value},this._schedulePreview()}}
|
||||
/>
|
||||
</div>`:l}
|
||||
<div class="row-target">
|
||||
→ ${this._targetLabel(e,t)}${this._existingEntryFor(e)?l:n` <span class="new-tag">${r("adopt_problem_new_object",t)}</span>`}
|
||||
</div>
|
||||
${this._covered[e.entity_id]?n`<div class="maybe">
|
||||
${r("setups_maybe_covered",t).replace("{name}",this._covered[e.entity_id].name)}
|
||||
</div>`:l}
|
||||
${e.suggested_part_name?n`<div class="row-part">
|
||||
<ha-icon icon="mdi:package-variant-closed"></ha-icon>
|
||||
${r("adopt_problem_part",t).replace("{name}",e.suggested_part_name)}
|
||||
</div>`:l}
|
||||
</div>
|
||||
</label>
|
||||
`})}
|
||||
</div>
|
||||
`}
|
||||
|
||||
${!this._loading&&this._sensors.length>0?this._summary(t):l}
|
||||
|
||||
${!this._loading&&this._sensors.length>0?n`
|
||||
<label class="responsible">
|
||||
<span>${r("for_at_least_minutes",t)}</span>
|
||||
<input
|
||||
class="for-input"
|
||||
type="number"
|
||||
min=${m[0]}
|
||||
max=${m[1]}
|
||||
.value=${this._forMinutes}
|
||||
@input=${e=>this._forMinutes=e.target.value}
|
||||
/>
|
||||
</label>
|
||||
<div class="for-hint">${r("adopt_for_minutes_hint",t)}</div>
|
||||
`:l}
|
||||
|
||||
${!this._loading&&this._sensors.length>0&&this._users.length>0?n`
|
||||
<label class="responsible">
|
||||
<span>${r("adopt_problem_responsible",t)}</span>
|
||||
<select
|
||||
.value=${this._responsible}
|
||||
@change=${e=>{this._responsible=e.target.value}}
|
||||
>
|
||||
<option value="" ?selected=${!this._responsible}>${r("no_user_assigned",t)}</option>
|
||||
${this._users.map(e=>n`<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}>
|
||||
${r("cancel",t)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._adopt}
|
||||
.disabled=${this._selected.size===0||this._adopting}
|
||||
>
|
||||
${r("adopt_problem_adopt",t)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`}};a.styles=u`
|
||||
.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-object { margin-top: 6px; }
|
||||
.row-object input {
|
||||
width: 100%; box-sizing: border-box; padding: 6px 8px; font: inherit;
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
background: var(--card-background-color); color: var(--primary-text-color);
|
||||
}
|
||||
.adopt-object-hint { margin: 0 0 8px; }
|
||||
.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;
|
||||
}
|
||||
.maybe {
|
||||
font-size: 11px;
|
||||
color: var(--warning-color, #ff9800);
|
||||
}
|
||||
.summary {
|
||||
font-size: 12px;
|
||||
border-top: 1px dashed var(--divider-color);
|
||||
padding-top: 6px;
|
||||
}
|
||||
.summary-title {
|
||||
font-weight: 500;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.summary-line {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.for-input {
|
||||
width: 70px;
|
||||
background: var(--card-background-color);
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 4px;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
.for-hint {
|
||||
font-size: 11px;
|
||||
color: var(--secondary-text-color);
|
||||
margin: -4px 0 2px;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
`,o([g({attribute:!1})],a.prototype,"hass",2),o([d()],a.prototype,"_open",2),o([d()],a.prototype,"_loading",2),o([d()],a.prototype,"_adopting",2),o([d()],a.prototype,"_error",2),o([d()],a.prototype,"_sensors",2),o([d()],a.prototype,"_selected",2),o([d()],a.prototype,"_objectNames",2),o([d()],a.prototype,"_objects",2),o([d()],a.prototype,"_covered",2),o([d()],a.prototype,"_users",2),o([d()],a.prototype,"_responsible",2),o([d()],a.prototype,"_forMinutes",2);customElements.get("maintenance-adopt-problem-sensors-dialog")||customElements.define("maintenance-adopt-problem-sensors-dialog",a);export{a as MaintenanceAdoptProblemSensorsDialog};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{e as y}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-FFPNBBZ6.js";import{d as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-QFIANZWP.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-MN2RZ73S.js";import{H as b,a as o,b as u,c as n,f as l,h as v,l as g,m as d,s as r,u as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._objectNames={};this._objects=[];this._covered={};this._users=[];this._responsible="";this._forMinutes="0";this._localeReady=!1;this._userService=null;this._toggle=t=>{let i=new Set(this._selected);i.has(t)?i.delete(t):i.add(t),this._selected=i};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(t=>t.entity_id))};this._adopt=async()=>{if(this._selected.size===0||this._adopting)return;this._error="";let t=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:this._existingEntryFor(e)??void 0,object_name:this._effectiveName(e),device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0,for_minutes:parseInt(this._forMinutes,10)>0?parseInt(this._forMinutes,10):void 0})),i=await h(this,{type:"maintenance_supporter/problem_sensors/adopt",selections:t},{busy:e=>{this._adopting=e},onError:e=>{this._error=e}});i!==void 0&&(this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:i})),this._open=!1)}}get _lang(){return b(this.hass)}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._sensors=[],this._selected=new Set,this._objectNames={},this._responsible="",this._forMinutes="0",this._userService?this._userService.updateHass(this.hass):this._userService=new y(this.hass);let[t,i,e]=await Promise.all([h(this,{type:"maintenance_supporter/problem_sensors/discover"},{onError:s=>{this._error=s}}),this._userService.getUsers().catch(()=>[]),this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"}).catch(()=>({objects:[]}))]);this._loading=!1,t!==void 0&&(this._objects=(e?.objects||[]).filter(s=>!s.object.archived_at).map(s=>({entry_id:s.entry_id,name:s.object.name,tasks:(s.tasks||[]).length})),this._sensors=t?.sensors||[],this._covered=Object.fromEntries(this._sensors.map(s=>[s.entity_id,s.covered_by??null])),this._selected=new Set(this._sensors.filter(s=>!s.covered_by).map(s=>s.entity_id)),this._users=i)}_defaultName(t){return t.suggested_entry_id?t.suggested_object_name:t.candidate?.name??t.suggested_object_name}_effectiveName(t){return(this._objectNames[t.entity_id]??"").trim()||this._defaultName(t)}_existingEntryFor(t){let i=this._effectiveName(t),e=t.suggested_entry_id||t.target_entry_id||null;if(i===this._defaultName(t)&&e)return e;let s=this._objects.find(c=>c.name.trim().toLowerCase()===i.toLowerCase());return s?s.entry_id:null}_schedulePreview(){clearTimeout(this._previewTimer),this._previewTimer=setTimeout(()=>{this._preview()},350)}async _preview(){let t=this._sensors.map(e=>({entity_id:e.entity_id,name:e.name,entry_id:this._existingEntryFor(e)})),i=await h(this,{type:"maintenance_supporter/problem_sensors/preview",selections:t},{onError:()=>{}});i?.covered&&(this._covered={...this._covered,...i.covered})}_summary(t){let i=new Map;for(let e of this._sensors){if(!this._selected.has(e.entity_id))continue;let s=this._existingEntryFor(e),c=this._effectiveName(e),_=s??`new:${c.toLowerCase()}`,p=i.get(_)??{name:c,entry:s,adding:0};p.adding+=1,i.set(_,p)}return i.size===0?l:n`
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
import{e as y}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-QKL6SKIH.js";import{d as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-M2CMCNR4.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-5USKKRUA.js";import{H as b,a as o,b as u,c as n,f as l,h as v,l as g,m as d,s as r,u as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZW2EWBUR.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._objectNames={};this._objects=[];this._covered={};this._users=[];this._responsible="";this._forMinutes="0";this._localeReady=!1;this._userService=null;this._toggle=t=>{let i=new Set(this._selected);i.has(t)?i.delete(t):i.add(t),this._selected=i};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(t=>t.entity_id))};this._adopt=async()=>{if(this._selected.size===0||this._adopting)return;this._error="";let t=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:this._existingEntryFor(e)??void 0,object_name:this._effectiveName(e),device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0,for_minutes:parseInt(this._forMinutes,10)>0?parseInt(this._forMinutes,10):void 0})),i=await h(this,{type:"maintenance_supporter/problem_sensors/adopt",selections:t},{busy:e=>{this._adopting=e},onError:e=>{this._error=e}});i!==void 0&&(this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:i})),this._open=!1)}}get _lang(){return b(this.hass)}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._sensors=[],this._selected=new Set,this._objectNames={},this._responsible="",this._forMinutes="0",this._userService?this._userService.updateHass(this.hass):this._userService=new y(this.hass);let[t,i,e]=await Promise.all([h(this,{type:"maintenance_supporter/problem_sensors/discover"},{onError:s=>{this._error=s}}),this._userService.getUsers().catch(()=>[]),this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"}).catch(()=>({objects:[]}))]);this._loading=!1,t!==void 0&&(this._objects=(e?.objects||[]).filter(s=>!s.object.archived_at).map(s=>({entry_id:s.entry_id,name:s.object.name,tasks:(s.tasks||[]).length})),this._sensors=t?.sensors||[],this._covered=Object.fromEntries(this._sensors.map(s=>[s.entity_id,s.covered_by??null])),this._selected=new Set(this._sensors.filter(s=>!s.covered_by).map(s=>s.entity_id)),this._users=i)}_defaultName(t){return t.suggested_entry_id?t.suggested_object_name:t.candidate?.name??t.suggested_object_name}_effectiveName(t){return(this._objectNames[t.entity_id]??"").trim()||this._defaultName(t)}_existingEntryFor(t){let i=this._effectiveName(t),e=t.suggested_entry_id||t.target_entry_id||null;if(i===this._defaultName(t)&&e)return e;let s=this._objects.find(c=>c.name.trim().toLowerCase()===i.toLowerCase());return s?s.entry_id:null}_schedulePreview(){clearTimeout(this._previewTimer),this._previewTimer=setTimeout(()=>{this._preview()},350)}async _preview(){let t=this._sensors.map(e=>({entity_id:e.entity_id,name:e.name,entry_id:this._existingEntryFor(e)})),i=await h(this,{type:"maintenance_supporter/problem_sensors/preview",selections:t},{onError:()=>{}});i?.covered&&(this._covered={...this._covered,...i.covered})}_summary(t){let i=new Map;for(let e of this._sensors){if(!this._selected.has(e.entity_id))continue;let s=this._existingEntryFor(e),c=this._effectiveName(e),_=s??`new:${c.toLowerCase()}`,p=i.get(_)??{name:c,entry:s,adding:0};p.adding+=1,i.set(_,p)}return i.size===0?l:n`
|
||||
<div class="summary">
|
||||
<div class="summary-title">${r("adopt_summary_title",t)}</div>
|
||||
${[...i.values()].map(e=>{if(!e.entry)return n`<div class="summary-line new">
|
||||
-301
@@ -1,301 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
import{e as y}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-PCR5FRSH.js";import{d as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-RHKFQ4Q2.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GM2CHGSG.js";import{H as b,a as o,b as u,c as n,f as l,h as v,l as g,m as d,s as r,u as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-3FGYBPXY.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._objectNames={};this._objects=[];this._covered={};this._users=[];this._responsible="";this._forMinutes="0";this._localeReady=!1;this._userService=null;this._toggle=t=>{let i=new Set(this._selected);i.has(t)?i.delete(t):i.add(t),this._selected=i};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(t=>t.entity_id))};this._adopt=async()=>{if(this._selected.size===0||this._adopting)return;this._error="";let t=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:this._existingEntryFor(e)??void 0,object_name:this._effectiveName(e),device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0,for_minutes:parseInt(this._forMinutes,10)>0?parseInt(this._forMinutes,10):void 0})),i=await h(this,{type:"maintenance_supporter/problem_sensors/adopt",selections:t},{busy:e=>{this._adopting=e},onError:e=>{this._error=e}});i!==void 0&&(this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:i})),this._open=!1)}}get _lang(){return b(this.hass)}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._sensors=[],this._selected=new Set,this._objectNames={},this._responsible="",this._forMinutes="0",this._userService?this._userService.updateHass(this.hass):this._userService=new y(this.hass);let[t,i,e]=await Promise.all([h(this,{type:"maintenance_supporter/problem_sensors/discover"},{onError:s=>{this._error=s}}),this._userService.getUsers().catch(()=>[]),this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"}).catch(()=>({objects:[]}))]);this._loading=!1,t!==void 0&&(this._objects=(e?.objects||[]).filter(s=>!s.object.archived_at).map(s=>({entry_id:s.entry_id,name:s.object.name,tasks:(s.tasks||[]).length})),this._sensors=t?.sensors||[],this._covered=Object.fromEntries(this._sensors.map(s=>[s.entity_id,s.covered_by??null])),this._selected=new Set(this._sensors.filter(s=>!s.covered_by).map(s=>s.entity_id)),this._users=i)}_defaultName(t){return t.suggested_entry_id?t.suggested_object_name:t.candidate?.name??t.suggested_object_name}_effectiveName(t){return(this._objectNames[t.entity_id]??"").trim()||this._defaultName(t)}_existingEntryFor(t){let i=this._effectiveName(t),e=t.suggested_entry_id||t.target_entry_id||null;if(i===this._defaultName(t)&&e)return e;let s=this._objects.find(c=>c.name.trim().toLowerCase()===i.toLowerCase());return s?s.entry_id:null}_schedulePreview(){clearTimeout(this._previewTimer),this._previewTimer=setTimeout(()=>{this._preview()},350)}async _preview(){let t=this._sensors.map(e=>({entity_id:e.entity_id,name:e.name,entry_id:this._existingEntryFor(e)})),i=await h(this,{type:"maintenance_supporter/problem_sensors/preview",selections:t},{onError:()=>{}});i?.covered&&(this._covered={...this._covered,...i.covered})}_summary(t){let i=new Map;for(let e of this._sensors){if(!this._selected.has(e.entity_id))continue;let s=this._existingEntryFor(e),c=this._effectiveName(e),_=s??`new:${c.toLowerCase()}`,p=i.get(_)??{name:c,entry:s,adding:0};p.adding+=1,i.set(_,p)}return i.size===0?l:n`
|
||||
<div class="summary">
|
||||
<div class="summary-title">${r("adopt_summary_title",t)}</div>
|
||||
${[...i.values()].map(e=>{if(!e.entry)return n`<div class="summary-line new">
|
||||
${r("setups_new_object_count",t).replace("{name}",e.name).replace("{count}",String(e.adding))}
|
||||
</div>`;let s=this._objects.find(c=>c.entry_id===e.entry)?.tasks??0;return n`<div class="summary-line">
|
||||
${r("adopt_summary_existing",t).replace("{name}",e.name).replace("{before}",String(s)).replace("{after}",String(s+e.adding))}
|
||||
</div>`})}
|
||||
</div>
|
||||
`}_close(){clearTimeout(this._previewTimer),this._open=!1}_targetLabel(t,i){if(t.candidate&&this._existingEntryFor(t)===t.candidate.entry_id){let e=t.candidate.reasons.map(s=>r(`setups_reason_${s}`,i)).join(", ");return r("setups_target_match",i).replace("{name}",t.candidate.name).replace("{reasons}",e)}return this._effectiveName(t)}render(){if(!this._open)return n``;let t=this._lang,i=this._sensors.length>0&&this._selected.size===this._sensors.length;return n`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||
<div class="title">${r("adopt_problem_title",t)}</div>
|
||||
<div class="hint">${r("adopt_problem_hint",t)}</div>
|
||||
${this._error?n`<div class="error">${this._error}</div>`:l}
|
||||
|
||||
${this._loading?n`<div class="loading">…</div>`:this._sensors.length===0?n`<div class="empty">${r("adopt_problem_none",t)}</div>`:n`
|
||||
<label class="select-all">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${i}
|
||||
@change=${this._toggleAll}
|
||||
/>
|
||||
<span>${r("selected",t)}: ${this._selected.size} / ${this._sensors.length}</span>
|
||||
</label>
|
||||
<div class="row-sub adopt-object-hint">${r("adopt_object_hint",t)}</div>
|
||||
<datalist id="adopt-object-names">
|
||||
${this._objects.map(e=>n`<option value=${e.name}></option>`)}
|
||||
</datalist>
|
||||
<div class="list">
|
||||
${this._sensors.map(e=>{let s=this._selected.has(e.entity_id),c=e.state==="on",_=[e.device_name,e.area_name].filter(Boolean).join(" \xB7 ");return n`
|
||||
<label class="row">
|
||||
<input
|
||||
type="checkbox"
|
||||
.checked=${s}
|
||||
@change=${()=>this._toggle(e.entity_id)}
|
||||
/>
|
||||
<div class="row-main">
|
||||
<div class="row-top">
|
||||
<span class="row-name">${e.name}</span>
|
||||
<span class="chip ${c?"chip-active":"chip-ok"}">
|
||||
${c?r("adopt_problem_active",t):r("adopt_problem_ok",t)}
|
||||
</span>
|
||||
</div>
|
||||
${_?n`<div class="row-sub">${_}</div>`:l}
|
||||
${s?n`<div class="row-object" @click=${p=>p.stopPropagation()}>
|
||||
<input
|
||||
class="adopt-object"
|
||||
list="adopt-object-names"
|
||||
aria-label=${r("object",t)}
|
||||
placeholder=${this._defaultName(e)}
|
||||
.value=${this._objectNames[e.entity_id]??this._defaultName(e)}
|
||||
@input=${p=>{this._objectNames={...this._objectNames,[e.entity_id]:p.target.value},this._schedulePreview()}}
|
||||
/>
|
||||
</div>`:l}
|
||||
<div class="row-target">
|
||||
→ ${this._targetLabel(e,t)}${this._existingEntryFor(e)?l:n` <span class="new-tag">${r("adopt_problem_new_object",t)}</span>`}
|
||||
</div>
|
||||
${this._covered[e.entity_id]?n`<div class="maybe">
|
||||
${r("setups_maybe_covered",t).replace("{name}",this._covered[e.entity_id].name)}
|
||||
</div>`:l}
|
||||
${e.suggested_part_name?n`<div class="row-part">
|
||||
<ha-icon icon="mdi:package-variant-closed"></ha-icon>
|
||||
${r("adopt_problem_part",t).replace("{name}",e.suggested_part_name)}
|
||||
</div>`:l}
|
||||
</div>
|
||||
</label>
|
||||
`})}
|
||||
</div>
|
||||
`}
|
||||
|
||||
${!this._loading&&this._sensors.length>0?this._summary(t):l}
|
||||
|
||||
${!this._loading&&this._sensors.length>0?n`
|
||||
<label class="responsible">
|
||||
<span>${r("for_at_least_minutes",t)}</span>
|
||||
<input
|
||||
class="for-input"
|
||||
type="number"
|
||||
min=${m[0]}
|
||||
max=${m[1]}
|
||||
.value=${this._forMinutes}
|
||||
@input=${e=>this._forMinutes=e.target.value}
|
||||
/>
|
||||
</label>
|
||||
<div class="for-hint">${r("adopt_for_minutes_hint",t)}</div>
|
||||
`:l}
|
||||
|
||||
${!this._loading&&this._sensors.length>0&&this._users.length>0?n`
|
||||
<label class="responsible">
|
||||
<span>${r("adopt_problem_responsible",t)}</span>
|
||||
<select
|
||||
.value=${this._responsible}
|
||||
@change=${e=>{this._responsible=e.target.value}}
|
||||
>
|
||||
<option value="" ?selected=${!this._responsible}>${r("no_user_assigned",t)}</option>
|
||||
${this._users.map(e=>n`<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}>
|
||||
${r("cancel",t)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._adopt}
|
||||
.disabled=${this._selected.size===0||this._adopting}
|
||||
>
|
||||
${r("adopt_problem_adopt",t)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`}};a.styles=u`
|
||||
.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-object { margin-top: 6px; }
|
||||
.row-object input {
|
||||
width: 100%; box-sizing: border-box; padding: 6px 8px; font: inherit;
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
background: var(--card-background-color); color: var(--primary-text-color);
|
||||
}
|
||||
.adopt-object-hint { margin: 0 0 8px; }
|
||||
.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;
|
||||
}
|
||||
.maybe {
|
||||
font-size: 11px;
|
||||
color: var(--warning-color, #ff9800);
|
||||
}
|
||||
.summary {
|
||||
font-size: 12px;
|
||||
border-top: 1px dashed var(--divider-color);
|
||||
padding-top: 6px;
|
||||
}
|
||||
.summary-title {
|
||||
font-weight: 500;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.summary-line {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.for-input {
|
||||
width: 70px;
|
||||
background: var(--card-background-color);
|
||||
color: var(--primary-text-color);
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 4px;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
.for-hint {
|
||||
font-size: 11px;
|
||||
color: var(--secondary-text-color);
|
||||
margin: -4px 0 2px;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
`,o([g({attribute:!1})],a.prototype,"hass",2),o([d()],a.prototype,"_open",2),o([d()],a.prototype,"_loading",2),o([d()],a.prototype,"_adopting",2),o([d()],a.prototype,"_error",2),o([d()],a.prototype,"_sensors",2),o([d()],a.prototype,"_selected",2),o([d()],a.prototype,"_objectNames",2),o([d()],a.prototype,"_objects",2),o([d()],a.prototype,"_covered",2),o([d()],a.prototype,"_users",2),o([d()],a.prototype,"_responsible",2),o([d()],a.prototype,"_forMinutes",2);customElements.get("maintenance-adopt-problem-sensors-dialog")||customElements.define("maintenance-adopt-problem-sensors-dialog",a);export{a as MaintenanceAdoptProblemSensorsDialog};
|
||||
@@ -1,279 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import{a as W}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-AKHM2FQS.js";import{a as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-R3GKJJ55.js";import{f as T,g as K,h as M,i as z,j as Y,k as Q,l as U,m as q,n as R,o as E,p as G}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BEGYKXHI.js";import{a as A}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-5ROMA2NQ.js";import{e as F,f as I}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-Z5US4BJZ.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-O7BSORZB.js";import{f as P}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-5SGCD2J3.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-HVQDZ5QR.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-KV46GCLQ.js";import{B as g,C as y,F as O,G as S,J as C,L as N,a as b,c as p,f as v,h as B,l as k,m as j,n as w,q as D,s as a,u as H,y as L}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";function X($,i,t,s){let l=$.entries.filter(e=>e.type==="completed").sort((e,n)=>e.ts-n.ts),d=`${$.from?t.date($.from):"\u2026"} \u2013 ${$.to?t.date($.to):"\u2026"}`,r=$.totals,h=[[i.completions,t.number(r.completions)],[i.totalCost,t.cost(r.totalCost)],[i.avgCost,r.avgCost!=null?t.cost(r.avgCost):i.none],[i.totalTime,r.totalDuration?t.duration(r.totalDuration):i.none]].map(([e,n])=>`<div class="kpi"><div class="k">${o(e)}</div><div class="v">${o(n)}</div></div>`).join(""),u=$.byObject.map(e=>`<tr>
|
||||
<td>${o(e.objectName)}</td>
|
||||
<td class="num">${o(t.number(e.completions))}</td>
|
||||
<td class="num">${o(t.cost(e.cost))}</td>
|
||||
<td class="num">${o(t.share(e.share))}</td>
|
||||
</tr>`).join(""),f=$.buckets.buckets.reduce((e,n)=>Math.max(e,n.cost),0),c=$.buckets.buckets.map(e=>{let n=f>0?Math.round(e.cost/f*100):0;return`<tr>
|
||||
<td class="nowrap">${o(t.bucket(e))}</td>
|
||||
<td class="num">${o(t.number(e.completions))}</td>
|
||||
<td class="bar-cell">${n>0?`<span class="bar" style="width:${n}%"></span>`:""}</td>
|
||||
<td class="num">${o(t.cost(e.cost))}</td>
|
||||
</tr>`}).join(""),m=l.map(e=>{let n=[e.notes,e.completedBy?`${i.completedBy}: ${e.completedBy}`:null].filter(Boolean).join(" \xB7 "),x=e.phaseName?`${e.taskName} \xB7 ${e.phaseName}`:e.taskName;return`<tr>
|
||||
<td class="nowrap">${o(t.date(e.timestamp))}</td>
|
||||
<td>${o(e.objectName)}</td>
|
||||
<td>${o(x)}</td>
|
||||
<td class="num">${e.cost!=null?o(t.cost(e.cost)):o(i.none)}</td>
|
||||
<td class="num">${e.duration!=null?o(t.duration(e.duration)):o(i.none)}</td>
|
||||
<td class="notes">${o(n)||o(i.none)}</td>
|
||||
</tr>`}).join(`
|
||||
`);return`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="color-scheme" content="light">
|
||||
<title>${o(i.title)} \u2014 ${o($.areaName)}</title>
|
||||
<style>
|
||||
/* Printable sheet: it opens as a blob in whatever viewer the OS supplies
|
||||
(Companion = WebView, dark phones paint a dark default canvas), so the
|
||||
document states its own light scheme and paints its background. */
|
||||
:root { color-scheme: light; }
|
||||
* { box-sizing: border-box; }
|
||||
body { font: 13px/1.5 -apple-system, Segoe UI, Roboto, sans-serif; color: #1a1a1a; background: #fff; margin: 32px; }
|
||||
h1 { font-size: 22px; margin: 0 0 2px; }
|
||||
h2 { font-size: 15px; margin: 24px 0 8px; }
|
||||
.sub { color: #666; margin: 0 0 16px; }
|
||||
.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 0 0 8px; }
|
||||
.kpi { border: 1px solid #ddd; border-radius: 6px; padding: 8px 10px; }
|
||||
.kpi .k { color: #777; font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; }
|
||||
.kpi .v { font-size: 16px; font-weight: 600; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: #666; border-bottom: 2px solid #ccc; padding: 6px 8px; }
|
||||
td { border-bottom: 1px solid #e5e5e5; padding: 6px 8px; vertical-align: top; }
|
||||
td.num, th.num { text-align: right; white-space: nowrap; }
|
||||
td.nowrap { white-space: nowrap; }
|
||||
td.notes { color: #444; white-space: pre-wrap; }
|
||||
td.bar-cell { width: 40%; vertical-align: middle; }
|
||||
.bar { display: block; height: 10px; background: #9aa7b8; border-radius: 0 3px 3px 0;
|
||||
-webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
tfoot td { border-bottom: none; border-top: 2px solid #ccc; font-weight: 600; }
|
||||
tr { break-inside: avoid; }
|
||||
.cap-note { margin-top: 14px; color: #888; font-size: 11px; }
|
||||
@media print { body { margin: 12mm; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>${o(i.title)} \u2014 ${o($.areaName)}</h1>
|
||||
<p class="sub">${o(i.period)}: ${o(d)} \xB7 ${o(i.generated)} ${o(t.date(s))}</p>
|
||||
<div class="kpis">${h}</div>
|
||||
|
||||
<h2>${o(i.costPerObject)}</h2>
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>${o(i.colObject)}</th><th class="num">${o(i.completions)}</th>
|
||||
<th class="num">${o(i.colCost)}</th><th class="num">${o(i.share)}</th>
|
||||
</tr></thead>
|
||||
<tbody>${u||`<tr><td colspan="4">${o(i.none)}</td></tr>`}</tbody>
|
||||
<tfoot><tr>
|
||||
<td>${o(i.totalCost)}</td><td class="num">${o(t.number(r.completions))}</td>
|
||||
<td class="num">${o(t.cost(r.totalCost))}</td><td></td>
|
||||
</tr></tfoot>
|
||||
</table>
|
||||
|
||||
<h2>${o(i.costPerBucket)}</h2>
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>${o(i.period)}</th><th class="num">${o(i.completions)}</th>
|
||||
<th></th><th class="num">${o(i.colCost)}</th>
|
||||
</tr></thead>
|
||||
<tbody>${c||`<tr><td colspan="4">${o(i.none)}</td></tr>`}</tbody>
|
||||
</table>
|
||||
|
||||
<h2>${o(i.historyHeading)} (${o(t.number(l.length))})</h2>
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>${o(i.colDate)}</th><th>${o(i.colObject)}</th><th>${o(i.colTask)}</th>
|
||||
<th class="num">${o(i.colCost)}</th><th class="num">${o(i.colDuration)}</th><th>${o(i.colNotes)}</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
${m||`<tr><td colspan="6">${o(i.none)}</td></tr>`}
|
||||
</tbody>
|
||||
<tfoot><tr>
|
||||
<td colspan="3">${o(i.totalCost)}</td>
|
||||
<td class="num">${o(t.cost(r.totalCost))}</td>
|
||||
<td class="num">${r.totalDuration?o(t.duration(r.totalDuration)):""}</td><td></td>
|
||||
</tr></tfoot>
|
||||
</table>
|
||||
${$.capped?`<p class="cap-note">${o(i.capNote)}</p>`:""}
|
||||
</body>
|
||||
</html>`}var J=25,Z=5,V={completed:w.ok,missed:w.overdue,reset:w.paused,skipped:"var(--secondary-text-color)"},_=class extends B{constructor(){super(...arguments);this.areaKey="";this.objects=[];this.showArchived=!1;this.currencySymbol="";this.userName=()=>null;this._from="";this._to="";this._entryFilter="";this._taskQuery="";this._expanded=!1;this._printing=!1;this._histories=new W(this);this._localeReady=!1;this._filtersFor=null;this._memo=null}createRenderRoot(){return this}get _lang(){return L(this.hass)}willUpdate(t){if(super.willUpdate(t),t.has("areaKey")&&this._filtersFor!==this.areaKey){this._filtersFor=this.areaKey;let s=R();this._from=s.from,this._to=s.to,this._entryFilter="",this._taskQuery="",this._expanded=!1}if(t.has("objects")||t.has("areaKey")||t.has("showArchived")||t.has("hass")&&t.get("hass")===void 0){let s=this._areaObjects().flatMap(l=>l.tasks.map(d=>({entryId:l.entry_id,task:d})));this._histories.sync(this.hass,s)}}updated(t){super.updated(t),!this._localeReady&&this.hass&&(this._localeReady=!0,H(this._lang).then(()=>this.requestUpdate()))}_areaObjects(){return M(this.objects,this.areaKey,this.showArchived).sort((t,s)=>t.object.name.localeCompare(s.object.name))}_entries(t){let s=[this.objects,this.areaKey,this.showArchived,this._histories.version];if(this._memo&&this._memo.deps.every((d,r)=>d===s[r]))return this._memo.entries;let l=z(t,(d,r)=>this._histories.historyOf(d,r));return this._memo={deps:s,entries:l},l}_figures(){let t=this._areaObjects(),s=this._entries(t),l={from:this._from||null,to:this._to||null},d=Y(s,{...l,entryId:this._entryFilter||null,taskQuery:this._taskQuery}),r=this._entryFilter?t.filter(h=>h.entry_id===this._entryFilter):t;return{objects:t,entries:s,filtered:d,totals:Q(d),buckets:q(d,l),byObject:U(d,r)}}_setRange(t){this._from=t.from,this._to=t.to,this._expanded=!1}_openObject(t){this.dispatchEvent(new CustomEvent("open-object",{detail:{entryId:t},bubbles:!0,composed:!0}))}_openTask(t,s){this.dispatchEvent(new CustomEvent("open-task",{detail:{entryId:t,taskId:s},bubbles:!0,composed:!0}))}_bucketLabel(t,s){return t.month==null?String(t.year):`${N(t.month,this._lang,s)} ${t.year}`}_countText(t,s,l){let d=this._lang;return l===1?a(s,d):a(t,d).replace("{n}",g(l,d))}async _print(){if(this._printing)return;let t=I();this._printing=!0;try{await this._histories.settled()}finally{this._printing=!1}let s=this._lang,l=this.currencySymbol,{filtered:d,totals:r,buckets:h,byObject:u}=this._figures(),f={title:a("area_report_title",s),generated:a("report_generated",s),period:a("area_report_period",s),completions:a("area_kpi_completions",s),totalCost:a("total_cost",s),avgCost:a("avg_cost",s),totalTime:a("area_kpi_total_time",s),costPerObject:a("area_cost_per_object",s),costPerBucket:h.unit==="month"?a("area_cost_per_month",s):a("area_cost_per_year",s),share:a("area_cost_share",s),historyHeading:a("area_history_section",s),colDate:a("date",s),colObject:a("object",s),colTask:a("task_name",s),colCost:a("cost",s),colDuration:a("duration",s),colNotes:a("notes_label",s),completedBy:a("completed_by",s),capNote:a("object_history_cap_note",s),none:"\u2014"},c=d.filter(n=>n.type==="completed"),m=d.map(n=>({...n,completedBy:n.completedBy?this.userName(n.completedBy):null,notes:n.notes?A(n.notes,s):null})),e=X({areaName:T(this.areaKey,this.hass?.areas,a("no_area",s)),from:this._from||c[c.length-1]?.timestamp||null,to:this._to||P(new Date),totals:r,byObject:u,buckets:h,entries:m,capped:this._histories.capped},f,{date:n=>O(n,s),cost:n=>y(n,l,s),duration:n=>C(n,s),bucket:n=>this._bucketLabel(n,"long"),share:n=>`${g(n*100,s,0)} %`,number:n=>g(n,s)},new Date().toISOString());F(e,t)}_renderRangeChips(t){let s=this._lang,l=new Date,d=R(l),r=u=>this._from===u.from&&this._to===u.to,h=G(t,l.getFullYear()).slice(0,Z);return p`
|
||||
<div class="filter-chips area-range-chips">
|
||||
<button class="filter-chip ${r(d)?"active":""}" @click=${()=>this._setRange(R())}>
|
||||
${a("area_range_12m",s)}
|
||||
</button>
|
||||
${h.map(u=>p`
|
||||
<button class="filter-chip ${r(E(u))?"active":""}" @click=${()=>this._setRange(E(u))}>${u}</button>
|
||||
`)}
|
||||
<button class="filter-chip ${!this._from&&!this._to?"active":""}" @click=${()=>this._setRange({from:"",to:""})}>
|
||||
${a("area_range_all",s)}
|
||||
</button>
|
||||
</div>
|
||||
`}_renderChart(t){let s=this._lang,l=this.currencySymbol,d=t.reduce((c,m)=>Math.max(c,m.cost),0),r=t.reduce((c,m)=>Math.min(c,m.cost),0);if(d<=0&&r>=0)return p`<p class="area-empty">${a("area_no_costs",s)}</p>`;let h=c=>Math.round(c/(d-r)*1e3)/10,u=Math.max(1,Math.ceil(t.length/12)),f=t.map((c,m)=>({b:c,i:m})).filter(({i:c})=>c%u===0);return p`
|
||||
<div class="area-chart">
|
||||
<div class="area-chart-max">${y(d,l,s)}</div>
|
||||
<div class="area-chart-bars">
|
||||
${r<0?p`<div class="area-chart-zero" style="bottom: ${h(-r)}%"></div>`:v}
|
||||
${t.map(c=>{let m=`${this._bucketLabel(c,"long")}: ${y(c.cost,l,s)} \xB7 ${a("area_kpi_completions",s)}: ${g(c.completions,s)}`,e=c.cost<0?h(c.cost-r):h(-r);return p`<div class="area-bar" title=${m} aria-label=${m}>
|
||||
${c.cost!==0?p`<div class="area-bar-fill ${c.cost<0?"credit":""}" style="height: ${h(Math.abs(c.cost))}%${e?`; bottom: ${e}%`:""}"></div>`:v}
|
||||
</div>`})}
|
||||
</div>
|
||||
${r<0?p`<div class="area-chart-min">${y(r,l,s)}</div>`:v}
|
||||
<div class="area-chart-axis ${u>1?"grouped":""}">
|
||||
${f.map(({b:c,i:m})=>p`<span class="area-bar-label" style="flex-grow: ${Math.min(u,t.length-m)}">${c.month==null?String(c.year):p`${N(c.month,s,"short")}${c.month===0||m===0?p`<br />${c.year}`:v}`}</span>`)}
|
||||
</div>
|
||||
</div>
|
||||
`}render(){if(!this.hass||!this.areaKey)return v;let t=this._lang,s=this.currencySymbol,{objects:l,entries:d,filtered:r,totals:h,buckets:u,byObject:f}=this._figures(),c=l.reduce((e,n)=>e+n.tasks.filter(x=>this.showArchived||!x.archived).length,0),m=this._expanded?r:r.slice(0,J);return p`
|
||||
<div class="detail-section area-view">
|
||||
<div class="detail-header">
|
||||
<h2 class="area-title">
|
||||
<ha-icon .icon=${K(this.areaKey,this.hass.areas)}></ha-icon>
|
||||
${T(this.areaKey,this.hass.areas,a("no_area",t))}
|
||||
</h2>
|
||||
<div class="action-buttons">
|
||||
<ha-button appearance="plain" class="area-print" .disabled=${this._printing} @click=${()=>this._print()}>
|
||||
<ha-icon icon="mdi:printer-outline"></ha-icon>
|
||||
${this._printing?a("loading",t):a("area_report_print",t)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="meta">
|
||||
${this._countText("area_object_count","area_object_count_one",l.length)} ·
|
||||
${this._countText("templates_task_count","templates_task_count_one",c)}
|
||||
${this._histories.loading?p` · <span class="area-loading">${a("loading",t)}</span>`:v}
|
||||
</p>
|
||||
|
||||
${this._renderRangeChips(d)}
|
||||
<div class="filter-bar area-filters">
|
||||
<ms-date-field
|
||||
kind="date"
|
||||
clearable
|
||||
.hass=${this.hass}
|
||||
.lang=${t}
|
||||
.label=${a("date_from",t)}
|
||||
.value=${this._from}
|
||||
@value-changed=${e=>{this._from=e.detail.value}}
|
||||
></ms-date-field>
|
||||
<ms-date-field
|
||||
kind="date"
|
||||
clearable
|
||||
.hass=${this.hass}
|
||||
.lang=${t}
|
||||
.label=${a("date_to",t)}
|
||||
.value=${this._to}
|
||||
@value-changed=${e=>{this._to=e.detail.value}}
|
||||
></ms-date-field>
|
||||
<label class="filter-field">
|
||||
<span class="filter-label">${a("object",t)}</span>
|
||||
<select class="area-object-filter" .value=${this._entryFilter}
|
||||
@change=${e=>{this._entryFilter=e.target.value}}>
|
||||
<option value="" ?selected=${!this._entryFilter}>${a("all_objects",t)}</option>
|
||||
${l.map(e=>p`<option value=${e.entry_id} ?selected=${e.entry_id===this._entryFilter}>${e.object.name}</option>`)}
|
||||
</select>
|
||||
</label>
|
||||
<input
|
||||
type="search"
|
||||
class="search-input area-task-filter"
|
||||
aria-label=${a("area_task_filter",t)}
|
||||
placeholder=${a("area_task_filter",t)}
|
||||
.value=${this._taskQuery}
|
||||
@input=${e=>{this._taskQuery=e.target.value}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="kpi-bar area-kpis">
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-label">${a("area_kpi_completions",t)}</div>
|
||||
<div class="kpi-value-large area-kpi-completions">${g(h.completions,t)}</div>
|
||||
</div>
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-label">${a("total_cost",t)}</div>
|
||||
<div class="kpi-value-large area-kpi-cost">${y(h.totalCost,s,t)}</div>
|
||||
</div>
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-label">${a("avg_cost",t)}</div>
|
||||
<div class="kpi-value-large">${h.avgCost!=null?y(h.avgCost,s,t):"\u2014"}</div>
|
||||
</div>
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-label">${a("area_kpi_total_time",t)}</div>
|
||||
<div class="kpi-value-large">${h.totalDuration?C(h.totalDuration,t):"\u2014"}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>${u.unit==="month"?a("area_cost_per_month",t):a("area_cost_per_year",t)}</h3>
|
||||
${this._renderChart(u.buckets)}
|
||||
|
||||
<h3>${a("area_cost_per_object",t)}</h3>
|
||||
<div class="objects-table-wrap">
|
||||
<table class="objects-table area-object-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>${a("object",t)}</th>
|
||||
<th class="num">${a("area_kpi_completions",t)}</th>
|
||||
<th class="num">${a("cost",t)}</th>
|
||||
<th class="num">${a("area_cost_share",t)}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${f.map(e=>p`
|
||||
<tr class="objects-table-row" @click=${()=>this._openObject(e.entryId)}>
|
||||
<td><span class="objects-table-name">${e.objectName}</span></td>
|
||||
<td class="num">${g(e.completions,t)}</td>
|
||||
<td class="num">${y(e.cost,s,t)}</td>
|
||||
<td class="num">
|
||||
<span class="area-share"><span class="area-share-fill" style="width: ${Math.round(e.share*100)}%"></span></span>
|
||||
${g(e.share*100,t,0)} %
|
||||
</td>
|
||||
</tr>
|
||||
`)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3>
|
||||
${a("area_history_section",t)}
|
||||
<span class="area-count">${g(r.length,t)}</span>
|
||||
</h3>
|
||||
${r.length===0?p`<p class="area-empty">${a("object_history_empty",t)}</p>`:p`
|
||||
<div class="objects-table-wrap">
|
||||
<table class="objects-table area-history-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>${a("date",t)}</th>
|
||||
<th></th>
|
||||
<th>${a("object",t)}</th>
|
||||
<th>${a("task_name",t)}</th>
|
||||
<th class="num">${a("cost",t)}</th>
|
||||
<th class="num">${a("duration",t)}</th>
|
||||
<th>${a("notes_label",t)}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${m.map(e=>{let n=e.notes?A(e.notes,t):"";return p`
|
||||
<tr class="objects-table-row area-history-row" @click=${()=>this._openTask(e.entryId,e.taskId)}>
|
||||
<td title=${S(e.timestamp,t)}>${O(e.timestamp,t)}</td>
|
||||
<td>
|
||||
<span class="area-entry-type" style="color: ${V[e.type]??"inherit"}">
|
||||
<ha-icon .icon=${D[e.type]||"mdi:circle"}></ha-icon>${a(e.type,t)}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button class="area-object-link" @click=${x=>{x.stopPropagation(),this._openObject(e.entryId)}}>
|
||||
${e.objectName}
|
||||
</button>
|
||||
</td>
|
||||
<td><button class="area-task-link">${e.taskName}${e.phaseName?` \xB7 ${e.phaseName}`:""}</button></td>
|
||||
<td class="num">${e.cost!=null?y(e.cost,s,t):"\u2014"}</td>
|
||||
<td class="num">${e.duration!=null?C(e.duration,t):"\u2014"}</td>
|
||||
<td class="oc-notes" title=${n}>${n||"\u2014"}</td>
|
||||
</tr>
|
||||
`})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
${r.length>m.length?p`<ha-button appearance="plain" class="area-more" @click=${()=>{this._expanded=!0}}>
|
||||
${a("show_all",t)} (${g(r.length,t)})
|
||||
</ha-button>`:v}
|
||||
`}
|
||||
${this._histories.capped?p`<p class="area-cap-note">${a("object_history_cap_note",t)}</p>`:v}
|
||||
</div>
|
||||
`}};b([k({attribute:!1})],_.prototype,"hass",2),b([k()],_.prototype,"areaKey",2),b([k({attribute:!1})],_.prototype,"objects",2),b([k({type:Boolean})],_.prototype,"showArchived",2),b([k()],_.prototype,"currencySymbol",2),b([k({attribute:!1})],_.prototype,"userName",2),b([j()],_.prototype,"_from",2),b([j()],_.prototype,"_to",2),b([j()],_.prototype,"_entryFilter",2),b([j()],_.prototype,"_taskQuery",2),b([j()],_.prototype,"_expanded",2),b([j()],_.prototype,"_printing",2);customElements.get("maintenance-area-view")||customElements.define("maintenance-area-view",_);export{_ as MaintenanceAreaView};
|
||||
@@ -1,279 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
import{a as X}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-MQRW7LAF.js";import{a as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-5MYBEQC2.js";import{f as E,g as M,h as z,i as Q,j as U,k as Y,l as q,m as G,n as R,o as A,p as W}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-MGSZZ3YF.js";import{a as B}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-EKN6HBJN.js";import{e as P,f as K}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DRT62KZF.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-SYPCMUXO.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-55ND3GKE.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-RUYEMIDM.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-JQXHX4U4.js";import{B as S,H as F,K as g,L as v,O as N,P as I,T as w,V as T,a as $,c as p,f as y,h as H,l as k,m as j,n as C,q as D,s as a,u as L,y as O}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-3FGYBPXY.js";function J(b,i,t,s){let l=b.entries.filter(e=>e.type==="completed").sort((e,n)=>e.ts-n.ts),d=`${b.from?t.date(b.from):"\u2026"} \u2013 ${b.to?t.date(b.to):"\u2026"}`,r=b.totals,h=[[i.completions,t.number(r.completions)],[i.totalCost,t.cost(r.totalCost)],[i.avgCost,r.avgCost!=null?t.cost(r.avgCost):i.none],[i.totalTime,r.totalDuration?t.duration(r.totalDuration):i.none]].map(([e,n])=>`<div class="kpi"><div class="k">${o(e)}</div><div class="v">${o(n)}</div></div>`).join(""),u=b.byObject.map(e=>`<tr>
|
||||
<td>${o(e.objectName)}</td>
|
||||
<td class="num">${o(t.number(e.completions))}</td>
|
||||
<td class="num">${o(t.cost(e.cost))}</td>
|
||||
<td class="num">${o(t.share(e.share))}</td>
|
||||
</tr>`).join(""),f=b.buckets.buckets.reduce((e,n)=>Math.max(e,n.cost),0),c=b.buckets.buckets.map(e=>{let n=f>0?Math.round(e.cost/f*100):0;return`<tr>
|
||||
<td class="nowrap">${o(t.bucket(e))}</td>
|
||||
<td class="num">${o(t.number(e.completions))}</td>
|
||||
<td class="bar-cell">${n>0?`<span class="bar" style="width:${n}%"></span>`:""}</td>
|
||||
<td class="num">${o(t.cost(e.cost))}</td>
|
||||
</tr>`}).join(""),m=l.map(e=>{let n=[e.notes,e.completedBy?`${i.completedBy}: ${e.completedBy}`:null].filter(Boolean).join(" \xB7 "),x=e.phaseName?`${e.taskName} \xB7 ${e.phaseName}`:e.taskName;return`<tr>
|
||||
<td class="nowrap">${o(t.date(e.timestamp))}</td>
|
||||
<td>${o(e.objectName)}</td>
|
||||
<td>${o(x)}</td>
|
||||
<td class="num">${e.cost!=null?o(t.cost(e.cost)):o(i.none)}</td>
|
||||
<td class="num">${e.duration!=null?o(t.duration(e.duration)):o(i.none)}</td>
|
||||
<td class="notes">${o(n)||o(i.none)}</td>
|
||||
</tr>`}).join(`
|
||||
`);return`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="color-scheme" content="light">
|
||||
<title>${o(i.title)} \u2014 ${o(b.areaName)}</title>
|
||||
<style>
|
||||
/* Printable sheet: it opens as a blob in whatever viewer the OS supplies
|
||||
(Companion = WebView, dark phones paint a dark default canvas), so the
|
||||
document states its own light scheme and paints its background. */
|
||||
:root { color-scheme: light; }
|
||||
* { box-sizing: border-box; }
|
||||
body { font: 13px/1.5 -apple-system, Segoe UI, Roboto, sans-serif; color: #1a1a1a; background: #fff; margin: 32px; }
|
||||
h1 { font-size: 22px; margin: 0 0 2px; }
|
||||
h2 { font-size: 15px; margin: 24px 0 8px; }
|
||||
.sub { color: #666; margin: 0 0 16px; }
|
||||
.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 0 0 8px; }
|
||||
.kpi { border: 1px solid #ddd; border-radius: 6px; padding: 8px 10px; }
|
||||
.kpi .k { color: #777; font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; }
|
||||
.kpi .v { font-size: 16px; font-weight: 600; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: #666; border-bottom: 2px solid #ccc; padding: 6px 8px; }
|
||||
td { border-bottom: 1px solid #e5e5e5; padding: 6px 8px; vertical-align: top; }
|
||||
td.num, th.num { text-align: right; white-space: nowrap; }
|
||||
td.nowrap { white-space: nowrap; }
|
||||
td.notes { color: #444; white-space: pre-wrap; }
|
||||
td.bar-cell { width: 40%; vertical-align: middle; }
|
||||
.bar { display: block; height: 10px; background: #9aa7b8; border-radius: 0 3px 3px 0;
|
||||
-webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
tfoot td { border-bottom: none; border-top: 2px solid #ccc; font-weight: 600; }
|
||||
tr { break-inside: avoid; }
|
||||
.cap-note { margin-top: 14px; color: #888; font-size: 11px; }
|
||||
@media print { body { margin: 12mm; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>${o(i.title)} \u2014 ${o(b.areaName)}</h1>
|
||||
<p class="sub">${o(i.period)}: ${o(d)} \xB7 ${o(i.generated)} ${o(t.date(s))}</p>
|
||||
<div class="kpis">${h}</div>
|
||||
|
||||
<h2>${o(i.costPerObject)}</h2>
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>${o(i.colObject)}</th><th class="num">${o(i.completions)}</th>
|
||||
<th class="num">${o(i.colCost)}</th><th class="num">${o(i.share)}</th>
|
||||
</tr></thead>
|
||||
<tbody>${u||`<tr><td colspan="4">${o(i.none)}</td></tr>`}</tbody>
|
||||
<tfoot><tr>
|
||||
<td>${o(i.totalCost)}</td><td class="num">${o(t.number(r.completions))}</td>
|
||||
<td class="num">${o(t.cost(r.totalCost))}</td><td></td>
|
||||
</tr></tfoot>
|
||||
</table>
|
||||
|
||||
<h2>${o(i.costPerBucket)}</h2>
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>${o(i.period)}</th><th class="num">${o(i.completions)}</th>
|
||||
<th></th><th class="num">${o(i.colCost)}</th>
|
||||
</tr></thead>
|
||||
<tbody>${c||`<tr><td colspan="4">${o(i.none)}</td></tr>`}</tbody>
|
||||
</table>
|
||||
|
||||
<h2>${o(i.historyHeading)} (${o(t.number(l.length))})</h2>
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>${o(i.colDate)}</th><th>${o(i.colObject)}</th><th>${o(i.colTask)}</th>
|
||||
<th class="num">${o(i.colCost)}</th><th class="num">${o(i.colDuration)}</th><th>${o(i.colNotes)}</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
${m||`<tr><td colspan="6">${o(i.none)}</td></tr>`}
|
||||
</tbody>
|
||||
<tfoot><tr>
|
||||
<td colspan="3">${o(i.totalCost)}</td>
|
||||
<td class="num">${o(t.cost(r.totalCost))}</td>
|
||||
<td class="num">${r.totalDuration?o(t.duration(r.totalDuration)):""}</td><td></td>
|
||||
</tr></tfoot>
|
||||
</table>
|
||||
${b.capped?`<p class="cap-note">${o(i.capNote)}</p>`:""}
|
||||
</body>
|
||||
</html>`}var Z=25,V=5,tt={completed:C.ok,missed:C.overdue,reset:C.paused,skipped:"var(--secondary-text-color)"},_=class extends H{constructor(){super(...arguments);this.areaKey="";this.objects=[];this.showArchived=!1;this.currencySymbol="";this.userName=()=>null;this._from="";this._to="";this._entryFilter="";this._taskQuery="";this._expanded=!1;this._printing=!1;this._histories=new X(this);this._localeReady=!1;this._filtersFor=null;this._memo=null}createRenderRoot(){return this}get _lang(){return F(this.hass)}willUpdate(t){if(super.willUpdate(t),t.has("areaKey")&&this._filtersFor!==this.areaKey){this._filtersFor=this.areaKey;let s=R();this._from=s.from,this._to=s.to,this._entryFilter="",this._taskQuery="",this._expanded=!1}if(t.has("objects")||t.has("areaKey")||t.has("showArchived")||t.has("hass")&&t.get("hass")===void 0){let s=this._areaObjects().flatMap(l=>l.tasks.map(d=>({entryId:l.entry_id,task:d})));this._histories.sync(this.hass,s)}}updated(t){super.updated(t),!this._localeReady&&this.hass&&(this._localeReady=!0,L(this._lang).then(()=>this.requestUpdate()))}_areaObjects(){return z(this.objects,this.areaKey,this.showArchived).sort((t,s)=>t.object.name.localeCompare(s.object.name))}_entries(t){let s=[this.objects,this.areaKey,this.showArchived,this._histories.version];if(this._memo&&this._memo.deps.every((d,r)=>d===s[r]))return this._memo.entries;let l=Q(t,(d,r)=>this._histories.historyOf(d,r));return this._memo={deps:s,entries:l},l}_figures(){let t=this._areaObjects(),s=this._entries(t),l={from:this._from||null,to:this._to||null},d=U(s,{...l,entryId:this._entryFilter||null,taskQuery:this._taskQuery}),r=this._entryFilter?t.filter(h=>h.entry_id===this._entryFilter):t;return{objects:t,entries:s,filtered:d,totals:Y(d),buckets:G(d,l),byObject:q(d,r)}}_setRange(t){this._from=t.from,this._to=t.to,this._expanded=!1}_openObject(t){this.dispatchEvent(new CustomEvent("open-object",{detail:{entryId:t},bubbles:!0,composed:!0}))}_openTask(t,s){this.dispatchEvent(new CustomEvent("open-task",{detail:{entryId:t,taskId:s},bubbles:!0,composed:!0}))}_bucketLabel(t,s){return t.month==null?String(t.year):`${T(t.month,this._lang,s)} ${t.year}`}_countText(t,s,l){let d=this._lang;return l===1?a(s,d):a(t,d).replace("{n}",g(l,d))}async _print(){if(this._printing)return;let t=K();this._printing=!0;try{await this._histories.settled()}finally{this._printing=!1}let s=this._lang,l=this.currencySymbol,{filtered:d,totals:r,buckets:h,byObject:u}=this._figures(),f={title:a("area_report_title",s),generated:a("report_generated",s),period:a("area_report_period",s),completions:a("area_kpi_completions",s),totalCost:a("total_cost",s),avgCost:a("avg_cost",s),totalTime:a("area_kpi_total_time",s),costPerObject:a("area_cost_per_object",s),costPerBucket:h.unit==="month"?a("area_cost_per_month",s):a("area_cost_per_year",s),share:a("area_cost_share",s),historyHeading:a("area_history_section",s),colDate:a("date",s),colObject:a("object",s),colTask:a("task_name",s),colCost:a("cost",s),colDuration:a("duration",s),colNotes:a("notes_label",s),completedBy:a("completed_by",s),capNote:a("object_history_cap_note",s),none:"\u2014"},c=d.filter(n=>n.type==="completed"),m=d.map(n=>({...n,completedBy:n.completedBy?this.userName(n.completedBy):null,notes:n.notes?B(n.notes,s):null})),e=J({areaName:E(this.areaKey,this.hass?.areas,a("no_area",s)),from:this._from||S(c[c.length-1]?.timestamp)||null,to:this._to||O(),totals:r,byObject:u,buckets:h,entries:m,capped:this._histories.capped},f,{date:n=>N(n,s),cost:n=>v(n,l,s),duration:n=>w(n,s),bucket:n=>this._bucketLabel(n,"long"),share:n=>`${g(n*100,s,0)} %`,number:n=>g(n,s)},new Date().toISOString());P(e,t)}_renderRangeChips(t){let s=this._lang,l=O(),d=R(l),r=u=>this._from===u.from&&this._to===u.to,h=W(t,Number(l.slice(0,4))).slice(0,V);return p`
|
||||
<div class="filter-chips area-range-chips">
|
||||
<button class="filter-chip ${r(d)?"active":""}" @click=${()=>this._setRange(R())}>
|
||||
${a("area_range_12m",s)}
|
||||
</button>
|
||||
${h.map(u=>p`
|
||||
<button class="filter-chip ${r(A(u))?"active":""}" @click=${()=>this._setRange(A(u))}>${u}</button>
|
||||
`)}
|
||||
<button class="filter-chip ${!this._from&&!this._to?"active":""}" @click=${()=>this._setRange({from:"",to:""})}>
|
||||
${a("area_range_all",s)}
|
||||
</button>
|
||||
</div>
|
||||
`}_renderChart(t){let s=this._lang,l=this.currencySymbol,d=t.reduce((c,m)=>Math.max(c,m.cost),0),r=t.reduce((c,m)=>Math.min(c,m.cost),0);if(d<=0&&r>=0)return p`<p class="area-empty">${a("area_no_costs",s)}</p>`;let h=c=>Math.round(c/(d-r)*1e3)/10,u=Math.max(1,Math.ceil(t.length/12)),f=t.map((c,m)=>({b:c,i:m})).filter(({i:c})=>c%u===0);return p`
|
||||
<div class="area-chart">
|
||||
<div class="area-chart-max">${v(d,l,s)}</div>
|
||||
<div class="area-chart-bars">
|
||||
${r<0?p`<div class="area-chart-zero" style="bottom: ${h(-r)}%"></div>`:y}
|
||||
${t.map(c=>{let m=`${this._bucketLabel(c,"long")}: ${v(c.cost,l,s)} \xB7 ${a("area_kpi_completions",s)}: ${g(c.completions,s)}`,e=c.cost<0?h(c.cost-r):h(-r);return p`<div class="area-bar" title=${m} aria-label=${m}>
|
||||
${c.cost!==0?p`<div class="area-bar-fill ${c.cost<0?"credit":""}" style="height: ${h(Math.abs(c.cost))}%${e?`; bottom: ${e}%`:""}"></div>`:y}
|
||||
</div>`})}
|
||||
</div>
|
||||
${r<0?p`<div class="area-chart-min">${v(r,l,s)}</div>`:y}
|
||||
<div class="area-chart-axis ${u>1?"grouped":""}">
|
||||
${f.map(({b:c,i:m})=>p`<span class="area-bar-label" style="flex-grow: ${Math.min(u,t.length-m)}">${c.month==null?String(c.year):p`${T(c.month,s,"short")}${c.month===0||m===0?p`<br />${c.year}`:y}`}</span>`)}
|
||||
</div>
|
||||
</div>
|
||||
`}render(){if(!this.hass||!this.areaKey)return y;let t=this._lang,s=this.currencySymbol,{objects:l,entries:d,filtered:r,totals:h,buckets:u,byObject:f}=this._figures(),c=l.reduce((e,n)=>e+n.tasks.filter(x=>this.showArchived||!x.archived).length,0),m=this._expanded?r:r.slice(0,Z);return p`
|
||||
<div class="detail-section area-view">
|
||||
<div class="detail-header">
|
||||
<h2 class="area-title">
|
||||
<ha-icon .icon=${M(this.areaKey,this.hass.areas)}></ha-icon>
|
||||
${E(this.areaKey,this.hass.areas,a("no_area",t))}
|
||||
</h2>
|
||||
<div class="action-buttons">
|
||||
<ha-button appearance="plain" class="area-print" .disabled=${this._printing} @click=${()=>this._print()}>
|
||||
<ha-icon icon="mdi:printer-outline"></ha-icon>
|
||||
${this._printing?a("loading",t):a("area_report_print",t)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="meta">
|
||||
${this._countText("area_object_count","area_object_count_one",l.length)} ·
|
||||
${this._countText("templates_task_count","templates_task_count_one",c)}
|
||||
${this._histories.loading?p` · <span class="area-loading">${a("loading",t)}</span>`:y}
|
||||
</p>
|
||||
|
||||
${this._renderRangeChips(d)}
|
||||
<div class="filter-bar area-filters">
|
||||
<ms-date-field
|
||||
kind="date"
|
||||
clearable
|
||||
.hass=${this.hass}
|
||||
.lang=${t}
|
||||
.label=${a("date_from",t)}
|
||||
.value=${this._from}
|
||||
@value-changed=${e=>{this._from=e.detail.value}}
|
||||
></ms-date-field>
|
||||
<ms-date-field
|
||||
kind="date"
|
||||
clearable
|
||||
.hass=${this.hass}
|
||||
.lang=${t}
|
||||
.label=${a("date_to",t)}
|
||||
.value=${this._to}
|
||||
@value-changed=${e=>{this._to=e.detail.value}}
|
||||
></ms-date-field>
|
||||
<label class="filter-field">
|
||||
<span class="filter-label">${a("object",t)}</span>
|
||||
<select class="area-object-filter" .value=${this._entryFilter}
|
||||
@change=${e=>{this._entryFilter=e.target.value}}>
|
||||
<option value="" ?selected=${!this._entryFilter}>${a("all_objects",t)}</option>
|
||||
${l.map(e=>p`<option value=${e.entry_id} ?selected=${e.entry_id===this._entryFilter}>${e.object.name}</option>`)}
|
||||
</select>
|
||||
</label>
|
||||
<input
|
||||
type="search"
|
||||
class="search-input area-task-filter"
|
||||
aria-label=${a("area_task_filter",t)}
|
||||
placeholder=${a("area_task_filter",t)}
|
||||
.value=${this._taskQuery}
|
||||
@input=${e=>{this._taskQuery=e.target.value}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="kpi-bar area-kpis">
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-label">${a("area_kpi_completions",t)}</div>
|
||||
<div class="kpi-value-large area-kpi-completions">${g(h.completions,t)}</div>
|
||||
</div>
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-label">${a("total_cost",t)}</div>
|
||||
<div class="kpi-value-large area-kpi-cost">${v(h.totalCost,s,t)}</div>
|
||||
</div>
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-label">${a("avg_cost",t)}</div>
|
||||
<div class="kpi-value-large">${h.avgCost!=null?v(h.avgCost,s,t):"\u2014"}</div>
|
||||
</div>
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-label">${a("area_kpi_total_time",t)}</div>
|
||||
<div class="kpi-value-large">${h.totalDuration?w(h.totalDuration,t):"\u2014"}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>${u.unit==="month"?a("area_cost_per_month",t):a("area_cost_per_year",t)}</h3>
|
||||
${this._renderChart(u.buckets)}
|
||||
|
||||
<h3>${a("area_cost_per_object",t)}</h3>
|
||||
<div class="objects-table-wrap">
|
||||
<table class="objects-table area-object-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>${a("object",t)}</th>
|
||||
<th class="num">${a("area_kpi_completions",t)}</th>
|
||||
<th class="num">${a("cost",t)}</th>
|
||||
<th class="num">${a("area_cost_share",t)}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${f.map(e=>p`
|
||||
<tr class="objects-table-row" @click=${()=>this._openObject(e.entryId)}>
|
||||
<td><span class="objects-table-name">${e.objectName}</span></td>
|
||||
<td class="num">${g(e.completions,t)}</td>
|
||||
<td class="num">${v(e.cost,s,t)}</td>
|
||||
<td class="num">
|
||||
<span class="area-share"><span class="area-share-fill" style="width: ${Math.round(e.share*100)}%"></span></span>
|
||||
${g(e.share*100,t,0)} %
|
||||
</td>
|
||||
</tr>
|
||||
`)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3>
|
||||
${a("area_history_section",t)}
|
||||
<span class="area-count">${g(r.length,t)}</span>
|
||||
</h3>
|
||||
${r.length===0?p`<p class="area-empty">${a("object_history_empty",t)}</p>`:p`
|
||||
<div class="objects-table-wrap">
|
||||
<table class="objects-table area-history-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>${a("date",t)}</th>
|
||||
<th></th>
|
||||
<th>${a("object",t)}</th>
|
||||
<th>${a("task_name",t)}</th>
|
||||
<th class="num">${a("cost",t)}</th>
|
||||
<th class="num">${a("duration",t)}</th>
|
||||
<th>${a("notes_label",t)}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${m.map(e=>{let n=e.notes?B(e.notes,t):"";return p`
|
||||
<tr class="objects-table-row area-history-row" @click=${()=>this._openTask(e.entryId,e.taskId)}>
|
||||
<td title=${I(e.timestamp,t)}>${N(e.timestamp,t)}</td>
|
||||
<td>
|
||||
<span class="area-entry-type" style="color: ${tt[e.type]??"inherit"}">
|
||||
<ha-icon .icon=${D[e.type]||"mdi:circle"}></ha-icon>${a(e.type,t)}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button class="area-object-link" @click=${x=>{x.stopPropagation(),this._openObject(e.entryId)}}>
|
||||
${e.objectName}
|
||||
</button>
|
||||
</td>
|
||||
<td><button class="area-task-link">${e.taskName}${e.phaseName?` \xB7 ${e.phaseName}`:""}</button></td>
|
||||
<td class="num">${e.cost!=null?v(e.cost,s,t):"\u2014"}</td>
|
||||
<td class="num">${e.duration!=null?w(e.duration,t):"\u2014"}</td>
|
||||
<td class="oc-notes" title=${n}>${n||"\u2014"}</td>
|
||||
</tr>
|
||||
`})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
${r.length>m.length?p`<ha-button appearance="plain" class="area-more" @click=${()=>{this._expanded=!0}}>
|
||||
${a("show_all",t)} (${g(r.length,t)})
|
||||
</ha-button>`:y}
|
||||
`}
|
||||
${this._histories.capped?p`<p class="area-cap-note">${a("object_history_cap_note",t)}</p>`:y}
|
||||
</div>
|
||||
`}};$([k({attribute:!1})],_.prototype,"hass",2),$([k()],_.prototype,"areaKey",2),$([k({attribute:!1})],_.prototype,"objects",2),$([k({type:Boolean})],_.prototype,"showArchived",2),$([k()],_.prototype,"currencySymbol",2),$([k({attribute:!1})],_.prototype,"userName",2),$([j()],_.prototype,"_from",2),$([j()],_.prototype,"_to",2),$([j()],_.prototype,"_entryFilter",2),$([j()],_.prototype,"_taskQuery",2),$([j()],_.prototype,"_expanded",2),$([j()],_.prototype,"_printing",2);customElements.get("maintenance-area-view")||customElements.define("maintenance-area-view",_);export{_ as MaintenanceAreaView};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{a as X}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-WH65ZHYZ.js";import{a as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DY5FF6TM.js";import{f as E,g as M,h as z,i as Q,j as U,k as Y,l as q,m as G,n as R,o as A,p as W}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-S7XZBRRU.js";import{a as B}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GGO5IKKD.js";import{e as P,f as K}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DLWOWMV7.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4PKMHUVO.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-NEWWPCTD.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-QKEXGIRG.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-OUHDI2FL.js";import{B as S,H as F,K as g,L as v,O as N,P as I,T as w,V as T,a as $,c as p,f as y,h as H,l as k,m as j,n as C,q as D,s as a,u as L,y as O}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";function J(b,i,t,s){let l=b.entries.filter(e=>e.type==="completed").sort((e,n)=>e.ts-n.ts),d=`${b.from?t.date(b.from):"\u2026"} \u2013 ${b.to?t.date(b.to):"\u2026"}`,r=b.totals,h=[[i.completions,t.number(r.completions)],[i.totalCost,t.cost(r.totalCost)],[i.avgCost,r.avgCost!=null?t.cost(r.avgCost):i.none],[i.totalTime,r.totalDuration?t.duration(r.totalDuration):i.none]].map(([e,n])=>`<div class="kpi"><div class="k">${o(e)}</div><div class="v">${o(n)}</div></div>`).join(""),u=b.byObject.map(e=>`<tr>
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
import{a as X}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-W3SEDH34.js";import{a as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-UO7KFJ6R.js";import{f as E,g as M,h as z,i as Q,j as U,k as Y,l as q,m as G,n as R,o as A,p as W}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZFJHBIVS.js";import{a as B}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-JFENKV7A.js";import{e as P,f as K}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GN3YV45M.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-U7674FZW.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-Q7CGGH4O.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-PO272ATG.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-C6NCKN5O.js";import{B as S,H as F,K as g,L as v,O as N,P as I,U as w,W as T,a as $,c as p,f as y,h as H,l as k,m as j,n as C,q as D,s as a,u as L,y as O}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZW2EWBUR.js";function J(b,i,t,s){let l=b.entries.filter(e=>e.type==="completed").sort((e,n)=>e.ts-n.ts),d=`${b.from?t.date(b.from):"\u2026"} \u2013 ${b.to?t.date(b.to):"\u2026"}`,r=b.totals,h=[[i.completions,t.number(r.completions)],[i.totalCost,t.cost(r.totalCost)],[i.avgCost,r.avgCost!=null?t.cost(r.avgCost):i.none],[i.totalTime,r.totalDuration?t.duration(r.totalDuration):i.none]].map(([e,n])=>`<div class="kpi"><div class="k">${o(e)}</div><div class="v">${o(n)}</div></div>`).join(""),u=b.byObject.map(e=>`<tr>
|
||||
<td>${o(e.objectName)}</td>
|
||||
<td class="num">${o(t.number(e.completions))}</td>
|
||||
<td class="num">${o(t.cost(e.cost))}</td>
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
import{a as O}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-MQRW7LAF.js";import{q as j,r as E,s as L,t as R,u as C}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-MGSZZ3YF.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-SYPCMUXO.js";import{a as _,b as S,c as A}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-HFZZVTW7.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-55ND3GKE.js";import{H as g,K as k,L as v,O as w,a as l,c as a,f as m,h as y,l as p,m as b,s as r,u as $,y as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-3FGYBPXY.js";var q=[{key:"name",label:"area",num:!1},{key:"objects",label:"objects",num:!0},{key:"tasks",label:"tasks",num:!0},{key:"overdue",label:"overdue",num:!0},{key:"due_soon",label:"due_soon",num:!0},{key:"cost_year",label:"area_cost_year",num:!0},{key:"cost_total",label:"total_cost",num:!0},{key:"last",label:"last_performed",num:!1}],i=class extends y{constructor(){super(...arguments);this.objects=[];this.showArchived=!1;this.currencySymbol="";this._query="";this._sort=E(S(_.areaSort));this._histories=new O(this);this._localeReady=!1;this._memo=null}createRenderRoot(){return this}get _lang(){return g(this.hass)}willUpdate(t){if(super.willUpdate(t),t.has("objects")||t.has("showArchived")||t.has("hass")&&t.get("hass")===void 0){let o=this.objects.filter(s=>this.showArchived||!s.object.archived).flatMap(s=>s.tasks.map(n=>({entryId:s.entry_id,task:n})));this._histories.sync(this.hass,o)}}updated(t){super.updated(t),!this._localeReady&&this.hass&&(this._localeReady=!0,$(this._lang).then(()=>this.requestUpdate()))}_rows(t){let o=this._lang,s=[this.objects,this.showArchived,this._histories.version,this.hass?.areas,o,t];if(this._memo&&this._memo.deps.every((c,h)=>c===s[h]))return this._memo.rows;let n=j(this.objects,{showArchived:this.showArchived,areas:this.hass?.areas,noAreaLabel:r("no_area",o),year:t,historyOf:(c,h)=>this._histories.historyOf(c,h)});return this._memo={deps:s,rows:n},n}_setSort(t){this._sort=L(this._sort,t),A(_.areaSort,`${this._sort.key}:${this._sort.dir}`)}_open(t){this.dispatchEvent(new CustomEvent("open-area",{detail:{areaKey:t},bubbles:!0,composed:!0}))}_toggleArchived(){this.dispatchEvent(new CustomEvent("archived-toggle",{bubbles:!0,composed:!0}))}_headerLabel(t,o,s){return t==="area_cost_year"?r("area_cost_year",s).replace("{year}",String(o)):r(t,s)}render(){if(!this.hass)return m;let t=this._lang,o=Number(f().slice(0,4)),s=this.currencySymbol,n=this._rows(o),c=R(C(n,this._query),this._sort),h=this.objects.filter(e=>e.object.archived).length,d=e=>k(e,t);return a`
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
import{a as O}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-W3SEDH34.js";import{q as j,r as E,s as L,t as R,u as C}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZFJHBIVS.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-U7674FZW.js";import{a as _,b as S,c as A}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-HFUWDHSL.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-Q7CGGH4O.js";import{H as g,K as k,L as v,O as w,a as l,c as a,f as m,h as y,l as p,m as b,s as r,u as $,y as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZW2EWBUR.js";var q=[{key:"name",label:"area",num:!1},{key:"objects",label:"objects",num:!0},{key:"tasks",label:"tasks",num:!0},{key:"overdue",label:"overdue",num:!0},{key:"due_soon",label:"due_soon",num:!0},{key:"cost_year",label:"area_cost_year",num:!0},{key:"cost_total",label:"total_cost",num:!0},{key:"last",label:"last_performed",num:!1}],i=class extends y{constructor(){super(...arguments);this.objects=[];this.showArchived=!1;this.currencySymbol="";this._query="";this._sort=E(S(_.areaSort));this._histories=new O(this);this._localeReady=!1;this._memo=null}createRenderRoot(){return this}get _lang(){return g(this.hass)}willUpdate(t){if(super.willUpdate(t),t.has("objects")||t.has("showArchived")||t.has("hass")&&t.get("hass")===void 0){let o=this.objects.filter(s=>this.showArchived||!s.object.archived).flatMap(s=>s.tasks.map(n=>({entryId:s.entry_id,task:n})));this._histories.sync(this.hass,o)}}updated(t){super.updated(t),!this._localeReady&&this.hass&&(this._localeReady=!0,$(this._lang).then(()=>this.requestUpdate()))}_rows(t){let o=this._lang,s=[this.objects,this.showArchived,this._histories.version,this.hass?.areas,o,t];if(this._memo&&this._memo.deps.every((c,h)=>c===s[h]))return this._memo.rows;let n=j(this.objects,{showArchived:this.showArchived,areas:this.hass?.areas,noAreaLabel:r("no_area",o),year:t,historyOf:(c,h)=>this._histories.historyOf(c,h)});return this._memo={deps:s,rows:n},n}_setSort(t){this._sort=L(this._sort,t),A(_.areaSort,`${this._sort.key}:${this._sort.dir}`)}_open(t){this.dispatchEvent(new CustomEvent("open-area",{detail:{areaKey:t},bubbles:!0,composed:!0}))}_toggleArchived(){this.dispatchEvent(new CustomEvent("archived-toggle",{bubbles:!0,composed:!0}))}_headerLabel(t,o,s){return t==="area_cost_year"?r("area_cost_year",s).replace("{year}",String(o)):r(t,s)}render(){if(!this.hass)return m;let t=this._lang,o=Number(f().slice(0,4)),s=this.currencySymbol,n=this._rows(o),c=R(C(n,this._query),this._sort),h=this.objects.filter(e=>e.object.archived).length,d=e=>k(e,t);return a`
|
||||
<div class="filter-bar area-filter-bar">
|
||||
<input
|
||||
type="search"
|
||||
@@ -1,54 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import{a as C}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-AKHM2FQS.js";import{q as A,r as j,s as E,t as L,u as R}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-BEGYKXHI.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-O7BSORZB.js";import{a as _,b as w,c as S}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-EPK25IMX.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-5SGCD2J3.js";import{B as g,C as v,F as k,a as l,c as a,f as m,h as y,l as p,m as b,s as r,u as $,y as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";var O=[{key:"name",label:"area",num:!1},{key:"objects",label:"objects",num:!0},{key:"tasks",label:"tasks",num:!0},{key:"overdue",label:"overdue",num:!0},{key:"due_soon",label:"due_soon",num:!0},{key:"cost_year",label:"area_cost_year",num:!0},{key:"cost_total",label:"total_cost",num:!0},{key:"last",label:"last_performed",num:!1}],i=class extends y{constructor(){super(...arguments);this.objects=[];this.showArchived=!1;this.currencySymbol="";this._query="";this._sort=j(w(_.areaSort));this._histories=new C(this);this._localeReady=!1;this._memo=null}createRenderRoot(){return this}get _lang(){return f(this.hass)}willUpdate(e){if(super.willUpdate(e),e.has("objects")||e.has("showArchived")||e.has("hass")&&e.get("hass")===void 0){let o=this.objects.filter(s=>this.showArchived||!s.object.archived).flatMap(s=>s.tasks.map(n=>({entryId:s.entry_id,task:n})));this._histories.sync(this.hass,o)}}updated(e){super.updated(e),!this._localeReady&&this.hass&&(this._localeReady=!0,$(this._lang).then(()=>this.requestUpdate()))}_rows(e){let o=this._lang,s=[this.objects,this.showArchived,this._histories.version,this.hass?.areas,o,e];if(this._memo&&this._memo.deps.every((c,h)=>c===s[h]))return this._memo.rows;let n=A(this.objects,{showArchived:this.showArchived,areas:this.hass?.areas,noAreaLabel:r("no_area",o),year:e,historyOf:(c,h)=>this._histories.historyOf(c,h)});return this._memo={deps:s,rows:n},n}_setSort(e){this._sort=E(this._sort,e),S(_.areaSort,`${this._sort.key}:${this._sort.dir}`)}_open(e){this.dispatchEvent(new CustomEvent("open-area",{detail:{areaKey:e},bubbles:!0,composed:!0}))}_toggleArchived(){this.dispatchEvent(new CustomEvent("archived-toggle",{bubbles:!0,composed:!0}))}_headerLabel(e,o,s){return e==="area_cost_year"?r("area_cost_year",s).replace("{year}",String(o)):r(e,s)}render(){if(!this.hass)return m;let e=this._lang,o=new Date().getFullYear(),s=this.currencySymbol,n=this._rows(o),c=L(R(n,this._query),this._sort),h=this.objects.filter(t=>t.object.archived).length,d=t=>g(t,e);return a`
|
||||
<div class="filter-bar area-filter-bar">
|
||||
<input
|
||||
type="search"
|
||||
class="search-input"
|
||||
aria-label=${r("areas_filter",e)}
|
||||
placeholder=${r("areas_filter",e)}
|
||||
.value=${this._query}
|
||||
@input=${t=>{this._query=t.target.value}}
|
||||
/>
|
||||
${this._histories.loading?a`<span class="area-loading">${r("loading",e)}</span>`:m}
|
||||
${h>0?a`<ha-button class="archived-toggle ${this.showArchived?"active":""}" @click=${()=>this._toggleArchived()}>
|
||||
<ha-icon icon="mdi:archive-outline"></ha-icon>
|
||||
${this.showArchived?r("hide_archived",e):`${r("show_archived",e)} (${h})`}
|
||||
</ha-button>`:m}
|
||||
</div>
|
||||
${n.length===0?a`<div class="empty-state">${r("no_objects",e)}</div>`:c.length===0?a`<div class="empty-state">${r("areas_filter_none",e)}</div>`:a`
|
||||
<div class="objects-table-wrap">
|
||||
<table class="objects-table areas-table">
|
||||
<thead>
|
||||
<tr>
|
||||
${O.map(t=>{let u=this._sort.key===t.key;return a`<th class=${t.num?"num":""}
|
||||
aria-sort=${u?this._sort.dir==="asc"?"ascending":"descending":"none"}>
|
||||
<button class="area-sort ${u?"active":""}" title=${r("sort_label",e)} @click=${()=>this._setSort(t.key)}>
|
||||
${this._headerLabel(t.label,o,e)}
|
||||
${u?a`<ha-icon icon=${this._sort.dir==="asc"?"mdi:arrow-up":"mdi:arrow-down"}></ha-icon>`:m}
|
||||
</button>
|
||||
</th>`})}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${c.map(t=>a`
|
||||
<tr class="objects-table-row" tabindex="0"
|
||||
@click=${()=>this._open(t.key)}
|
||||
@keydown=${u=>{u.key==="Enter"&&this._open(t.key)}}>
|
||||
<td>
|
||||
<ha-icon class="area-row-icon" .icon=${t.icon}></ha-icon>
|
||||
<span class="objects-table-name">${t.name}</span>
|
||||
</td>
|
||||
<td class="num">${d(t.objects)}</td>
|
||||
<td class="num">${d(t.tasks)}</td>
|
||||
<td class="num">${t.overdue?a`<span class="area-count overdue">${d(t.overdue)}</span>`:d(0)}</td>
|
||||
<td class="num">${t.dueSoon?a`<span class="area-count due-soon">${d(t.dueSoon)}</span>`:d(0)}</td>
|
||||
<td class="num">${v(t.costYear,s,e)}</td>
|
||||
<td class="num">${v(t.costTotal,s,e)}</td>
|
||||
<td>${t.lastCompletion?k(t.lastCompletion,e):"\u2014"}</td>
|
||||
</tr>
|
||||
`)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
`}
|
||||
`}};l([p({attribute:!1})],i.prototype,"hass",2),l([p({attribute:!1})],i.prototype,"objects",2),l([p({type:Boolean})],i.prototype,"showArchived",2),l([p()],i.prototype,"currencySymbol",2),l([b()],i.prototype,"_query",2),l([b()],i.prototype,"_sort",2);customElements.get("maintenance-areas-view")||customElements.define("maintenance-areas-view",i);export{i as MaintenanceAreasView};
|
||||
@@ -1,54 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{a as O}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-WH65ZHYZ.js";import{q as j,r as E,s as L,t as R,u as C}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-S7XZBRRU.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4PKMHUVO.js";import{a as _,b as S,c as A}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-KKVMZFOV.js";import"/maintenance_supporter_panelfiles/panel-chunks/chunk-NEWWPCTD.js";import{H as g,K as k,L as v,O as w,a as l,c as a,f as m,h as y,l as p,m as b,s as r,u as $,y as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";var q=[{key:"name",label:"area",num:!1},{key:"objects",label:"objects",num:!0},{key:"tasks",label:"tasks",num:!0},{key:"overdue",label:"overdue",num:!0},{key:"due_soon",label:"due_soon",num:!0},{key:"cost_year",label:"area_cost_year",num:!0},{key:"cost_total",label:"total_cost",num:!0},{key:"last",label:"last_performed",num:!1}],i=class extends y{constructor(){super(...arguments);this.objects=[];this.showArchived=!1;this.currencySymbol="";this._query="";this._sort=E(S(_.areaSort));this._histories=new O(this);this._localeReady=!1;this._memo=null}createRenderRoot(){return this}get _lang(){return g(this.hass)}willUpdate(t){if(super.willUpdate(t),t.has("objects")||t.has("showArchived")||t.has("hass")&&t.get("hass")===void 0){let o=this.objects.filter(s=>this.showArchived||!s.object.archived).flatMap(s=>s.tasks.map(n=>({entryId:s.entry_id,task:n})));this._histories.sync(this.hass,o)}}updated(t){super.updated(t),!this._localeReady&&this.hass&&(this._localeReady=!0,$(this._lang).then(()=>this.requestUpdate()))}_rows(t){let o=this._lang,s=[this.objects,this.showArchived,this._histories.version,this.hass?.areas,o,t];if(this._memo&&this._memo.deps.every((c,h)=>c===s[h]))return this._memo.rows;let n=j(this.objects,{showArchived:this.showArchived,areas:this.hass?.areas,noAreaLabel:r("no_area",o),year:t,historyOf:(c,h)=>this._histories.historyOf(c,h)});return this._memo={deps:s,rows:n},n}_setSort(t){this._sort=L(this._sort,t),A(_.areaSort,`${this._sort.key}:${this._sort.dir}`)}_open(t){this.dispatchEvent(new CustomEvent("open-area",{detail:{areaKey:t},bubbles:!0,composed:!0}))}_toggleArchived(){this.dispatchEvent(new CustomEvent("archived-toggle",{bubbles:!0,composed:!0}))}_headerLabel(t,o,s){return t==="area_cost_year"?r("area_cost_year",s).replace("{year}",String(o)):r(t,s)}render(){if(!this.hass)return m;let t=this._lang,o=Number(f().slice(0,4)),s=this.currencySymbol,n=this._rows(o),c=R(C(n,this._query),this._sort),h=this.objects.filter(e=>e.object.archived).length,d=e=>k(e,t);return a`
|
||||
<div class="filter-bar area-filter-bar">
|
||||
<input
|
||||
type="search"
|
||||
class="search-input"
|
||||
aria-label=${r("areas_filter",t)}
|
||||
placeholder=${r("areas_filter",t)}
|
||||
.value=${this._query}
|
||||
@input=${e=>{this._query=e.target.value}}
|
||||
/>
|
||||
${this._histories.loading?a`<span class="area-loading">${r("loading",t)}</span>`:m}
|
||||
${h>0?a`<ha-button class="archived-toggle ${this.showArchived?"active":""}" @click=${()=>this._toggleArchived()}>
|
||||
<ha-icon icon="mdi:archive-outline"></ha-icon>
|
||||
${this.showArchived?r("hide_archived",t):`${r("show_archived",t)} (${h})`}
|
||||
</ha-button>`:m}
|
||||
</div>
|
||||
${n.length===0?a`<div class="empty-state">${r("no_objects",t)}</div>`:c.length===0?a`<div class="empty-state">${r("areas_filter_none",t)}</div>`:a`
|
||||
<div class="objects-table-wrap">
|
||||
<table class="objects-table areas-table">
|
||||
<thead>
|
||||
<tr>
|
||||
${q.map(e=>{let u=this._sort.key===e.key;return a`<th class=${e.num?"num":""}
|
||||
aria-sort=${u?this._sort.dir==="asc"?"ascending":"descending":"none"}>
|
||||
<button class="area-sort ${u?"active":""}" title=${r("sort_label",t)} @click=${()=>this._setSort(e.key)}>
|
||||
${this._headerLabel(e.label,o,t)}
|
||||
${u?a`<ha-icon icon=${this._sort.dir==="asc"?"mdi:arrow-up":"mdi:arrow-down"}></ha-icon>`:m}
|
||||
</button>
|
||||
</th>`})}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${c.map(e=>a`
|
||||
<tr class="objects-table-row" tabindex="0"
|
||||
@click=${()=>this._open(e.key)}
|
||||
@keydown=${u=>{u.key==="Enter"&&this._open(e.key)}}>
|
||||
<td>
|
||||
<ha-icon class="area-row-icon" .icon=${e.icon}></ha-icon>
|
||||
<span class="objects-table-name">${e.name}</span>
|
||||
</td>
|
||||
<td class="num">${d(e.objects)}</td>
|
||||
<td class="num">${d(e.tasks)}</td>
|
||||
<td class="num">${e.overdue?a`<span class="area-count overdue">${d(e.overdue)}</span>`:d(0)}</td>
|
||||
<td class="num">${e.dueSoon?a`<span class="area-count due-soon">${d(e.dueSoon)}</span>`:d(0)}</td>
|
||||
<td class="num">${v(e.costYear,s,t)}</td>
|
||||
<td class="num">${v(e.costTotal,s,t)}</td>
|
||||
<td>${e.lastCompletion?w(e.lastCompletion,t):"\u2014"}</td>
|
||||
</tr>
|
||||
`)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
`}
|
||||
`}};l([p({attribute:!1})],i.prototype,"hass",2),l([p({attribute:!1})],i.prototype,"objects",2),l([p({type:Boolean})],i.prototype,"showArchived",2),l([p()],i.prototype,"currencySymbol",2),l([b()],i.prototype,"_query",2),l([b()],i.prototype,"_sort",2);customElements.get("maintenance-areas-view")||customElements.define("maintenance-areas-view",i);export{i as MaintenanceAreasView};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-ISGNEPYP.js";import{H as u,a as n,b as _,c as o,f as p,h as c,l as g,m as a,s}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";var d=["round_robin","least_completed","random"],v=["low","normal","high"],m=365,i=class extends c{constructor(){super(...arguments);this._open=!1;this._mode="assign";this._count=0;this._users=[];this._present=[];this._assignKind="one";this._person="";this._pool=new Set;this._rotation=d[0];this._addText="";this._remove=new Set;this._setWarning=!1;this._warning=7;this._setPriority=!1;this._priority="normal";this._setMute=!1;this._mute=!1;this._resolve=null}get _lang(){return u(this.hass)}open(t,e,r){return this._resolve?.(null),this._mode=t,this._count=e.length,this._users=[...r].sort((l,h)=>l.name.localeCompare(h.name)),this._present=[...new Set(e.flatMap(l=>l.labels||[]))].sort((l,h)=>l.localeCompare(h)),this._assignKind="one",this._person="",this._pool=new Set,this._rotation=d[0],this._addText="",this._remove=new Set,this._setWarning=!1,this._warning=7,this._setPriority=!1,this._priority="normal",this._setMute=!1,this._mute=!1,this._open=!0,new Promise(l=>{this._resolve=l})}_finish(t){this._open=!1;let e=this._resolve;this._resolve=null,e?.(t)}changes(){if(this._mode==="assign"){if(this._assignKind==="one")return{responsible_user_id:this._person||null,assignee_pool:null,rotation_strategy:null};let e=this._users.map(r=>r.id).filter(r=>this._pool.has(r));return e.length<2?null:{assignee_pool:e,rotation_strategy:this._rotation,responsible_user_id:null}}if(this._mode==="labels"){let e=[...new Set(this._addText.split(",").map(l=>l.trim()).filter(Boolean))],r=[...this._remove];return e.length||r.length?{labels_add:e,labels_remove:r}:null}let t={};return this._setWarning&&(t.warning_days=this._warning),this._setPriority&&(t.priority=this._priority),this._setMute&&(t.notify_enabled=!this._mute),Object.keys(t).length?t:null}_toggle(t,e){let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r}_renderAssign(t){return o`
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-TX5O4PHL.js";import{H as u,a as n,b as _,c as o,f as p,h as c,l as g,m as a,s}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZW2EWBUR.js";var d=["round_robin","least_completed","random"],v=["low","normal","high"],m=365,i=class extends c{constructor(){super(...arguments);this._open=!1;this._mode="assign";this._count=0;this._users=[];this._present=[];this._assignKind="one";this._person="";this._pool=new Set;this._rotation=d[0];this._addText="";this._remove=new Set;this._setWarning=!1;this._warning=7;this._setPriority=!1;this._priority="normal";this._setMute=!1;this._mute=!1;this._resolve=null}get _lang(){return u(this.hass)}open(t,e,r){return this._resolve?.(null),this._mode=t,this._count=e.length,this._users=[...r].sort((l,h)=>l.name.localeCompare(h.name)),this._present=[...new Set(e.flatMap(l=>l.labels||[]))].sort((l,h)=>l.localeCompare(h)),this._assignKind="one",this._person="",this._pool=new Set,this._rotation=d[0],this._addText="",this._remove=new Set,this._setWarning=!1,this._warning=7,this._setPriority=!1,this._priority="normal",this._setMute=!1,this._mute=!1,this._open=!0,new Promise(l=>{this._resolve=l})}_finish(t){this._open=!1;let e=this._resolve;this._resolve=null,e?.(t)}changes(){if(this._mode==="assign"){if(this._assignKind==="one")return{responsible_user_id:this._person||null,assignee_pool:null,rotation_strategy:null};let e=this._users.map(r=>r.id).filter(r=>this._pool.has(r));return e.length<2?null:{assignee_pool:e,rotation_strategy:this._rotation,responsible_user_id:null}}if(this._mode==="labels"){let e=[...new Set(this._addText.split(",").map(l=>l.trim()).filter(Boolean))],r=[...this._remove];return e.length||r.length?{labels_add:e,labels_remove:r}:null}let t={};return this._setWarning&&(t.warning_days=this._warning),this._setPriority&&(t.priority=this._priority),this._setMute&&(t.notify_enabled=!this._mute),Object.keys(t).length?t:null}_toggle(t,e){let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r}_renderAssign(t){return o`
|
||||
<div class="hint">${s("bulk_assign_hint",t)}</div>
|
||||
<label class="choice">
|
||||
<input type="radio" name="kind" .checked=${this._assignKind==="one"} @change=${()=>this._assignKind="one"} />
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-TX2GMEMJ.js";import{H as u,a as n,b as _,c as o,f as p,h as c,l as g,m as a,s}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-3FGYBPXY.js";var d=["round_robin","least_completed","random"],v=["low","normal","high"],m=365,i=class extends c{constructor(){super(...arguments);this._open=!1;this._mode="assign";this._count=0;this._users=[];this._present=[];this._assignKind="one";this._person="";this._pool=new Set;this._rotation=d[0];this._addText="";this._remove=new Set;this._setWarning=!1;this._warning=7;this._setPriority=!1;this._priority="normal";this._setMute=!1;this._mute=!1;this._resolve=null}get _lang(){return u(this.hass)}open(t,e,r){return this._resolve?.(null),this._mode=t,this._count=e.length,this._users=[...r].sort((l,h)=>l.name.localeCompare(h.name)),this._present=[...new Set(e.flatMap(l=>l.labels||[]))].sort((l,h)=>l.localeCompare(h)),this._assignKind="one",this._person="",this._pool=new Set,this._rotation=d[0],this._addText="",this._remove=new Set,this._setWarning=!1,this._warning=7,this._setPriority=!1,this._priority="normal",this._setMute=!1,this._mute=!1,this._open=!0,new Promise(l=>{this._resolve=l})}_finish(t){this._open=!1;let e=this._resolve;this._resolve=null,e?.(t)}changes(){if(this._mode==="assign"){if(this._assignKind==="one")return{responsible_user_id:this._person||null,assignee_pool:null,rotation_strategy:null};let e=this._users.map(r=>r.id).filter(r=>this._pool.has(r));return e.length<2?null:{assignee_pool:e,rotation_strategy:this._rotation,responsible_user_id:null}}if(this._mode==="labels"){let e=[...new Set(this._addText.split(",").map(l=>l.trim()).filter(Boolean))],r=[...this._remove];return e.length||r.length?{labels_add:e,labels_remove:r}:null}let t={};return this._setWarning&&(t.warning_days=this._warning),this._setPriority&&(t.priority=this._priority),this._setMute&&(t.notify_enabled=!this._mute),Object.keys(t).length?t:null}_toggle(t,e){let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r}_renderAssign(t){return o`
|
||||
<div class="hint">${s("bulk_assign_hint",t)}</div>
|
||||
<label class="choice">
|
||||
<input type="radio" name="kind" .checked=${this._assignKind==="one"} @change=${()=>this._assignKind="one"} />
|
||||
${s("bulk_assign_one",t)}
|
||||
</label>
|
||||
${this._assignKind==="one"?o`<select class="person" .value=${this._person} @change=${e=>this._person=e.target.value}>
|
||||
<option value="" ?selected=${!this._person}>${s("unassigned",t)}</option>
|
||||
${this._users.map(e=>o`<option value=${e.id} ?selected=${this._person===e.id}>${e.name}</option>`)}
|
||||
</select>`:p}
|
||||
<label class="choice">
|
||||
<input type="radio" name="kind" .checked=${this._assignKind==="rotate"} @change=${()=>this._assignKind="rotate"} />
|
||||
${s("bulk_assign_rotate",t)}
|
||||
</label>
|
||||
${this._assignKind==="rotate"?o`<div class="pool">
|
||||
${this._users.map(e=>o`<label class="row">
|
||||
<input type="checkbox" .checked=${this._pool.has(e.id)} @change=${()=>this._pool=this._toggle(this._pool,e.id)} />
|
||||
${e.name}
|
||||
</label>`)}
|
||||
</div>
|
||||
<label class="field">
|
||||
<span>${s("rotation_strategy",t)}</span>
|
||||
<select class="rotation" .value=${this._rotation} @change=${e=>this._rotation=e.target.value}>
|
||||
${d.map(e=>o`<option value=${e} ?selected=${this._rotation===e}>${s(`rotation_${e}`,t)}</option>`)}
|
||||
</select>
|
||||
</label>
|
||||
${this._pool.size<2?o`<div class="hint">${s("bulk_rotation_min_two",t)}</div>`:p}`:p}
|
||||
`}_renderLabels(t){return o`
|
||||
<ms-textfield
|
||||
class="labels-add"
|
||||
label=${s("bulk_labels_add",t)}
|
||||
.helper=${s("labels_help",t)}
|
||||
.value=${this._addText}
|
||||
@input=${e=>this._addText=e.target.value}
|
||||
></ms-textfield>
|
||||
${this._present.length?o`<div class="section-title">${s("bulk_labels_remove",t)}</div>
|
||||
<div class="pool">
|
||||
${this._present.map(e=>o`<label class="row">
|
||||
<input type="checkbox" .checked=${this._remove.has(e)} @change=${()=>this._remove=this._toggle(this._remove,e)} />
|
||||
${e}
|
||||
</label>`)}
|
||||
</div>`:p}
|
||||
`}_renderEdit(t){return o`
|
||||
<div class="hint">${s("bulk_edit_hint",t)}</div>
|
||||
<div class="row edit-row">
|
||||
<input type="checkbox" class="set-warning" .checked=${this._setWarning} @change=${e=>this._setWarning=e.target.checked} />
|
||||
<span class="grow">${s("warning_days",t)}</span>
|
||||
<input type="number" class="warning" min="0" max=${m} .value=${String(this._warning)} ?disabled=${!this._setWarning}
|
||||
@change=${e=>{let r=parseInt(e.target.value,10);this._warning=Number.isInteger(r)?Math.min(Math.max(r,0),m):this._warning}} />
|
||||
</div>
|
||||
<div class="row edit-row">
|
||||
<input type="checkbox" class="set-priority" .checked=${this._setPriority} @change=${e=>this._setPriority=e.target.checked} />
|
||||
<span class="grow">${s("priority",t)}</span>
|
||||
<select class="priority" .value=${this._priority} ?disabled=${!this._setPriority} @change=${e=>this._priority=e.target.value}>
|
||||
${v.map(e=>o`<option value=${e} ?selected=${this._priority===e}>${s(`priority_${e}`,t)}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
<div class="row edit-row">
|
||||
<input type="checkbox" class="set-mute" .checked=${this._setMute} @change=${e=>this._setMute=e.target.checked} />
|
||||
<span class="grow">${s("bulk_no_notifications",t)}</span>
|
||||
<input type="checkbox" class="mute" .checked=${this._mute} ?disabled=${!this._setMute} @change=${e=>this._mute=e.target.checked} />
|
||||
</div>
|
||||
`}render(){if(!this._open)return o``;let t=this._lang,e=this._mode==="assign"?s("bulk_assign",t):this._mode==="labels"?s("labels",t):s("edit",t),r=this.changes()!==null;return o`
|
||||
<ha-dialog open @closed=${()=>this._finish(null)}>
|
||||
<div class="dialog-title">${e}</div>
|
||||
<div class="content">
|
||||
<div class="count">${s("bulk_n_selected",t).replace("{n}",String(this._count))}</div>
|
||||
${this._mode==="assign"?this._renderAssign(t):this._mode==="labels"?this._renderLabels(t):this._renderEdit(t)}
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${()=>this._finish(null)}>${s("cancel",t)}</ha-button>
|
||||
<ha-button class="apply" .disabled=${!r} @click=${()=>this._finish(this.changes())}>${s("save",t)}</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}};i.styles=_`
|
||||
.dialog-title { font-size: 18px; font-weight: 500; padding-bottom: 12px; }
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
min-width: min(360px, calc(100vw - 24px));
|
||||
max-width: 520px;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.content { min-width: 0; max-width: none; max-height: none; }
|
||||
}
|
||||
.count, .hint { color: var(--secondary-text-color); font-size: 13px; }
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
.choice, .row { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }
|
||||
.pool { display: flex; flex-direction: column; gap: 4px; padding-left: 26px; }
|
||||
.field { display: flex; align-items: center; gap: 8px; justify-content: space-between; font-size: 14px; }
|
||||
.grow { flex: 1; min-width: 0; }
|
||||
select, input[type="number"] {
|
||||
font: inherit;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 4px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
max-width: 100%;
|
||||
}
|
||||
input[type="number"] { width: 72px; }
|
||||
select.person { margin-left: 26px; }
|
||||
.dialog-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 16px; }
|
||||
`,n([g({attribute:!1})],i.prototype,"hass",2),n([a()],i.prototype,"_open",2),n([a()],i.prototype,"_mode",2),n([a()],i.prototype,"_count",2),n([a()],i.prototype,"_users",2),n([a()],i.prototype,"_present",2),n([a()],i.prototype,"_assignKind",2),n([a()],i.prototype,"_person",2),n([a()],i.prototype,"_pool",2),n([a()],i.prototype,"_rotation",2),n([a()],i.prototype,"_addText",2),n([a()],i.prototype,"_remove",2),n([a()],i.prototype,"_setWarning",2),n([a()],i.prototype,"_warning",2),n([a()],i.prototype,"_setPriority",2),n([a()],i.prototype,"_priority",2),n([a()],i.prototype,"_setMute",2),n([a()],i.prototype,"_mute",2);customElements.get("maintenance-bulk-edit-dialog")||customElements.define("maintenance-bulk-edit-dialog",i);export{i as MaintenanceBulkEditDialog};
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-4CRDSGBT.js";import{a as n,b as _,c as o,f as p,h as c,l as g,m as a,s,y as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";var d=["round_robin","least_completed","random"],v=["low","normal","high"],m=365,i=class extends c{constructor(){super(...arguments);this._open=!1;this._mode="assign";this._count=0;this._users=[];this._present=[];this._assignKind="one";this._person="";this._pool=new Set;this._rotation=d[0];this._addText="";this._remove=new Set;this._setWarning=!1;this._warning=7;this._setPriority=!1;this._priority="normal";this._setMute=!1;this._mute=!1;this._resolve=null}get _lang(){return u(this.hass)}open(t,e,r){return this._resolve?.(null),this._mode=t,this._count=e.length,this._users=[...r].sort((l,h)=>l.name.localeCompare(h.name)),this._present=[...new Set(e.flatMap(l=>l.labels||[]))].sort((l,h)=>l.localeCompare(h)),this._assignKind="one",this._person="",this._pool=new Set,this._rotation=d[0],this._addText="",this._remove=new Set,this._setWarning=!1,this._warning=7,this._setPriority=!1,this._priority="normal",this._setMute=!1,this._mute=!1,this._open=!0,new Promise(l=>{this._resolve=l})}_finish(t){this._open=!1;let e=this._resolve;this._resolve=null,e?.(t)}changes(){if(this._mode==="assign"){if(this._assignKind==="one")return{responsible_user_id:this._person||null,assignee_pool:null,rotation_strategy:null};let e=this._users.map(r=>r.id).filter(r=>this._pool.has(r));return e.length<2?null:{assignee_pool:e,rotation_strategy:this._rotation,responsible_user_id:null}}if(this._mode==="labels"){let e=[...new Set(this._addText.split(",").map(l=>l.trim()).filter(Boolean))],r=[...this._remove];return e.length||r.length?{labels_add:e,labels_remove:r}:null}let t={};return this._setWarning&&(t.warning_days=this._warning),this._setPriority&&(t.priority=this._priority),this._setMute&&(t.notify_enabled=!this._mute),Object.keys(t).length?t:null}_toggle(t,e){let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r}_renderAssign(t){return o`
|
||||
<div class="hint">${s("bulk_assign_hint",t)}</div>
|
||||
<label class="choice">
|
||||
<input type="radio" name="kind" .checked=${this._assignKind==="one"} @change=${()=>this._assignKind="one"} />
|
||||
${s("bulk_assign_one",t)}
|
||||
</label>
|
||||
${this._assignKind==="one"?o`<select class="person" .value=${this._person} @change=${e=>this._person=e.target.value}>
|
||||
<option value="" ?selected=${!this._person}>${s("unassigned",t)}</option>
|
||||
${this._users.map(e=>o`<option value=${e.id} ?selected=${this._person===e.id}>${e.name}</option>`)}
|
||||
</select>`:p}
|
||||
<label class="choice">
|
||||
<input type="radio" name="kind" .checked=${this._assignKind==="rotate"} @change=${()=>this._assignKind="rotate"} />
|
||||
${s("bulk_assign_rotate",t)}
|
||||
</label>
|
||||
${this._assignKind==="rotate"?o`<div class="pool">
|
||||
${this._users.map(e=>o`<label class="row">
|
||||
<input type="checkbox" .checked=${this._pool.has(e.id)} @change=${()=>this._pool=this._toggle(this._pool,e.id)} />
|
||||
${e.name}
|
||||
</label>`)}
|
||||
</div>
|
||||
<label class="field">
|
||||
<span>${s("rotation_strategy",t)}</span>
|
||||
<select class="rotation" .value=${this._rotation} @change=${e=>this._rotation=e.target.value}>
|
||||
${d.map(e=>o`<option value=${e} ?selected=${this._rotation===e}>${s(`rotation_${e}`,t)}</option>`)}
|
||||
</select>
|
||||
</label>
|
||||
${this._pool.size<2?o`<div class="hint">${s("bulk_rotation_min_two",t)}</div>`:p}`:p}
|
||||
`}_renderLabels(t){return o`
|
||||
<ms-textfield
|
||||
class="labels-add"
|
||||
label=${s("bulk_labels_add",t)}
|
||||
.helper=${s("labels_help",t)}
|
||||
.value=${this._addText}
|
||||
@input=${e=>this._addText=e.target.value}
|
||||
></ms-textfield>
|
||||
${this._present.length?o`<div class="section-title">${s("bulk_labels_remove",t)}</div>
|
||||
<div class="pool">
|
||||
${this._present.map(e=>o`<label class="row">
|
||||
<input type="checkbox" .checked=${this._remove.has(e)} @change=${()=>this._remove=this._toggle(this._remove,e)} />
|
||||
${e}
|
||||
</label>`)}
|
||||
</div>`:p}
|
||||
`}_renderEdit(t){return o`
|
||||
<div class="hint">${s("bulk_edit_hint",t)}</div>
|
||||
<div class="row edit-row">
|
||||
<input type="checkbox" class="set-warning" .checked=${this._setWarning} @change=${e=>this._setWarning=e.target.checked} />
|
||||
<span class="grow">${s("warning_days",t)}</span>
|
||||
<input type="number" class="warning" min="0" max=${m} .value=${String(this._warning)} ?disabled=${!this._setWarning}
|
||||
@change=${e=>{let r=parseInt(e.target.value,10);this._warning=Number.isInteger(r)?Math.min(Math.max(r,0),m):this._warning}} />
|
||||
</div>
|
||||
<div class="row edit-row">
|
||||
<input type="checkbox" class="set-priority" .checked=${this._setPriority} @change=${e=>this._setPriority=e.target.checked} />
|
||||
<span class="grow">${s("priority",t)}</span>
|
||||
<select class="priority" .value=${this._priority} ?disabled=${!this._setPriority} @change=${e=>this._priority=e.target.value}>
|
||||
${v.map(e=>o`<option value=${e} ?selected=${this._priority===e}>${s(`priority_${e}`,t)}</option>`)}
|
||||
</select>
|
||||
</div>
|
||||
<div class="row edit-row">
|
||||
<input type="checkbox" class="set-mute" .checked=${this._setMute} @change=${e=>this._setMute=e.target.checked} />
|
||||
<span class="grow">${s("bulk_no_notifications",t)}</span>
|
||||
<input type="checkbox" class="mute" .checked=${this._mute} ?disabled=${!this._setMute} @change=${e=>this._mute=e.target.checked} />
|
||||
</div>
|
||||
`}render(){if(!this._open)return o``;let t=this._lang,e=this._mode==="assign"?s("bulk_assign",t):this._mode==="labels"?s("labels",t):s("edit",t),r=this.changes()!==null;return o`
|
||||
<ha-dialog open @closed=${()=>this._finish(null)}>
|
||||
<div class="dialog-title">${e}</div>
|
||||
<div class="content">
|
||||
<div class="count">${s("bulk_n_selected",t).replace("{n}",String(this._count))}</div>
|
||||
${this._mode==="assign"?this._renderAssign(t):this._mode==="labels"?this._renderLabels(t):this._renderEdit(t)}
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${()=>this._finish(null)}>${s("cancel",t)}</ha-button>
|
||||
<ha-button class="apply" .disabled=${!r} @click=${()=>this._finish(this.changes())}>${s("save",t)}</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}};i.styles=_`
|
||||
.dialog-title { font-size: 18px; font-weight: 500; padding-bottom: 12px; }
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
min-width: min(360px, calc(100vw - 24px));
|
||||
max-width: 520px;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.content { min-width: 0; max-width: none; max-height: none; }
|
||||
}
|
||||
.count, .hint { color: var(--secondary-text-color); font-size: 13px; }
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
.choice, .row { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }
|
||||
.pool { display: flex; flex-direction: column; gap: 4px; padding-left: 26px; }
|
||||
.field { display: flex; align-items: center; gap: 8px; justify-content: space-between; font-size: 14px; }
|
||||
.grow { flex: 1; min-width: 0; }
|
||||
select, input[type="number"] {
|
||||
font: inherit;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 4px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
max-width: 100%;
|
||||
}
|
||||
input[type="number"] { width: 72px; }
|
||||
select.person { margin-left: 26px; }
|
||||
.dialog-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 16px; }
|
||||
`,n([g({attribute:!1})],i.prototype,"hass",2),n([a()],i.prototype,"_open",2),n([a()],i.prototype,"_mode",2),n([a()],i.prototype,"_count",2),n([a()],i.prototype,"_users",2),n([a()],i.prototype,"_present",2),n([a()],i.prototype,"_assignKind",2),n([a()],i.prototype,"_person",2),n([a()],i.prototype,"_pool",2),n([a()],i.prototype,"_rotation",2),n([a()],i.prototype,"_addText",2),n([a()],i.prototype,"_remove",2),n([a()],i.prototype,"_setWarning",2),n([a()],i.prototype,"_warning",2),n([a()],i.prototype,"_setPriority",2),n([a()],i.prototype,"_priority",2),n([a()],i.prototype,"_setMute",2),n([a()],i.prototype,"_mute",2);customElements.get("maintenance-bulk-edit-dialog")||customElements.define("maintenance-bulk-edit-dialog",i);export{i as MaintenanceBulkEditDialog};
|
||||
File diff suppressed because one or more lines are too long
@@ -1,37 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import{B as R,D as k,R as x,a as m,b as h,c as g,f as v,h as b,l as y,m as _,s as l}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";function w(i){return`${i.entry_id??""}\0${i.part_id}`}function E(i,t,e,o){let n=!!i.entry_id&&i.entry_id!==t,r=n?i.entry_id:t,s=e.find(p=>p.entry_id===r),a=(s?.parts||[]).find(p=>p.id===i.part_id)||null,c=n&&s?.object?.name||"",u=a?.name||l("shared_part_unknown",o);return{part:a,foreign:n,ownerName:c,label:c?`${u} (${c})`:u}}function L(i,t,e,o){let{part:n,label:r}=E(i,t,e,o),s=n&&n.stock!==null&&n.stock!==void 0?` (${k(n.stock,n.unit,o)})`:"",a=n?.storage_location?` \u2014 ${n.storage_location}`:"";return`${R(i.quantity,o)}\xD7 ${r}${s}${a}`}function $(i,t,e,o){let r=(e.find(a=>a.entry_id===t)?.parts||[]).map(a=>({...a})),s=new Set(r.map(a=>w({part_id:a.id})));for(let a of i?.consumes_parts||[]){if(!a.entry_id||a.entry_id===t)continue;let c=w(a);if(s.has(c))continue;s.add(c);let{part:u,ownerName:p}=E(a,t,e,o);r.push({id:a.part_id,name:u?.name||l("shared_part_unknown",o),unit:u?.unit,stock:u?.stock??null,storage_location:u?.storage_location,entry_id:a.entry_id,owner_name:p})}return r}function O(){let i=new Uint8Array(4);return(globalThis.crypto??{getRandomValues:t=>t.map(()=>Math.floor(Math.random()*256))}).getRandomValues(i),Array.from(i,t=>t.toString(16).padStart(2,"0")).join("")}function f(i){let t=i?.reading_values;if(!Array.isArray(t))return[];let e=[],o=new Set;for(let n of t){if(!n||typeof n!="object")continue;let r=n;typeof r.id!="string"||!r.id||o.has(r.id)||typeof r.value!="number"||!Number.isFinite(r.value)||(o.add(r.id),e.push({id:r.id,name:typeof r.name=="string"?r.name:r.id,unit:typeof r.unit=="string"?r.unit:null,value:r.value}))}return e}function S(i){return i.filter(t=>t.type==="completed"&&(t.reading_value!=null||f(t).length>0)).sort((t,e)=>t.timestamp.localeCompare(e.timestamp))}function V(i){return S(i??[]).map(t=>({timestamp:t.timestamp,values:f(t)})).filter(t=>t.values.length>0)}function H(i,t,e){let o;for(let n of i){if(e!==void 0){let s=new Date(n.timestamp).getTime();if(!isNaN(s)&&s>=e)break}let r=n.values.find(s=>s.id===t);r&&(o=r)}return o}function T(i,t,e){let o=f(t).find(r=>r.id===e);if(!o)return null;let n=null;for(let r of S(i)){if(r.timestamp>=t.timestamp)break;let s=f(r).find(a=>a.id===e);s&&(n=s.value)}return n==null?null:o.value-n}function A(i){let t=new Set,e=new Set;for(let o of i){let n=(o.name||"").trim().toLowerCase();n&&(t.has(n)?e.add(o.id):t.add(n))}return e}function M(i){let t=[],e=new Set,o=new Set;for(let n of i){let r=(n.name||"").trim();if(!(!r||e.has(n.id)||o.has(r.toLowerCase()))&&(e.add(n.id),o.add(r.toLowerCase()),t.push({id:n.id,name:r,unit:(n.unit||"").trim()||null}),t.length>=20))break}return t}function C(i){let t=(i??"").trim();if(t==="")return null;let e=Number(t.replace(",","."));return!Number.isFinite(e)||e<0?null:Math.round(e)}var U=["notes","cost","duration","photo","user"],j={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};var d=class extends b{constructor(){super(...arguments);this.value="";this.lang="en";this._credit=!1;this._amount=""}willUpdate(e){if(!e.has("value"))return;let o=(this.value??"").trim();if(o===this._signed())return;let n=parseFloat(o);if(o===""||Number.isNaN(n)){this._amount="",this._credit=!1;return}this._credit=n<0,this._amount=String(Math.abs(n))}_signed(){let e=this._amount.trim();return e===""?"":this._credit?`-${e}`:e}_emit(){this.value=this._signed(),this.dispatchEvent(new CustomEvent("value-changed",{detail:{value:this.value},bubbles:!0,composed:!0}))}_setCredit(e){this._credit!==e&&(this._credit=e,this._emit())}_onInput(e){let o=e.target.value;o.startsWith("-")&&(this._credit=!0),this._amount=o.replace(/^-+/,""),this._emit()}render(){let e=this.lang;return g`
|
||||
<div class="wrap">
|
||||
<div class="sign" role="group">
|
||||
<button type="button" class="kind cost ${this._credit?"":"on"}" aria-pressed=${String(!this._credit)}
|
||||
@click=${()=>this._setCredit(!1)}>${l("cost",e)}</button>
|
||||
<button type="button" class="kind credit ${this._credit?"on":""}" aria-pressed=${String(this._credit)}
|
||||
@click=${()=>this._setCredit(!0)}>${l("cost_kind_credit",e)}</button>
|
||||
</div>
|
||||
<input type="number" step="0.01" min="0" inputmode="decimal" class="field-input amount"
|
||||
.value=${this._amount} @input=${this._onInput} />
|
||||
</div>
|
||||
${this._credit?g`<div class="hint">${l("cost_credit_hint",e)}</div>`:v}
|
||||
`}};d.styles=[x,h`
|
||||
:host { display: block; }
|
||||
.wrap { display: flex; gap: 8px; align-items: stretch; }
|
||||
.sign {
|
||||
display: inline-flex;
|
||||
flex: none;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.kind {
|
||||
font: inherit;
|
||||
font-size: 13px;
|
||||
padding: 0 10px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--secondary-text-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
.kind.on { background: var(--primary-color); color: var(--text-primary-color, #fff); }
|
||||
.kind.credit.on { background: var(--success-color, #43a047); }
|
||||
.amount { flex: 1; min-width: 0; }
|
||||
.hint { margin-top: 4px; font-size: 12px; color: var(--secondary-text-color); }
|
||||
`],m([y()],d.prototype,"value",2),m([y()],d.prototype,"lang",2),m([_()],d.prototype,"_credit",2),m([_()],d.prototype,"_amount",2);customElements.get("ms-cost-input")||customElements.define("ms-cost-input",d);export{w as a,L as b,$ as c,O as d,f as e,V as f,H as g,T as h,A as i,M as j,C as k,U as l,j as m};
|
||||
@@ -1,79 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import{a as r,b as l,c as i,f as o,h as n,l as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";var e=class extends n{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1;this.multiline=!1;this.rows=3}_onInput(s){let a=s.target.value;this.value=a,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:a}}))}render(){return i`
|
||||
<label class="field">
|
||||
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:o}</span>`:o}
|
||||
${this.multiline?i`
|
||||
<textarea
|
||||
.value=${this.value??""}
|
||||
rows=${this.rows}
|
||||
?required=${this.required}
|
||||
?disabled=${this.disabled}
|
||||
placeholder=${this.placeholder}
|
||||
@input=${this._onInput}
|
||||
@change=${this._onInput}
|
||||
></textarea>`:i`
|
||||
<input
|
||||
.value=${this.value??""}
|
||||
.type=${this.type}
|
||||
?required=${this.required}
|
||||
?disabled=${this.disabled}
|
||||
placeholder=${this.placeholder}
|
||||
step=${this.step??o}
|
||||
min=${this.min??o}
|
||||
max=${this.max??o}
|
||||
pattern=${this.pattern??o}
|
||||
@input=${this._onInput}
|
||||
@change=${this._onInput}
|
||||
/>`}
|
||||
${this.helper?i`<span class="helper">${this.helper}</span>`:o}
|
||||
</label>
|
||||
`}};e.styles=l`
|
||||
: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; }
|
||||
textarea {
|
||||
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;
|
||||
resize: vertical;
|
||||
}
|
||||
textarea:focus { border-color: var(--primary-color); }
|
||||
textarea:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.helper {
|
||||
font-size: 11px;
|
||||
color: var(--secondary-text-color);
|
||||
font-style: italic;
|
||||
}
|
||||
`,r([t()],e.prototype,"label",2),r([t()],e.prototype,"value",2),r([t()],e.prototype,"placeholder",2),r([t()],e.prototype,"type",2),r([t({type:Boolean})],e.prototype,"required",2),r([t({type:Boolean})],e.prototype,"disabled",2),r([t()],e.prototype,"step",2),r([t()],e.prototype,"min",2),r([t()],e.prototype,"max",2),r([t()],e.prototype,"pattern",2),r([t()],e.prototype,"helper",2),r([t({type:Boolean})],e.prototype,"multiline",2),r([t({type:Number})],e.prototype,"rows",2);customElements.get("ms-textfield")||customElements.define("ms-textfield",e);
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import{F as n,s as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";var l={"Completed from dashboard button":"hist_note_button","Completed from the To-do list":"hist_note_todo","Completed by voice":"hist_note_voice","Completed from the notification":"hist_note_notification","Completed via NFC tag":"hist_note_nfc","Completed from the shopping list":"hist_note_shopping_list","Completed from a mirrored to-do list":"hist_note_todo_mirror","Skipped from notification":"hist_note_skipped_notification","Skipped from dashboard button":"hist_note_skipped_button","Sensor trigger activated":"hist_note_sensor_triggered","Initial value set during task creation":"hist_note_initial"},m=[[/^Auto-completed: sensor recovered \((.+)\)$/,"hist_note_auto_recovered",t=>({value:t[1]})],[/^Reset to (\d{4}-\d{2}-\d{2})$/,"hist_note_reset",(t,e)=>({date:n(t[1],e)})],[/^Trigger entity replaced: (.+) → (.+)$/,"hist_note_trigger_replaced",t=>({old:t[1],new:t[2]})],[/^Sensor trigger removed \(entity was: (.+)\)\. Schedule converted to (\w+)\.$/,"hist_note_trigger_removed",(t,e)=>({entity:t[1],schedule:o(t[2],e)})],[/^Entity (.+) removed from compound trigger; (\d+) conditions remain\.$/,"hist_note_compound_removed",t=>({entity:t[1],count:t[2]})]];function h(t,e){if(!t)return"";let i=l[t.trim()];if(i)return o(i,e);for(let[s,d,_]of m){let r=t.trim().match(s);if(r){let c=_(r,e);return o(d,e).replace(/\{(\w+)\}/g,(a,g)=>c[g]??a)}}return t}export{h as a};
|
||||
@@ -1,37 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{$ as w,A as k,K as R,M as x,a as m,b as h,c as g,f as v,h as b,l as y,m as _,s as l}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";function E(i){return`${i.entry_id??""}\0${i.part_id}`}function S(i,t,e,o){let n=!!i.entry_id&&i.entry_id!==t,r=n?i.entry_id:t,s=e.find(p=>p.entry_id===r),a=(s?.parts||[]).find(p=>p.id===i.part_id)||null,c=n&&s?.object?.name||"",u=a?.name||l("shared_part_unknown",o);return{part:a,foreign:n,ownerName:c,label:c?`${u} (${c})`:u}}function N(i,t,e,o){let{part:n,label:r}=S(i,t,e,o),s=n&&n.stock!==null&&n.stock!==void 0?` (${x(n.stock,n.unit,o)})`:"",a=n?.storage_location?` \u2014 ${n.storage_location}`:"";return`${R(i.quantity,o)}\xD7 ${r}${s}${a}`}function V(i,t,e,o){let r=(e.find(a=>a.entry_id===t)?.parts||[]).map(a=>({...a})),s=new Set(r.map(a=>E({part_id:a.id})));for(let a of i?.consumes_parts||[]){if(!a.entry_id||a.entry_id===t)continue;let c=E(a);if(s.has(c))continue;s.add(c);let{part:u,ownerName:p}=S(a,t,e,o);r.push({id:a.part_id,name:u?.name||l("shared_part_unknown",o),unit:u?.unit,stock:u?.stock??null,storage_location:u?.storage_location,entry_id:a.entry_id,owner_name:p})}return r}var L=20;function T(){let i=new Uint8Array(4);return(globalThis.crypto??{getRandomValues:t=>t.map(()=>Math.floor(Math.random()*256))}).getRandomValues(i),Array.from(i,t=>t.toString(16).padStart(2,"0")).join("")}function f(i){let t=i?.reading_values;if(!Array.isArray(t))return[];let e=[],o=new Set;for(let n of t){if(!n||typeof n!="object")continue;let r=n;typeof r.id!="string"||!r.id||o.has(r.id)||typeof r.value!="number"||!Number.isFinite(r.value)||(o.add(r.id),e.push({id:r.id,name:typeof r.name=="string"?r.name:r.id,unit:typeof r.unit=="string"?r.unit:null,value:r.value}))}return e}function P(i){return i.filter(t=>t.type==="completed"&&(t.reading_value!=null||f(t).length>0)).sort((t,e)=>t.timestamp.localeCompare(e.timestamp))}function M(i){return P(i??[]).map(t=>({timestamp:t.timestamp,values:f(t)})).filter(t=>t.values.length>0)}function A(i,t,e){let o;for(let n of i){if(e!==void 0){let s=k(n.timestamp);if(!isNaN(s)&&s>=e)break}let r=n.values.find(s=>s.id===t);r&&(o=r)}return o}function C(i,t,e){let o=f(t).find(r=>r.id===e);if(!o)return null;let n=null;for(let r of P(i)){if(r.timestamp>=t.timestamp)break;let s=f(r).find(a=>a.id===e);s&&(n=s.value)}return n==null?null:o.value-n}function D(i){let t=new Set,e=new Set;for(let o of i){let n=(o.name||"").trim().toLowerCase();n&&(t.has(n)?e.add(o.id):t.add(n))}return e}function F(i){let t=[],e=new Set,o=new Set;for(let n of i){let r=(n.name||"").trim();if(!(!r||e.has(n.id)||o.has(r.toLowerCase()))&&(e.add(n.id),o.add(r.toLowerCase()),t.push({id:n.id,name:r,unit:(n.unit||"").trim()||null}),t.length>=L))break}return t}function j(i){let t=(i??"").trim();if(t==="")return null;let e=Number(t.replace(",","."));return!Number.isFinite(e)||e<0?null:Math.round(e)}var B=["notes","cost","duration","photo","user"],I={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};var d=class extends b{constructor(){super(...arguments);this.value="";this.lang="en";this._credit=!1;this._amount=""}willUpdate(e){if(!e.has("value"))return;let o=(this.value??"").trim();if(o===this._signed())return;let n=parseFloat(o);if(o===""||Number.isNaN(n)){this._amount="",this._credit=!1;return}this._credit=n<0,this._amount=String(Math.abs(n))}_signed(){let e=this._amount.trim();return e===""?"":this._credit?`-${e}`:e}_emit(){this.value=this._signed(),this.dispatchEvent(new CustomEvent("value-changed",{detail:{value:this.value},bubbles:!0,composed:!0}))}_setCredit(e){this._credit!==e&&(this._credit=e,this._emit())}_onInput(e){let o=e.target.value;o.startsWith("-")&&(this._credit=!0),this._amount=o.replace(/^-+/,""),this._emit()}render(){let e=this.lang;return g`
|
||||
<div class="wrap">
|
||||
<div class="sign" role="group">
|
||||
<button type="button" class="kind cost ${this._credit?"":"on"}" aria-pressed=${String(!this._credit)}
|
||||
@click=${()=>this._setCredit(!1)}>${l("cost",e)}</button>
|
||||
<button type="button" class="kind credit ${this._credit?"on":""}" aria-pressed=${String(this._credit)}
|
||||
@click=${()=>this._setCredit(!0)}>${l("cost_kind_credit",e)}</button>
|
||||
</div>
|
||||
<input type="number" step="0.01" min="0" inputmode="decimal" class="field-input amount"
|
||||
.value=${this._amount} @input=${this._onInput} />
|
||||
</div>
|
||||
${this._credit?g`<div class="hint">${l("cost_credit_hint",e)}</div>`:v}
|
||||
`}};d.styles=[w,h`
|
||||
:host { display: block; }
|
||||
.wrap { display: flex; gap: 8px; align-items: stretch; }
|
||||
.sign {
|
||||
display: inline-flex;
|
||||
flex: none;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.kind {
|
||||
font: inherit;
|
||||
font-size: 13px;
|
||||
padding: 0 10px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--secondary-text-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
.kind.on { background: var(--primary-color); color: var(--text-primary-color, #fff); }
|
||||
.kind.credit.on { background: var(--success-color, #43a047); }
|
||||
.amount { flex: 1; min-width: 0; }
|
||||
.hint { margin-top: 4px; font-size: 12px; color: var(--secondary-text-color); }
|
||||
`],m([y()],d.prototype,"value",2),m([y()],d.prototype,"lang",2),m([_()],d.prototype,"_credit",2),m([_()],d.prototype,"_amount",2);customElements.get("ms-cost-input")||customElements.define("ms-cost-input",d);export{E as a,N as b,V as c,L as d,T as e,f,M as g,A as h,C as i,D as j,F as k,j as l,B as m,I as n};
|
||||
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{s as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";var _=[{key:"name",labelKey:"name",required:!0},{key:"ref_no",labelKey:"ref_number"},{key:"manufacturer",labelKey:"manufacturer"},{key:"model",labelKey:"model"},{key:"serial_number",labelKey:"serial_number_label"},{key:"installation_date",labelKey:"installed"},{key:"warranty_expiry",labelKey:"warranty"},{key:"area_id",labelKey:"area"},{key:"documentation_url",labelKey:"documentation_url_label"},{key:"notes",labelKey:"object_notes_label"},{key:"task_count",labelKey:"tasks"},{key:"actions",labelKey:"actions"}],u=_.map(e=>e.key),i=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function g(e){if(!Array.isArray(e))return[...i];let n=new Set,r=[];for(let t of e)typeof t=="string"&&u.includes(t)&&!n.has(t)&&(n.add(t),r.push(t));return r.length?(r.includes("name")||r.unshift("name"),r):[...i]}function f(e,n){return a(`home_dwelling_${e==="house"||e==="apartment"?e:"unknown"}`,n)}function m(e,n){if(!e)return"";try{return new Intl.DisplayNames([n],{type:"region"}).of(e)||e}catch{return e}}var l={floors:"home_reason_floors",basement_floor:"home_reason_basement",area_basement:"home_reason_basement",area_garden:"home_reason_garden",area_shed:"home_reason_shed",area_driveway:"home_reason_driveway",area_garage:"home_reason_garage",entity_garage:"home_reason_garage",area_attic:"home_reason_attic",entity_lawn_mower:"home_reason_lawn_mower",entity_gate:"home_reason_gate",area_balcony:"home_reason_balcony",small_home:"home_reason_small_home"},c={ups:"home_reason_ups"};function d(e,n){let r=[];for(let t of e){let o=l[t];if(!o)continue;let s=a(o,n);r.includes(s)||r.push(s)}return r.join(", ")}function b(e,n,r){if(e==="starter")return a("home_reason_starter",n);if(e==="country")return a("home_reason_country",n).replace("{country}",m(r,n));if(e.startsWith("feature_")){let t=e.slice(8),o=l[`area_${t}`]??c[t];return a("home_reason_feature",n).replace("{feature}",o?a(o,n):e)}return a(`home_trait_${e}`,n)}export{_ as a,i as b,g as c,f as d,m as e,d as f,b as g};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+5
-5
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
function c(o,t,e){let l=new Blob([o],{type:e}),d=URL.createObjectURL(l),n=document.createElement("a");n.href=d,n.download=t,n.target="_blank",n.rel="noopener",n.style.display="none",document.body.appendChild(n),n.dispatchEvent(new MouseEvent("click")),document.body.removeChild(n),setTimeout(()=>URL.revokeObjectURL(d),6e4)}function r(o,t){let e=document.createElement("a");e.href=o,e.download=t,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}export{c as a,r as b};
|
||||
File diff suppressed because one or more lines are too long
@@ -1,234 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{a as q}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-OUHDI2FL.js";import{H as k,a,b as f,c as n,f as u,h as x,l as h,m as c,s as e}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";function d(r){return r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function _(r){return!r.startsWith("data:image/svg+xml,")&&!r.startsWith("data:image/png;base64,")?"":d(r)}function y(r){return r.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var l=class extends x{constructor(){super(...arguments);this.lang="";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._quickResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}get _dialogLang(){return this.lang||k(this.hass)}openForObject(t,i){this._entryId=t,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._quickResult=null,this._open=!0,this._generate()}openForTask(t,i,s,o){this._entryId=t,this._taskId=i,this._objectName=s,this._taskName=o,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._quickResult=null,this._open=!0,this._generate()}async _generate(){let t=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null,this._quickResult=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 s=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&(s.push(this.hass.connection.sendMessagePromise({...i,action:"complete"})),await this._hasQuickCompleteDefaults()&&s.push(this.hass.connection.sendMessagePromise({...i,action:"quick_complete"})));let o=await Promise.all(s);if(t!==this._generateSeq)return;this._viewResult=o[0],o.length>1&&(this._completeResult=o[1]),o.length>2&&(this._quickResult=o[2])}catch(i){if(t!==this._generateSeq)return;let s=i?.code,o=i?.message;this._error=s==="no_url"||typeof o=="string"&&o.includes("No Home Assistant URL")?e("qr_error_no_url",this._dialogLang):e("qr_error",this._dialogLang)}finally{t===this._generateSeq&&(this._loading=!1)}}async _hasQuickCompleteDefaults(){try{let i=((await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object",entry_id:this._entryId})).tasks||[]).find(s=>s.id===this._taskId);return!!i?.quick_complete_defaults&&Object.keys(i.quick_complete_defaults).length>0}catch{return!1}}_setUrlMode(t){this._urlMode!==t&&(this._urlMode=t,this._generate())}_print(){if(!this._viewResult)return;let t=this._viewResult,i=t.label.task_name?`${t.label.object_name} \u2014 ${t.label.task_name}`:t.label.object_name,s=[t.label.manufacturer,t.label.model].filter(Boolean).join(" "),o=window.open("","_blank","width=600,height=500");if(!o)return;let p=this._dialogLang,m=d(i),g=d(s),v=!!this._completeResult,b=!!this._quickResult,w=d(e("qr_action_view",p)),$=d(e("qr_action_complete",p)),R=d(e("qr_action_quick_complete",p));o.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
<meta name="color-scheme" content="light">
|
||||
<title>${m}</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:${b?"170px":v?"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>${m}</h2>
|
||||
${g?`<div class="sub">${g}</div>`:""}
|
||||
<div class="qr-row">
|
||||
<div class="qr-col">
|
||||
<img src="${_(this._viewResult.svg_data_uri)}" alt="QR Info" />
|
||||
<div class="qr-label">${w}</div>
|
||||
</div>
|
||||
${v?`<div class="qr-col">
|
||||
<img src="${_(this._completeResult.svg_data_uri)}" alt="QR Complete" />
|
||||
<div class="qr-label">${$}</div>
|
||||
</div>`:""}
|
||||
${b?`<div class="qr-col">
|
||||
<img src="${_(this._quickResult.svg_data_uri)}" alt="QR Quick-complete" />
|
||||
<div class="qr-label">${R}</div>
|
||||
</div>`:""}
|
||||
</div>
|
||||
<div class="url">${d(this._viewResult.url)}</div>
|
||||
<script>setTimeout(()=>window.print(),300)<\/script>
|
||||
</body></html>`),o.document.close()}_downloadSvg(t,i){let s=decodeURIComponent(t.svg_data_uri.replace("data:image/svg+xml,","")),o=this._taskName?`${this._objectName}-${this._taskName}`:this._objectName;q(s,`qr-${y(o)}-${i}.svg`,"image/svg+xml")}_close(){this._open=!1,this._viewResult=null,this._completeResult=null,this._quickResult=null,this._error="",this._loading=!1}render(){if(!this._open)return n``;let t=this._dialogLang,i=this._taskName?`${e("qr_code",t)}: ${this._objectName} \u2014 ${this._taskName}`:`${e("qr_code",t)}: ${this._objectName}`,s=!!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">${e("qr_generating",t)}</div>`:this._error?n`<div class="error">${this._error}</div>`:s?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">${e("qr_action_view",t)}</div>
|
||||
<button class="dl-btn"
|
||||
@click=${()=>this._downloadSvg(this._viewResult,"info")}>
|
||||
<ha-icon icon="mdi:download"></ha-icon>
|
||||
${e("qr_download",t)}
|
||||
</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">${e("qr_action_complete",t)}</div>
|
||||
<button class="dl-btn"
|
||||
@click=${()=>this._downloadSvg(this._completeResult,"complete")}>
|
||||
<ha-icon icon="mdi:download"></ha-icon>
|
||||
${e("qr_download",t)}
|
||||
</button>
|
||||
</div>
|
||||
`:u}
|
||||
${this._quickResult?n`
|
||||
<div class="qr-item quick">
|
||||
<img
|
||||
class="qr-image small"
|
||||
src="${this._quickResult.svg_data_uri}"
|
||||
alt="QR Quick-complete"
|
||||
/>
|
||||
<div class="qr-item-label">${e("qr_action_quick_complete",t)}</div>
|
||||
<button class="dl-btn"
|
||||
@click=${()=>this._downloadSvg(this._quickResult,"quick-complete")}>
|
||||
<ha-icon icon="mdi:download"></ha-icon>
|
||||
${e("qr_download",t)}
|
||||
</button>
|
||||
</div>
|
||||
`:u}
|
||||
</div>
|
||||
<div class="url-display">${this._viewResult.url}</div>
|
||||
`:u}
|
||||
<div class="action-row">
|
||||
<label>${e("qr_url_mode",t)}</label>
|
||||
<div class="action-toggle">
|
||||
<button class="toggle-btn ${this._urlMode==="companion"?"active":""}"
|
||||
@click=${()=>this._setUrlMode("companion")}>${e("qr_mode_companion",t)}</button>
|
||||
<button class="toggle-btn ${this._urlMode==="local"?"active":""}"
|
||||
@click=${()=>this._setUrlMode("local")}>${e("qr_mode_local",t)}</button>
|
||||
<button class="toggle-btn ${this._urlMode==="server"?"active":""}"
|
||||
@click=${()=>this._setUrlMode("server")}>${e("qr_mode_server",t)}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${e("cancel",t)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._print}
|
||||
.disabled=${!s}
|
||||
>
|
||||
${e("qr_print",t)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}};l.styles=f`
|
||||
.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;
|
||||
flex-wrap: wrap; /* three codes (quick-complete, #192) wrap on a phone */
|
||||
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 {
|
||||
max-width: 180px;
|
||||
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([h({attribute:!1})],l.prototype,"hass",2),a([h()],l.prototype,"lang",2),a([c()],l.prototype,"_open",2),a([c()],l.prototype,"_loading",2),a([c()],l.prototype,"_error",2),a([c()],l.prototype,"_viewResult",2),a([c()],l.prototype,"_completeResult",2),a([c()],l.prototype,"_quickResult",2),a([c()],l.prototype,"_urlMode",2);customElements.get("maintenance-qr-dialog")||customElements.define("maintenance-qr-dialog",l);export{l as a};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
import{b as s}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-JQXHX4U4.js";async function a(o,n,t=300){return(await o.connection.sendMessagePromise({type:"auth/sign_path",path:n,expires:t})).path}async function r(o,n,t=300){return a(o,`/api/maintenance_supporter/document/${n}`,t)}async function p(o,n,t=""){let e=window.open("about:blank","_blank");try{let i=await r(o,n);e&&(e.location.href=new URL(i+t,window.location.origin).href)}catch(i){throw e&&e.close(),i}}async function l(o,n,t){s(await r(o,n,30),t)}function m(o,n=null){let t=URL.createObjectURL(new Blob([o],{type:"text/html"}));n&&!n.closed?n.location.href=t:window.open(t,"_blank"),setTimeout(()=>URL.revokeObjectURL(t),6e4)}function u(){return window.open("about:blank","_blank")}export{a,r as b,p as c,l as d,m as e,u as f};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
function r(t){return String(t??"").replace(/[&<>"']/g,n=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[n])}export{r as a};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{c as r,f as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";var a=["#c62828","#ad1457","#6a1b9a","#4527a0","#283593","#1565c0","#00838f","#2e7d32","#558b2f","#ef6c00","#6d4c41","#546e7a"];function u(e){let s=(e||"").split(/\s+/).filter(Boolean);return s.length===0?"?":s.length===1?s[0][0].toUpperCase():(s[0][0]+s[s.length-1][0]).toUpperCase()}function c(e){let s=0;for(let n of e)s=s*31+n.charCodeAt(0)>>>0;return a[s%a.length]}function o(e){return e?{id:e.id,name:e.name,initials:e.initials||u(e.name),color:e.color||c(e.id)}:null}function h(e){return e?r`<span class="person-avatar" style="--person-color: ${e.color}" title=${e.name}>${e.initials}</span>`:i}function m(e,s=""){return e?r`<span class="person-chip ${s}" title=${e.name}>${h(e)}<span class="person-name">${e.name}</span></span>`:i}var l=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 n=Date.now();if(!s&&this.usersCache&&n-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=n,this.usersCache}catch(t){return console.error("Failed to fetch users:",t),this.usersCache||[]}}async assignUser(s,n,t){await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/assign_user",entry_id:s,task_id:n,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}getPerson(s){return o(this.getUser(s))}getUser(s){return!s||!this.usersCache?null:this.usersCache.find(n=>n.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{a,o as b,h as c,m as d,l as e};
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
import{b as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-55ND3GKE.js";import{a as l}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-RHKFQ4Q2.js";var a={operatorWriteEnabled:!1,operatorIds:[]};function m(e,t=a){return e?e.is_admin?!0:t.operatorWriteEnabled&&t.operatorIds.includes(e.id):!1}var _=["buttons_compact","buttons","icons"];function p(e){let[t,n]=l.default_warning_days,s=e?.general?.default_warning_days,r=e?.general?.row_action_style;return{features:{...o.features,...e?.features??{}},defaultWarningDays:typeof s=="number"&&Number.isFinite(s)&&s>=t&&s<=n?s:o.defaultWarningDays,rowActionStyle:_.includes(r??"")?r:o.rowActionStyle,access:{operatorWriteEnabled:e?.operator_write_enabled===!0,operatorIds:Array.isArray(e?.admin_panel_user_ids)?e.admin_panel_user_ids.filter(d=>typeof d=="string"):[]},budget:e?.budget??null,rowActionNoticePending:e?.general?.row_action_notice_pending===!0,refsInLists:e?.general?.ref_numbers_in_lists===!0,objectsTableColumns:Array.isArray(e?.objects_table_columns)?e.objects_table_columns:void 0,partsCostMode:i(e?.budget?.parts_cost_mode)}}var o={features:{adaptive:!1,seasonal:!1,environmental:!1,budget:!1,groups:!1,checklists:!1,schedule_time:!1,completion_actions:!1,places:!1},defaultWarningDays:7,rowActionStyle:"buttons_compact",access:a,budget:null,rowActionNoticePending:!1,refsInLists:!1,objectsTableColumns:void 0,partsCostMode:"purchase"};function c(){let e=window;return e.__msSettingsCache??={promise:null}}function S(e){let t=c();if(t.promise)return t.promise;let n=e.connection.sendMessagePromise({type:"maintenance_supporter/settings"}).then(s=>p(s)).catch(()=>(t.promise===n&&(t.promise=null),o));return t.promise=n,n}function y(){c().promise=null}var u=class{constructor(){this._handle=null}schedule(t,n=4e3){this.clear(),this._handle=setTimeout(()=>{this._handle=null,t()},n)}clear(){this._handle!==null&&(clearTimeout(this._handle),this._handle=null)}get pending(){return this._handle!==null}};export{a,m as b,_ as c,p as d,S as e,y as f,u as g};
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
import{b as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-Q7CGGH4O.js";import{a as l}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-M2CMCNR4.js";var a={operatorWriteEnabled:!1,operatorIds:[]};function m(e,t=a){return e?e.is_admin?!0:t.operatorWriteEnabled&&t.operatorIds.includes(e.id):!1}var _=["buttons_compact","buttons","icons"];function p(e){let[t,n]=l.default_warning_days,s=e?.general?.default_warning_days,r=e?.general?.row_action_style;return{features:{...o.features,...e?.features??{}},defaultWarningDays:typeof s=="number"&&Number.isFinite(s)&&s>=t&&s<=n?s:o.defaultWarningDays,rowActionStyle:_.includes(r??"")?r:o.rowActionStyle,access:{operatorWriteEnabled:e?.operator_write_enabled===!0,operatorIds:Array.isArray(e?.admin_panel_user_ids)?e.admin_panel_user_ids.filter(d=>typeof d=="string"):[]},budget:e?.budget??null,rowActionNoticePending:e?.general?.row_action_notice_pending===!0,refsInLists:e?.general?.ref_numbers_in_lists===!0,objectsTableColumns:Array.isArray(e?.objects_table_columns)?e.objects_table_columns:void 0,partsCostMode:i(e?.budget?.parts_cost_mode)}}var o={features:{adaptive:!1,seasonal:!1,environmental:!1,budget:!1,groups:!1,checklists:!1,schedule_time:!1,completion_actions:!1,places:!1},defaultWarningDays:7,rowActionStyle:"buttons_compact",access:a,budget:null,rowActionNoticePending:!1,refsInLists:!1,objectsTableColumns:void 0,partsCostMode:"purchase"};function c(){let e=window;return e.__msSettingsCache??={promise:null}}function S(e){let t=c();if(t.promise)return t.promise;let n=e.connection.sendMessagePromise({type:"maintenance_supporter/settings"}).then(s=>p(s)).catch(()=>(t.promise===n&&(t.promise=null),o));return t.promise=n,n}function y(){c().promise=null}var u=class{constructor(){this._handle=null}schedule(t,n=4e3){this.clear(),this._handle=setTimeout(()=>{this._handle=null,t()},n)}clear(){this._handle!==null&&(clearTimeout(this._handle),this._handle=null)}get pending(){return this._handle!==null}};export{a,m as b,_ as c,p as d,S as e,y as f,u as g};
|
||||
@@ -1,217 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GVLO7RZ4.js";import{a as s,b as p,c as l,f as o,h,l as c,m as n,s as i,y as v}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";var r=class extends h{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;this._replacing=!1;this._oldDeviceId="";this._replaceDevice="keep"}get _lang(){return v(this.hass)}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._replacing=!1,this._error="",this._open=!0}openReplace(e,a){this._entryId=e,this._replacing=!0,this._name=a.name||"",this._oldDeviceId=a.ha_device_id||"",this._haDeviceId="",this._replaceDevice="keep",this._error="",this._open=!0}openEdit(e,a){this._entryId=e,this._name=a.name||"",this._manufacturer=a.manufacturer||"",this._model=a.model||"",this._serialNumber=a.serial_number||"",this._areaId=a.area_id||"",this._installationDate=a.installation_date||"",this._warrantyExpiry=a.warranty_expiry||"",this._documentationUrl=a.documentation_url||"",this._notes=a.notes||"",this._haDeviceId=a.ha_device_id||"",this._parentEntryId=a.parent_entry_id||"",this._replacing=!1,this._error="",this._open=!0}async _replace(){if(this._loading||!this._entryId)return;let e={type:"maintenance_supporter/object/replace",entry_id:this._entryId,name:this._name.trim()||null};this._oldDeviceId?(this._replaceDevice==="other"&&(e.ha_device_id=this._haDeviceId),this._replaceDevice==="none"&&(e.ha_device_id=null)):this._haDeviceId&&(e.ha_device_id=this._haDeviceId);let a=await _(this,e,{busy:t=>{this._loading=t},fallbackKey:"save_error",onError:t=>{this._error=t}});a!==void 0&&(this._open=!1,this.dispatchEvent(new CustomEvent("object-replaced",{detail:{entry_id:a?.entry_id,device_swap:a?.device_swap}})))}_deviceName(e){let t=this.hass?.devices?.[e];return t?.name_by_user||t?.name||e}_deviceSelector(e){return l`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${{device:this._haDeviceId||void 0}}
|
||||
.schema=${[{name:"device",selector:{device:{}}}]}
|
||||
.computeLabel=${()=>e}
|
||||
@value-changed=${a=>this._haDeviceId=a.detail.value?.device||""}
|
||||
></ha-form>`}_renderReplace(){let e=this._lang,a=(d,u)=>l`<label class="radio-row">
|
||||
<input
|
||||
type="radio"
|
||||
name="replace-device"
|
||||
.checked=${this._replaceDevice===d}
|
||||
@change=${()=>{this._replaceDevice=d}}
|
||||
/>
|
||||
<span>${u}</span>
|
||||
</label>`,t=this._replaceDevice==="other"&&!this._haDeviceId;return l`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${i("replace_object",e)}</div>
|
||||
<div class="content">
|
||||
${this._error?l`<div class="error">${this._error}</div>`:o}
|
||||
<div class="hint">${i("replace_object_prompt",e)}</div>
|
||||
<ms-textfield
|
||||
label="${i("replace_name_label",e)}"
|
||||
.value=${this._name}
|
||||
@input=${d=>this._name=d.target.value}
|
||||
></ms-textfield>
|
||||
${this._oldDeviceId?l`<div class="radio-group" role="radiogroup" aria-label=${i("replace_device_heading",e)}>
|
||||
<div class="textarea-label">${i("replace_device_heading",e)}</div>
|
||||
${a("keep",i("replace_device_keep",e).replace("{device}",this._deviceName(this._oldDeviceId)))}
|
||||
${this._replaceDevice==="keep"?l`<div class="hint">${i("replace_device_keep_hint",e)}</div>`:o}
|
||||
${a("other",i("replace_device_other",e))}
|
||||
${this._replaceDevice==="other"?l`${this._deviceSelector(i("replace_device_pick",e))}
|
||||
<div class="hint">${i("replace_device_other_hint",e)}</div>`:o}
|
||||
${a("none",i("replace_device_none",e))}
|
||||
</div>`:this._deviceSelector(i("link_device_optional",e))}
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${i("cancel",e)}
|
||||
</ha-button>
|
||||
<ha-button @click=${this._replace} .disabled=${this._loading||t}>
|
||||
${this._loading?i("saving",e):i("replace_object",e)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`}async _save(){if(this._loading||!this._name.trim())return;this._error="";let e={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},a=await _(this,this._entryId?{type:"maintenance_supporter/object/update",entry_id:this._entryId,...e}:{type:"maintenance_supporter/object/create",...e},{busy:t=>{this._loading=t},fallbackKey:"save_error",onError:t=>{this._error=t}});a!==void 0&&(this._open=!1,this.dispatchEvent(new CustomEvent("object-saved",{detail:{device_swap:a?.device_swap}})))}_parentChoices(){return(this.objects||[]).filter(e=>e.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;if(this._replacing)return this._renderReplace();let e=this._lang,a=this._entryId?i("edit_object",e):i("new_object",e);return l`
|
||||
<ha-dialog open @closed=${this._close}>
|
||||
<div class="dialog-title">${a}</div>
|
||||
<div class="content">
|
||||
${this._error?l`<div class="error">${this._error}</div>`:o}
|
||||
<ms-textfield
|
||||
label="${i("name",e)}"
|
||||
required
|
||||
.value=${this._name}
|
||||
@input=${t=>this._name=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("manufacturer_optional",e)}"
|
||||
.value=${this._manufacturer}
|
||||
@input=${t=>this._manufacturer=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("model_optional",e)}"
|
||||
.value=${this._model}
|
||||
@input=${t=>this._model=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("serial_number_optional",e)}"
|
||||
.value=${this._serialNumber}
|
||||
@input=${t=>this._serialNumber=t.target.value}
|
||||
></ms-textfield>
|
||||
<ms-textfield
|
||||
label="${i("documentation_url_optional",e)}"
|
||||
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",e)}"
|
||||
.value=${this._areaId}
|
||||
@value-changed=${t=>this._areaId=t.detail.value||""}
|
||||
></ha-area-picker>
|
||||
<ms-date-field
|
||||
kind="date"
|
||||
clearable
|
||||
.hass=${this.hass}
|
||||
.lang=${e}
|
||||
label="${i("installation_date_optional",e)}"
|
||||
.value=${this._installationDate}
|
||||
@value-changed=${t=>this._installationDate=t.detail.value}
|
||||
></ms-date-field>
|
||||
<ms-date-field
|
||||
kind="date"
|
||||
clearable
|
||||
.hass=${this.hass}
|
||||
.lang=${e}
|
||||
label="${i("warranty_expiry_optional",e)}"
|
||||
.value=${this._warrantyExpiry}
|
||||
@value-changed=${t=>this._warrantyExpiry=t.detail.value}
|
||||
></ms-date-field>
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${{device:this._haDeviceId||void 0}}
|
||||
.schema=${[{name:"device",selector:{device:{}}}]}
|
||||
.computeLabel=${()=>i("link_device_optional",e)}
|
||||
@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",e)}</span>
|
||||
<select
|
||||
class="parent-select"
|
||||
.value=${this._parentEntryId}
|
||||
@change=${t=>this._parentEntryId=t.target.value}
|
||||
>
|
||||
<option value="" ?selected=${!this._parentEntryId}>
|
||||
${i("parent_none",e)}
|
||||
</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",e)}</span>
|
||||
<textarea
|
||||
rows="3"
|
||||
.value=${this._notes}
|
||||
@input=${t=>this._notes=t.target.value}
|
||||
></textarea>
|
||||
<span class="md-hint">${i("notes_markdown_hint",e)}</span>
|
||||
</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>
|
||||
`}};r.styles=p`
|
||||
.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);
|
||||
}
|
||||
.md-hint {
|
||||
font-size: 11px; color: var(--secondary-text-color); font-style: italic;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.hint {
|
||||
font-size: 13px;
|
||||
color: var(--secondary-text-color);
|
||||
line-height: 1.4;
|
||||
}
|
||||
.radio-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.radio-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.radio-row input {
|
||||
margin: 0;
|
||||
}
|
||||
`,s([c({attribute:!1})],r.prototype,"hass",2),s([c({attribute:!1})],r.prototype,"objects",2),s([n()],r.prototype,"_open",2),s([n()],r.prototype,"_loading",2),s([n()],r.prototype,"_error",2),s([n()],r.prototype,"_name",2),s([n()],r.prototype,"_manufacturer",2),s([n()],r.prototype,"_model",2),s([n()],r.prototype,"_serialNumber",2),s([n()],r.prototype,"_areaId",2),s([n()],r.prototype,"_installationDate",2),s([n()],r.prototype,"_warrantyExpiry",2),s([n()],r.prototype,"_documentationUrl",2),s([n()],r.prototype,"_notes",2),s([n()],r.prototype,"_haDeviceId",2),s([n()],r.prototype,"_parentEntryId",2),s([n()],r.prototype,"_entryId",2),s([n()],r.prototype,"_replacing",2),s([n()],r.prototype,"_oldDeviceId",2),s([n()],r.prototype,"_replaceDevice",2);customElements.get("maintenance-object-dialog")||customElements.define("maintenance-object-dialog",r);export{r as a};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{O as n,s as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";var l={"Completed from dashboard button":"hist_note_button","Completed from the To-do list":"hist_note_todo","Completed by voice":"hist_note_voice","Completed from the notification":"hist_note_notification","Completed via NFC tag":"hist_note_nfc","Completed from the shopping list":"hist_note_shopping_list","Completed from a mirrored to-do list":"hist_note_todo_mirror","Skipped from notification":"hist_note_skipped_notification","Skipped from dashboard button":"hist_note_skipped_button","Sensor trigger activated":"hist_note_sensor_triggered","Initial value set during task creation":"hist_note_initial"},m=[[/^Auto-completed: sensor recovered \((.+)\)$/,"hist_note_auto_recovered",t=>({value:t[1]})],[/^Reset to (\d{4}-\d{2}-\d{2})$/,"hist_note_reset",(t,e)=>({date:n(t[1],e)})],[/^Trigger entity replaced: (.+) → (.+)$/,"hist_note_trigger_replaced",t=>({old:t[1],new:t[2]})],[/^Sensor trigger removed \(entity was: (.+)\)\. Schedule converted to (\w+)\.$/,"hist_note_trigger_removed",(t,e)=>({entity:t[1],schedule:o(t[2],e)})],[/^Entity (.+) removed from compound trigger; (\d+) conditions remain\.$/,"hist_note_compound_removed",t=>({entity:t[1],count:t[2]})]];function h(t,e){if(!t)return"";let i=l[t.trim()];if(i)return o(i,e);for(let[s,d,_]of m){let r=t.trim().match(s);if(r){let c=_(r,e);return o(d,e).replace(/\{(\w+)\}/g,(a,g)=>c[g]??a)}}return t}export{h as a};
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{b as s}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-OUHDI2FL.js";async function a(o,n,t=300){return(await o.connection.sendMessagePromise({type:"auth/sign_path",path:n,expires:t})).path}async function r(o,n,t=300){return a(o,`/api/maintenance_supporter/document/${n}`,t)}async function p(o,n,t=""){let e=window.open("about:blank","_blank");try{let i=await r(o,n);e&&(e.location.href=new URL(i+t,window.location.origin).href)}catch(i){throw e&&e.close(),i}}async function l(o,n,t){s(await r(o,n,30),t)}function m(o,n=null){let t=URL.createObjectURL(new Blob([o],{type:"text/html"}));n&&!n.closed?n.location.href=t:window.open(t,"_blank"),setTimeout(()=>URL.revokeObjectURL(t),6e4)}function u(){return window.open("about:blank","_blank")}export{a,r as b,p as c,l as d,m as e,u as f};
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
import{b as s}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C6NCKN5O.js";async function a(o,n,t=300){return(await o.connection.sendMessagePromise({type:"auth/sign_path",path:n,expires:t})).path}async function r(o,n,t=300){return a(o,`/api/maintenance_supporter/document/${n}`,t)}async function p(o,n,t=""){let e=window.open("about:blank","_blank");try{let i=await r(o,n);e&&(e.location.href=new URL(i+t,window.location.origin).href)}catch(i){throw e&&e.close(),i}}async function l(o,n,t){s(await r(o,n,30),t)}function m(o,n=null){let t=URL.createObjectURL(new Blob([o],{type:"text/html"}));n&&!n.closed?n.location.href=t:window.open(t,"_blank"),setTimeout(()=>URL.revokeObjectURL(t),6e4)}function u(){return window.open("about:blank","_blank")}export{a,r as b,p as c,l as d,m as e,u as f};
|
||||
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
var r={objectSections:"msp-object-sections",printOptions:"msp-print-options",batteryRosterOpen:"msp-bf-roster-open",docSort:"msp-doc-sort",cameraLabel:"msp-camera-label",overviewTab:"msp-overview-tab",collapsedSections:"msp-collapsed-sections",chartRange:"msp-chart-range",chartHideOutliers:"msp-chart-hide-outliers",taskSort:"maintenance_supporter_sort",objectSort:"maintenance_supporter_object_sort",groupBy:"maintenance_supporter_groupby",objectView:"maintenance_supporter_object_view",objectsCache:"msp-objects-cache",gettingStartedDismissed:"msp-gs-dismissed",batteryRosterSort:"ms_bf_roster_sort",areaSort:"msp-area-sort"};function s(t){try{return localStorage.getItem(t)}catch{return null}}function o(t,e){try{localStorage.setItem(t,e)}catch{}}export{r as a,s as b,o as c};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
var r={objectSections:"msp-object-sections",printOptions:"msp-print-options",batteryRosterOpen:"msp-bf-roster-open",docSort:"msp-doc-sort",cameraLabel:"msp-camera-label",overviewTab:"msp-overview-tab",collapsedSections:"msp-collapsed-sections",chartRange:"msp-chart-range",chartHideOutliers:"msp-chart-hide-outliers",taskSort:"maintenance_supporter_sort",objectSort:"maintenance_supporter_object_sort",groupBy:"maintenance_supporter_groupby",objectView:"maintenance_supporter_object_view",objectsCache:"msp-objects-cache",gettingStartedDismissed:"msp-gs-dismissed",batteryRosterSort:"ms_bf_roster_sort",areaSort:"msp-area-sort"};function s(t){try{return localStorage.getItem(t)}catch{return null}}function o(t,e){try{localStorage.setItem(t,e)}catch{}}export{r as a,s as b,o as c};
|
||||
@@ -1,88 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import{F as m,a,b as y,c as s,f as l,h as g,l as o,m as f,s as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";function $(n){let t=m("2001-02-03",n).match(/\d+/g)||[],e=v=>t.findIndex(_=>Number(_)===v),h=e(2001),c=e(2),u=e(3);return h===0?"YMD":c>=0&&u>=0&&c<u?"MDY":"DMY"}function p(n,i,t){if(n<1e3||n>9999||i<1||i>12||t<1||t>31)return null;let e=new Date(n,i-1,t);return e.getFullYear()!==n||e.getMonth()!==i-1||e.getDate()!==t?null:`${n}-${String(i).padStart(2,"0")}-${String(t).padStart(2,"0")}`}function b(n,i){let t=n.trim(),e;if(e=t.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/))return p(+e[1],+e[2],+e[3]);if(e=t.match(/^(\d{4})$/))return p(+e[1],1,1);if(e=t.match(/^(\d{1,2})[./](\d{4})$/))return p(+e[2],+e[1],1);if(e=t.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/))return p(+e[3],+e[2],+e[1]);if(e=t.match(/^(\d{1,2})[/-](\d{1,2})[/-](\d{4})$/)){let h=+e[1],c=+e[2],u=+e[3];return $(i)==="MDY"?p(u,h,c):p(u,c,h)}return null}function x(n,i){if(i)switch(n){case"date":return i.split("T")[0];case"time":return i.length===5?`${i}:00`:i;case"datetime":{let[t,e="00:00:00"]=i.split("T");return`${t} ${e.length===5?`${e}:00`:e}`}}}function k(n,i){if(typeof i!="string"||!i)return"";switch(n){case"date":return i.slice(0,10);case"time":return i.slice(0,5);case"datetime":{let[t,e="00:00:00"]=i.split(" ");return`${t}T${e.length===5?`${e}:00`:e}`}}}var r=class extends g{constructor(){super(...arguments);this.kind="date";this.label="";this.value="";this.clearable=!1;this.disabled=!1;this.required=!1;this.lang="en";this._typing=!1;this._typed="";this._typedInvalid=!1}_startTyping(){this._typed=this.value,this._typedInvalid=!1,this._typing=!0,this.updateComplete.then(()=>this.shadowRoot?.querySelector("input.typed")?.focus())}_commitTyped(){if(!this._typed.trim()){this._typing=!1;return}let t=b(this._typed,this.lang);if(!t){this._typedInvalid=!0;return}this._typing=!1,this._typedInvalid=!1,this._emit(t)}_onTypedKey(t){t.key==="Enter"?(t.preventDefault(),this._commitTyped()):t.key==="Escape"&&(t.preventDefault(),this._typing=!1,this._typedInvalid=!1)}_selector(){switch(this.kind){case"date":return{date:{}};case"time":return{time:{no_second:!0}};case"datetime":return{datetime:{}}}}_onSelectorChange(t){t.stopPropagation(),this._emit(k(this.kind,t.detail?.value))}_clear(){this._emit("")}_emit(t){t!==this.value&&(this.value=t,this.dispatchEvent(new CustomEvent("value-changed",{bubbles:!0,composed:!0,detail:{value:t}})))}render(){return s`
|
||||
<div class="field">
|
||||
${this.label?s`<span class="label">${this.label}${this.required?s`<span class="req">*</span>`:l}</span>`:l}
|
||||
<div class="row">
|
||||
${this._typing?s`<input class="typed" type="text" inputmode="numeric" autocomplete="off"
|
||||
.value=${this._typed}
|
||||
placeholder=${m("1978-03-15",this.lang)}
|
||||
aria-invalid=${this._typedInvalid?"true":"false"}
|
||||
@input=${t=>{this._typed=t.target.value,this._typedInvalid=!1}}
|
||||
@keydown=${this._onTypedKey}
|
||||
@blur=${this._commitTyped} />`:s`<ha-selector
|
||||
.hass=${this.hass}
|
||||
.selector=${this._selector()}
|
||||
.value=${x(this.kind,this.value)}
|
||||
.required=${this.required}
|
||||
.disabled=${this.disabled}
|
||||
@value-changed=${this._onSelectorChange}
|
||||
></ha-selector>`}
|
||||
${this.kind==="date"&&!this.disabled&&!this._typing?s`<button type="button" class="type-toggle" title=${d("date_type_toggle",this.lang)} aria-label=${d("date_type_toggle",this.lang)} @click=${this._startTyping}>
|
||||
<ha-icon icon="mdi:keyboard-outline"></ha-icon>
|
||||
</button>`:l}
|
||||
${this.clearable&&this.value&&!this.disabled&&!this._typing?s`<button type="button" class="clear" title=${d("clear",this.lang)} aria-label=${d("clear",this.lang)} @click=${this._clear}>
|
||||
<ha-icon icon="mdi:close"></ha-icon>
|
||||
</button>`:l}
|
||||
</div>
|
||||
${this._typedInvalid?s`<span class="helper invalid">${d("date_type_invalid",this.lang)}</span>`:this.helper?s`<span class="helper">${this.helper}</span>`:l}
|
||||
</div>
|
||||
`}};r.styles=y`
|
||||
: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; }
|
||||
.row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
ha-selector {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.clear, .type-toggle {
|
||||
flex: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
background: transparent;
|
||||
color: var(--secondary-text-color);
|
||||
cursor: pointer;
|
||||
--mdc-icon-size: 20px;
|
||||
}
|
||||
.clear:hover, .type-toggle:hover { background: rgba(var(--rgb-primary-text-color, 0, 0, 0), 0.08); }
|
||||
.clear:focus-visible, .type-toggle:focus-visible { outline: 2px solid var(--primary-color); }
|
||||
.helper {
|
||||
font-size: 11px;
|
||||
color: var(--secondary-text-color);
|
||||
font-style: italic;
|
||||
}
|
||||
.helper.invalid { color: var(--error-color, #f44336); font-style: normal; }
|
||||
input.typed {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 40px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 12px;
|
||||
border: 1px solid var(--divider-color, #ccc);
|
||||
border-radius: 4px;
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
font: inherit;
|
||||
}
|
||||
input.typed[aria-invalid="true"] { border-color: var(--error-color, #f44336); }
|
||||
input.typed:focus { outline: 2px solid var(--primary-color); outline-offset: -1px; }
|
||||
`,a([o({attribute:!1})],r.prototype,"hass",2),a([o()],r.prototype,"kind",2),a([o()],r.prototype,"label",2),a([o()],r.prototype,"value",2),a([o()],r.prototype,"helper",2),a([o({type:Boolean})],r.prototype,"clearable",2),a([o({type:Boolean})],r.prototype,"disabled",2),a([o({type:Boolean})],r.prototype,"required",2),a([o()],r.prototype,"lang",2),a([f()],r.prototype,"_typing",2),a([f()],r.prototype,"_typed",2),a([f()],r.prototype,"_typedInvalid",2);customElements.get("ms-date-field")||customElements.define("ms-date-field",r);
|
||||
+2
-2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,79 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.98.0 */
|
||||
import{a as r,b as l,c as i,f as o,h as n,l as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-27MZ7YLE.js";var e=class extends n{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1;this.multiline=!1;this.rows=3}_onInput(s){let a=s.target.value;this.value=a,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:a}}))}render(){return i`
|
||||
<label class="field">
|
||||
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:o}</span>`:o}
|
||||
${this.multiline?i`
|
||||
<textarea
|
||||
.value=${this.value??""}
|
||||
rows=${this.rows}
|
||||
?required=${this.required}
|
||||
?disabled=${this.disabled}
|
||||
placeholder=${this.placeholder}
|
||||
@input=${this._onInput}
|
||||
@change=${this._onInput}
|
||||
></textarea>`:i`
|
||||
<input
|
||||
.value=${this.value??""}
|
||||
.type=${this.type}
|
||||
?required=${this.required}
|
||||
?disabled=${this.disabled}
|
||||
placeholder=${this.placeholder}
|
||||
step=${this.step??o}
|
||||
min=${this.min??o}
|
||||
max=${this.max??o}
|
||||
pattern=${this.pattern??o}
|
||||
@input=${this._onInput}
|
||||
@change=${this._onInput}
|
||||
/>`}
|
||||
${this.helper?i`<span class="helper">${this.helper}</span>`:o}
|
||||
</label>
|
||||
`}};e.styles=l`
|
||||
: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; }
|
||||
textarea {
|
||||
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;
|
||||
resize: vertical;
|
||||
}
|
||||
textarea:focus { border-color: var(--primary-color); }
|
||||
textarea:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.helper {
|
||||
font-size: 11px;
|
||||
color: var(--secondary-text-color);
|
||||
font-style: italic;
|
||||
}
|
||||
`,r([t()],e.prototype,"label",2),r([t()],e.prototype,"value",2),r([t()],e.prototype,"placeholder",2),r([t()],e.prototype,"type",2),r([t({type:Boolean})],e.prototype,"required",2),r([t({type:Boolean})],e.prototype,"disabled",2),r([t()],e.prototype,"step",2),r([t()],e.prototype,"min",2),r([t()],e.prototype,"max",2),r([t()],e.prototype,"pattern",2),r([t()],e.prototype,"helper",2),r([t({type:Boolean})],e.prototype,"multiline",2),r([t({type:Number})],e.prototype,"rows",2);customElements.get("ms-textfield")||customElements.define("ms-textfield",e);
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
import{a as q}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-JQXHX4U4.js";import{H as k,a,b as f,c as n,f as u,h as x,l as h,m as c,s as e}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-3FGYBPXY.js";function d(r){return r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function _(r){return!r.startsWith("data:image/svg+xml,")&&!r.startsWith("data:image/png;base64,")?"":d(r)}function y(r){return r.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var l=class extends x{constructor(){super(...arguments);this.lang="";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._quickResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}get _dialogLang(){return this.lang||k(this.hass)}openForObject(t,i){this._entryId=t,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._quickResult=null,this._open=!0,this._generate()}openForTask(t,i,s,o){this._entryId=t,this._taskId=i,this._objectName=s,this._taskName=o,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._quickResult=null,this._open=!0,this._generate()}async _generate(){let t=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null,this._quickResult=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 s=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&(s.push(this.hass.connection.sendMessagePromise({...i,action:"complete"})),await this._hasQuickCompleteDefaults()&&s.push(this.hass.connection.sendMessagePromise({...i,action:"quick_complete"})));let o=await Promise.all(s);if(t!==this._generateSeq)return;this._viewResult=o[0],o.length>1&&(this._completeResult=o[1]),o.length>2&&(this._quickResult=o[2])}catch(i){if(t!==this._generateSeq)return;let s=i?.code,o=i?.message;this._error=s==="no_url"||typeof o=="string"&&o.includes("No Home Assistant URL")?e("qr_error_no_url",this._dialogLang):e("qr_error",this._dialogLang)}finally{t===this._generateSeq&&(this._loading=!1)}}async _hasQuickCompleteDefaults(){try{let i=((await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object",entry_id:this._entryId})).tasks||[]).find(s=>s.id===this._taskId);return!!i?.quick_complete_defaults&&Object.keys(i.quick_complete_defaults).length>0}catch{return!1}}_setUrlMode(t){this._urlMode!==t&&(this._urlMode=t,this._generate())}_print(){if(!this._viewResult)return;let t=this._viewResult,i=t.label.task_name?`${t.label.object_name} \u2014 ${t.label.task_name}`:t.label.object_name,s=[t.label.manufacturer,t.label.model].filter(Boolean).join(" "),o=window.open("","_blank","width=600,height=500");if(!o)return;let p=this._dialogLang,m=d(i),g=d(s),v=!!this._completeResult,b=!!this._quickResult,w=d(e("qr_action_view",p)),$=d(e("qr_action_complete",p)),R=d(e("qr_action_quick_complete",p));o.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
import{a as q}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C6NCKN5O.js";import{H as k,a,b as f,c as n,f as u,h as x,l as h,m as c,s as e}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZW2EWBUR.js";function d(r){return r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function _(r){return!r.startsWith("data:image/svg+xml,")&&!r.startsWith("data:image/png;base64,")?"":d(r)}function y(r){return r.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var l=class extends x{constructor(){super(...arguments);this.lang="";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._quickResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}get _dialogLang(){return this.lang||k(this.hass)}openForObject(t,i){this._entryId=t,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._quickResult=null,this._open=!0,this._generate()}openForTask(t,i,s,o){this._entryId=t,this._taskId=i,this._objectName=s,this._taskName=o,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._quickResult=null,this._open=!0,this._generate()}async _generate(){let t=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null,this._quickResult=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 s=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&(s.push(this.hass.connection.sendMessagePromise({...i,action:"complete"})),await this._hasQuickCompleteDefaults()&&s.push(this.hass.connection.sendMessagePromise({...i,action:"quick_complete"})));let o=await Promise.all(s);if(t!==this._generateSeq)return;this._viewResult=o[0],o.length>1&&(this._completeResult=o[1]),o.length>2&&(this._quickResult=o[2])}catch(i){if(t!==this._generateSeq)return;let s=i?.code,o=i?.message;this._error=s==="no_url"||typeof o=="string"&&o.includes("No Home Assistant URL")?e("qr_error_no_url",this._dialogLang):e("qr_error",this._dialogLang)}finally{t===this._generateSeq&&(this._loading=!1)}}async _hasQuickCompleteDefaults(){try{let i=((await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object",entry_id:this._entryId})).tasks||[]).find(s=>s.id===this._taskId);return!!i?.quick_complete_defaults&&Object.keys(i.quick_complete_defaults).length>0}catch{return!1}}_setUrlMode(t){this._urlMode!==t&&(this._urlMode=t,this._generate())}_print(){if(!this._viewResult)return;let t=this._viewResult,i=t.label.task_name?`${t.label.object_name} \u2014 ${t.label.task_name}`:t.label.object_name,s=[t.label.manufacturer,t.label.model].filter(Boolean).join(" "),o=window.open("","_blank","width=600,height=500");if(!o)return;let p=this._dialogLang,m=d(i),g=d(s),v=!!this._completeResult,b=!!this._quickResult,w=d(e("qr_action_view",p)),$=d(e("qr_action_complete",p)),R=d(e("qr_action_quick_complete",p));o.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
<meta name="color-scheme" content="light">
|
||||
<title>${m}</title>
|
||||
<style>
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
/*! maintenance_supporter frontend 2.99.0 */
|
||||
import{O as n,s as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-3FGYBPXY.js";var l={"Completed from dashboard button":"hist_note_button","Completed from the To-do list":"hist_note_todo","Completed by voice":"hist_note_voice","Completed from the notification":"hist_note_notification","Completed via NFC tag":"hist_note_nfc","Completed from the shopping list":"hist_note_shopping_list","Completed from a mirrored to-do list":"hist_note_todo_mirror","Skipped from notification":"hist_note_skipped_notification","Skipped from dashboard button":"hist_note_skipped_button","Sensor trigger activated":"hist_note_sensor_triggered","Initial value set during task creation":"hist_note_initial"},m=[[/^Auto-completed: sensor recovered \((.+)\)$/,"hist_note_auto_recovered",t=>({value:t[1]})],[/^Reset to (\d{4}-\d{2}-\d{2})$/,"hist_note_reset",(t,e)=>({date:n(t[1],e)})],[/^Trigger entity replaced: (.+) → (.+)$/,"hist_note_trigger_replaced",t=>({old:t[1],new:t[2]})],[/^Sensor trigger removed \(entity was: (.+)\)\. Schedule converted to (\w+)\.$/,"hist_note_trigger_removed",(t,e)=>({entity:t[1],schedule:o(t[2],e)})],[/^Entity (.+) removed from compound trigger; (\d+) conditions remain\.$/,"hist_note_compound_removed",t=>({entity:t[1],count:t[2]})]];function h(t,e){if(!t)return"";let i=l[t.trim()];if(i)return o(i,e);for(let[s,d,_]of m){let r=t.trim().match(s);if(r){let c=_(r,e);return o(d,e).replace(/\{(\w+)\}/g,(a,g)=>c[g]??a)}}return t}export{h as a};
|
||||
/*! maintenance_supporter frontend 2.100.0 */
|
||||
import{O as n,s as o}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZW2EWBUR.js";var l={"Completed from dashboard button":"hist_note_button","Completed from the To-do list":"hist_note_todo","Completed by voice":"hist_note_voice","Completed from the notification":"hist_note_notification","Completed via NFC tag":"hist_note_nfc","Completed from the shopping list":"hist_note_shopping_list","Completed from a mirrored to-do list":"hist_note_todo_mirror","Skipped from notification":"hist_note_skipped_notification","Skipped from dashboard button":"hist_note_skipped_button","Sensor trigger activated":"hist_note_sensor_triggered","Initial value set during task creation":"hist_note_initial"},m=[[/^Auto-completed: sensor recovered \((.+)\)$/,"hist_note_auto_recovered",t=>({value:t[1]})],[/^Reset to (\d{4}-\d{2}-\d{2})$/,"hist_note_reset",(t,e)=>({date:n(t[1],e)})],[/^Trigger entity replaced: (.+) → (.+)$/,"hist_note_trigger_replaced",t=>({old:t[1],new:t[2]})],[/^Sensor trigger removed \(entity was: (.+)\)\. Schedule converted to (\w+)\.$/,"hist_note_trigger_removed",(t,e)=>({entity:t[1],schedule:o(t[2],e)})],[/^Entity (.+) removed from compound trigger; (\d+) conditions remain\.$/,"hist_note_compound_removed",t=>({entity:t[1],count:t[2]})]];function h(t,e){if(!t)return"";let i=l[t.trim()];if(i)return o(i,e);for(let[s,d,_]of m){let r=t.trim().match(s);if(r){let c=_(r,e);return o(d,e).replace(/\{(\w+)\}/g,(a,g)=>c[g]??a)}}return t}export{h as a};
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! maintenance_supporter frontend 2.97.1 */
|
||||
import{s as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-YJXVPPWG.js";var _=[{key:"name",labelKey:"name",required:!0},{key:"ref_no",labelKey:"ref_number"},{key:"manufacturer",labelKey:"manufacturer"},{key:"model",labelKey:"model"},{key:"serial_number",labelKey:"serial_number_label"},{key:"installation_date",labelKey:"installed"},{key:"warranty_expiry",labelKey:"warranty"},{key:"area_id",labelKey:"area"},{key:"documentation_url",labelKey:"documentation_url_label"},{key:"notes",labelKey:"object_notes_label"},{key:"task_count",labelKey:"tasks"},{key:"actions",labelKey:"actions"}],u=_.map(e=>e.key),i=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function g(e){if(!Array.isArray(e))return[...i];let n=new Set,r=[];for(let t of e)typeof t=="string"&&u.includes(t)&&!n.has(t)&&(n.add(t),r.push(t));return r.length?(r.includes("name")||r.unshift("name"),r):[...i]}function f(e,n){return a(`home_dwelling_${e==="house"||e==="apartment"?e:"unknown"}`,n)}function m(e,n){if(!e)return"";try{return new Intl.DisplayNames([n],{type:"region"}).of(e)||e}catch{return e}}var l={floors:"home_reason_floors",basement_floor:"home_reason_basement",area_basement:"home_reason_basement",area_garden:"home_reason_garden",area_shed:"home_reason_shed",area_driveway:"home_reason_driveway",area_garage:"home_reason_garage",entity_garage:"home_reason_garage",area_attic:"home_reason_attic",entity_lawn_mower:"home_reason_lawn_mower",entity_gate:"home_reason_gate",area_balcony:"home_reason_balcony",small_home:"home_reason_small_home"},c={ups:"home_reason_ups"};function d(e,n){let r=[];for(let t of e){let o=l[t];if(!o)continue;let s=a(o,n);r.includes(s)||r.push(s)}return r.join(", ")}function b(e,n,r){if(e==="starter")return a("home_reason_starter",n);if(e==="country")return a("home_reason_country",n).replace("{country}",m(r,n));if(e.startsWith("feature_")){let t=e.slice(8),o=l[`area_${t}`]??c[t];return a("home_reason_feature",n).replace("{feature}",o?a(o,n):e)}return a(`home_trait_${e}`,n)}export{_ as a,i as b,g as c,f as d,m as e,d as f,b as g};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user