108 files
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
{"pid": 71, "version": 1, "ha_version": "2026.8.1", "start_ts": 1786576922.6768394}
|
{"pid": 72, "version": 1, "ha_version": "2026.8.1", "start_ts": 1786664044.1505892}
|
||||||
+25
-25
@@ -81,117 +81,117 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "88b90f2b1d6b45f0b44bee786ee1a525",
|
"id": "88b90f2b1d6b45f0b44bee786ee1a525",
|
||||||
"url": "/taskmate/taskmate-attr-resolver.js?v=5.1.0",
|
"url": "/taskmate/taskmate-attr-resolver.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "0796c92931dd458e81dc9c2677248274",
|
"id": "0796c92931dd458e81dc9c2677248274",
|
||||||
"url": "/taskmate/taskmate-localize.js?v=5.1.0",
|
"url": "/taskmate/taskmate-localize.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "d2e281920ac7409583eafff1f1db69bd",
|
"id": "d2e281920ac7409583eafff1f1db69bd",
|
||||||
"url": "/taskmate/taskmate-design.js?v=5.1.0",
|
"url": "/taskmate/taskmate-design.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "9eae9632f0734480be5edd784b030673",
|
"id": "9eae9632f0734480be5edd784b030673",
|
||||||
"url": "/taskmate/taskmate-badges-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-badges-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "5df49cd8a4eb420497b5df22cb31362c",
|
"id": "5df49cd8a4eb420497b5df22cb31362c",
|
||||||
"url": "/taskmate/taskmate-child-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-child-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "b44c87d0d74f468cb96c5eabc340f9ee",
|
"id": "b44c87d0d74f468cb96c5eabc340f9ee",
|
||||||
"url": "/taskmate/taskmate-rewards-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-rewards-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "787a96f9c30548708165a48457c99feb",
|
"id": "787a96f9c30548708165a48457c99feb",
|
||||||
"url": "/taskmate/taskmate-approvals-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-approvals-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "84031597de424ad68e7c2bc66d06b72e",
|
"id": "84031597de424ad68e7c2bc66d06b72e",
|
||||||
"url": "/taskmate/taskmate-points-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-points-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "02613225844746b699bfbfac9642eca2",
|
"id": "02613225844746b699bfbfac9642eca2",
|
||||||
"url": "/taskmate/taskmate-reorder-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-reorder-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "7a06a07e17ba4b31b712bc91b77360b4",
|
"id": "7a06a07e17ba4b31b712bc91b77360b4",
|
||||||
"url": "/taskmate/taskmate-overview-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-overview-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "08b42b53b33b4fa88db932455cf8d5aa",
|
"id": "08b42b53b33b4fa88db932455cf8d5aa",
|
||||||
"url": "/taskmate/taskmate-activity-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-activity-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "15907eff51784acdba88ff694b574509",
|
"id": "15907eff51784acdba88ff694b574509",
|
||||||
"url": "/taskmate/taskmate-streak-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-streak-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "1bd6bb5c0a6d4f0d916e3d82cb7fac39",
|
"id": "1bd6bb5c0a6d4f0d916e3d82cb7fac39",
|
||||||
"url": "/taskmate/taskmate-weekly-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-weekly-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "289ce5943f5a4972a593697db4c96ece",
|
"id": "289ce5943f5a4972a593697db4c96ece",
|
||||||
"url": "/taskmate/taskmate-graph-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-graph-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "d2904acee4c74a398dcc7b996c23e7e7",
|
"id": "d2904acee4c74a398dcc7b996c23e7e7",
|
||||||
"url": "/taskmate/taskmate-reward-progress-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-reward-progress-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "46d378736fd54a26be253f2dfb27202e",
|
"id": "46d378736fd54a26be253f2dfb27202e",
|
||||||
"url": "/taskmate/taskmate-leaderboard-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-leaderboard-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "db11ae36457842fa826c7991e1d9c6f4",
|
"id": "db11ae36457842fa826c7991e1d9c6f4",
|
||||||
"url": "/taskmate/taskmate-parent-dashboard-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-parent-dashboard-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "ce85f301b59a412e9abfe5ffd51cb9a2",
|
"id": "ce85f301b59a412e9abfe5ffd51cb9a2",
|
||||||
"url": "/taskmate/taskmate-penalties-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-penalties-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "1959e1629de2422daa8adaf87069c288",
|
"id": "1959e1629de2422daa8adaf87069c288",
|
||||||
"url": "/taskmate/taskmate-bonuses-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-bonuses-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "2548524b269c4959bc7e0e967df943af",
|
"id": "2548524b269c4959bc7e0e967df943af",
|
||||||
"url": "/taskmate/taskmate-points-display-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-points-display-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "36ada49368db4187a283fbbbef45454f",
|
"id": "36ada49368db4187a283fbbbef45454f",
|
||||||
"url": "/taskmate/taskmate-calendar-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-calendar-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "67c32687acd2497b90030ef141f4b6db",
|
"id": "67c32687acd2497b90030ef141f4b6db",
|
||||||
"url": "/taskmate/taskmate-photo-gallery-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-photo-gallery-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "6f0c8348a91f4b74a9b846ab3f62621f",
|
"id": "6f0c8348a91f4b74a9b846ab3f62621f",
|
||||||
"url": "/taskmate/taskmate-family-goal-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-family-goal-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -281,7 +281,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "73dbd2de03de4530b451a55bfe6c46cf",
|
"id": "73dbd2de03de4530b451a55bfe6c46cf",
|
||||||
"url": "/taskmate/taskmate-routine-card.js?v=5.1.0",
|
"url": "/taskmate/taskmate-routine-card.js?v=5.1.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -310,7 +310,7 @@
|
|||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "5ba9f58b81f54f7a947d2d74df45025c",
|
"id": "8b8ada495c23458095cf669821c07524",
|
||||||
"url": "/climate_scheduler/static/climate-scheduler-card.js?v=1.15.1",
|
"url": "/climate_scheduler/static/climate-scheduler-card.js?v=1.15.1",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1025,17 +1025,39 @@ class MaintenanceCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||||||
actual_interval = None
|
actual_interval = None
|
||||||
|
|
||||||
# #99: enrich the per-completion parts selection with names so the
|
# #99: enrich the per-completion parts selection with names so the
|
||||||
# history entry is readable without a part-id lookup.
|
# history entry is readable without a part-id lookup. Since #130 the
|
||||||
|
# AUTOMATIC path records too: with no explicit selection, the task's
|
||||||
|
# consumes_parts links — exactly what async_handle_completion_parts
|
||||||
|
# will consume below — go on the record, so completions from the
|
||||||
|
# no-dialog surfaces (service, button, QR, to-do, voice, recovery)
|
||||||
|
# stay correctable through the history editor like dialog ones.
|
||||||
|
record_links = (
|
||||||
|
used_parts if used_parts is not None else (merged[task_id].get("consumes_parts") or [])
|
||||||
|
)
|
||||||
enriched_used: list[dict[str, Any]] | None = None
|
enriched_used: list[dict[str, Any]] | None = None
|
||||||
if used_parts is not None:
|
if used_parts is not None or record_links:
|
||||||
parts_catalog = self.entry.data.get("parts") or {}
|
own_catalog = self.entry.data.get("parts") or {}
|
||||||
|
|
||||||
|
def _part_name(link: dict[str, Any]) -> str:
|
||||||
|
owner_id = link.get("entry_id")
|
||||||
|
catalog: dict[str, Any] = own_catalog
|
||||||
|
if owner_id and owner_id != self.entry.entry_id:
|
||||||
|
owner = self.hass.config_entries.async_get_entry(owner_id)
|
||||||
|
catalog = (owner.data.get("parts") or {}) if owner else {}
|
||||||
|
name = (catalog.get(link["part_id"]) or {}).get("name")
|
||||||
|
return str(name) if name else str(link["part_id"])
|
||||||
|
|
||||||
enriched_used = [
|
enriched_used = [
|
||||||
{
|
{
|
||||||
"part_id": link["part_id"],
|
"part_id": link["part_id"],
|
||||||
"name": (parts_catalog.get(link["part_id"]) or {}).get("name") or link["part_id"],
|
"name": _part_name(link),
|
||||||
"quantity": link.get("quantity", 1),
|
"quantity": link.get("quantity", 1),
|
||||||
|
# #130: keep the pool owner on the record so a later
|
||||||
|
# history edit can resolve the part without guessing.
|
||||||
|
**({"entry_id": link["entry_id"]} if link.get("entry_id") else {}),
|
||||||
}
|
}
|
||||||
for link in used_parts
|
for link in record_links
|
||||||
|
if isinstance(link, dict) and link.get("part_id")
|
||||||
]
|
]
|
||||||
|
|
||||||
task.complete(
|
task.complete(
|
||||||
|
|||||||
@@ -126,6 +126,10 @@ def _build_export_object(
|
|||||||
"on_complete_action": tdata.get("on_complete_action"),
|
"on_complete_action": tdata.get("on_complete_action"),
|
||||||
"quick_complete_defaults": tdata.get("quick_complete_defaults"),
|
"quick_complete_defaults": tdata.get("quick_complete_defaults"),
|
||||||
"assignee_pool": tdata.get("assignee_pool") or [],
|
"assignee_pool": tdata.get("assignee_pool") or [],
|
||||||
|
# v2.44: demanded completion details — the import has mirrored this
|
||||||
|
# key from day one; the export builder lost it (found by the #130
|
||||||
|
# export audit), so backups silently dropped the requirement.
|
||||||
|
"required_completion_fields": tdata.get("required_completion_fields"),
|
||||||
"rotation_strategy": tdata.get("rotation_strategy"),
|
"rotation_strategy": tdata.get("rotation_strategy"),
|
||||||
"reading_unit": tdata.get("reading_unit"),
|
"reading_unit": tdata.get("reading_unit"),
|
||||||
# Spare parts: consumption links + the auto-buy-task marker.
|
# Spare parts: consumption links + the auto-buy-task marker.
|
||||||
|
|||||||
+136
@@ -23,6 +23,19 @@ export interface HistoryEntryDraft {
|
|||||||
cost: number | null;
|
cost: number | null;
|
||||||
duration: number | null;
|
duration: number | null;
|
||||||
completed_by: string | null;
|
completed_by: string | null;
|
||||||
|
// #130: the entry's recorded part consumption ({part_id, name, quantity,
|
||||||
|
// entry_id? for pooled parts}); absent/empty = nothing consumed.
|
||||||
|
used_parts?: Array<{ part_id: string; name?: string; quantity: number; entry_id?: string }> | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** One selectable part option in the edit dialog — the object's own parts
|
||||||
|
* plus pooled parts this task links to, fetched via parts/overview. */
|
||||||
|
interface PartOption {
|
||||||
|
part_id: string;
|
||||||
|
name: string;
|
||||||
|
entry_id: string; // owning object
|
||||||
|
foreign: boolean; // pooled (#111) — carried into the saved link
|
||||||
|
object_name: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MaintenanceHistoryEditDialog extends LitElement {
|
export class MaintenanceHistoryEditDialog extends LitElement {
|
||||||
@@ -40,6 +53,12 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
|||||||
return this.hass?.language || "en";
|
return this.hass?.language || "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #130: selectable parts + the edited selection (part key -> quantity;
|
||||||
|
// 0/absent = not consumed). Key = `${entry_id}:${part_id}` (pool-safe).
|
||||||
|
@state() private _partOptions: PartOption[] | null = null;
|
||||||
|
@state() private _partQty: Record<string, number> = {};
|
||||||
|
private _partQtyOriginal = "";
|
||||||
|
|
||||||
/** Open the dialog with the given history-entry data. The caller must
|
/** Open the dialog with the given history-entry data. The caller must
|
||||||
* pass `original_timestamp` (the entry's current timestamp before edit)
|
* pass `original_timestamp` (the entry's current timestamp before edit)
|
||||||
* so the backend can find the entry. */
|
* so the backend can find the entry. */
|
||||||
@@ -48,6 +67,71 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
|||||||
this._originalSnapshot = { ...draft };
|
this._originalSnapshot = { ...draft };
|
||||||
this._error = "";
|
this._error = "";
|
||||||
this._open = true;
|
this._open = true;
|
||||||
|
this._partOptions = null;
|
||||||
|
this._partQty = {};
|
||||||
|
this._partQtyOriginal = "";
|
||||||
|
void this._loadPartOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The object's own parts + pooled parts this task draws on — from the
|
||||||
|
* instance-wide overview so pooled owners resolve without extra calls. */
|
||||||
|
private async _loadPartOptions(): Promise<void> {
|
||||||
|
const draft = this._draft;
|
||||||
|
if (!draft) return;
|
||||||
|
try {
|
||||||
|
const result = await this.hass.connection.sendMessagePromise({
|
||||||
|
type: "maintenance_supporter/parts/overview",
|
||||||
|
}) as {
|
||||||
|
parts: Array<{
|
||||||
|
part_id: string; name: string; entry_id: string; object_name: string | null;
|
||||||
|
consumers: Array<{ entry_id: string; task_id: string }>;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
const options: PartOption[] = [];
|
||||||
|
for (const row of result.parts || []) {
|
||||||
|
const own = row.entry_id === draft.entry_id;
|
||||||
|
const linked = row.consumers.some((c) => c.entry_id === draft.entry_id && c.task_id === draft.task_id);
|
||||||
|
if (!own && !linked) continue;
|
||||||
|
options.push({
|
||||||
|
part_id: row.part_id,
|
||||||
|
name: row.name,
|
||||||
|
entry_id: row.entry_id,
|
||||||
|
foreign: !own,
|
||||||
|
object_name: row.object_name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Recorded parts whose catalog entry vanished stay selectable so a
|
||||||
|
// correction can still zero them out.
|
||||||
|
for (const link of draft.used_parts || []) {
|
||||||
|
const owner = link.entry_id || draft.entry_id;
|
||||||
|
if (!options.some((o) => o.part_id === link.part_id && o.entry_id === owner)) {
|
||||||
|
options.push({
|
||||||
|
part_id: link.part_id,
|
||||||
|
name: link.name || link.part_id,
|
||||||
|
entry_id: owner,
|
||||||
|
foreign: owner !== draft.entry_id,
|
||||||
|
object_name: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const qty: Record<string, number> = {};
|
||||||
|
for (const link of draft.used_parts || []) {
|
||||||
|
qty[`${link.entry_id || draft.entry_id}:${link.part_id}`] = link.quantity ?? 1;
|
||||||
|
}
|
||||||
|
this._partOptions = options;
|
||||||
|
this._partQty = qty;
|
||||||
|
this._partQtyOriginal = this._partSelectionKey();
|
||||||
|
} catch {
|
||||||
|
this._partOptions = []; // parts UI unavailable — the rest still edits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _partSelectionKey(): string {
|
||||||
|
return JSON.stringify(
|
||||||
|
Object.entries(this._partQty)
|
||||||
|
.filter(([, q]) => q > 0)
|
||||||
|
.sort(([a], [b]) => a.localeCompare(b)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public close(): void {
|
public close(): void {
|
||||||
@@ -92,6 +176,17 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
|||||||
if (this._draft.completed_by !== this._originalSnapshot.completed_by) {
|
if (this._draft.completed_by !== this._originalSnapshot.completed_by) {
|
||||||
patch.completed_by = this._draft.completed_by;
|
patch.completed_by = this._draft.completed_by;
|
||||||
}
|
}
|
||||||
|
// #130: send the parts selection only when it actually changed — the
|
||||||
|
// backend reconciles stock by the delta, so a no-op must stay silent.
|
||||||
|
if (this._partOptions !== null && this._partSelectionKey() !== this._partQtyOriginal) {
|
||||||
|
patch.used_parts = (this._partOptions || [])
|
||||||
|
.filter((o) => (this._partQty[`${o.entry_id}:${o.part_id}`] || 0) > 0)
|
||||||
|
.map((o) => ({
|
||||||
|
part_id: o.part_id,
|
||||||
|
quantity: this._partQty[`${o.entry_id}:${o.part_id}`],
|
||||||
|
...(o.foreign ? { entry_id: o.entry_id } : {}),
|
||||||
|
}));
|
||||||
|
}
|
||||||
// Nothing changed → close without WS call
|
// Nothing changed → close without WS call
|
||||||
const changedKeys = Object.keys(patch).filter(
|
const changedKeys = Object.keys(patch).filter(
|
||||||
(k) => !["type", "entry_id", "task_id", "original_timestamp"].includes(k),
|
(k) => !["type", "entry_id", "task_id", "original_timestamp"].includes(k),
|
||||||
@@ -173,6 +268,33 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
|||||||
}} />
|
}} />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
${this._partOptions && this._partOptions.length > 0 ? html`
|
||||||
|
<div class="parts-block">
|
||||||
|
<span class="parts-title">${t("complete_parts_used", L)}</span>
|
||||||
|
${this._partOptions.map((o) => {
|
||||||
|
const key = `${o.entry_id}:${o.part_id}`;
|
||||||
|
const qty = this._partQty[key] || 0;
|
||||||
|
return html`
|
||||||
|
<label class="part-row-edit">
|
||||||
|
<input type="checkbox" .checked=${qty > 0}
|
||||||
|
@change=${(e: Event) => {
|
||||||
|
const on = (e.target as HTMLInputElement).checked;
|
||||||
|
this._partQty = { ...this._partQty, [key]: on ? 1 : 0 };
|
||||||
|
}} />
|
||||||
|
<span class="part-label">${o.name}${o.foreign && o.object_name ? ` (${o.object_name})` : ""}</span>
|
||||||
|
${qty > 0 ? html`
|
||||||
|
<input class="part-qty" type="number" min="0.01" max="999" step="0.01"
|
||||||
|
.value=${String(qty)}
|
||||||
|
@input=${(e: Event) => {
|
||||||
|
const v = parseFloat((e.target as HTMLInputElement).value);
|
||||||
|
if (!isNaN(v) && v > 0) this._partQty = { ...this._partQty, [key]: v };
|
||||||
|
}} />
|
||||||
|
` : nothing}
|
||||||
|
</label>
|
||||||
|
`;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
` : nothing}
|
||||||
${this._error ? html`<div class="error">${this._error}</div>` : nothing}
|
${this._error ? html`<div class="error">${this._error}</div>` : nothing}
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="cancel" @click=${this.close} ?disabled=${this._saving}>
|
<button class="cancel" @click=${this.close} ?disabled=${this._saving}>
|
||||||
@@ -248,6 +370,20 @@ export class MaintenanceHistoryEditDialog extends LitElement {
|
|||||||
background: rgba(211,47,47,0.1);
|
background: rgba(211,47,47,0.1);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
/* #130: parts on the entry */
|
||||||
|
.parts-block {
|
||||||
|
display: flex; flex-direction: column; gap: 6px;
|
||||||
|
border: 1px solid var(--divider-color, #444);
|
||||||
|
border-radius: 6px; padding: 8px;
|
||||||
|
}
|
||||||
|
.parts-title { color: var(--secondary-text-color); font-size: 13px; }
|
||||||
|
.part-row-edit {
|
||||||
|
display: flex; flex-direction: row; align-items: center; gap: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.part-row-edit input[type="checkbox"] { width: auto; }
|
||||||
|
.part-label { flex: 1; color: var(--primary-text-color); }
|
||||||
|
.part-qty { width: 76px; }
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -320,6 +320,7 @@ export class MaintenanceTaskQuickActionsDialog extends LitElement {
|
|||||||
cost: entry.cost ?? null,
|
cost: entry.cost ?? null,
|
||||||
duration: entry.duration ?? null,
|
duration: entry.duration ?? null,
|
||||||
completed_by: entry.completed_by ?? null,
|
completed_by: entry.completed_by ?? null,
|
||||||
|
used_parts: entry.used_parts ?? null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Typ",
|
"sort_type": "Typ",
|
||||||
"sort_task_name": "Název úkolu",
|
"sort_task_name": "Název úkolu",
|
||||||
"all_objects": "Všechny objekty",
|
"all_objects": "Všechny objekty",
|
||||||
|
"all_parts": "Všechny díly",
|
||||||
"tasks_lower": "úkolů",
|
"tasks_lower": "úkolů",
|
||||||
"no_tasks_yet": "Zatím žádné úkoly",
|
"no_tasks_yet": "Zatím žádné úkoly",
|
||||||
"add_first_task": "Přidat první úkol",
|
"add_first_task": "Přidat první úkol",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Množství doplnění",
|
"part_restock_quantity": "Množství doplnění",
|
||||||
"part_auto_buy": "Úkol nákupu při nízké zásobě",
|
"part_auto_buy": "Úkol nákupu při nízké zásobě",
|
||||||
"part_restock": "Upravit zásobu",
|
"part_restock": "Upravit zásobu",
|
||||||
|
"parts_used_by": "Používá",
|
||||||
"restock_quantity_label": "Zakoupené množství",
|
"restock_quantity_label": "Zakoupené množství",
|
||||||
"consumes_parts_label": "Spotřebovává díly",
|
"consumes_parts_label": "Spotřebovává díly",
|
||||||
"shared_parts_other_objects": "Díly z jiných objektů",
|
"shared_parts_other_objects": "Díly z jiných objektů",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "stav při posledním servisu (volitelné)",
|
"setups_baseline_hint": "stav při posledním servisu (volitelné)",
|
||||||
"baseline_start_help_edit": "Ponechte prázdné pro zachování stávajícího počítání. Zadaná hodnota počítání znovu ukotví (např. stav při posledním servisu).",
|
"baseline_start_help_edit": "Ponechte prázdné pro zachování stávajícího počítání. Zadaná hodnota počítání znovu ukotví (např. stav při posledním servisu).",
|
||||||
"baseline_current_effective": "Aktuálně platná počáteční hodnota: {value}",
|
"baseline_current_effective": "Aktuálně platná počáteční hodnota: {value}",
|
||||||
"runtime_on_states": "Aktivní stavy (oddělené čárkami)",
|
"runtime_on_states": "Aktivní stavy",
|
||||||
"runtime_on_states_help": "Stavy počítané jako doba běhu — výchozí: on. Např. mowing, cleaning, printing. Při zvoleném atributu se porovnávají jeho hodnoty.",
|
"runtime_on_states_help": "Stavy počítané jako doba běhu — výchozí: on. Např. mowing, cleaning, printing. Při zvoleném atributu se porovnávají jeho hodnoty.",
|
||||||
"setups_target_new": "Vytvořit nový: {name}",
|
"setups_target_new": "Vytvořit nový: {name}",
|
||||||
"schedule_preview_title": "Nejbližší termíny",
|
"schedule_preview_title": "Nejbližší termíny",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Opgavenavn",
|
"sort_task_name": "Opgavenavn",
|
||||||
"all_objects": "Alle objekter",
|
"all_objects": "Alle objekter",
|
||||||
|
"all_parts": "Alle dele",
|
||||||
"tasks_lower": "opgaver",
|
"tasks_lower": "opgaver",
|
||||||
"no_tasks_yet": "Ingen opgaver endnu",
|
"no_tasks_yet": "Ingen opgaver endnu",
|
||||||
"add_first_task": "Tilføj første opgave",
|
"add_first_task": "Tilføj første opgave",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Genopfyldningsmængde",
|
"part_restock_quantity": "Genopfyldningsmængde",
|
||||||
"part_auto_buy": "Købsopgave ved lav beholdning",
|
"part_auto_buy": "Købsopgave ved lav beholdning",
|
||||||
"part_restock": "Justér lager",
|
"part_restock": "Justér lager",
|
||||||
|
"parts_used_by": "Bruges af",
|
||||||
"restock_quantity_label": "Købt mængde",
|
"restock_quantity_label": "Købt mængde",
|
||||||
"consumes_parts_label": "Forbruger dele",
|
"consumes_parts_label": "Forbruger dele",
|
||||||
"shared_parts_other_objects": "Dele fra andre objekter",
|
"shared_parts_other_objects": "Dele fra andre objekter",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "aflæsning ved sidste service (valgfrit)",
|
"setups_baseline_hint": "aflæsning ved sidste service (valgfrit)",
|
||||||
"baseline_start_help_edit": "Lad feltet stå tomt for at beholde den eksisterende tælling. En indtastet værdi forankrer tællingen på ny (f.eks. aflæsningen ved sidste service).",
|
"baseline_start_help_edit": "Lad feltet stå tomt for at beholde den eksisterende tælling. En indtastet værdi forankrer tællingen på ny (f.eks. aflæsningen ved sidste service).",
|
||||||
"baseline_current_effective": "Aktuelt gældende startværdi: {value}",
|
"baseline_current_effective": "Aktuelt gældende startværdi: {value}",
|
||||||
"runtime_on_states": "Aktive tilstande (kommaseparerede)",
|
"runtime_on_states": "Aktive tilstande",
|
||||||
"runtime_on_states_help": "Tilstande der tæller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med en valgt attribut sammenlignes dens værdier i stedet.",
|
"runtime_on_states_help": "Tilstande der tæller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med en valgt attribut sammenlignes dens værdier i stedet.",
|
||||||
"setups_target_new": "Opret ny: {name}",
|
"setups_target_new": "Opret ny: {name}",
|
||||||
"schedule_preview_title": "Kommende datoer",
|
"schedule_preview_title": "Kommende datoer",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Typ",
|
"sort_type": "Typ",
|
||||||
"sort_task_name": "Aufgaben-Name",
|
"sort_task_name": "Aufgaben-Name",
|
||||||
"all_objects": "Alle Objekte",
|
"all_objects": "Alle Objekte",
|
||||||
|
"all_parts": "Alle Teile",
|
||||||
"tasks_lower": "Aufgaben",
|
"tasks_lower": "Aufgaben",
|
||||||
"no_tasks_yet": "Noch keine Aufgaben",
|
"no_tasks_yet": "Noch keine Aufgaben",
|
||||||
"add_first_task": "Erste Aufgabe hinzufügen",
|
"add_first_task": "Erste Aufgabe hinzufügen",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Auffüllmenge",
|
"part_restock_quantity": "Auffüllmenge",
|
||||||
"part_auto_buy": "Kauf-Task bei Niedrigbestand",
|
"part_auto_buy": "Kauf-Task bei Niedrigbestand",
|
||||||
"part_restock": "Bestand anpassen",
|
"part_restock": "Bestand anpassen",
|
||||||
|
"parts_used_by": "Verwendet von",
|
||||||
"restock_quantity_label": "Gekaufte Menge",
|
"restock_quantity_label": "Gekaufte Menge",
|
||||||
"consumes_parts_label": "Verbraucht Teile",
|
"consumes_parts_label": "Verbraucht Teile",
|
||||||
"shared_parts_other_objects": "Teile anderer Objekte",
|
"shared_parts_other_objects": "Teile anderer Objekte",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "Stand beim letzten Service (optional)",
|
"setups_baseline_hint": "Stand beim letzten Service (optional)",
|
||||||
"baseline_start_help_edit": "Leer lassen, um die bestehende Zählung zu behalten. Ein eingetragener Wert verankert die Zählung neu (z. B. der Stand beim letzten Service).",
|
"baseline_start_help_edit": "Leer lassen, um die bestehende Zählung zu behalten. Ein eingetragener Wert verankert die Zählung neu (z. B. der Stand beim letzten Service).",
|
||||||
"baseline_current_effective": "Aktuell wirksamer Startwert: {value}",
|
"baseline_current_effective": "Aktuell wirksamer Startwert: {value}",
|
||||||
"runtime_on_states": "Aktive Zustände (kommagetrennt)",
|
"runtime_on_states": "Aktive Zustände",
|
||||||
"runtime_on_states_help": "Zustände, die als Laufzeit zählen — Standard: on. Z. B. mowing, cleaning, printing. Bei gewähltem Attribut werden dessen Werte verglichen.",
|
"runtime_on_states_help": "Zustände, die als Laufzeit zählen — Standard: on. Z. B. mowing, cleaning, printing. Bei gewähltem Attribut werden dessen Werte verglichen.",
|
||||||
"setups_target_new": "Neu anlegen: {name}",
|
"setups_target_new": "Neu anlegen: {name}",
|
||||||
"schedule_preview_title": "Nächste Termine",
|
"schedule_preview_title": "Nächste Termine",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Task name",
|
"sort_task_name": "Task name",
|
||||||
"all_objects": "All objects",
|
"all_objects": "All objects",
|
||||||
|
"all_parts": "All parts",
|
||||||
"tasks_lower": "tasks",
|
"tasks_lower": "tasks",
|
||||||
"no_tasks_yet": "No tasks yet",
|
"no_tasks_yet": "No tasks yet",
|
||||||
"add_first_task": "Add first task",
|
"add_first_task": "Add first task",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "Restock quantity",
|
"part_restock_quantity": "Restock quantity",
|
||||||
"part_auto_buy": "Auto-create buy task when low",
|
"part_auto_buy": "Auto-create buy task when low",
|
||||||
"part_restock": "Adjust stock",
|
"part_restock": "Adjust stock",
|
||||||
|
"parts_used_by": "Used by",
|
||||||
"restock_quantity_label": "Quantity bought",
|
"restock_quantity_label": "Quantity bought",
|
||||||
"consumes_parts_label": "Consumes parts",
|
"consumes_parts_label": "Consumes parts",
|
||||||
"shared_parts_other_objects": "Parts from other objects",
|
"shared_parts_other_objects": "Parts from other objects",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "reading at last service (optional)",
|
"setups_baseline_hint": "reading at last service (optional)",
|
||||||
"baseline_start_help_edit": "Leave empty to keep the existing counting. Entering a value re-anchors the counting (e.g. the reading at the last service).",
|
"baseline_start_help_edit": "Leave empty to keep the existing counting. Entering a value re-anchors the counting (e.g. the reading at the last service).",
|
||||||
"baseline_current_effective": "Currently effective start value: {value}",
|
"baseline_current_effective": "Currently effective start value: {value}",
|
||||||
"runtime_on_states": "Active states (comma-separated)",
|
"runtime_on_states": "Active states",
|
||||||
"runtime_on_states_help": "States that count as running — default: on. E.g. mowing, cleaning, printing. With an attribute selected, its values are matched instead.",
|
"runtime_on_states_help": "States that count as running — default: on. E.g. mowing, cleaning, printing. With an attribute selected, its values are matched instead.",
|
||||||
"setups_target_new": "Create new: {name}",
|
"setups_target_new": "Create new: {name}",
|
||||||
"schedule_preview_title": "Next dates",
|
"schedule_preview_title": "Next dates",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Tipo",
|
"sort_type": "Tipo",
|
||||||
"sort_task_name": "Nombre de la tarea",
|
"sort_task_name": "Nombre de la tarea",
|
||||||
"all_objects": "Todos los objetos",
|
"all_objects": "Todos los objetos",
|
||||||
|
"all_parts": "Todas las piezas",
|
||||||
"tasks_lower": "tareas",
|
"tasks_lower": "tareas",
|
||||||
"no_tasks_yet": "Aún no hay tareas",
|
"no_tasks_yet": "Aún no hay tareas",
|
||||||
"add_first_task": "Agregar primera tarea",
|
"add_first_task": "Agregar primera tarea",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Cantidad de reposición",
|
"part_restock_quantity": "Cantidad de reposición",
|
||||||
"part_auto_buy": "Crear tarea de compra si bajo",
|
"part_auto_buy": "Crear tarea de compra si bajo",
|
||||||
"part_restock": "Ajustar existencias",
|
"part_restock": "Ajustar existencias",
|
||||||
|
"parts_used_by": "Usado por",
|
||||||
"restock_quantity_label": "Cantidad comprada",
|
"restock_quantity_label": "Cantidad comprada",
|
||||||
"consumes_parts_label": "Consume piezas",
|
"consumes_parts_label": "Consume piezas",
|
||||||
"shared_parts_other_objects": "Piezas de otros objetos",
|
"shared_parts_other_objects": "Piezas de otros objetos",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "lectura en el último mantenimiento (opcional)",
|
"setups_baseline_hint": "lectura en el último mantenimiento (opcional)",
|
||||||
"baseline_start_help_edit": "Déjalo vacío para mantener el conteo actual. Un valor introducido reancla el conteo (p. ej., la lectura del último mantenimiento).",
|
"baseline_start_help_edit": "Déjalo vacío para mantener el conteo actual. Un valor introducido reancla el conteo (p. ej., la lectura del último mantenimiento).",
|
||||||
"baseline_current_effective": "Valor inicial vigente: {value}",
|
"baseline_current_effective": "Valor inicial vigente: {value}",
|
||||||
"runtime_on_states": "Estados activos (separados por comas)",
|
"runtime_on_states": "Estados activos",
|
||||||
"runtime_on_states_help": "Estados que cuentan como en funcionamiento — predeterminado: on. P. ej. mowing, cleaning, printing. Con un atributo seleccionado se comparan sus valores.",
|
"runtime_on_states_help": "Estados que cuentan como en funcionamiento — predeterminado: on. P. ej. mowing, cleaning, printing. Con un atributo seleccionado se comparan sus valores.",
|
||||||
"setups_target_new": "Crear nuevo: {name}",
|
"setups_target_new": "Crear nuevo: {name}",
|
||||||
"schedule_preview_title": "Próximas fechas",
|
"schedule_preview_title": "Próximas fechas",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Tyyppi",
|
"sort_type": "Tyyppi",
|
||||||
"sort_task_name": "Tehtävän nimi",
|
"sort_task_name": "Tehtävän nimi",
|
||||||
"all_objects": "Kaikki kohteet",
|
"all_objects": "Kaikki kohteet",
|
||||||
|
"all_parts": "Kaikki osat",
|
||||||
"tasks_lower": "tehtävää",
|
"tasks_lower": "tehtävää",
|
||||||
"no_tasks_yet": "Ei vielä tehtäviä",
|
"no_tasks_yet": "Ei vielä tehtäviä",
|
||||||
"add_first_task": "Lisää ensimmäinen tehtävä",
|
"add_first_task": "Lisää ensimmäinen tehtävä",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Täydennysmäärä",
|
"part_restock_quantity": "Täydennysmäärä",
|
||||||
"part_auto_buy": "Ostotehtävä kun vähissä",
|
"part_auto_buy": "Ostotehtävä kun vähissä",
|
||||||
"part_restock": "Muuta varastoa",
|
"part_restock": "Muuta varastoa",
|
||||||
|
"parts_used_by": "Käyttäjät",
|
||||||
"restock_quantity_label": "Ostettu määrä",
|
"restock_quantity_label": "Ostettu määrä",
|
||||||
"consumes_parts_label": "Kuluttaa osia",
|
"consumes_parts_label": "Kuluttaa osia",
|
||||||
"shared_parts_other_objects": "Muiden kohteiden osat",
|
"shared_parts_other_objects": "Muiden kohteiden osat",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "lukema viime huollossa (valinnainen)",
|
"setups_baseline_hint": "lukema viime huollossa (valinnainen)",
|
||||||
"baseline_start_help_edit": "Jätä tyhjäksi säilyttääksesi nykyisen laskennan. Syötetty arvo ankkuroi laskennan uudelleen (esim. viimeisimmän huollon lukema).",
|
"baseline_start_help_edit": "Jätä tyhjäksi säilyttääksesi nykyisen laskennan. Syötetty arvo ankkuroi laskennan uudelleen (esim. viimeisimmän huollon lukema).",
|
||||||
"baseline_current_effective": "Nyt voimassa oleva aloitusarvo: {value}",
|
"baseline_current_effective": "Nyt voimassa oleva aloitusarvo: {value}",
|
||||||
"runtime_on_states": "Aktiiviset tilat (pilkuin eroteltuina)",
|
"runtime_on_states": "Aktiiviset tilat",
|
||||||
"runtime_on_states_help": "Tilat, jotka lasketaan käyntiajaksi — oletus: on. Esim. mowing, cleaning, printing. Jos attribuutti on valittu, verrataan sen arvoja.",
|
"runtime_on_states_help": "Tilat, jotka lasketaan käyntiajaksi — oletus: on. Esim. mowing, cleaning, printing. Jos attribuutti on valittu, verrataan sen arvoja.",
|
||||||
"setups_target_new": "Luo uusi: {name}",
|
"setups_target_new": "Luo uusi: {name}",
|
||||||
"schedule_preview_title": "Seuraavat päivämäärät",
|
"schedule_preview_title": "Seuraavat päivämäärät",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Nom de la tâche",
|
"sort_task_name": "Nom de la tâche",
|
||||||
"all_objects": "Tous les objets",
|
"all_objects": "Tous les objets",
|
||||||
|
"all_parts": "Toutes les pièces",
|
||||||
"tasks_lower": "tâches",
|
"tasks_lower": "tâches",
|
||||||
"no_tasks_yet": "Pas encore de tâches",
|
"no_tasks_yet": "Pas encore de tâches",
|
||||||
"add_first_task": "Ajouter la première tâche",
|
"add_first_task": "Ajouter la première tâche",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Quantité de réappro",
|
"part_restock_quantity": "Quantité de réappro",
|
||||||
"part_auto_buy": "Tâche d'achat auto si bas",
|
"part_auto_buy": "Tâche d'achat auto si bas",
|
||||||
"part_restock": "Ajuster le stock",
|
"part_restock": "Ajuster le stock",
|
||||||
|
"parts_used_by": "Utilisé par",
|
||||||
"restock_quantity_label": "Quantité achetée",
|
"restock_quantity_label": "Quantité achetée",
|
||||||
"consumes_parts_label": "Consomme des pièces",
|
"consumes_parts_label": "Consomme des pièces",
|
||||||
"shared_parts_other_objects": "Pièces d'autres objets",
|
"shared_parts_other_objects": "Pièces d'autres objets",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "relevé au dernier entretien (facultatif)",
|
"setups_baseline_hint": "relevé au dernier entretien (facultatif)",
|
||||||
"baseline_start_help_edit": "Laissez vide pour conserver le comptage existant. Une valeur saisie réancre le comptage (p. ex. le relevé du dernier entretien).",
|
"baseline_start_help_edit": "Laissez vide pour conserver le comptage existant. Une valeur saisie réancre le comptage (p. ex. le relevé du dernier entretien).",
|
||||||
"baseline_current_effective": "Valeur de départ actuellement en vigueur : {value}",
|
"baseline_current_effective": "Valeur de départ actuellement en vigueur : {value}",
|
||||||
"runtime_on_states": "États actifs (séparés par des virgules)",
|
"runtime_on_states": "États actifs",
|
||||||
"runtime_on_states_help": "États comptés comme en fonctionnement — par défaut : on. P. ex. mowing, cleaning, printing. Si un attribut est sélectionné, ce sont ses valeurs qui sont comparées.",
|
"runtime_on_states_help": "États comptés comme en fonctionnement — par défaut : on. P. ex. mowing, cleaning, printing. Si un attribut est sélectionné, ce sont ses valeurs qui sont comparées.",
|
||||||
"setups_target_new": "Créer : {name}",
|
"setups_target_new": "Créer : {name}",
|
||||||
"schedule_preview_title": "Prochaines échéances",
|
"schedule_preview_title": "Prochaines échéances",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "प्रकार",
|
"sort_type": "प्रकार",
|
||||||
"sort_task_name": "कार्य का नाम",
|
"sort_task_name": "कार्य का नाम",
|
||||||
"all_objects": "सभी वस्तुएँ",
|
"all_objects": "सभी वस्तुएँ",
|
||||||
|
"all_parts": "सभी पुर्ज़े",
|
||||||
"tasks_lower": "कार्य",
|
"tasks_lower": "कार्य",
|
||||||
"no_tasks_yet": "अभी कोई कार्य नहीं",
|
"no_tasks_yet": "अभी कोई कार्य नहीं",
|
||||||
"add_first_task": "पहला कार्य जोड़ें",
|
"add_first_task": "पहला कार्य जोड़ें",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "पुनःपूर्ति मात्रा",
|
"part_restock_quantity": "पुनःपूर्ति मात्रा",
|
||||||
"part_auto_buy": "कम होने पर खरीद कार्य",
|
"part_auto_buy": "कम होने पर खरीद कार्य",
|
||||||
"part_restock": "स्टॉक समायोजित करें",
|
"part_restock": "स्टॉक समायोजित करें",
|
||||||
|
"parts_used_by": "द्वारा उपयोग",
|
||||||
"restock_quantity_label": "खरीदी गई मात्रा",
|
"restock_quantity_label": "खरीदी गई मात्रा",
|
||||||
"consumes_parts_label": "पुर्ज़े खपत",
|
"consumes_parts_label": "पुर्ज़े खपत",
|
||||||
"shared_parts_other_objects": "अन्य वस्तुओं के पुर्ज़े",
|
"shared_parts_other_objects": "अन्य वस्तुओं के पुर्ज़े",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "पिछली सर्विस पर रीडिंग (वैकल्पिक)",
|
"setups_baseline_hint": "पिछली सर्विस पर रीडिंग (वैकल्पिक)",
|
||||||
"baseline_start_help_edit": "मौजूदा गिनती बनाए रखने के लिए खाली छोड़ें। दर्ज किया गया मान गिनती को फिर से स्थिर करता है (जैसे पिछली सर्विस के समय की रीडिंग)।",
|
"baseline_start_help_edit": "मौजूदा गिनती बनाए रखने के लिए खाली छोड़ें। दर्ज किया गया मान गिनती को फिर से स्थिर करता है (जैसे पिछली सर्विस के समय की रीडिंग)।",
|
||||||
"baseline_current_effective": "वर्तमान में प्रभावी प्रारंभिक मान: {value}",
|
"baseline_current_effective": "वर्तमान में प्रभावी प्रारंभिक मान: {value}",
|
||||||
"runtime_on_states": "सक्रिय अवस्थाएँ (अल्पविराम से अलग)",
|
"runtime_on_states": "सक्रिय अवस्थाएँ",
|
||||||
"runtime_on_states_help": "वे अवस्थाएँ जो चालू समय में गिनी जाती हैं — डिफ़ॉल्ट: on। जैसे mowing, cleaning, printing। विशेषता चुनी होने पर उसकी मानों की तुलना होती है।",
|
"runtime_on_states_help": "वे अवस्थाएँ जो चालू समय में गिनी जाती हैं — डिफ़ॉल्ट: on। जैसे mowing, cleaning, printing। विशेषता चुनी होने पर उसकी मानों की तुलना होती है।",
|
||||||
"setups_target_new": "नया बनाएँ: {name}",
|
"setups_target_new": "नया बनाएँ: {name}",
|
||||||
"schedule_preview_title": "अगली तिथियाँ",
|
"schedule_preview_title": "अगली तिथियाँ",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Típus",
|
"sort_type": "Típus",
|
||||||
"sort_task_name": "Feladat neve",
|
"sort_task_name": "Feladat neve",
|
||||||
"all_objects": "Minden objektum",
|
"all_objects": "Minden objektum",
|
||||||
|
"all_parts": "Összes alkatrész",
|
||||||
"tasks_lower": "feladat",
|
"tasks_lower": "feladat",
|
||||||
"no_tasks_yet": "Még nincs feladat",
|
"no_tasks_yet": "Még nincs feladat",
|
||||||
"add_first_task": "Első feladat hozzáadása",
|
"add_first_task": "Első feladat hozzáadása",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "Feltöltési mennyiség",
|
"part_restock_quantity": "Feltöltési mennyiség",
|
||||||
"part_auto_buy": "Vásárlási feladat automatikus létrehozása, ha kevés van",
|
"part_auto_buy": "Vásárlási feladat automatikus létrehozása, ha kevés van",
|
||||||
"part_restock": "Készlet módosítása",
|
"part_restock": "Készlet módosítása",
|
||||||
|
"parts_used_by": "Használja",
|
||||||
"restock_quantity_label": "Vásárolt mennyiség",
|
"restock_quantity_label": "Vásárolt mennyiség",
|
||||||
"consumes_parts_label": "Felhasznált alkatrészek",
|
"consumes_parts_label": "Felhasznált alkatrészek",
|
||||||
"shared_parts_other_objects": "Más objektumok alkatrészei",
|
"shared_parts_other_objects": "Más objektumok alkatrészei",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "érték az utolsó szerviznél (opcionális)",
|
"setups_baseline_hint": "érték az utolsó szerviznél (opcionális)",
|
||||||
"baseline_start_help_edit": "Üresen hagyva a meglévő számlálás marad. Érték megadása újrahorgonyozza a számlálást (pl. az utolsó szerviz leolvasott értéke).",
|
"baseline_start_help_edit": "Üresen hagyva a meglévő számlálás marad. Érték megadása újrahorgonyozza a számlálást (pl. az utolsó szerviz leolvasott értéke).",
|
||||||
"baseline_current_effective": "Jelenleg érvényes kezdőérték: {value}",
|
"baseline_current_effective": "Jelenleg érvényes kezdőérték: {value}",
|
||||||
"runtime_on_states": "Aktív állapotok (vesszővel elválasztva)",
|
"runtime_on_states": "Aktív állapotok",
|
||||||
"runtime_on_states_help": "Működésként számító állapotok — alapértelmezés: on. Pl. mowing, cleaning, printing. Attribútum kiválasztásakor annak értékei számítanak.",
|
"runtime_on_states_help": "Működésként számító állapotok — alapértelmezés: on. Pl. mowing, cleaning, printing. Attribútum kiválasztásakor annak értékei számítanak.",
|
||||||
"setups_target_new": "Új létrehozása: {name}",
|
"setups_target_new": "Új létrehozása: {name}",
|
||||||
"schedule_preview_title": "Következő dátumok",
|
"schedule_preview_title": "Következő dátumok",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Tipo",
|
"sort_type": "Tipo",
|
||||||
"sort_task_name": "Nome attività",
|
"sort_task_name": "Nome attività",
|
||||||
"all_objects": "Tutti gli oggetti",
|
"all_objects": "Tutti gli oggetti",
|
||||||
|
"all_parts": "Tutti i ricambi",
|
||||||
"tasks_lower": "attività",
|
"tasks_lower": "attività",
|
||||||
"no_tasks_yet": "Nessuna attività",
|
"no_tasks_yet": "Nessuna attività",
|
||||||
"add_first_task": "Aggiungi prima attività",
|
"add_first_task": "Aggiungi prima attività",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Quantità di riordino",
|
"part_restock_quantity": "Quantità di riordino",
|
||||||
"part_auto_buy": "Task d'acquisto se scarso",
|
"part_auto_buy": "Task d'acquisto se scarso",
|
||||||
"part_restock": "Correggi scorta",
|
"part_restock": "Correggi scorta",
|
||||||
|
"parts_used_by": "Usato da",
|
||||||
"restock_quantity_label": "Quantità acquistata",
|
"restock_quantity_label": "Quantità acquistata",
|
||||||
"consumes_parts_label": "Consuma ricambi",
|
"consumes_parts_label": "Consuma ricambi",
|
||||||
"shared_parts_other_objects": "Ricambi di altri oggetti",
|
"shared_parts_other_objects": "Ricambi di altri oggetti",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "lettura all'ultima manutenzione (facoltativo)",
|
"setups_baseline_hint": "lettura all'ultima manutenzione (facoltativo)",
|
||||||
"baseline_start_help_edit": "Lascia vuoto per mantenere il conteggio esistente. Un valore inserito riancora il conteggio (ad es. la lettura dell'ultima manutenzione).",
|
"baseline_start_help_edit": "Lascia vuoto per mantenere il conteggio esistente. Un valore inserito riancora il conteggio (ad es. la lettura dell'ultima manutenzione).",
|
||||||
"baseline_current_effective": "Valore iniziale attualmente in vigore: {value}",
|
"baseline_current_effective": "Valore iniziale attualmente in vigore: {value}",
|
||||||
"runtime_on_states": "Stati attivi (separati da virgole)",
|
"runtime_on_states": "Stati attivi",
|
||||||
"runtime_on_states_help": "Stati che contano come in funzione — predefinito: on. Ad es. mowing, cleaning, printing. Con un attributo selezionato vengono confrontati i suoi valori.",
|
"runtime_on_states_help": "Stati che contano come in funzione — predefinito: on. Ad es. mowing, cleaning, printing. Con un attributo selezionato vengono confrontati i suoi valori.",
|
||||||
"setups_target_new": "Crea nuovo: {name}",
|
"setups_target_new": "Crea nuovo: {name}",
|
||||||
"schedule_preview_title": "Prossime date",
|
"schedule_preview_title": "Prossime date",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "種別",
|
"sort_type": "種別",
|
||||||
"sort_task_name": "タスク名",
|
"sort_task_name": "タスク名",
|
||||||
"all_objects": "すべての対象",
|
"all_objects": "すべての対象",
|
||||||
|
"all_parts": "すべての部品",
|
||||||
"tasks_lower": "タスク",
|
"tasks_lower": "タスク",
|
||||||
"no_tasks_yet": "タスクがまだありません",
|
"no_tasks_yet": "タスクがまだありません",
|
||||||
"add_first_task": "最初のタスクを追加",
|
"add_first_task": "最初のタスクを追加",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "補充数量",
|
"part_restock_quantity": "補充数量",
|
||||||
"part_auto_buy": "在庫少で購入タスク",
|
"part_auto_buy": "在庫少で購入タスク",
|
||||||
"part_restock": "在庫を調整",
|
"part_restock": "在庫を調整",
|
||||||
|
"parts_used_by": "使用タスク",
|
||||||
"restock_quantity_label": "購入数量",
|
"restock_quantity_label": "購入数量",
|
||||||
"consumes_parts_label": "部品を消費",
|
"consumes_parts_label": "部品を消費",
|
||||||
"shared_parts_other_objects": "他の対象の部品",
|
"shared_parts_other_objects": "他の対象の部品",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "前回整備時の値(任意)",
|
"setups_baseline_hint": "前回整備時の値(任意)",
|
||||||
"baseline_start_help_edit": "空欄のままにすると現在のカウントを維持します。値を入力するとカウントの起点を再設定します(例:前回整備時の値)。",
|
"baseline_start_help_edit": "空欄のままにすると現在のカウントを維持します。値を入力するとカウントの起点を再設定します(例:前回整備時の値)。",
|
||||||
"baseline_current_effective": "現在有効な開始値:{value}",
|
"baseline_current_effective": "現在有効な開始値:{value}",
|
||||||
"runtime_on_states": "稼働中とみなす状態(カンマ区切り)",
|
"runtime_on_states": "稼働中とみなす状態",
|
||||||
"runtime_on_states_help": "稼働時間として数える状態 — 既定値:on。例:mowing, cleaning, printing。属性を選択している場合はその値が比較されます。",
|
"runtime_on_states_help": "稼働時間として数える状態 — 既定値:on。例:mowing, cleaning, printing。属性を選択している場合はその値が比較されます。",
|
||||||
"setups_target_new": "新規作成:{name}",
|
"setups_target_new": "新規作成:{name}",
|
||||||
"schedule_preview_title": "次回の予定日",
|
"schedule_preview_title": "次回の予定日",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "유형",
|
"sort_type": "유형",
|
||||||
"sort_task_name": "작업 이름",
|
"sort_task_name": "작업 이름",
|
||||||
"all_objects": "모든 객체",
|
"all_objects": "모든 객체",
|
||||||
|
"all_parts": "모든 부품",
|
||||||
"tasks_lower": "작업",
|
"tasks_lower": "작업",
|
||||||
"no_tasks_yet": "아직 작업 없음",
|
"no_tasks_yet": "아직 작업 없음",
|
||||||
"add_first_task": "첫 작업 추가",
|
"add_first_task": "첫 작업 추가",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "보충 수량",
|
"part_restock_quantity": "보충 수량",
|
||||||
"part_auto_buy": "재고 부족 시 구매 작업 자동 생성",
|
"part_auto_buy": "재고 부족 시 구매 작업 자동 생성",
|
||||||
"part_restock": "재고 조정",
|
"part_restock": "재고 조정",
|
||||||
|
"parts_used_by": "사용처",
|
||||||
"restock_quantity_label": "구매 수량",
|
"restock_quantity_label": "구매 수량",
|
||||||
"consumes_parts_label": "사용하는 부품",
|
"consumes_parts_label": "사용하는 부품",
|
||||||
"shared_parts_other_objects": "다른 객체의 부품",
|
"shared_parts_other_objects": "다른 객체의 부품",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "마지막 정비 시점의 값 (선택)",
|
"setups_baseline_hint": "마지막 정비 시점의 값 (선택)",
|
||||||
"baseline_start_help_edit": "비워두면 기존 계수를 유지합니다. 값을 입력하면 계수 기준이 다시 설정됩니다 (예: 마지막 정비 시점의 값).",
|
"baseline_start_help_edit": "비워두면 기존 계수를 유지합니다. 값을 입력하면 계수 기준이 다시 설정됩니다 (예: 마지막 정비 시점의 값).",
|
||||||
"baseline_current_effective": "현재 적용 중인 시작 값: {value}",
|
"baseline_current_effective": "현재 적용 중인 시작 값: {value}",
|
||||||
"runtime_on_states": "활성 상태 (쉼표로 구분)",
|
"runtime_on_states": "활성 상태",
|
||||||
"runtime_on_states_help": "가동 중으로 계산할 상태입니다 — 기본값: on. 예: mowing, cleaning, printing. 속성을 선택한 경우 해당 속성 값과 비교합니다.",
|
"runtime_on_states_help": "가동 중으로 계산할 상태입니다 — 기본값: on. 예: mowing, cleaning, printing. 속성을 선택한 경우 해당 속성 값과 비교합니다.",
|
||||||
"setups_target_new": "새로 만들기: {name}",
|
"setups_target_new": "새로 만들기: {name}",
|
||||||
"schedule_preview_title": "다음 예정일",
|
"schedule_preview_title": "다음 예정일",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Oppgavenavn",
|
"sort_task_name": "Oppgavenavn",
|
||||||
"all_objects": "Alle objekter",
|
"all_objects": "Alle objekter",
|
||||||
|
"all_parts": "Alle deler",
|
||||||
"tasks_lower": "oppgaver",
|
"tasks_lower": "oppgaver",
|
||||||
"no_tasks_yet": "Ingen oppgaver ennå",
|
"no_tasks_yet": "Ingen oppgaver ennå",
|
||||||
"add_first_task": "Legg til første oppgave",
|
"add_first_task": "Legg til første oppgave",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Påfyllingsmengde",
|
"part_restock_quantity": "Påfyllingsmengde",
|
||||||
"part_auto_buy": "Kjøpsoppgave ved lavt lager",
|
"part_auto_buy": "Kjøpsoppgave ved lavt lager",
|
||||||
"part_restock": "Juster lager",
|
"part_restock": "Juster lager",
|
||||||
|
"parts_used_by": "Brukes av",
|
||||||
"restock_quantity_label": "Kjøpt mengde",
|
"restock_quantity_label": "Kjøpt mengde",
|
||||||
"consumes_parts_label": "Forbruker deler",
|
"consumes_parts_label": "Forbruker deler",
|
||||||
"shared_parts_other_objects": "Deler fra andre objekter",
|
"shared_parts_other_objects": "Deler fra andre objekter",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "avlesning ved forrige service (valgfritt)",
|
"setups_baseline_hint": "avlesning ved forrige service (valgfritt)",
|
||||||
"baseline_start_help_edit": "La stå tomt for å beholde den eksisterende tellingen. En angitt verdi forankrer tellingen på nytt (f.eks. avlesningen ved forrige service).",
|
"baseline_start_help_edit": "La stå tomt for å beholde den eksisterende tellingen. En angitt verdi forankrer tellingen på nytt (f.eks. avlesningen ved forrige service).",
|
||||||
"baseline_current_effective": "Gjeldende startverdi: {value}",
|
"baseline_current_effective": "Gjeldende startverdi: {value}",
|
||||||
"runtime_on_states": "Aktive tilstander (kommaseparert)",
|
"runtime_on_states": "Aktive tilstander",
|
||||||
"runtime_on_states_help": "Tilstander som teller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med et valgt attributt sammenlignes verdiene dets i stedet.",
|
"runtime_on_states_help": "Tilstander som teller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med et valgt attributt sammenlignes verdiene dets i stedet.",
|
||||||
"setups_target_new": "Opprett ny: {name}",
|
"setups_target_new": "Opprett ny: {name}",
|
||||||
"schedule_preview_title": "Kommende datoer",
|
"schedule_preview_title": "Kommende datoer",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Taaknaam",
|
"sort_task_name": "Taaknaam",
|
||||||
"all_objects": "Alle objecten",
|
"all_objects": "Alle objecten",
|
||||||
|
"all_parts": "Alle onderdelen",
|
||||||
"tasks_lower": "taken",
|
"tasks_lower": "taken",
|
||||||
"no_tasks_yet": "Nog geen taken",
|
"no_tasks_yet": "Nog geen taken",
|
||||||
"add_first_task": "Eerste taak toevoegen",
|
"add_first_task": "Eerste taak toevoegen",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Aanvulhoeveelheid",
|
"part_restock_quantity": "Aanvulhoeveelheid",
|
||||||
"part_auto_buy": "Kooptaak bij lage voorraad",
|
"part_auto_buy": "Kooptaak bij lage voorraad",
|
||||||
"part_restock": "Voorraad aanpassen",
|
"part_restock": "Voorraad aanpassen",
|
||||||
|
"parts_used_by": "Gebruikt door",
|
||||||
"restock_quantity_label": "Gekochte hoeveelheid",
|
"restock_quantity_label": "Gekochte hoeveelheid",
|
||||||
"consumes_parts_label": "Verbruikt onderdelen",
|
"consumes_parts_label": "Verbruikt onderdelen",
|
||||||
"shared_parts_other_objects": "Onderdelen van andere objecten",
|
"shared_parts_other_objects": "Onderdelen van andere objecten",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "stand bij laatste onderhoud (optioneel)",
|
"setups_baseline_hint": "stand bij laatste onderhoud (optioneel)",
|
||||||
"baseline_start_help_edit": "Laat leeg om de bestaande telling te behouden. Een ingevulde waarde verankert de telling opnieuw (bijv. de stand bij de laatste servicebeurt).",
|
"baseline_start_help_edit": "Laat leeg om de bestaande telling te behouden. Een ingevulde waarde verankert de telling opnieuw (bijv. de stand bij de laatste servicebeurt).",
|
||||||
"baseline_current_effective": "Momenteel geldende startwaarde: {value}",
|
"baseline_current_effective": "Momenteel geldende startwaarde: {value}",
|
||||||
"runtime_on_states": "Actieve statussen (kommagescheiden)",
|
"runtime_on_states": "Actieve statussen",
|
||||||
"runtime_on_states_help": "Statussen die als draaitijd tellen — standaard: on. Bijv. mowing, cleaning, printing. Met een geselecteerd attribuut worden de waarden daarvan vergeleken.",
|
"runtime_on_states_help": "Statussen die als draaitijd tellen — standaard: on. Bijv. mowing, cleaning, printing. Met een geselecteerd attribuut worden de waarden daarvan vergeleken.",
|
||||||
"setups_target_new": "Nieuw aanmaken: {name}",
|
"setups_target_new": "Nieuw aanmaken: {name}",
|
||||||
"schedule_preview_title": "Volgende data",
|
"schedule_preview_title": "Volgende data",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Typ",
|
"sort_type": "Typ",
|
||||||
"sort_task_name": "Nazwa zadania",
|
"sort_task_name": "Nazwa zadania",
|
||||||
"all_objects": "Wszystkie obiekty",
|
"all_objects": "Wszystkie obiekty",
|
||||||
|
"all_parts": "Wszystkie części",
|
||||||
"tasks_lower": "zadań",
|
"tasks_lower": "zadań",
|
||||||
"no_tasks_yet": "Jeszcze brak zadań",
|
"no_tasks_yet": "Jeszcze brak zadań",
|
||||||
"add_first_task": "Dodaj pierwsze zadanie",
|
"add_first_task": "Dodaj pierwsze zadanie",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Ilość uzupełnienia",
|
"part_restock_quantity": "Ilość uzupełnienia",
|
||||||
"part_auto_buy": "Zadanie zakupu przy niskim stanie",
|
"part_auto_buy": "Zadanie zakupu przy niskim stanie",
|
||||||
"part_restock": "Koryguj stan",
|
"part_restock": "Koryguj stan",
|
||||||
|
"parts_used_by": "Używane przez",
|
||||||
"restock_quantity_label": "Kupiona ilość",
|
"restock_quantity_label": "Kupiona ilość",
|
||||||
"consumes_parts_label": "Zużywa części",
|
"consumes_parts_label": "Zużywa części",
|
||||||
"shared_parts_other_objects": "Części z innych obiektów",
|
"shared_parts_other_objects": "Części z innych obiektów",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "stan przy ostatnim serwisie (opcjonalnie)",
|
"setups_baseline_hint": "stan przy ostatnim serwisie (opcjonalnie)",
|
||||||
"baseline_start_help_edit": "Pozostaw puste, aby zachować dotychczasowe liczenie. Wpisana wartość zakotwicza liczenie na nowo (np. stan przy ostatnim serwisie).",
|
"baseline_start_help_edit": "Pozostaw puste, aby zachować dotychczasowe liczenie. Wpisana wartość zakotwicza liczenie na nowo (np. stan przy ostatnim serwisie).",
|
||||||
"baseline_current_effective": "Obecnie obowiązująca wartość początkowa: {value}",
|
"baseline_current_effective": "Obecnie obowiązująca wartość początkowa: {value}",
|
||||||
"runtime_on_states": "Stany aktywne (rozdzielone przecinkami)",
|
"runtime_on_states": "Stany aktywne",
|
||||||
"runtime_on_states_help": "Stany liczone jako czas pracy — domyślnie: on. Np. mowing, cleaning, printing. Przy wybranym atrybucie porównywane są jego wartości.",
|
"runtime_on_states_help": "Stany liczone jako czas pracy — domyślnie: on. Np. mowing, cleaning, printing. Przy wybranym atrybucie porównywane są jego wartości.",
|
||||||
"setups_target_new": "Utwórz nowy: {name}",
|
"setups_target_new": "Utwórz nowy: {name}",
|
||||||
"schedule_preview_title": "Najbliższe terminy",
|
"schedule_preview_title": "Najbliższe terminy",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Tipo",
|
"sort_type": "Tipo",
|
||||||
"sort_task_name": "Nome da tarefa",
|
"sort_task_name": "Nome da tarefa",
|
||||||
"all_objects": "Todos os objetos",
|
"all_objects": "Todos os objetos",
|
||||||
|
"all_parts": "Todas as peças",
|
||||||
"tasks_lower": "tarefas",
|
"tasks_lower": "tarefas",
|
||||||
"no_tasks_yet": "Ainda sem tarefas",
|
"no_tasks_yet": "Ainda sem tarefas",
|
||||||
"add_first_task": "Adicionar a primeira tarefa",
|
"add_first_task": "Adicionar a primeira tarefa",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "Quantidade de reposição",
|
"part_restock_quantity": "Quantidade de reposição",
|
||||||
"part_auto_buy": "Criar tarefa de compra automaticamente quando estiver baixo",
|
"part_auto_buy": "Criar tarefa de compra automaticamente quando estiver baixo",
|
||||||
"part_restock": "Ajustar estoque",
|
"part_restock": "Ajustar estoque",
|
||||||
|
"parts_used_by": "Usado por",
|
||||||
"restock_quantity_label": "Quantidade comprada",
|
"restock_quantity_label": "Quantidade comprada",
|
||||||
"consumes_parts_label": "Consome peças",
|
"consumes_parts_label": "Consome peças",
|
||||||
"shared_parts_other_objects": "Peças de outros objetos",
|
"shared_parts_other_objects": "Peças de outros objetos",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
||||||
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Informar um valor reancora a contagem (ex.: a leitura da última manutenção).",
|
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Informar um valor reancora a contagem (ex.: a leitura da última manutenção).",
|
||||||
"baseline_current_effective": "Valor inicial efetivo atual: {value}",
|
"baseline_current_effective": "Valor inicial efetivo atual: {value}",
|
||||||
"runtime_on_states": "Estados ativos (separados por vírgula)",
|
"runtime_on_states": "Estados ativos",
|
||||||
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. Ex.: mowing, cleaning, printing. Com um atributo selecionado, os valores dele são comparados.",
|
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. Ex.: mowing, cleaning, printing. Com um atributo selecionado, os valores dele são comparados.",
|
||||||
"setups_target_new": "Criar novo: {name}",
|
"setups_target_new": "Criar novo: {name}",
|
||||||
"schedule_preview_title": "Próximas datas",
|
"schedule_preview_title": "Próximas datas",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Tipo",
|
"sort_type": "Tipo",
|
||||||
"sort_task_name": "Nome da tarefa",
|
"sort_task_name": "Nome da tarefa",
|
||||||
"all_objects": "Todos os objetos",
|
"all_objects": "Todos os objetos",
|
||||||
|
"all_parts": "Todas as peças",
|
||||||
"tasks_lower": "tarefas",
|
"tasks_lower": "tarefas",
|
||||||
"no_tasks_yet": "Ainda sem tarefas",
|
"no_tasks_yet": "Ainda sem tarefas",
|
||||||
"add_first_task": "Adicionar primeira tarefa",
|
"add_first_task": "Adicionar primeira tarefa",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Quantidade de reposição",
|
"part_restock_quantity": "Quantidade de reposição",
|
||||||
"part_auto_buy": "Tarefa de compra se baixo",
|
"part_auto_buy": "Tarefa de compra se baixo",
|
||||||
"part_restock": "Ajustar estoque",
|
"part_restock": "Ajustar estoque",
|
||||||
|
"parts_used_by": "Usado por",
|
||||||
"restock_quantity_label": "Quantidade comprada",
|
"restock_quantity_label": "Quantidade comprada",
|
||||||
"consumes_parts_label": "Consome peças",
|
"consumes_parts_label": "Consome peças",
|
||||||
"shared_parts_other_objects": "Peças de outros objetos",
|
"shared_parts_other_objects": "Peças de outros objetos",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
||||||
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Um valor introduzido reancora a contagem (p. ex., a leitura da última manutenção).",
|
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Um valor introduzido reancora a contagem (p. ex., a leitura da última manutenção).",
|
||||||
"baseline_current_effective": "Valor inicial atualmente em vigor: {value}",
|
"baseline_current_effective": "Valor inicial atualmente em vigor: {value}",
|
||||||
"runtime_on_states": "Estados ativos (separados por vírgulas)",
|
"runtime_on_states": "Estados ativos",
|
||||||
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. P. ex. mowing, cleaning, printing. Com um atributo selecionado, são comparados os valores dele.",
|
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. P. ex. mowing, cleaning, printing. Com um atributo selecionado, são comparados os valores dele.",
|
||||||
"setups_target_new": "Criar novo: {name}",
|
"setups_target_new": "Criar novo: {name}",
|
||||||
"schedule_preview_title": "Próximas datas",
|
"schedule_preview_title": "Próximas datas",
|
||||||
|
|||||||
@@ -176,6 +176,7 @@
|
|||||||
"sort_type": "Тип",
|
"sort_type": "Тип",
|
||||||
"sort_task_name": "Имя задачи",
|
"sort_task_name": "Имя задачи",
|
||||||
"all_objects": "Все объекты",
|
"all_objects": "Все объекты",
|
||||||
|
"all_parts": "Все детали",
|
||||||
"tasks_lower": "задач",
|
"tasks_lower": "задач",
|
||||||
"no_tasks_yet": "Пока нет задач",
|
"no_tasks_yet": "Пока нет задач",
|
||||||
"add_first_task": "Добавить первую задачу",
|
"add_first_task": "Добавить первую задачу",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Количество пополнения",
|
"part_restock_quantity": "Количество пополнения",
|
||||||
"part_auto_buy": "Задача покупки при малом запасе",
|
"part_auto_buy": "Задача покупки при малом запасе",
|
||||||
"part_restock": "Изменить запас",
|
"part_restock": "Изменить запас",
|
||||||
|
"parts_used_by": "Используется",
|
||||||
"restock_quantity_label": "Куплено, шт.",
|
"restock_quantity_label": "Куплено, шт.",
|
||||||
"consumes_parts_label": "Расходует детали",
|
"consumes_parts_label": "Расходует детали",
|
||||||
"shared_parts_other_objects": "Детали других объектов",
|
"shared_parts_other_objects": "Детали других объектов",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "показание при последнем обслуживании (необязательно)",
|
"setups_baseline_hint": "показание при последнем обслуживании (необязательно)",
|
||||||
"baseline_start_help_edit": "Оставьте пустым, чтобы сохранить текущий отсчёт. Введённое значение заново привязывает отсчёт (например, показание при последнем обслуживании).",
|
"baseline_start_help_edit": "Оставьте пустым, чтобы сохранить текущий отсчёт. Введённое значение заново привязывает отсчёт (например, показание при последнем обслуживании).",
|
||||||
"baseline_current_effective": "Действующее начальное значение: {value}",
|
"baseline_current_effective": "Действующее начальное значение: {value}",
|
||||||
"runtime_on_states": "Активные состояния (через запятую)",
|
"runtime_on_states": "Активные состояния",
|
||||||
"runtime_on_states_help": "Состояния, засчитываемые как работа — по умолчанию: on. Напр. mowing, cleaning, printing. Если выбран атрибут, сравниваются его значения.",
|
"runtime_on_states_help": "Состояния, засчитываемые как работа — по умолчанию: on. Напр. mowing, cleaning, printing. Если выбран атрибут, сравниваются его значения.",
|
||||||
"setups_target_new": "Создать новый: {name}",
|
"setups_target_new": "Создать новый: {name}",
|
||||||
"schedule_preview_title": "Ближайшие даты",
|
"schedule_preview_title": "Ближайшие даты",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Typ",
|
"sort_type": "Typ",
|
||||||
"sort_task_name": "Uppgiftsnamn",
|
"sort_task_name": "Uppgiftsnamn",
|
||||||
"all_objects": "Alla objekt",
|
"all_objects": "Alla objekt",
|
||||||
|
"all_parts": "Alla delar",
|
||||||
"tasks_lower": "uppgifter",
|
"tasks_lower": "uppgifter",
|
||||||
"no_tasks_yet": "Inga uppgifter ännu",
|
"no_tasks_yet": "Inga uppgifter ännu",
|
||||||
"add_first_task": "Lägg till första uppgift",
|
"add_first_task": "Lägg till första uppgift",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Påfyllningsantal",
|
"part_restock_quantity": "Påfyllningsantal",
|
||||||
"part_auto_buy": "Köpuppgift vid lågt lager",
|
"part_auto_buy": "Köpuppgift vid lågt lager",
|
||||||
"part_restock": "Justera lager",
|
"part_restock": "Justera lager",
|
||||||
|
"parts_used_by": "Används av",
|
||||||
"restock_quantity_label": "Köpt antal",
|
"restock_quantity_label": "Köpt antal",
|
||||||
"consumes_parts_label": "Förbrukar delar",
|
"consumes_parts_label": "Förbrukar delar",
|
||||||
"shared_parts_other_objects": "Delar från andra objekt",
|
"shared_parts_other_objects": "Delar från andra objekt",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "mätarställning vid senaste service (valfritt)",
|
"setups_baseline_hint": "mätarställning vid senaste service (valfritt)",
|
||||||
"baseline_start_help_edit": "Lämna tomt för att behålla den befintliga räkningen. Ett angivet värde förankrar räkningen på nytt (t.ex. mätarställningen vid senaste servicen).",
|
"baseline_start_help_edit": "Lämna tomt för att behålla den befintliga räkningen. Ett angivet värde förankrar räkningen på nytt (t.ex. mätarställningen vid senaste servicen).",
|
||||||
"baseline_current_effective": "Nu gällande startvärde: {value}",
|
"baseline_current_effective": "Nu gällande startvärde: {value}",
|
||||||
"runtime_on_states": "Aktiva tillstånd (kommaseparerade)",
|
"runtime_on_states": "Aktiva tillstånd",
|
||||||
"runtime_on_states_help": "Tillstånd som räknas som drifttid — standard: on. T.ex. mowing, cleaning, printing. Med ett valt attribut jämförs dess värden i stället.",
|
"runtime_on_states_help": "Tillstånd som räknas som drifttid — standard: on. T.ex. mowing, cleaning, printing. Med ett valt attribut jämförs dess värden i stället.",
|
||||||
"setups_target_new": "Skapa ny: {name}",
|
"setups_target_new": "Skapa ny: {name}",
|
||||||
"schedule_preview_title": "Kommande datum",
|
"schedule_preview_title": "Kommande datum",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Tür",
|
"sort_type": "Tür",
|
||||||
"sort_task_name": "Görev adı",
|
"sort_task_name": "Görev adı",
|
||||||
"all_objects": "Tüm nesneler",
|
"all_objects": "Tüm nesneler",
|
||||||
|
"all_parts": "Tüm parçalar",
|
||||||
"tasks_lower": "görev",
|
"tasks_lower": "görev",
|
||||||
"no_tasks_yet": "Henüz görev yok",
|
"no_tasks_yet": "Henüz görev yok",
|
||||||
"add_first_task": "İlk görevi ekle",
|
"add_first_task": "İlk görevi ekle",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "Stok yenileme miktarı",
|
"part_restock_quantity": "Stok yenileme miktarı",
|
||||||
"part_auto_buy": "Azaldığında otomatik satın alma görevi oluştur",
|
"part_auto_buy": "Azaldığında otomatik satın alma görevi oluştur",
|
||||||
"part_restock": "Stoku ayarla",
|
"part_restock": "Stoku ayarla",
|
||||||
|
"parts_used_by": "Kullanan",
|
||||||
"restock_quantity_label": "Satın alınan miktar",
|
"restock_quantity_label": "Satın alınan miktar",
|
||||||
"consumes_parts_label": "Parça tüketir",
|
"consumes_parts_label": "Parça tüketir",
|
||||||
"shared_parts_other_objects": "Diğer nesnelerin parçaları",
|
"shared_parts_other_objects": "Diğer nesnelerin parçaları",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "son servisteki okuma (isteğe bağlı)",
|
"setups_baseline_hint": "son servisteki okuma (isteğe bağlı)",
|
||||||
"baseline_start_help_edit": "Mevcut sayımı korumak için boş bırakın. Bir değer girmek sayımı yeniden sabitler (örn. son servisteki okuma).",
|
"baseline_start_help_edit": "Mevcut sayımı korumak için boş bırakın. Bir değer girmek sayımı yeniden sabitler (örn. son servisteki okuma).",
|
||||||
"baseline_current_effective": "Şu anda geçerli başlangıç değeri: {value}",
|
"baseline_current_effective": "Şu anda geçerli başlangıç değeri: {value}",
|
||||||
"runtime_on_states": "Etkin durumlar (virgülle ayrılmış)",
|
"runtime_on_states": "Etkin durumlar",
|
||||||
"runtime_on_states_help": "Çalışıyor sayılan durumlar — varsayılan: on. Örn. mowing, cleaning, printing. Bir öznitelik seçiliyse onun değerleri eşleştirilir.",
|
"runtime_on_states_help": "Çalışıyor sayılan durumlar — varsayılan: on. Örn. mowing, cleaning, printing. Bir öznitelik seçiliyse onun değerleri eşleştirilir.",
|
||||||
"setups_target_new": "Yeni oluştur: {name}",
|
"setups_target_new": "Yeni oluştur: {name}",
|
||||||
"schedule_preview_title": "Sonraki tarihler",
|
"schedule_preview_title": "Sonraki tarihler",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Тип",
|
"sort_type": "Тип",
|
||||||
"sort_task_name": "Назва завдання",
|
"sort_task_name": "Назва завдання",
|
||||||
"all_objects": "Всі об'єкти",
|
"all_objects": "Всі об'єкти",
|
||||||
|
"all_parts": "Усі деталі",
|
||||||
"tasks_lower": "завдань",
|
"tasks_lower": "завдань",
|
||||||
"no_tasks_yet": "Завдань ще немає",
|
"no_tasks_yet": "Завдань ще немає",
|
||||||
"add_first_task": "Додати перше завдання",
|
"add_first_task": "Додати перше завдання",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Кількість поповнення",
|
"part_restock_quantity": "Кількість поповнення",
|
||||||
"part_auto_buy": "Завдання купівлі при малому запасі",
|
"part_auto_buy": "Завдання купівлі при малому запасі",
|
||||||
"part_restock": "Змінити запас",
|
"part_restock": "Змінити запас",
|
||||||
|
"parts_used_by": "Використовується",
|
||||||
"restock_quantity_label": "Куплена кількість",
|
"restock_quantity_label": "Куплена кількість",
|
||||||
"consumes_parts_label": "Витрачає деталі",
|
"consumes_parts_label": "Витрачає деталі",
|
||||||
"shared_parts_other_objects": "Деталі інших об'єктів",
|
"shared_parts_other_objects": "Деталі інших об'єктів",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "показання під час останнього обслуговування (необов'язково)",
|
"setups_baseline_hint": "показання під час останнього обслуговування (необов'язково)",
|
||||||
"baseline_start_help_edit": "Залиште порожнім, щоб зберегти поточний відлік. Введене значення заново прив'язує відлік (наприклад, показання під час останнього обслуговування).",
|
"baseline_start_help_edit": "Залиште порожнім, щоб зберегти поточний відлік. Введене значення заново прив'язує відлік (наприклад, показання під час останнього обслуговування).",
|
||||||
"baseline_current_effective": "Чинне початкове значення: {value}",
|
"baseline_current_effective": "Чинне початкове значення: {value}",
|
||||||
"runtime_on_states": "Активні стани (через кому)",
|
"runtime_on_states": "Активні стани",
|
||||||
"runtime_on_states_help": "Стани, що зараховуються як робота — типово: on. Напр. mowing, cleaning, printing. Якщо вибрано атрибут, порівнюються його значення.",
|
"runtime_on_states_help": "Стани, що зараховуються як робота — типово: on. Напр. mowing, cleaning, printing. Якщо вибрано атрибут, порівнюються його значення.",
|
||||||
"setups_target_new": "Створити новий: {name}",
|
"setups_target_new": "Створити новий: {name}",
|
||||||
"schedule_preview_title": "Найближчі дати",
|
"schedule_preview_title": "Найближчі дати",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "类型",
|
"sort_type": "类型",
|
||||||
"sort_task_name": "任务名称",
|
"sort_task_name": "任务名称",
|
||||||
"all_objects": "所有维护项",
|
"all_objects": "所有维护项",
|
||||||
|
"all_parts": "所有配件",
|
||||||
"tasks_lower": "任务",
|
"tasks_lower": "任务",
|
||||||
"no_tasks_yet": "尚无任务",
|
"no_tasks_yet": "尚无任务",
|
||||||
"add_first_task": "添加首个任务",
|
"add_first_task": "添加首个任务",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "补货数量",
|
"part_restock_quantity": "补货数量",
|
||||||
"part_auto_buy": "库存低时自动建购买任务",
|
"part_auto_buy": "库存低时自动建购买任务",
|
||||||
"part_restock": "调整库存",
|
"part_restock": "调整库存",
|
||||||
|
"parts_used_by": "使用于",
|
||||||
"restock_quantity_label": "购买数量",
|
"restock_quantity_label": "购买数量",
|
||||||
"consumes_parts_label": "消耗配件",
|
"consumes_parts_label": "消耗配件",
|
||||||
"shared_parts_other_objects": "其他设备的配件",
|
"shared_parts_other_objects": "其他设备的配件",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "上次保养时的读数(可选)",
|
"setups_baseline_hint": "上次保养时的读数(可选)",
|
||||||
"baseline_start_help_edit": "留空以保留现有计数。填写数值会重新锚定计数(例如上次保养时的读数)。",
|
"baseline_start_help_edit": "留空以保留现有计数。填写数值会重新锚定计数(例如上次保养时的读数)。",
|
||||||
"baseline_current_effective": "当前生效的起始读数:{value}",
|
"baseline_current_effective": "当前生效的起始读数:{value}",
|
||||||
"runtime_on_states": "活动状态(逗号分隔)",
|
"runtime_on_states": "活动状态",
|
||||||
"runtime_on_states_help": "计入运行时间的状态 — 默认:on。例如 mowing、cleaning、printing。选择了属性时将比较该属性的值。",
|
"runtime_on_states_help": "计入运行时间的状态 — 默认:on。例如 mowing、cleaning、printing。选择了属性时将比较该属性的值。",
|
||||||
"setups_target_new": "新建:{name}",
|
"setups_target_new": "新建:{name}",
|
||||||
"schedule_preview_title": "下次日期",
|
"schedule_preview_title": "下次日期",
|
||||||
|
|||||||
@@ -1142,6 +1142,7 @@ function registerLlCustomHandler(): void {
|
|||||||
cost: (histEntry.cost as number | undefined) ?? null,
|
cost: (histEntry.cost as number | undefined) ?? null,
|
||||||
duration: (histEntry.duration as number | undefined) ?? null,
|
duration: (histEntry.duration as number | undefined) ?? null,
|
||||||
completed_by: (histEntry.completed_by as string) ?? null,
|
completed_by: (histEntry.completed_by as string) ?? null,
|
||||||
|
used_parts: (histEntry.used_parts as Array<{ part_id: string; name?: string; quantity: number; entry_id?: string }> | null) ?? null,
|
||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
deepLink("/maintenance-supporter");
|
deepLink("/maintenance-supporter");
|
||||||
|
|||||||
@@ -79,7 +79,32 @@ import { renderUserBadge, type TaskDetailContext } from "./renderers/task-detail
|
|||||||
import "./components/task-detail-view";
|
import "./components/task-detail-view";
|
||||||
import { computeWindow, VIRTUAL_MIN_ROWS } from "./helpers/virtual-window";
|
import { computeWindow, VIRTUAL_MIN_ROWS } from "./helpers/virtual-window";
|
||||||
|
|
||||||
type View = "overview" | "object" | "task" | "all_objects";
|
type View = "overview" | "object" | "task" | "all_objects" | "all_parts";
|
||||||
|
|
||||||
|
/** One row of the instance-wide parts overview (#130) — the WS response of
|
||||||
|
* `parts/overview`: the stored part fields plus owner, live stock and the
|
||||||
|
* consuming tasks (own + pooled #111 links). */
|
||||||
|
interface PartsOverviewRow {
|
||||||
|
part_id: string;
|
||||||
|
entry_id: string;
|
||||||
|
object_name: string | null;
|
||||||
|
name: string;
|
||||||
|
unit?: string | null;
|
||||||
|
cost?: number | null;
|
||||||
|
storage_location?: string | null;
|
||||||
|
vendor?: string | null;
|
||||||
|
reorder_threshold?: number | null;
|
||||||
|
stock: number | null;
|
||||||
|
low: boolean;
|
||||||
|
consumers: Array<{
|
||||||
|
entry_id: string;
|
||||||
|
object_name: string | null;
|
||||||
|
task_id: string;
|
||||||
|
task_name: string | null;
|
||||||
|
quantity: number;
|
||||||
|
pooled: boolean;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
type SortMode = "due_date" | "object" | "type" | "task_name" | "area" | "assigned_user" | "group";
|
type SortMode = "due_date" | "object" | "type" | "task_name" | "area" | "assigned_user" | "group";
|
||||||
type ObjectSortMode = "alphabetical" | "due_soonest" | "task_count";
|
type ObjectSortMode = "alphabetical" | "due_soonest" | "task_count";
|
||||||
type GroupByMode = "none" | "area" | "group" | "user";
|
type GroupByMode = "none" | "area" | "group" | "user";
|
||||||
@@ -95,6 +120,8 @@ export class MaintenanceSupporterPanel extends LitElement {
|
|||||||
@state() private _objects: MaintenanceObjectResponse[] = [];
|
@state() private _objects: MaintenanceObjectResponse[] = [];
|
||||||
@state() private _stats: StatisticsResponse | null = null;
|
@state() private _stats: StatisticsResponse | null = null;
|
||||||
@state() private _view: View = "overview";
|
@state() private _view: View = "overview";
|
||||||
|
// #130: rows of the all-parts view; null until first load.
|
||||||
|
@state() private _allParts: PartsOverviewRow[] | null = null;
|
||||||
@state() private _selectedEntryId: string | null = null;
|
@state() private _selectedEntryId: string | null = null;
|
||||||
@state() private _selectedTaskId: string | null = null;
|
@state() private _selectedTaskId: string | null = null;
|
||||||
@state() private _filterStatus = "";
|
@state() private _filterStatus = "";
|
||||||
@@ -813,6 +840,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
|||||||
this._selectedEntryId = s.msp_entry || null;
|
this._selectedEntryId = s.msp_entry || null;
|
||||||
this._selectedTaskId = s.msp_task || null;
|
this._selectedTaskId = s.msp_task || null;
|
||||||
this._moreMenuOpen = false;
|
this._moreMenuOpen = false;
|
||||||
|
if (s.msp_view === "all_parts") void this._loadAllParts();
|
||||||
if (s.msp_view === "task" && s.msp_entry && s.msp_task) {
|
if (s.msp_view === "task" && s.msp_entry && s.msp_task) {
|
||||||
this._historyFilter = null;
|
this._historyFilter = null;
|
||||||
const task = this._getTask(s.msp_entry, s.msp_task);
|
const task = this._getTask(s.msp_entry, s.msp_task);
|
||||||
@@ -839,6 +867,27 @@ export class MaintenanceSupporterPanel extends LitElement {
|
|||||||
this._scrollContentToTop();
|
this._scrollContentToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #130: instance-wide parts inventory, sibling view of All objects.
|
||||||
|
private _showAllParts(): void {
|
||||||
|
this._pushPanelState("all_parts");
|
||||||
|
this._view = "all_parts";
|
||||||
|
this._selectedEntryId = null;
|
||||||
|
this._selectedTaskId = null;
|
||||||
|
this._scrollContentToTop();
|
||||||
|
void this._loadAllParts();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _loadAllParts(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const result = await this.hass.connection.sendMessagePromise({
|
||||||
|
type: "maintenance_supporter/parts/overview",
|
||||||
|
}) as { parts: PartsOverviewRow[] };
|
||||||
|
this._allParts = result.parts || [];
|
||||||
|
} catch {
|
||||||
|
this._allParts = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** v2.1.0 (Discussion #49 — @byoung79): tap a KPI value to auto-filter
|
/** v2.1.0 (Discussion #49 — @byoung79): tap a KPI value to auto-filter
|
||||||
* the task list. Empty string clears the filter (used by "Tasks" KPI). */
|
* the task list. Empty string clears the filter (used by "Tasks" KPI). */
|
||||||
private _filterByStatus(status: string): void {
|
private _filterByStatus(status: string): void {
|
||||||
@@ -1990,6 +2039,8 @@ export class MaintenanceSupporterPanel extends LitElement {
|
|||||||
? this._renderOverview()
|
? this._renderOverview()
|
||||||
: this._view === "all_objects"
|
: this._view === "all_objects"
|
||||||
? this._renderAllObjects()
|
? this._renderAllObjects()
|
||||||
|
: this._view === "all_parts"
|
||||||
|
? this._renderAllParts()
|
||||||
: this._view === "object"
|
: this._view === "object"
|
||||||
? this._renderObjectDetail()
|
? this._renderObjectDetail()
|
||||||
: this._renderTaskDetail()}
|
: this._renderTaskDetail()}
|
||||||
@@ -2703,6 +2754,9 @@ export class MaintenanceSupporterPanel extends LitElement {
|
|||||||
<ha-icon icon="mdi:arrow-left"></ha-icon>
|
<ha-icon icon="mdi:arrow-left"></ha-icon>
|
||||||
</ha-icon-button>
|
</ha-icon-button>
|
||||||
<span>${t("all_objects", L)}</span>
|
<span>${t("all_objects", L)}</span>
|
||||||
|
<button class="sibling-view-chip" @click=${() => this._showAllParts()}>
|
||||||
|
<ha-icon icon="mdi:package-variant-closed"></ha-icon> ${t("all_parts", L)}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-bar">
|
<div class="filter-bar">
|
||||||
<label class="filter-field">
|
<label class="filter-field">
|
||||||
@@ -2792,6 +2846,106 @@ export class MaintenanceSupporterPanel extends LitElement {
|
|||||||
localStorage.setItem(LS_KEYS.objectView, mode);
|
localStorage.setItem(LS_KEYS.objectView, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── #130: instance-wide parts overview ────────────────────────────────────
|
||||||
|
|
||||||
|
private _renderAllParts() {
|
||||||
|
const L = this._lang;
|
||||||
|
const rows = this._allParts;
|
||||||
|
const currency = this._budget?.currency_symbol || "";
|
||||||
|
return html`
|
||||||
|
<div class="breadcrumb">
|
||||||
|
<ha-icon-button @click=${() => this._showAllObjects()}>
|
||||||
|
<ha-icon icon="mdi:arrow-left"></ha-icon>
|
||||||
|
</ha-icon-button>
|
||||||
|
<span>${t("all_parts", L)}</span>
|
||||||
|
<button class="sibling-view-chip" @click=${() => this._showAllObjects()}>
|
||||||
|
<ha-icon icon="mdi:devices"></ha-icon> ${t("all_objects", L)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="filter-bar">
|
||||||
|
<ha-button appearance="plain" @click=${() => this._exportPartsCsv()}>
|
||||||
|
<ha-icon icon="mdi:file-delimited-outline"></ha-icon> ${t("settings_export_csv", L)}
|
||||||
|
</ha-button>
|
||||||
|
</div>
|
||||||
|
${rows === null
|
||||||
|
? html`<div class="empty-state">…</div>`
|
||||||
|
: rows.length === 0
|
||||||
|
? html`<div class="empty-state">${t("parts_section", L)}: 0</div>`
|
||||||
|
: html`
|
||||||
|
<div class="objects-table-wrap">
|
||||||
|
<table class="objects-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>${t("part_name", L)}</th>
|
||||||
|
<th>${t("object", L)}</th>
|
||||||
|
<th>${t("part_stock", L)}</th>
|
||||||
|
<th>${t("part_reorder_threshold", L)}</th>
|
||||||
|
<th>${t("part_cost", L)}</th>
|
||||||
|
<th>${t("part_storage_location", L)}</th>
|
||||||
|
<th>${t("parts_used_by", L)}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
${rows.map((row) => html`
|
||||||
|
<tr class="objects-table-row" @click=${() => this._showObject(row.entry_id)}>
|
||||||
|
<td>
|
||||||
|
<span class="objects-table-name">${row.name}</span>
|
||||||
|
${row.low
|
||||||
|
? html`<ha-icon class="part-low-icon" icon="mdi:cart-arrow-down"
|
||||||
|
title="${t("part_reorder_threshold", L)}: ${row.reorder_threshold}"></ha-icon>`
|
||||||
|
: nothing}
|
||||||
|
</td>
|
||||||
|
<td>${row.object_name || "—"}</td>
|
||||||
|
<td>${row.stock !== null ? `${row.stock}${row.unit ? ` ${row.unit}` : ""}` : "—"}</td>
|
||||||
|
<td>${row.reorder_threshold ?? "—"}</td>
|
||||||
|
<td>${row.cost != null ? `${row.cost} ${currency}`.trim() : "—"}</td>
|
||||||
|
<td>${row.storage_location || "—"}</td>
|
||||||
|
<td>
|
||||||
|
${row.consumers.length === 0
|
||||||
|
? "—"
|
||||||
|
: row.consumers.map((c) => html`
|
||||||
|
<span
|
||||||
|
class="part-consumer-chip${c.pooled ? " pooled" : ""}"
|
||||||
|
title=${`${c.object_name ?? ""}: ${c.task_name ?? c.task_id} (×${c.quantity})`}
|
||||||
|
>${c.pooled ? `${c.object_name} · ` : ""}${c.task_name ?? c.task_id}</span>
|
||||||
|
`)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Client-side CSV of the loaded overview rows (the objects table's CSV is
|
||||||
|
* server-built; the parts rows are already fully materialized here). */
|
||||||
|
private _exportPartsCsv(): void {
|
||||||
|
const rows = this._allParts || [];
|
||||||
|
const esc = (v: unknown): string => {
|
||||||
|
const s = v == null ? "" : String(v);
|
||||||
|
return /[",\n;]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
||||||
|
};
|
||||||
|
const header = ["name", "object", "stock", "unit", "reorder_threshold", "unit_cost", "storage_location", "vendor", "used_by"];
|
||||||
|
const lines = [header.join(",")];
|
||||||
|
for (const row of rows) {
|
||||||
|
lines.push([
|
||||||
|
esc(row.name),
|
||||||
|
esc(row.object_name),
|
||||||
|
esc(row.stock),
|
||||||
|
esc(row.unit),
|
||||||
|
esc(row.reorder_threshold),
|
||||||
|
esc(row.cost),
|
||||||
|
esc(row.storage_location),
|
||||||
|
esc(row.vendor),
|
||||||
|
esc(row.consumers.map((c) => `${c.object_name ?? ""}/${c.task_name ?? c.task_id}×${c.quantity}`).join(" | ")),
|
||||||
|
].join(","));
|
||||||
|
}
|
||||||
|
const ts = new Date().toISOString().slice(0, 10);
|
||||||
|
downloadTextFile(lines.join("\n"), `maintenance_parts_${ts}.csv`, "text/csv;charset=utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
// (#67 / Phase 3) Download all objects as a one-row-per-object CSV.
|
// (#67 / Phase 3) Download all objects as a one-row-per-object CSV.
|
||||||
private async _exportObjectsCsv(): Promise<void> {
|
private async _exportObjectsCsv(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
@@ -3602,6 +3756,7 @@ export class MaintenanceSupporterPanel extends LitElement {
|
|||||||
cost: entry.cost ?? null,
|
cost: entry.cost ?? null,
|
||||||
duration: entry.duration ?? null,
|
duration: entry.duration ?? null,
|
||||||
completed_by: entry.completed_by ?? null,
|
completed_by: entry.completed_by ?? null,
|
||||||
|
used_parts: entry.used_parts ?? null,
|
||||||
};
|
};
|
||||||
this.shadowRoot
|
this.shadowRoot
|
||||||
?.querySelector<MaintenanceHistoryEditDialog>("maintenance-history-edit-dialog")
|
?.querySelector<MaintenanceHistoryEditDialog>("maintenance-history-edit-dialog")
|
||||||
|
|||||||
@@ -605,6 +605,43 @@ export const panelStyles = css`
|
|||||||
}
|
}
|
||||||
.view-toggle-btn ha-icon { --mdc-icon-size: 18px; }
|
.view-toggle-btn ha-icon { --mdc-icon-size: 18px; }
|
||||||
|
|
||||||
|
/* (#130) All-parts view: sibling chip in the breadcrumb + table extras */
|
||||||
|
.sibling-view-chip {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
margin-left: 12px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
border: 1px solid var(--divider-color);
|
||||||
|
border-radius: 14px;
|
||||||
|
background: none;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
font: inherit;
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.sibling-view-chip:hover {
|
||||||
|
background: var(--secondary-background-color, rgba(0, 0, 0, 0.04));
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
}
|
||||||
|
.sibling-view-chip ha-icon { --mdc-icon-size: 16px; }
|
||||||
|
.part-low-icon {
|
||||||
|
--mdc-icon-size: 16px;
|
||||||
|
color: var(--warning-color, #ff9800);
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
.part-consumer-chip {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 1px 4px 1px 0;
|
||||||
|
padding: 1px 8px;
|
||||||
|
border: 1px solid var(--divider-color);
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
.part-consumer-chip.pooled { border-style: dashed; }
|
||||||
|
|
||||||
/* (#67) Objects table (desktop All-Objects view) */
|
/* (#67) Objects table (desktop All-Objects view) */
|
||||||
.objects-table-wrap {
|
.objects-table-wrap {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ export interface HistoryEntry {
|
|||||||
photo_doc_id?: string | null;
|
photo_doc_id?: string | null;
|
||||||
/** v2.20 (#83): recorded value for `reading`-type tasks. */
|
/** v2.20 (#83): recorded value for `reading`-type tasks. */
|
||||||
reading_value?: number | null;
|
reading_value?: number | null;
|
||||||
|
/** #99/#130: the completion's part consumption (entry_id set for pooled). */
|
||||||
|
used_parts?: Array<{ part_id: string; name?: string; quantity: number; entry_id?: string }> | null;
|
||||||
/** v2.37: completion recorded by the system itself (trigger recovered),
|
/** v2.37: completion recorded by the system itself (trigger recovered),
|
||||||
* not performed by a user in the UI. */
|
* not performed by a user in the UI. */
|
||||||
auto?: boolean;
|
auto?: boolean;
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Typ",
|
"sort_type": "Typ",
|
||||||
"sort_task_name": "Název úkolu",
|
"sort_task_name": "Název úkolu",
|
||||||
"all_objects": "Všechny objekty",
|
"all_objects": "Všechny objekty",
|
||||||
|
"all_parts": "Všechny díly",
|
||||||
"tasks_lower": "úkolů",
|
"tasks_lower": "úkolů",
|
||||||
"no_tasks_yet": "Zatím žádné úkoly",
|
"no_tasks_yet": "Zatím žádné úkoly",
|
||||||
"add_first_task": "Přidat první úkol",
|
"add_first_task": "Přidat první úkol",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Množství doplnění",
|
"part_restock_quantity": "Množství doplnění",
|
||||||
"part_auto_buy": "Úkol nákupu při nízké zásobě",
|
"part_auto_buy": "Úkol nákupu při nízké zásobě",
|
||||||
"part_restock": "Upravit zásobu",
|
"part_restock": "Upravit zásobu",
|
||||||
|
"parts_used_by": "Používá",
|
||||||
"restock_quantity_label": "Zakoupené množství",
|
"restock_quantity_label": "Zakoupené množství",
|
||||||
"consumes_parts_label": "Spotřebovává díly",
|
"consumes_parts_label": "Spotřebovává díly",
|
||||||
"shared_parts_other_objects": "Díly z jiných objektů",
|
"shared_parts_other_objects": "Díly z jiných objektů",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "stav při posledním servisu (volitelné)",
|
"setups_baseline_hint": "stav při posledním servisu (volitelné)",
|
||||||
"baseline_start_help_edit": "Ponechte prázdné pro zachování stávajícího počítání. Zadaná hodnota počítání znovu ukotví (např. stav při posledním servisu).",
|
"baseline_start_help_edit": "Ponechte prázdné pro zachování stávajícího počítání. Zadaná hodnota počítání znovu ukotví (např. stav při posledním servisu).",
|
||||||
"baseline_current_effective": "Aktuálně platná počáteční hodnota: {value}",
|
"baseline_current_effective": "Aktuálně platná počáteční hodnota: {value}",
|
||||||
"runtime_on_states": "Aktivní stavy (oddělené čárkami)",
|
"runtime_on_states": "Aktivní stavy",
|
||||||
"runtime_on_states_help": "Stavy počítané jako doba běhu — výchozí: on. Např. mowing, cleaning, printing. Při zvoleném atributu se porovnávají jeho hodnoty.",
|
"runtime_on_states_help": "Stavy počítané jako doba běhu — výchozí: on. Např. mowing, cleaning, printing. Při zvoleném atributu se porovnávají jeho hodnoty.",
|
||||||
"setups_target_new": "Vytvořit nový: {name}",
|
"setups_target_new": "Vytvořit nový: {name}",
|
||||||
"schedule_preview_title": "Nejbližší termíny",
|
"schedule_preview_title": "Nejbližší termíny",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Opgavenavn",
|
"sort_task_name": "Opgavenavn",
|
||||||
"all_objects": "Alle objekter",
|
"all_objects": "Alle objekter",
|
||||||
|
"all_parts": "Alle dele",
|
||||||
"tasks_lower": "opgaver",
|
"tasks_lower": "opgaver",
|
||||||
"no_tasks_yet": "Ingen opgaver endnu",
|
"no_tasks_yet": "Ingen opgaver endnu",
|
||||||
"add_first_task": "Tilføj første opgave",
|
"add_first_task": "Tilføj første opgave",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Genopfyldningsmængde",
|
"part_restock_quantity": "Genopfyldningsmængde",
|
||||||
"part_auto_buy": "Købsopgave ved lav beholdning",
|
"part_auto_buy": "Købsopgave ved lav beholdning",
|
||||||
"part_restock": "Justér lager",
|
"part_restock": "Justér lager",
|
||||||
|
"parts_used_by": "Bruges af",
|
||||||
"restock_quantity_label": "Købt mængde",
|
"restock_quantity_label": "Købt mængde",
|
||||||
"consumes_parts_label": "Forbruger dele",
|
"consumes_parts_label": "Forbruger dele",
|
||||||
"shared_parts_other_objects": "Dele fra andre objekter",
|
"shared_parts_other_objects": "Dele fra andre objekter",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "aflæsning ved sidste service (valgfrit)",
|
"setups_baseline_hint": "aflæsning ved sidste service (valgfrit)",
|
||||||
"baseline_start_help_edit": "Lad feltet stå tomt for at beholde den eksisterende tælling. En indtastet værdi forankrer tællingen på ny (f.eks. aflæsningen ved sidste service).",
|
"baseline_start_help_edit": "Lad feltet stå tomt for at beholde den eksisterende tælling. En indtastet værdi forankrer tællingen på ny (f.eks. aflæsningen ved sidste service).",
|
||||||
"baseline_current_effective": "Aktuelt gældende startværdi: {value}",
|
"baseline_current_effective": "Aktuelt gældende startværdi: {value}",
|
||||||
"runtime_on_states": "Aktive tilstande (kommaseparerede)",
|
"runtime_on_states": "Aktive tilstande",
|
||||||
"runtime_on_states_help": "Tilstande der tæller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med en valgt attribut sammenlignes dens værdier i stedet.",
|
"runtime_on_states_help": "Tilstande der tæller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med en valgt attribut sammenlignes dens værdier i stedet.",
|
||||||
"setups_target_new": "Opret ny: {name}",
|
"setups_target_new": "Opret ny: {name}",
|
||||||
"schedule_preview_title": "Kommende datoer",
|
"schedule_preview_title": "Kommende datoer",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Typ",
|
"sort_type": "Typ",
|
||||||
"sort_task_name": "Aufgaben-Name",
|
"sort_task_name": "Aufgaben-Name",
|
||||||
"all_objects": "Alle Objekte",
|
"all_objects": "Alle Objekte",
|
||||||
|
"all_parts": "Alle Teile",
|
||||||
"tasks_lower": "Aufgaben",
|
"tasks_lower": "Aufgaben",
|
||||||
"no_tasks_yet": "Noch keine Aufgaben",
|
"no_tasks_yet": "Noch keine Aufgaben",
|
||||||
"add_first_task": "Erste Aufgabe hinzufügen",
|
"add_first_task": "Erste Aufgabe hinzufügen",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Auffüllmenge",
|
"part_restock_quantity": "Auffüllmenge",
|
||||||
"part_auto_buy": "Kauf-Task bei Niedrigbestand",
|
"part_auto_buy": "Kauf-Task bei Niedrigbestand",
|
||||||
"part_restock": "Bestand anpassen",
|
"part_restock": "Bestand anpassen",
|
||||||
|
"parts_used_by": "Verwendet von",
|
||||||
"restock_quantity_label": "Gekaufte Menge",
|
"restock_quantity_label": "Gekaufte Menge",
|
||||||
"consumes_parts_label": "Verbraucht Teile",
|
"consumes_parts_label": "Verbraucht Teile",
|
||||||
"shared_parts_other_objects": "Teile anderer Objekte",
|
"shared_parts_other_objects": "Teile anderer Objekte",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "Stand beim letzten Service (optional)",
|
"setups_baseline_hint": "Stand beim letzten Service (optional)",
|
||||||
"baseline_start_help_edit": "Leer lassen, um die bestehende Zählung zu behalten. Ein eingetragener Wert verankert die Zählung neu (z. B. der Stand beim letzten Service).",
|
"baseline_start_help_edit": "Leer lassen, um die bestehende Zählung zu behalten. Ein eingetragener Wert verankert die Zählung neu (z. B. der Stand beim letzten Service).",
|
||||||
"baseline_current_effective": "Aktuell wirksamer Startwert: {value}",
|
"baseline_current_effective": "Aktuell wirksamer Startwert: {value}",
|
||||||
"runtime_on_states": "Aktive Zustände (kommagetrennt)",
|
"runtime_on_states": "Aktive Zustände",
|
||||||
"runtime_on_states_help": "Zustände, die als Laufzeit zählen — Standard: on. Z. B. mowing, cleaning, printing. Bei gewähltem Attribut werden dessen Werte verglichen.",
|
"runtime_on_states_help": "Zustände, die als Laufzeit zählen — Standard: on. Z. B. mowing, cleaning, printing. Bei gewähltem Attribut werden dessen Werte verglichen.",
|
||||||
"setups_target_new": "Neu anlegen: {name}",
|
"setups_target_new": "Neu anlegen: {name}",
|
||||||
"schedule_preview_title": "Nächste Termine",
|
"schedule_preview_title": "Nächste Termine",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Task name",
|
"sort_task_name": "Task name",
|
||||||
"all_objects": "All objects",
|
"all_objects": "All objects",
|
||||||
|
"all_parts": "All parts",
|
||||||
"tasks_lower": "tasks",
|
"tasks_lower": "tasks",
|
||||||
"no_tasks_yet": "No tasks yet",
|
"no_tasks_yet": "No tasks yet",
|
||||||
"add_first_task": "Add first task",
|
"add_first_task": "Add first task",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "Restock quantity",
|
"part_restock_quantity": "Restock quantity",
|
||||||
"part_auto_buy": "Auto-create buy task when low",
|
"part_auto_buy": "Auto-create buy task when low",
|
||||||
"part_restock": "Adjust stock",
|
"part_restock": "Adjust stock",
|
||||||
|
"parts_used_by": "Used by",
|
||||||
"restock_quantity_label": "Quantity bought",
|
"restock_quantity_label": "Quantity bought",
|
||||||
"consumes_parts_label": "Consumes parts",
|
"consumes_parts_label": "Consumes parts",
|
||||||
"shared_parts_other_objects": "Parts from other objects",
|
"shared_parts_other_objects": "Parts from other objects",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "reading at last service (optional)",
|
"setups_baseline_hint": "reading at last service (optional)",
|
||||||
"baseline_start_help_edit": "Leave empty to keep the existing counting. Entering a value re-anchors the counting (e.g. the reading at the last service).",
|
"baseline_start_help_edit": "Leave empty to keep the existing counting. Entering a value re-anchors the counting (e.g. the reading at the last service).",
|
||||||
"baseline_current_effective": "Currently effective start value: {value}",
|
"baseline_current_effective": "Currently effective start value: {value}",
|
||||||
"runtime_on_states": "Active states (comma-separated)",
|
"runtime_on_states": "Active states",
|
||||||
"runtime_on_states_help": "States that count as running — default: on. E.g. mowing, cleaning, printing. With an attribute selected, its values are matched instead.",
|
"runtime_on_states_help": "States that count as running — default: on. E.g. mowing, cleaning, printing. With an attribute selected, its values are matched instead.",
|
||||||
"setups_target_new": "Create new: {name}",
|
"setups_target_new": "Create new: {name}",
|
||||||
"schedule_preview_title": "Next dates",
|
"schedule_preview_title": "Next dates",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Tipo",
|
"sort_type": "Tipo",
|
||||||
"sort_task_name": "Nombre de la tarea",
|
"sort_task_name": "Nombre de la tarea",
|
||||||
"all_objects": "Todos los objetos",
|
"all_objects": "Todos los objetos",
|
||||||
|
"all_parts": "Todas las piezas",
|
||||||
"tasks_lower": "tareas",
|
"tasks_lower": "tareas",
|
||||||
"no_tasks_yet": "Aún no hay tareas",
|
"no_tasks_yet": "Aún no hay tareas",
|
||||||
"add_first_task": "Agregar primera tarea",
|
"add_first_task": "Agregar primera tarea",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Cantidad de reposición",
|
"part_restock_quantity": "Cantidad de reposición",
|
||||||
"part_auto_buy": "Crear tarea de compra si bajo",
|
"part_auto_buy": "Crear tarea de compra si bajo",
|
||||||
"part_restock": "Ajustar existencias",
|
"part_restock": "Ajustar existencias",
|
||||||
|
"parts_used_by": "Usado por",
|
||||||
"restock_quantity_label": "Cantidad comprada",
|
"restock_quantity_label": "Cantidad comprada",
|
||||||
"consumes_parts_label": "Consume piezas",
|
"consumes_parts_label": "Consume piezas",
|
||||||
"shared_parts_other_objects": "Piezas de otros objetos",
|
"shared_parts_other_objects": "Piezas de otros objetos",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "lectura en el último mantenimiento (opcional)",
|
"setups_baseline_hint": "lectura en el último mantenimiento (opcional)",
|
||||||
"baseline_start_help_edit": "Déjalo vacío para mantener el conteo actual. Un valor introducido reancla el conteo (p. ej., la lectura del último mantenimiento).",
|
"baseline_start_help_edit": "Déjalo vacío para mantener el conteo actual. Un valor introducido reancla el conteo (p. ej., la lectura del último mantenimiento).",
|
||||||
"baseline_current_effective": "Valor inicial vigente: {value}",
|
"baseline_current_effective": "Valor inicial vigente: {value}",
|
||||||
"runtime_on_states": "Estados activos (separados por comas)",
|
"runtime_on_states": "Estados activos",
|
||||||
"runtime_on_states_help": "Estados que cuentan como en funcionamiento — predeterminado: on. P. ej. mowing, cleaning, printing. Con un atributo seleccionado se comparan sus valores.",
|
"runtime_on_states_help": "Estados que cuentan como en funcionamiento — predeterminado: on. P. ej. mowing, cleaning, printing. Con un atributo seleccionado se comparan sus valores.",
|
||||||
"setups_target_new": "Crear nuevo: {name}",
|
"setups_target_new": "Crear nuevo: {name}",
|
||||||
"schedule_preview_title": "Próximas fechas",
|
"schedule_preview_title": "Próximas fechas",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Tyyppi",
|
"sort_type": "Tyyppi",
|
||||||
"sort_task_name": "Tehtävän nimi",
|
"sort_task_name": "Tehtävän nimi",
|
||||||
"all_objects": "Kaikki kohteet",
|
"all_objects": "Kaikki kohteet",
|
||||||
|
"all_parts": "Kaikki osat",
|
||||||
"tasks_lower": "tehtävää",
|
"tasks_lower": "tehtävää",
|
||||||
"no_tasks_yet": "Ei vielä tehtäviä",
|
"no_tasks_yet": "Ei vielä tehtäviä",
|
||||||
"add_first_task": "Lisää ensimmäinen tehtävä",
|
"add_first_task": "Lisää ensimmäinen tehtävä",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Täydennysmäärä",
|
"part_restock_quantity": "Täydennysmäärä",
|
||||||
"part_auto_buy": "Ostotehtävä kun vähissä",
|
"part_auto_buy": "Ostotehtävä kun vähissä",
|
||||||
"part_restock": "Muuta varastoa",
|
"part_restock": "Muuta varastoa",
|
||||||
|
"parts_used_by": "Käyttäjät",
|
||||||
"restock_quantity_label": "Ostettu määrä",
|
"restock_quantity_label": "Ostettu määrä",
|
||||||
"consumes_parts_label": "Kuluttaa osia",
|
"consumes_parts_label": "Kuluttaa osia",
|
||||||
"shared_parts_other_objects": "Muiden kohteiden osat",
|
"shared_parts_other_objects": "Muiden kohteiden osat",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "lukema viime huollossa (valinnainen)",
|
"setups_baseline_hint": "lukema viime huollossa (valinnainen)",
|
||||||
"baseline_start_help_edit": "Jätä tyhjäksi säilyttääksesi nykyisen laskennan. Syötetty arvo ankkuroi laskennan uudelleen (esim. viimeisimmän huollon lukema).",
|
"baseline_start_help_edit": "Jätä tyhjäksi säilyttääksesi nykyisen laskennan. Syötetty arvo ankkuroi laskennan uudelleen (esim. viimeisimmän huollon lukema).",
|
||||||
"baseline_current_effective": "Nyt voimassa oleva aloitusarvo: {value}",
|
"baseline_current_effective": "Nyt voimassa oleva aloitusarvo: {value}",
|
||||||
"runtime_on_states": "Aktiiviset tilat (pilkuin eroteltuina)",
|
"runtime_on_states": "Aktiiviset tilat",
|
||||||
"runtime_on_states_help": "Tilat, jotka lasketaan käyntiajaksi — oletus: on. Esim. mowing, cleaning, printing. Jos attribuutti on valittu, verrataan sen arvoja.",
|
"runtime_on_states_help": "Tilat, jotka lasketaan käyntiajaksi — oletus: on. Esim. mowing, cleaning, printing. Jos attribuutti on valittu, verrataan sen arvoja.",
|
||||||
"setups_target_new": "Luo uusi: {name}",
|
"setups_target_new": "Luo uusi: {name}",
|
||||||
"schedule_preview_title": "Seuraavat päivämäärät",
|
"schedule_preview_title": "Seuraavat päivämäärät",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Nom de la tâche",
|
"sort_task_name": "Nom de la tâche",
|
||||||
"all_objects": "Tous les objets",
|
"all_objects": "Tous les objets",
|
||||||
|
"all_parts": "Toutes les pièces",
|
||||||
"tasks_lower": "tâches",
|
"tasks_lower": "tâches",
|
||||||
"no_tasks_yet": "Pas encore de tâches",
|
"no_tasks_yet": "Pas encore de tâches",
|
||||||
"add_first_task": "Ajouter la première tâche",
|
"add_first_task": "Ajouter la première tâche",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Quantité de réappro",
|
"part_restock_quantity": "Quantité de réappro",
|
||||||
"part_auto_buy": "Tâche d'achat auto si bas",
|
"part_auto_buy": "Tâche d'achat auto si bas",
|
||||||
"part_restock": "Ajuster le stock",
|
"part_restock": "Ajuster le stock",
|
||||||
|
"parts_used_by": "Utilisé par",
|
||||||
"restock_quantity_label": "Quantité achetée",
|
"restock_quantity_label": "Quantité achetée",
|
||||||
"consumes_parts_label": "Consomme des pièces",
|
"consumes_parts_label": "Consomme des pièces",
|
||||||
"shared_parts_other_objects": "Pièces d'autres objets",
|
"shared_parts_other_objects": "Pièces d'autres objets",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "relevé au dernier entretien (facultatif)",
|
"setups_baseline_hint": "relevé au dernier entretien (facultatif)",
|
||||||
"baseline_start_help_edit": "Laissez vide pour conserver le comptage existant. Une valeur saisie réancre le comptage (p. ex. le relevé du dernier entretien).",
|
"baseline_start_help_edit": "Laissez vide pour conserver le comptage existant. Une valeur saisie réancre le comptage (p. ex. le relevé du dernier entretien).",
|
||||||
"baseline_current_effective": "Valeur de départ actuellement en vigueur : {value}",
|
"baseline_current_effective": "Valeur de départ actuellement en vigueur : {value}",
|
||||||
"runtime_on_states": "États actifs (séparés par des virgules)",
|
"runtime_on_states": "États actifs",
|
||||||
"runtime_on_states_help": "États comptés comme en fonctionnement — par défaut : on. P. ex. mowing, cleaning, printing. Si un attribut est sélectionné, ce sont ses valeurs qui sont comparées.",
|
"runtime_on_states_help": "États comptés comme en fonctionnement — par défaut : on. P. ex. mowing, cleaning, printing. Si un attribut est sélectionné, ce sont ses valeurs qui sont comparées.",
|
||||||
"setups_target_new": "Créer : {name}",
|
"setups_target_new": "Créer : {name}",
|
||||||
"schedule_preview_title": "Prochaines échéances",
|
"schedule_preview_title": "Prochaines échéances",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "प्रकार",
|
"sort_type": "प्रकार",
|
||||||
"sort_task_name": "कार्य का नाम",
|
"sort_task_name": "कार्य का नाम",
|
||||||
"all_objects": "सभी वस्तुएँ",
|
"all_objects": "सभी वस्तुएँ",
|
||||||
|
"all_parts": "सभी पुर्ज़े",
|
||||||
"tasks_lower": "कार्य",
|
"tasks_lower": "कार्य",
|
||||||
"no_tasks_yet": "अभी कोई कार्य नहीं",
|
"no_tasks_yet": "अभी कोई कार्य नहीं",
|
||||||
"add_first_task": "पहला कार्य जोड़ें",
|
"add_first_task": "पहला कार्य जोड़ें",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "पुनःपूर्ति मात्रा",
|
"part_restock_quantity": "पुनःपूर्ति मात्रा",
|
||||||
"part_auto_buy": "कम होने पर खरीद कार्य",
|
"part_auto_buy": "कम होने पर खरीद कार्य",
|
||||||
"part_restock": "स्टॉक समायोजित करें",
|
"part_restock": "स्टॉक समायोजित करें",
|
||||||
|
"parts_used_by": "द्वारा उपयोग",
|
||||||
"restock_quantity_label": "खरीदी गई मात्रा",
|
"restock_quantity_label": "खरीदी गई मात्रा",
|
||||||
"consumes_parts_label": "पुर्ज़े खपत",
|
"consumes_parts_label": "पुर्ज़े खपत",
|
||||||
"shared_parts_other_objects": "अन्य वस्तुओं के पुर्ज़े",
|
"shared_parts_other_objects": "अन्य वस्तुओं के पुर्ज़े",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "पिछली सर्विस पर रीडिंग (वैकल्पिक)",
|
"setups_baseline_hint": "पिछली सर्विस पर रीडिंग (वैकल्पिक)",
|
||||||
"baseline_start_help_edit": "मौजूदा गिनती बनाए रखने के लिए खाली छोड़ें। दर्ज किया गया मान गिनती को फिर से स्थिर करता है (जैसे पिछली सर्विस के समय की रीडिंग)।",
|
"baseline_start_help_edit": "मौजूदा गिनती बनाए रखने के लिए खाली छोड़ें। दर्ज किया गया मान गिनती को फिर से स्थिर करता है (जैसे पिछली सर्विस के समय की रीडिंग)।",
|
||||||
"baseline_current_effective": "वर्तमान में प्रभावी प्रारंभिक मान: {value}",
|
"baseline_current_effective": "वर्तमान में प्रभावी प्रारंभिक मान: {value}",
|
||||||
"runtime_on_states": "सक्रिय अवस्थाएँ (अल्पविराम से अलग)",
|
"runtime_on_states": "सक्रिय अवस्थाएँ",
|
||||||
"runtime_on_states_help": "वे अवस्थाएँ जो चालू समय में गिनी जाती हैं — डिफ़ॉल्ट: on। जैसे mowing, cleaning, printing। विशेषता चुनी होने पर उसकी मानों की तुलना होती है।",
|
"runtime_on_states_help": "वे अवस्थाएँ जो चालू समय में गिनी जाती हैं — डिफ़ॉल्ट: on। जैसे mowing, cleaning, printing। विशेषता चुनी होने पर उसकी मानों की तुलना होती है।",
|
||||||
"setups_target_new": "नया बनाएँ: {name}",
|
"setups_target_new": "नया बनाएँ: {name}",
|
||||||
"schedule_preview_title": "अगली तिथियाँ",
|
"schedule_preview_title": "अगली तिथियाँ",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Típus",
|
"sort_type": "Típus",
|
||||||
"sort_task_name": "Feladat neve",
|
"sort_task_name": "Feladat neve",
|
||||||
"all_objects": "Minden objektum",
|
"all_objects": "Minden objektum",
|
||||||
|
"all_parts": "Összes alkatrész",
|
||||||
"tasks_lower": "feladat",
|
"tasks_lower": "feladat",
|
||||||
"no_tasks_yet": "Még nincs feladat",
|
"no_tasks_yet": "Még nincs feladat",
|
||||||
"add_first_task": "Első feladat hozzáadása",
|
"add_first_task": "Első feladat hozzáadása",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "Feltöltési mennyiség",
|
"part_restock_quantity": "Feltöltési mennyiség",
|
||||||
"part_auto_buy": "Vásárlási feladat automatikus létrehozása, ha kevés van",
|
"part_auto_buy": "Vásárlási feladat automatikus létrehozása, ha kevés van",
|
||||||
"part_restock": "Készlet módosítása",
|
"part_restock": "Készlet módosítása",
|
||||||
|
"parts_used_by": "Használja",
|
||||||
"restock_quantity_label": "Vásárolt mennyiség",
|
"restock_quantity_label": "Vásárolt mennyiség",
|
||||||
"consumes_parts_label": "Felhasznált alkatrészek",
|
"consumes_parts_label": "Felhasznált alkatrészek",
|
||||||
"shared_parts_other_objects": "Más objektumok alkatrészei",
|
"shared_parts_other_objects": "Más objektumok alkatrészei",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "érték az utolsó szerviznél (opcionális)",
|
"setups_baseline_hint": "érték az utolsó szerviznél (opcionális)",
|
||||||
"baseline_start_help_edit": "Üresen hagyva a meglévő számlálás marad. Érték megadása újrahorgonyozza a számlálást (pl. az utolsó szerviz leolvasott értéke).",
|
"baseline_start_help_edit": "Üresen hagyva a meglévő számlálás marad. Érték megadása újrahorgonyozza a számlálást (pl. az utolsó szerviz leolvasott értéke).",
|
||||||
"baseline_current_effective": "Jelenleg érvényes kezdőérték: {value}",
|
"baseline_current_effective": "Jelenleg érvényes kezdőérték: {value}",
|
||||||
"runtime_on_states": "Aktív állapotok (vesszővel elválasztva)",
|
"runtime_on_states": "Aktív állapotok",
|
||||||
"runtime_on_states_help": "Működésként számító állapotok — alapértelmezés: on. Pl. mowing, cleaning, printing. Attribútum kiválasztásakor annak értékei számítanak.",
|
"runtime_on_states_help": "Működésként számító állapotok — alapértelmezés: on. Pl. mowing, cleaning, printing. Attribútum kiválasztásakor annak értékei számítanak.",
|
||||||
"setups_target_new": "Új létrehozása: {name}",
|
"setups_target_new": "Új létrehozása: {name}",
|
||||||
"schedule_preview_title": "Következő dátumok",
|
"schedule_preview_title": "Következő dátumok",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Tipo",
|
"sort_type": "Tipo",
|
||||||
"sort_task_name": "Nome attività",
|
"sort_task_name": "Nome attività",
|
||||||
"all_objects": "Tutti gli oggetti",
|
"all_objects": "Tutti gli oggetti",
|
||||||
|
"all_parts": "Tutti i ricambi",
|
||||||
"tasks_lower": "attività",
|
"tasks_lower": "attività",
|
||||||
"no_tasks_yet": "Nessuna attività",
|
"no_tasks_yet": "Nessuna attività",
|
||||||
"add_first_task": "Aggiungi prima attività",
|
"add_first_task": "Aggiungi prima attività",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Quantità di riordino",
|
"part_restock_quantity": "Quantità di riordino",
|
||||||
"part_auto_buy": "Task d'acquisto se scarso",
|
"part_auto_buy": "Task d'acquisto se scarso",
|
||||||
"part_restock": "Correggi scorta",
|
"part_restock": "Correggi scorta",
|
||||||
|
"parts_used_by": "Usato da",
|
||||||
"restock_quantity_label": "Quantità acquistata",
|
"restock_quantity_label": "Quantità acquistata",
|
||||||
"consumes_parts_label": "Consuma ricambi",
|
"consumes_parts_label": "Consuma ricambi",
|
||||||
"shared_parts_other_objects": "Ricambi di altri oggetti",
|
"shared_parts_other_objects": "Ricambi di altri oggetti",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "lettura all'ultima manutenzione (facoltativo)",
|
"setups_baseline_hint": "lettura all'ultima manutenzione (facoltativo)",
|
||||||
"baseline_start_help_edit": "Lascia vuoto per mantenere il conteggio esistente. Un valore inserito riancora il conteggio (ad es. la lettura dell'ultima manutenzione).",
|
"baseline_start_help_edit": "Lascia vuoto per mantenere il conteggio esistente. Un valore inserito riancora il conteggio (ad es. la lettura dell'ultima manutenzione).",
|
||||||
"baseline_current_effective": "Valore iniziale attualmente in vigore: {value}",
|
"baseline_current_effective": "Valore iniziale attualmente in vigore: {value}",
|
||||||
"runtime_on_states": "Stati attivi (separati da virgole)",
|
"runtime_on_states": "Stati attivi",
|
||||||
"runtime_on_states_help": "Stati che contano come in funzione — predefinito: on. Ad es. mowing, cleaning, printing. Con un attributo selezionato vengono confrontati i suoi valori.",
|
"runtime_on_states_help": "Stati che contano come in funzione — predefinito: on. Ad es. mowing, cleaning, printing. Con un attributo selezionato vengono confrontati i suoi valori.",
|
||||||
"setups_target_new": "Crea nuovo: {name}",
|
"setups_target_new": "Crea nuovo: {name}",
|
||||||
"schedule_preview_title": "Prossime date",
|
"schedule_preview_title": "Prossime date",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "種別",
|
"sort_type": "種別",
|
||||||
"sort_task_name": "タスク名",
|
"sort_task_name": "タスク名",
|
||||||
"all_objects": "すべての対象",
|
"all_objects": "すべての対象",
|
||||||
|
"all_parts": "すべての部品",
|
||||||
"tasks_lower": "タスク",
|
"tasks_lower": "タスク",
|
||||||
"no_tasks_yet": "タスクがまだありません",
|
"no_tasks_yet": "タスクがまだありません",
|
||||||
"add_first_task": "最初のタスクを追加",
|
"add_first_task": "最初のタスクを追加",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "補充数量",
|
"part_restock_quantity": "補充数量",
|
||||||
"part_auto_buy": "在庫少で購入タスク",
|
"part_auto_buy": "在庫少で購入タスク",
|
||||||
"part_restock": "在庫を調整",
|
"part_restock": "在庫を調整",
|
||||||
|
"parts_used_by": "使用タスク",
|
||||||
"restock_quantity_label": "購入数量",
|
"restock_quantity_label": "購入数量",
|
||||||
"consumes_parts_label": "部品を消費",
|
"consumes_parts_label": "部品を消費",
|
||||||
"shared_parts_other_objects": "他の対象の部品",
|
"shared_parts_other_objects": "他の対象の部品",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "前回整備時の値(任意)",
|
"setups_baseline_hint": "前回整備時の値(任意)",
|
||||||
"baseline_start_help_edit": "空欄のままにすると現在のカウントを維持します。値を入力するとカウントの起点を再設定します(例:前回整備時の値)。",
|
"baseline_start_help_edit": "空欄のままにすると現在のカウントを維持します。値を入力するとカウントの起点を再設定します(例:前回整備時の値)。",
|
||||||
"baseline_current_effective": "現在有効な開始値:{value}",
|
"baseline_current_effective": "現在有効な開始値:{value}",
|
||||||
"runtime_on_states": "稼働中とみなす状態(カンマ区切り)",
|
"runtime_on_states": "稼働中とみなす状態",
|
||||||
"runtime_on_states_help": "稼働時間として数える状態 — 既定値:on。例:mowing, cleaning, printing。属性を選択している場合はその値が比較されます。",
|
"runtime_on_states_help": "稼働時間として数える状態 — 既定値:on。例:mowing, cleaning, printing。属性を選択している場合はその値が比較されます。",
|
||||||
"setups_target_new": "新規作成:{name}",
|
"setups_target_new": "新規作成:{name}",
|
||||||
"schedule_preview_title": "次回の予定日",
|
"schedule_preview_title": "次回の予定日",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "유형",
|
"sort_type": "유형",
|
||||||
"sort_task_name": "작업 이름",
|
"sort_task_name": "작업 이름",
|
||||||
"all_objects": "모든 객체",
|
"all_objects": "모든 객체",
|
||||||
|
"all_parts": "모든 부품",
|
||||||
"tasks_lower": "작업",
|
"tasks_lower": "작업",
|
||||||
"no_tasks_yet": "아직 작업 없음",
|
"no_tasks_yet": "아직 작업 없음",
|
||||||
"add_first_task": "첫 작업 추가",
|
"add_first_task": "첫 작업 추가",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "보충 수량",
|
"part_restock_quantity": "보충 수량",
|
||||||
"part_auto_buy": "재고 부족 시 구매 작업 자동 생성",
|
"part_auto_buy": "재고 부족 시 구매 작업 자동 생성",
|
||||||
"part_restock": "재고 조정",
|
"part_restock": "재고 조정",
|
||||||
|
"parts_used_by": "사용처",
|
||||||
"restock_quantity_label": "구매 수량",
|
"restock_quantity_label": "구매 수량",
|
||||||
"consumes_parts_label": "사용하는 부품",
|
"consumes_parts_label": "사용하는 부품",
|
||||||
"shared_parts_other_objects": "다른 객체의 부품",
|
"shared_parts_other_objects": "다른 객체의 부품",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "마지막 정비 시점의 값 (선택)",
|
"setups_baseline_hint": "마지막 정비 시점의 값 (선택)",
|
||||||
"baseline_start_help_edit": "비워두면 기존 계수를 유지합니다. 값을 입력하면 계수 기준이 다시 설정됩니다 (예: 마지막 정비 시점의 값).",
|
"baseline_start_help_edit": "비워두면 기존 계수를 유지합니다. 값을 입력하면 계수 기준이 다시 설정됩니다 (예: 마지막 정비 시점의 값).",
|
||||||
"baseline_current_effective": "현재 적용 중인 시작 값: {value}",
|
"baseline_current_effective": "현재 적용 중인 시작 값: {value}",
|
||||||
"runtime_on_states": "활성 상태 (쉼표로 구분)",
|
"runtime_on_states": "활성 상태",
|
||||||
"runtime_on_states_help": "가동 중으로 계산할 상태입니다 — 기본값: on. 예: mowing, cleaning, printing. 속성을 선택한 경우 해당 속성 값과 비교합니다.",
|
"runtime_on_states_help": "가동 중으로 계산할 상태입니다 — 기본값: on. 예: mowing, cleaning, printing. 속성을 선택한 경우 해당 속성 값과 비교합니다.",
|
||||||
"setups_target_new": "새로 만들기: {name}",
|
"setups_target_new": "새로 만들기: {name}",
|
||||||
"schedule_preview_title": "다음 예정일",
|
"schedule_preview_title": "다음 예정일",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Oppgavenavn",
|
"sort_task_name": "Oppgavenavn",
|
||||||
"all_objects": "Alle objekter",
|
"all_objects": "Alle objekter",
|
||||||
|
"all_parts": "Alle deler",
|
||||||
"tasks_lower": "oppgaver",
|
"tasks_lower": "oppgaver",
|
||||||
"no_tasks_yet": "Ingen oppgaver ennå",
|
"no_tasks_yet": "Ingen oppgaver ennå",
|
||||||
"add_first_task": "Legg til første oppgave",
|
"add_first_task": "Legg til første oppgave",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Påfyllingsmengde",
|
"part_restock_quantity": "Påfyllingsmengde",
|
||||||
"part_auto_buy": "Kjøpsoppgave ved lavt lager",
|
"part_auto_buy": "Kjøpsoppgave ved lavt lager",
|
||||||
"part_restock": "Juster lager",
|
"part_restock": "Juster lager",
|
||||||
|
"parts_used_by": "Brukes av",
|
||||||
"restock_quantity_label": "Kjøpt mengde",
|
"restock_quantity_label": "Kjøpt mengde",
|
||||||
"consumes_parts_label": "Forbruker deler",
|
"consumes_parts_label": "Forbruker deler",
|
||||||
"shared_parts_other_objects": "Deler fra andre objekter",
|
"shared_parts_other_objects": "Deler fra andre objekter",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "avlesning ved forrige service (valgfritt)",
|
"setups_baseline_hint": "avlesning ved forrige service (valgfritt)",
|
||||||
"baseline_start_help_edit": "La stå tomt for å beholde den eksisterende tellingen. En angitt verdi forankrer tellingen på nytt (f.eks. avlesningen ved forrige service).",
|
"baseline_start_help_edit": "La stå tomt for å beholde den eksisterende tellingen. En angitt verdi forankrer tellingen på nytt (f.eks. avlesningen ved forrige service).",
|
||||||
"baseline_current_effective": "Gjeldende startverdi: {value}",
|
"baseline_current_effective": "Gjeldende startverdi: {value}",
|
||||||
"runtime_on_states": "Aktive tilstander (kommaseparert)",
|
"runtime_on_states": "Aktive tilstander",
|
||||||
"runtime_on_states_help": "Tilstander som teller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med et valgt attributt sammenlignes verdiene dets i stedet.",
|
"runtime_on_states_help": "Tilstander som teller som driftstid — standard: on. F.eks. mowing, cleaning, printing. Med et valgt attributt sammenlignes verdiene dets i stedet.",
|
||||||
"setups_target_new": "Opprett ny: {name}",
|
"setups_target_new": "Opprett ny: {name}",
|
||||||
"schedule_preview_title": "Kommende datoer",
|
"schedule_preview_title": "Kommende datoer",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Type",
|
"sort_type": "Type",
|
||||||
"sort_task_name": "Taaknaam",
|
"sort_task_name": "Taaknaam",
|
||||||
"all_objects": "Alle objecten",
|
"all_objects": "Alle objecten",
|
||||||
|
"all_parts": "Alle onderdelen",
|
||||||
"tasks_lower": "taken",
|
"tasks_lower": "taken",
|
||||||
"no_tasks_yet": "Nog geen taken",
|
"no_tasks_yet": "Nog geen taken",
|
||||||
"add_first_task": "Eerste taak toevoegen",
|
"add_first_task": "Eerste taak toevoegen",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Aanvulhoeveelheid",
|
"part_restock_quantity": "Aanvulhoeveelheid",
|
||||||
"part_auto_buy": "Kooptaak bij lage voorraad",
|
"part_auto_buy": "Kooptaak bij lage voorraad",
|
||||||
"part_restock": "Voorraad aanpassen",
|
"part_restock": "Voorraad aanpassen",
|
||||||
|
"parts_used_by": "Gebruikt door",
|
||||||
"restock_quantity_label": "Gekochte hoeveelheid",
|
"restock_quantity_label": "Gekochte hoeveelheid",
|
||||||
"consumes_parts_label": "Verbruikt onderdelen",
|
"consumes_parts_label": "Verbruikt onderdelen",
|
||||||
"shared_parts_other_objects": "Onderdelen van andere objecten",
|
"shared_parts_other_objects": "Onderdelen van andere objecten",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "stand bij laatste onderhoud (optioneel)",
|
"setups_baseline_hint": "stand bij laatste onderhoud (optioneel)",
|
||||||
"baseline_start_help_edit": "Laat leeg om de bestaande telling te behouden. Een ingevulde waarde verankert de telling opnieuw (bijv. de stand bij de laatste servicebeurt).",
|
"baseline_start_help_edit": "Laat leeg om de bestaande telling te behouden. Een ingevulde waarde verankert de telling opnieuw (bijv. de stand bij de laatste servicebeurt).",
|
||||||
"baseline_current_effective": "Momenteel geldende startwaarde: {value}",
|
"baseline_current_effective": "Momenteel geldende startwaarde: {value}",
|
||||||
"runtime_on_states": "Actieve statussen (kommagescheiden)",
|
"runtime_on_states": "Actieve statussen",
|
||||||
"runtime_on_states_help": "Statussen die als draaitijd tellen — standaard: on. Bijv. mowing, cleaning, printing. Met een geselecteerd attribuut worden de waarden daarvan vergeleken.",
|
"runtime_on_states_help": "Statussen die als draaitijd tellen — standaard: on. Bijv. mowing, cleaning, printing. Met een geselecteerd attribuut worden de waarden daarvan vergeleken.",
|
||||||
"setups_target_new": "Nieuw aanmaken: {name}",
|
"setups_target_new": "Nieuw aanmaken: {name}",
|
||||||
"schedule_preview_title": "Volgende data",
|
"schedule_preview_title": "Volgende data",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Typ",
|
"sort_type": "Typ",
|
||||||
"sort_task_name": "Nazwa zadania",
|
"sort_task_name": "Nazwa zadania",
|
||||||
"all_objects": "Wszystkie obiekty",
|
"all_objects": "Wszystkie obiekty",
|
||||||
|
"all_parts": "Wszystkie części",
|
||||||
"tasks_lower": "zadań",
|
"tasks_lower": "zadań",
|
||||||
"no_tasks_yet": "Jeszcze brak zadań",
|
"no_tasks_yet": "Jeszcze brak zadań",
|
||||||
"add_first_task": "Dodaj pierwsze zadanie",
|
"add_first_task": "Dodaj pierwsze zadanie",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Ilość uzupełnienia",
|
"part_restock_quantity": "Ilość uzupełnienia",
|
||||||
"part_auto_buy": "Zadanie zakupu przy niskim stanie",
|
"part_auto_buy": "Zadanie zakupu przy niskim stanie",
|
||||||
"part_restock": "Koryguj stan",
|
"part_restock": "Koryguj stan",
|
||||||
|
"parts_used_by": "Używane przez",
|
||||||
"restock_quantity_label": "Kupiona ilość",
|
"restock_quantity_label": "Kupiona ilość",
|
||||||
"consumes_parts_label": "Zużywa części",
|
"consumes_parts_label": "Zużywa części",
|
||||||
"shared_parts_other_objects": "Części z innych obiektów",
|
"shared_parts_other_objects": "Części z innych obiektów",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "stan przy ostatnim serwisie (opcjonalnie)",
|
"setups_baseline_hint": "stan przy ostatnim serwisie (opcjonalnie)",
|
||||||
"baseline_start_help_edit": "Pozostaw puste, aby zachować dotychczasowe liczenie. Wpisana wartość zakotwicza liczenie na nowo (np. stan przy ostatnim serwisie).",
|
"baseline_start_help_edit": "Pozostaw puste, aby zachować dotychczasowe liczenie. Wpisana wartość zakotwicza liczenie na nowo (np. stan przy ostatnim serwisie).",
|
||||||
"baseline_current_effective": "Obecnie obowiązująca wartość początkowa: {value}",
|
"baseline_current_effective": "Obecnie obowiązująca wartość początkowa: {value}",
|
||||||
"runtime_on_states": "Stany aktywne (rozdzielone przecinkami)",
|
"runtime_on_states": "Stany aktywne",
|
||||||
"runtime_on_states_help": "Stany liczone jako czas pracy — domyślnie: on. Np. mowing, cleaning, printing. Przy wybranym atrybucie porównywane są jego wartości.",
|
"runtime_on_states_help": "Stany liczone jako czas pracy — domyślnie: on. Np. mowing, cleaning, printing. Przy wybranym atrybucie porównywane są jego wartości.",
|
||||||
"setups_target_new": "Utwórz nowy: {name}",
|
"setups_target_new": "Utwórz nowy: {name}",
|
||||||
"schedule_preview_title": "Najbliższe terminy",
|
"schedule_preview_title": "Najbliższe terminy",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Tipo",
|
"sort_type": "Tipo",
|
||||||
"sort_task_name": "Nome da tarefa",
|
"sort_task_name": "Nome da tarefa",
|
||||||
"all_objects": "Todos os objetos",
|
"all_objects": "Todos os objetos",
|
||||||
|
"all_parts": "Todas as peças",
|
||||||
"tasks_lower": "tarefas",
|
"tasks_lower": "tarefas",
|
||||||
"no_tasks_yet": "Ainda sem tarefas",
|
"no_tasks_yet": "Ainda sem tarefas",
|
||||||
"add_first_task": "Adicionar a primeira tarefa",
|
"add_first_task": "Adicionar a primeira tarefa",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "Quantidade de reposição",
|
"part_restock_quantity": "Quantidade de reposição",
|
||||||
"part_auto_buy": "Criar tarefa de compra automaticamente quando estiver baixo",
|
"part_auto_buy": "Criar tarefa de compra automaticamente quando estiver baixo",
|
||||||
"part_restock": "Ajustar estoque",
|
"part_restock": "Ajustar estoque",
|
||||||
|
"parts_used_by": "Usado por",
|
||||||
"restock_quantity_label": "Quantidade comprada",
|
"restock_quantity_label": "Quantidade comprada",
|
||||||
"consumes_parts_label": "Consome peças",
|
"consumes_parts_label": "Consome peças",
|
||||||
"shared_parts_other_objects": "Peças de outros objetos",
|
"shared_parts_other_objects": "Peças de outros objetos",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
||||||
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Informar um valor reancora a contagem (ex.: a leitura da última manutenção).",
|
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Informar um valor reancora a contagem (ex.: a leitura da última manutenção).",
|
||||||
"baseline_current_effective": "Valor inicial efetivo atual: {value}",
|
"baseline_current_effective": "Valor inicial efetivo atual: {value}",
|
||||||
"runtime_on_states": "Estados ativos (separados por vírgula)",
|
"runtime_on_states": "Estados ativos",
|
||||||
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. Ex.: mowing, cleaning, printing. Com um atributo selecionado, os valores dele são comparados.",
|
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. Ex.: mowing, cleaning, printing. Com um atributo selecionado, os valores dele são comparados.",
|
||||||
"setups_target_new": "Criar novo: {name}",
|
"setups_target_new": "Criar novo: {name}",
|
||||||
"schedule_preview_title": "Próximas datas",
|
"schedule_preview_title": "Próximas datas",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Tipo",
|
"sort_type": "Tipo",
|
||||||
"sort_task_name": "Nome da tarefa",
|
"sort_task_name": "Nome da tarefa",
|
||||||
"all_objects": "Todos os objetos",
|
"all_objects": "Todos os objetos",
|
||||||
|
"all_parts": "Todas as peças",
|
||||||
"tasks_lower": "tarefas",
|
"tasks_lower": "tarefas",
|
||||||
"no_tasks_yet": "Ainda sem tarefas",
|
"no_tasks_yet": "Ainda sem tarefas",
|
||||||
"add_first_task": "Adicionar primeira tarefa",
|
"add_first_task": "Adicionar primeira tarefa",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Quantidade de reposição",
|
"part_restock_quantity": "Quantidade de reposição",
|
||||||
"part_auto_buy": "Tarefa de compra se baixo",
|
"part_auto_buy": "Tarefa de compra se baixo",
|
||||||
"part_restock": "Ajustar estoque",
|
"part_restock": "Ajustar estoque",
|
||||||
|
"parts_used_by": "Usado por",
|
||||||
"restock_quantity_label": "Quantidade comprada",
|
"restock_quantity_label": "Quantidade comprada",
|
||||||
"consumes_parts_label": "Consome peças",
|
"consumes_parts_label": "Consome peças",
|
||||||
"shared_parts_other_objects": "Peças de outros objetos",
|
"shared_parts_other_objects": "Peças de outros objetos",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
"setups_baseline_hint": "leitura na última manutenção (opcional)",
|
||||||
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Um valor introduzido reancora a contagem (p. ex., a leitura da última manutenção).",
|
"baseline_start_help_edit": "Deixe vazio para manter a contagem existente. Um valor introduzido reancora a contagem (p. ex., a leitura da última manutenção).",
|
||||||
"baseline_current_effective": "Valor inicial atualmente em vigor: {value}",
|
"baseline_current_effective": "Valor inicial atualmente em vigor: {value}",
|
||||||
"runtime_on_states": "Estados ativos (separados por vírgulas)",
|
"runtime_on_states": "Estados ativos",
|
||||||
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. P. ex. mowing, cleaning, printing. Com um atributo selecionado, são comparados os valores dele.",
|
"runtime_on_states_help": "Estados que contam como em funcionamento — padrão: on. P. ex. mowing, cleaning, printing. Com um atributo selecionado, são comparados os valores dele.",
|
||||||
"setups_target_new": "Criar novo: {name}",
|
"setups_target_new": "Criar novo: {name}",
|
||||||
"schedule_preview_title": "Próximas datas",
|
"schedule_preview_title": "Próximas datas",
|
||||||
|
|||||||
@@ -176,6 +176,7 @@
|
|||||||
"sort_type": "Тип",
|
"sort_type": "Тип",
|
||||||
"sort_task_name": "Имя задачи",
|
"sort_task_name": "Имя задачи",
|
||||||
"all_objects": "Все объекты",
|
"all_objects": "Все объекты",
|
||||||
|
"all_parts": "Все детали",
|
||||||
"tasks_lower": "задач",
|
"tasks_lower": "задач",
|
||||||
"no_tasks_yet": "Пока нет задач",
|
"no_tasks_yet": "Пока нет задач",
|
||||||
"add_first_task": "Добавить первую задачу",
|
"add_first_task": "Добавить первую задачу",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Количество пополнения",
|
"part_restock_quantity": "Количество пополнения",
|
||||||
"part_auto_buy": "Задача покупки при малом запасе",
|
"part_auto_buy": "Задача покупки при малом запасе",
|
||||||
"part_restock": "Изменить запас",
|
"part_restock": "Изменить запас",
|
||||||
|
"parts_used_by": "Используется",
|
||||||
"restock_quantity_label": "Куплено, шт.",
|
"restock_quantity_label": "Куплено, шт.",
|
||||||
"consumes_parts_label": "Расходует детали",
|
"consumes_parts_label": "Расходует детали",
|
||||||
"shared_parts_other_objects": "Детали других объектов",
|
"shared_parts_other_objects": "Детали других объектов",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "показание при последнем обслуживании (необязательно)",
|
"setups_baseline_hint": "показание при последнем обслуживании (необязательно)",
|
||||||
"baseline_start_help_edit": "Оставьте пустым, чтобы сохранить текущий отсчёт. Введённое значение заново привязывает отсчёт (например, показание при последнем обслуживании).",
|
"baseline_start_help_edit": "Оставьте пустым, чтобы сохранить текущий отсчёт. Введённое значение заново привязывает отсчёт (например, показание при последнем обслуживании).",
|
||||||
"baseline_current_effective": "Действующее начальное значение: {value}",
|
"baseline_current_effective": "Действующее начальное значение: {value}",
|
||||||
"runtime_on_states": "Активные состояния (через запятую)",
|
"runtime_on_states": "Активные состояния",
|
||||||
"runtime_on_states_help": "Состояния, засчитываемые как работа — по умолчанию: on. Напр. mowing, cleaning, printing. Если выбран атрибут, сравниваются его значения.",
|
"runtime_on_states_help": "Состояния, засчитываемые как работа — по умолчанию: on. Напр. mowing, cleaning, printing. Если выбран атрибут, сравниваются его значения.",
|
||||||
"setups_target_new": "Создать новый: {name}",
|
"setups_target_new": "Создать новый: {name}",
|
||||||
"schedule_preview_title": "Ближайшие даты",
|
"schedule_preview_title": "Ближайшие даты",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Typ",
|
"sort_type": "Typ",
|
||||||
"sort_task_name": "Uppgiftsnamn",
|
"sort_task_name": "Uppgiftsnamn",
|
||||||
"all_objects": "Alla objekt",
|
"all_objects": "Alla objekt",
|
||||||
|
"all_parts": "Alla delar",
|
||||||
"tasks_lower": "uppgifter",
|
"tasks_lower": "uppgifter",
|
||||||
"no_tasks_yet": "Inga uppgifter ännu",
|
"no_tasks_yet": "Inga uppgifter ännu",
|
||||||
"add_first_task": "Lägg till första uppgift",
|
"add_first_task": "Lägg till första uppgift",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Påfyllningsantal",
|
"part_restock_quantity": "Påfyllningsantal",
|
||||||
"part_auto_buy": "Köpuppgift vid lågt lager",
|
"part_auto_buy": "Köpuppgift vid lågt lager",
|
||||||
"part_restock": "Justera lager",
|
"part_restock": "Justera lager",
|
||||||
|
"parts_used_by": "Används av",
|
||||||
"restock_quantity_label": "Köpt antal",
|
"restock_quantity_label": "Köpt antal",
|
||||||
"consumes_parts_label": "Förbrukar delar",
|
"consumes_parts_label": "Förbrukar delar",
|
||||||
"shared_parts_other_objects": "Delar från andra objekt",
|
"shared_parts_other_objects": "Delar från andra objekt",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "mätarställning vid senaste service (valfritt)",
|
"setups_baseline_hint": "mätarställning vid senaste service (valfritt)",
|
||||||
"baseline_start_help_edit": "Lämna tomt för att behålla den befintliga räkningen. Ett angivet värde förankrar räkningen på nytt (t.ex. mätarställningen vid senaste servicen).",
|
"baseline_start_help_edit": "Lämna tomt för att behålla den befintliga räkningen. Ett angivet värde förankrar räkningen på nytt (t.ex. mätarställningen vid senaste servicen).",
|
||||||
"baseline_current_effective": "Nu gällande startvärde: {value}",
|
"baseline_current_effective": "Nu gällande startvärde: {value}",
|
||||||
"runtime_on_states": "Aktiva tillstånd (kommaseparerade)",
|
"runtime_on_states": "Aktiva tillstånd",
|
||||||
"runtime_on_states_help": "Tillstånd som räknas som drifttid — standard: on. T.ex. mowing, cleaning, printing. Med ett valt attribut jämförs dess värden i stället.",
|
"runtime_on_states_help": "Tillstånd som räknas som drifttid — standard: on. T.ex. mowing, cleaning, printing. Med ett valt attribut jämförs dess värden i stället.",
|
||||||
"setups_target_new": "Skapa ny: {name}",
|
"setups_target_new": "Skapa ny: {name}",
|
||||||
"schedule_preview_title": "Kommande datum",
|
"schedule_preview_title": "Kommande datum",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "Tür",
|
"sort_type": "Tür",
|
||||||
"sort_task_name": "Görev adı",
|
"sort_task_name": "Görev adı",
|
||||||
"all_objects": "Tüm nesneler",
|
"all_objects": "Tüm nesneler",
|
||||||
|
"all_parts": "Tüm parçalar",
|
||||||
"tasks_lower": "görev",
|
"tasks_lower": "görev",
|
||||||
"no_tasks_yet": "Henüz görev yok",
|
"no_tasks_yet": "Henüz görev yok",
|
||||||
"add_first_task": "İlk görevi ekle",
|
"add_first_task": "İlk görevi ekle",
|
||||||
@@ -742,6 +743,7 @@
|
|||||||
"part_restock_quantity": "Stok yenileme miktarı",
|
"part_restock_quantity": "Stok yenileme miktarı",
|
||||||
"part_auto_buy": "Azaldığında otomatik satın alma görevi oluştur",
|
"part_auto_buy": "Azaldığında otomatik satın alma görevi oluştur",
|
||||||
"part_restock": "Stoku ayarla",
|
"part_restock": "Stoku ayarla",
|
||||||
|
"parts_used_by": "Kullanan",
|
||||||
"restock_quantity_label": "Satın alınan miktar",
|
"restock_quantity_label": "Satın alınan miktar",
|
||||||
"consumes_parts_label": "Parça tüketir",
|
"consumes_parts_label": "Parça tüketir",
|
||||||
"shared_parts_other_objects": "Diğer nesnelerin parçaları",
|
"shared_parts_other_objects": "Diğer nesnelerin parçaları",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "son servisteki okuma (isteğe bağlı)",
|
"setups_baseline_hint": "son servisteki okuma (isteğe bağlı)",
|
||||||
"baseline_start_help_edit": "Mevcut sayımı korumak için boş bırakın. Bir değer girmek sayımı yeniden sabitler (örn. son servisteki okuma).",
|
"baseline_start_help_edit": "Mevcut sayımı korumak için boş bırakın. Bir değer girmek sayımı yeniden sabitler (örn. son servisteki okuma).",
|
||||||
"baseline_current_effective": "Şu anda geçerli başlangıç değeri: {value}",
|
"baseline_current_effective": "Şu anda geçerli başlangıç değeri: {value}",
|
||||||
"runtime_on_states": "Etkin durumlar (virgülle ayrılmış)",
|
"runtime_on_states": "Etkin durumlar",
|
||||||
"runtime_on_states_help": "Çalışıyor sayılan durumlar — varsayılan: on. Örn. mowing, cleaning, printing. Bir öznitelik seçiliyse onun değerleri eşleştirilir.",
|
"runtime_on_states_help": "Çalışıyor sayılan durumlar — varsayılan: on. Örn. mowing, cleaning, printing. Bir öznitelik seçiliyse onun değerleri eşleştirilir.",
|
||||||
"setups_target_new": "Yeni oluştur: {name}",
|
"setups_target_new": "Yeni oluştur: {name}",
|
||||||
"schedule_preview_title": "Sonraki tarihler",
|
"schedule_preview_title": "Sonraki tarihler",
|
||||||
|
|||||||
@@ -177,6 +177,7 @@
|
|||||||
"sort_type": "Тип",
|
"sort_type": "Тип",
|
||||||
"sort_task_name": "Назва завдання",
|
"sort_task_name": "Назва завдання",
|
||||||
"all_objects": "Всі об'єкти",
|
"all_objects": "Всі об'єкти",
|
||||||
|
"all_parts": "Усі деталі",
|
||||||
"tasks_lower": "завдань",
|
"tasks_lower": "завдань",
|
||||||
"no_tasks_yet": "Завдань ще немає",
|
"no_tasks_yet": "Завдань ще немає",
|
||||||
"add_first_task": "Додати перше завдання",
|
"add_first_task": "Додати перше завдання",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "Кількість поповнення",
|
"part_restock_quantity": "Кількість поповнення",
|
||||||
"part_auto_buy": "Завдання купівлі при малому запасі",
|
"part_auto_buy": "Завдання купівлі при малому запасі",
|
||||||
"part_restock": "Змінити запас",
|
"part_restock": "Змінити запас",
|
||||||
|
"parts_used_by": "Використовується",
|
||||||
"restock_quantity_label": "Куплена кількість",
|
"restock_quantity_label": "Куплена кількість",
|
||||||
"consumes_parts_label": "Витрачає деталі",
|
"consumes_parts_label": "Витрачає деталі",
|
||||||
"shared_parts_other_objects": "Деталі інших об'єктів",
|
"shared_parts_other_objects": "Деталі інших об'єктів",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "показання під час останнього обслуговування (необов'язково)",
|
"setups_baseline_hint": "показання під час останнього обслуговування (необов'язково)",
|
||||||
"baseline_start_help_edit": "Залиште порожнім, щоб зберегти поточний відлік. Введене значення заново прив'язує відлік (наприклад, показання під час останнього обслуговування).",
|
"baseline_start_help_edit": "Залиште порожнім, щоб зберегти поточний відлік. Введене значення заново прив'язує відлік (наприклад, показання під час останнього обслуговування).",
|
||||||
"baseline_current_effective": "Чинне початкове значення: {value}",
|
"baseline_current_effective": "Чинне початкове значення: {value}",
|
||||||
"runtime_on_states": "Активні стани (через кому)",
|
"runtime_on_states": "Активні стани",
|
||||||
"runtime_on_states_help": "Стани, що зараховуються як робота — типово: on. Напр. mowing, cleaning, printing. Якщо вибрано атрибут, порівнюються його значення.",
|
"runtime_on_states_help": "Стани, що зараховуються як робота — типово: on. Напр. mowing, cleaning, printing. Якщо вибрано атрибут, порівнюються його значення.",
|
||||||
"setups_target_new": "Створити новий: {name}",
|
"setups_target_new": "Створити новий: {name}",
|
||||||
"schedule_preview_title": "Найближчі дати",
|
"schedule_preview_title": "Найближчі дати",
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
"sort_type": "类型",
|
"sort_type": "类型",
|
||||||
"sort_task_name": "任务名称",
|
"sort_task_name": "任务名称",
|
||||||
"all_objects": "所有维护项",
|
"all_objects": "所有维护项",
|
||||||
|
"all_parts": "所有配件",
|
||||||
"tasks_lower": "任务",
|
"tasks_lower": "任务",
|
||||||
"no_tasks_yet": "尚无任务",
|
"no_tasks_yet": "尚无任务",
|
||||||
"add_first_task": "添加首个任务",
|
"add_first_task": "添加首个任务",
|
||||||
@@ -736,6 +737,7 @@
|
|||||||
"part_restock_quantity": "补货数量",
|
"part_restock_quantity": "补货数量",
|
||||||
"part_auto_buy": "库存低时自动建购买任务",
|
"part_auto_buy": "库存低时自动建购买任务",
|
||||||
"part_restock": "调整库存",
|
"part_restock": "调整库存",
|
||||||
|
"parts_used_by": "使用于",
|
||||||
"restock_quantity_label": "购买数量",
|
"restock_quantity_label": "购买数量",
|
||||||
"consumes_parts_label": "消耗配件",
|
"consumes_parts_label": "消耗配件",
|
||||||
"shared_parts_other_objects": "其他设备的配件",
|
"shared_parts_other_objects": "其他设备的配件",
|
||||||
@@ -800,7 +802,7 @@
|
|||||||
"setups_baseline_hint": "上次保养时的读数(可选)",
|
"setups_baseline_hint": "上次保养时的读数(可选)",
|
||||||
"baseline_start_help_edit": "留空以保留现有计数。填写数值会重新锚定计数(例如上次保养时的读数)。",
|
"baseline_start_help_edit": "留空以保留现有计数。填写数值会重新锚定计数(例如上次保养时的读数)。",
|
||||||
"baseline_current_effective": "当前生效的起始读数:{value}",
|
"baseline_current_effective": "当前生效的起始读数:{value}",
|
||||||
"runtime_on_states": "活动状态(逗号分隔)",
|
"runtime_on_states": "活动状态",
|
||||||
"runtime_on_states_help": "计入运行时间的状态 — 默认:on。例如 mowing、cleaning、printing。选择了属性时将比较该属性的值。",
|
"runtime_on_states_help": "计入运行时间的状态 — 默认:on。例如 mowing、cleaning、printing。选择了属性时将比较该属性的值。",
|
||||||
"setups_target_new": "新建:{name}",
|
"setups_target_new": "新建:{name}",
|
||||||
"schedule_preview_title": "下次日期",
|
"schedule_preview_title": "下次日期",
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
var S="2.56.0";var l="maintenance-supporter",T=`ll-strategy-dashboard-${l}`,D="hui-maintenance-supporter-strategy-editor",C=`/maintenance_supporter_strategy/maintenance-dashboard-strategy.js?v=${S}`,m=null;function v(){return m||(m=import(C)),m}async function I(){let r=await v();if(!r.MaintenanceDashboardStrategy)throw new Error("[maintenance-supporter] strategy bundle loaded but did not export MaintenanceDashboardStrategy");return r.MaintenanceDashboardStrategy}var p=class extends HTMLElement{static getCreateSuggestions(c){return{title:"Maintenance Supporter",icon:"mdi:wrench-clock"}}static async getConfigElement(){return await v(),document.createElement(D)}static async generate(c,f){return(await I()).generate(c,f)}};function M(){try{customElements.define(T,p)}catch{}}M();var w=window;w.customStrategies=w.customStrategies||[];w.customStrategies.some(r=>r.type===l&&r.strategyType==="dashboard")||w.customStrategies.push({type:l,strategyType:"dashboard",name:"Maintenance Supporter",description:"Auto-generated dashboard. Group views by area, status, floor, or due date \u2014 picked from the strategy editor or YAML.",documentationURL:"https://github.com/iluebbe/maintenance_supporter#dashboard-strategy"});(()=>{let r=window;if(r.__msStrategyHealActive)return;r.__msStrategyHealActive=!0;let c=/^\/(auth|config|developer-tools|profile|hassio|history|logbook|map|media-browser|energy|todo|calendar)\b/,f=/Timeout waiting for strategy element ll-strategy-(dashboard-)?maintenance-supporter/i,g=`custom:${l}`;function R(a){let t=[document.documentElement],n=0;for(;t.length&&n<9e3;){let o=t.pop();if(n++,!o)continue;let e=o;if(e.nodeType===1&&e.tagName&&e.tagName.toLowerCase()===a)return e;e.shadowRoot&&t.push(e.shadowRoot);let i=o.children;if(i)for(let d of Array.from(i))t.push(d)}return null}function k(a){let t=a?.views;if(!Array.isArray(t)||!t.length)return null;let n=window.location.pathname.split("/").filter(Boolean).pop()||"",o=t.find(i=>i?.path===n);if(o)return o;let e=Number(n);return Number.isInteger(e)&&t[e]?t[e]:t[0]}function b(){try{let t=R("ha-panel-lovelace")?.lovelace;if(!t)return!1;let n=o=>o?.type;for(let o of[t.config,t.rawConfig]){if(!o)continue;if(n(o.strategy)===g)return!0;let e=k(o);if(e&&n(e.strategy)===g)return!0}return!1}catch{return!1}}function A(){let a=!1,t=0,n=!1,o=!1,e=[document.documentElement],i=0;for(;e.length&&i<9e3;){let d=e.pop();if(i++,!d)continue;let u=d;if(u.nodeType===1&&u.tagName){let s=u.tagName.toLowerCase();(s==="hui-view"||s==="hui-sections-view")&&(a=!0),(s==="ha-card"||s==="hui-card")&&t++,s==="hui-empty-state-card"&&(o=!0),s==="hui-error-card"&&f.test(u.textContent||"")&&(n=!0)}u.shadowRoot&&e.push(u.shadowRoot);let E=d.children;if(E)for(let s of Array.from(E))e.push(s)}return n?!0:o?!1:a&&t<3&&b()}let N="/maintenance_supporter_strategy_shim.js",y=0,_=0;function L(){let a=Date.now();a-_<5e3||y>=3||(_=a,y+=1,import(`${N}?heal=${a}`).catch(()=>{}).finally(()=>{let t=window.location.pathname+window.location.search;history.pushState(null,"","/lovelace"),window.dispatchEvent(new CustomEvent("location-changed")),window.setTimeout(()=>{history.pushState(null,"",t),window.dispatchEvent(new CustomEvent("location-changed"))},200)}))}function h(){if(c.test(window.location.pathname))return;let a=0,t=Date.now(),n=window.setInterval(()=>{a++;try{if(Date.now()-t<6e3)return;if(c.test(window.location.pathname)){window.clearInterval(n);return}A()?L():window.clearInterval(n),a>=30&&window.clearInterval(n)}catch{window.clearInterval(n)}},500)}try{document.readyState==="loading"?window.addEventListener("DOMContentLoaded",h):h(),window.addEventListener("location-changed",()=>{c.test(window.location.pathname)||h()})}catch{}})();
|
var S="2.57.0";var l="maintenance-supporter",T=`ll-strategy-dashboard-${l}`,D="hui-maintenance-supporter-strategy-editor",C=`/maintenance_supporter_strategy/maintenance-dashboard-strategy.js?v=${S}`,m=null;function v(){return m||(m=import(C)),m}async function I(){let r=await v();if(!r.MaintenanceDashboardStrategy)throw new Error("[maintenance-supporter] strategy bundle loaded but did not export MaintenanceDashboardStrategy");return r.MaintenanceDashboardStrategy}var p=class extends HTMLElement{static getCreateSuggestions(c){return{title:"Maintenance Supporter",icon:"mdi:wrench-clock"}}static async getConfigElement(){return await v(),document.createElement(D)}static async generate(c,f){return(await I()).generate(c,f)}};function M(){try{customElements.define(T,p)}catch{}}M();var w=window;w.customStrategies=w.customStrategies||[];w.customStrategies.some(r=>r.type===l&&r.strategyType==="dashboard")||w.customStrategies.push({type:l,strategyType:"dashboard",name:"Maintenance Supporter",description:"Auto-generated dashboard. Group views by area, status, floor, or due date \u2014 picked from the strategy editor or YAML.",documentationURL:"https://github.com/iluebbe/maintenance_supporter#dashboard-strategy"});(()=>{let r=window;if(r.__msStrategyHealActive)return;r.__msStrategyHealActive=!0;let c=/^\/(auth|config|developer-tools|profile|hassio|history|logbook|map|media-browser|energy|todo|calendar)\b/,f=/Timeout waiting for strategy element ll-strategy-(dashboard-)?maintenance-supporter/i,g=`custom:${l}`;function R(a){let t=[document.documentElement],n=0;for(;t.length&&n<9e3;){let o=t.pop();if(n++,!o)continue;let e=o;if(e.nodeType===1&&e.tagName&&e.tagName.toLowerCase()===a)return e;e.shadowRoot&&t.push(e.shadowRoot);let i=o.children;if(i)for(let d of Array.from(i))t.push(d)}return null}function k(a){let t=a?.views;if(!Array.isArray(t)||!t.length)return null;let n=window.location.pathname.split("/").filter(Boolean).pop()||"",o=t.find(i=>i?.path===n);if(o)return o;let e=Number(n);return Number.isInteger(e)&&t[e]?t[e]:t[0]}function b(){try{let t=R("ha-panel-lovelace")?.lovelace;if(!t)return!1;let n=o=>o?.type;for(let o of[t.config,t.rawConfig]){if(!o)continue;if(n(o.strategy)===g)return!0;let e=k(o);if(e&&n(e.strategy)===g)return!0}return!1}catch{return!1}}function A(){let a=!1,t=0,n=!1,o=!1,e=[document.documentElement],i=0;for(;e.length&&i<9e3;){let d=e.pop();if(i++,!d)continue;let u=d;if(u.nodeType===1&&u.tagName){let s=u.tagName.toLowerCase();(s==="hui-view"||s==="hui-sections-view")&&(a=!0),(s==="ha-card"||s==="hui-card")&&t++,s==="hui-empty-state-card"&&(o=!0),s==="hui-error-card"&&f.test(u.textContent||"")&&(n=!0)}u.shadowRoot&&e.push(u.shadowRoot);let E=d.children;if(E)for(let s of Array.from(E))e.push(s)}return n?!0:o?!1:a&&t<3&&b()}let N="/maintenance_supporter_strategy_shim.js",y=0,_=0;function L(){let a=Date.now();a-_<5e3||y>=3||(_=a,y+=1,import(`${N}?heal=${a}`).catch(()=>{}).finally(()=>{let t=window.location.pathname+window.location.search;history.pushState(null,"","/lovelace"),window.dispatchEvent(new CustomEvent("location-changed")),window.setTimeout(()=>{history.pushState(null,"",t),window.dispatchEvent(new CustomEvent("location-changed"))},200)}))}function h(){if(c.test(window.location.pathname))return;let a=0,t=Date.now(),n=window.setInterval(()=>{a++;try{if(Date.now()-t<6e3)return;if(c.test(window.location.pathname)){window.clearInterval(n);return}A()?L():window.clearInterval(n),a>=30&&window.clearInterval(n)}catch{window.clearInterval(n)}},500)}try{document.readyState==="loading"?window.addEventListener("DOMContentLoaded",h):h(),window.addEventListener("location-changed",()=>{c.test(window.location.pathname)||h()})}catch{}})();
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-6RMRSFSY.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,p as v}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var r=class extends h{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._users=[];this._responsible="";this._localeReady=!1;this._userService=null;this._toggle=s=>{let o=new Set(this._selected);o.has(s)?o.delete(s):o.add(s),this._selected=o};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(s=>s.entity_id))};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let s=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:e.suggested_entry_id??void 0,object_name:e.suggested_object_name,device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0})),o=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/adopt",selections:s});this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:o})),this._open=!1}catch(s){this._error=d(s,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,v(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._sensors=[],this._selected=new Set,this._responsible="";try{this._userService?this._userService.updateHass(this.hass):this._userService=new u(this.hass);let[s,o]=await Promise.all([this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/discover"}),this._userService.getUsers().catch(()=>[])]);this._sensors=s.sensors||[],this._selected=new Set(this._sensors.map(e=>e.entity_id)),this._users=o}catch(s){this._error=d(s,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return t``;let s=this._lang,o=this._sensors.length>0&&this._selected.size===this._sensors.length;return t`
|
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NU5DR7VT.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GKQ6LXK5.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,p as v}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var r=class extends h{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._users=[];this._responsible="";this._localeReady=!1;this._userService=null;this._toggle=s=>{let o=new Set(this._selected);o.has(s)?o.delete(s):o.add(s),this._selected=o};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(s=>s.entity_id))};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let s=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:e.suggested_entry_id??void 0,object_name:e.suggested_object_name,device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0})),o=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/adopt",selections:s});this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:o})),this._open=!1}catch(s){this._error=d(s,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,v(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._sensors=[],this._selected=new Set,this._responsible="";try{this._userService?this._userService.updateHass(this.hass):this._userService=new u(this.hass);let[s,o]=await Promise.all([this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/discover"}),this._userService.getUsers().catch(()=>[])]);this._sensors=s.sensors||[],this._selected=new Set(this._sensors.map(e=>e.entity_id)),this._users=o}catch(s){this._error=d(s,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return t``;let s=this._lang,o=this._sensors.length>0&&this._selected.size===this._sensors.length;return t`
|
||||||
<div class="overlay" @click=${this._close}>
|
<div class="overlay" @click=${this._close}>
|
||||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||||
<div class="title">${i("adopt_problem_title",s)}</div>
|
<div class="title">${i("adopt_problem_title",s)}</div>
|
||||||
-222
@@ -1,222 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
|
||||||
import{a as d}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LJXSDCLS.js";import{a as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-I7J3AORE.js";import{a,b as _,c as t,f as l,g as h,i as g,j as n,n as i,p as v}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var r=class extends h{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._sensors=[];this._selected=new Set;this._users=[];this._responsible="";this._localeReady=!1;this._userService=null;this._toggle=s=>{let o=new Set(this._selected);o.has(s)?o.delete(s):o.add(s),this._selected=o};this._toggleAll=()=>{this._selected.size===this._sensors.length?this._selected=new Set:this._selected=new Set(this._sensors.map(s=>s.entity_id))};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let s=this._sensors.filter(e=>this._selected.has(e.entity_id)).map(e=>({entity_id:e.entity_id,name:e.name,entry_id:e.suggested_entry_id??void 0,object_name:e.suggested_object_name,device_id:e.device_id??void 0,part_id:e.suggested_part_id??void 0,responsible_user_id:this._responsible||void 0})),o=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/adopt",selections:s});this.dispatchEvent(new CustomEvent("problem-sensors-adopted",{bubbles:!0,composed:!0,detail:o})),this._open=!1}catch(s){this._error=d(s,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(s){s.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,v(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._sensors=[],this._selected=new Set,this._responsible="";try{this._userService?this._userService.updateHass(this.hass):this._userService=new u(this.hass);let[s,o]=await Promise.all([this.hass.connection.sendMessagePromise({type:"maintenance_supporter/problem_sensors/discover"}),this._userService.getUsers().catch(()=>[])]);this._sensors=s.sensors||[],this._selected=new Set(this._sensors.map(e=>e.entity_id)),this._users=o}catch(s){this._error=d(s,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return t``;let s=this._lang,o=this._sensors.length>0&&this._selected.size===this._sensors.length;return t`
|
|
||||||
<div class="overlay" @click=${this._close}>
|
|
||||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
|
||||||
<div class="title">${i("adopt_problem_title",s)}</div>
|
|
||||||
<div class="hint">${i("adopt_problem_hint",s)}</div>
|
|
||||||
${this._error?t`<div class="error">${this._error}</div>`:l}
|
|
||||||
|
|
||||||
${this._loading?t`<div class="loading">…</div>`:this._sensors.length===0?t`<div class="empty">${i("adopt_problem_none",s)}</div>`:t`
|
|
||||||
<label class="select-all">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
.checked=${o}
|
|
||||||
@change=${this._toggleAll}
|
|
||||||
/>
|
|
||||||
<span>${i("selected",s)}: ${this._selected.size} / ${this._sensors.length}</span>
|
|
||||||
</label>
|
|
||||||
<div class="list">
|
|
||||||
${this._sensors.map(e=>{let m=this._selected.has(e.entity_id),p=e.state==="on",c=[e.device_name,e.area_name].filter(Boolean).join(" \xB7 ");return t`
|
|
||||||
<label class="row">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
.checked=${m}
|
|
||||||
@change=${()=>this._toggle(e.entity_id)}
|
|
||||||
/>
|
|
||||||
<div class="row-main">
|
|
||||||
<div class="row-top">
|
|
||||||
<span class="row-name">${e.name}</span>
|
|
||||||
<span class="chip ${p?"chip-active":"chip-ok"}">
|
|
||||||
${p?i("adopt_problem_active",s):i("adopt_problem_ok",s)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
${c?t`<div class="row-sub">${c}</div>`:l}
|
|
||||||
<div class="row-target">
|
|
||||||
→ ${e.suggested_object_name}${e.suggested_entry_id?l:t` <span class="new-tag">${i("adopt_problem_new_object",s)}</span>`}
|
|
||||||
</div>
|
|
||||||
${e.suggested_part_name?t`<div class="row-part">
|
|
||||||
<ha-icon icon="mdi:package-variant-closed"></ha-icon>
|
|
||||||
${i("adopt_problem_part",s).replace("{name}",e.suggested_part_name)}
|
|
||||||
</div>`:l}
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
`})}
|
|
||||||
</div>
|
|
||||||
`}
|
|
||||||
|
|
||||||
${!this._loading&&this._sensors.length>0&&this._users.length>0?t`
|
|
||||||
<label class="responsible">
|
|
||||||
<span>${i("adopt_problem_responsible",s)}</span>
|
|
||||||
<select
|
|
||||||
.value=${this._responsible}
|
|
||||||
@change=${e=>{this._responsible=e.target.value}}
|
|
||||||
>
|
|
||||||
<option value="" ?selected=${!this._responsible}>${i("no_user_assigned",s)}</option>
|
|
||||||
${this._users.map(e=>t`<option value=${e.id} ?selected=${e.id===this._responsible}>${e.name}</option>`)}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
`:l}
|
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<ha-button appearance="plain" @click=${this._close}>
|
|
||||||
${i("cancel",s)}
|
|
||||||
</ha-button>
|
|
||||||
<ha-button
|
|
||||||
@click=${this._adopt}
|
|
||||||
.disabled=${this._selected.size===0||this._adopting}
|
|
||||||
>
|
|
||||||
${i("adopt_problem_adopt",s)}
|
|
||||||
</ha-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`}};r.styles=_`
|
|
||||||
.overlay {
|
|
||||||
position: fixed;
|
|
||||||
inset: 0;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
background: var(--card-background-color, #fff);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 12px;
|
|
||||||
min-width: min(360px, calc(100vw - 24px));
|
|
||||||
max-width: 560px;
|
|
||||||
width: 90vw;
|
|
||||||
max-height: 80vh;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
.title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.hint {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
.error {
|
|
||||||
color: var(--error-color, #f44336);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
.loading,
|
|
||||||
.empty {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 12px 0;
|
|
||||||
}
|
|
||||||
.select-all {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.select-all input {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 6px;
|
|
||||||
overflow-y: auto;
|
|
||||||
max-height: 50vh;
|
|
||||||
}
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 10px;
|
|
||||||
padding: 8px;
|
|
||||||
border: 1px solid var(--divider-color);
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.row input {
|
|
||||||
margin-top: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.row-main {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 2px;
|
|
||||||
min-width: 0;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.row-top {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
.row-name {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
.row-sub {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
.row-target {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
.row-part {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
.row-part ha-icon {
|
|
||||||
--mdc-icon-size: 14px;
|
|
||||||
}
|
|
||||||
.new-tag {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.chip {
|
|
||||||
font-size: 11px;
|
|
||||||
padding: 1px 8px;
|
|
||||||
border-radius: 10px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.chip-active {
|
|
||||||
background: var(--error-color, #f44336);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.chip-ok {
|
|
||||||
background: var(--divider-color);
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
.responsible {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.responsible select {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 140px;
|
|
||||||
padding: 4px 6px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid var(--divider-color);
|
|
||||||
background: var(--card-background-color, #fff);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
.actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 8px;
|
|
||||||
padding-top: 8px;
|
|
||||||
}
|
|
||||||
`,a([g({attribute:!1})],r.prototype,"hass",2),a([n()],r.prototype,"_open",2),a([n()],r.prototype,"_loading",2),a([n()],r.prototype,"_adopting",2),a([n()],r.prototype,"_error",2),a([n()],r.prototype,"_sensors",2),a([n()],r.prototype,"_selected",2),a([n()],r.prototype,"_users",2),a([n()],r.prototype,"_responsible",2);customElements.get("maintenance-adopt-problem-sensors-dialog")||customElements.define("maintenance-adopt-problem-sensors-dialog",r);export{r as MaintenanceAdoptProblemSensorsDialog};
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
|
||||||
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";function _(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let t=!!e.entry_id&&e.entry_id!==r,a=t?e.entry_id:r,o=s.find(p=>p.entry_id===a),n=(o?.parts||[]).find(p=>p.id===e.part_id)||null,d=t&&o?.object?.name||"",i=n?.name||u("shared_part_unknown",c);return{part:n,foreign:t,ownerName:d,label:d?`${i} (${d})`:i}}function f(e,r,s,c){let{part:t,label:a}=l(e,r,s,c),o=t&&t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:"",n=t?.storage_location?` \u2014 ${t.storage_location}`:"";return`${e.quantity}\xD7 ${a}${o}${n}`}function g(e,r,s,c){let a=(s.find(n=>n.entry_id===r)?.parts||[]).map(n=>({...n})),o=new Set(a.map(n=>_({part_id:n.id})));for(let n of e?.consumes_parts||[]){if(!n.entry_id||n.entry_id===r)continue;let d=_(n);if(o.has(d))continue;o.add(d);let{part:i,ownerName:p}=l(n,r,s,c);a.push({id:n.part_id,name:i?.name||u("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:n.entry_id,owner_name:p})}return a}export{_ as a,f as b,g as c};
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
|
||||||
var r=class{constructor(s){this.usersCache=null;this.cacheTimestamp=0;this.CACHE_TTL_MS=6e4;this.hass=s}updateHass(s){this.hass=s}async getUsers(s=!1){let e=Date.now();if(!s&&this.usersCache&&e-this.cacheTimestamp<this.CACHE_TTL_MS)return this.usersCache;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/users/list"});return this.usersCache=t.users,this.cacheTimestamp=e,this.usersCache}catch(t){return console.error("Failed to fetch users:",t),this.usersCache||[]}}async assignUser(s,e,t){await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/assign_user",entry_id:s,task_id:e,user_id:t})}async getTasksByUser(s){return(await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/tasks/by_user",user_id:s})).tasks}getUserName(s){return!s||!this.usersCache?null:this.usersCache.find(t=>t.id===s)?.name||null}getUser(s){return!s||!this.usersCache?null:this.usersCache.find(e=>e.id===s)||null}getCurrentUserId(){return this.hass.user?.id||null}isCurrentUser(s){return s?s===this.getCurrentUserId():!1}clearCache(){this.usersCache=null,this.cacheTimestamp=0}};export{r as a};
|
|
||||||
+2
-2
@@ -1,2 +1,2 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";function _(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let t=!!e.entry_id&&e.entry_id!==r,a=t?e.entry_id:r,o=s.find(p=>p.entry_id===a),n=(o?.parts||[]).find(p=>p.id===e.part_id)||null,d=t&&o?.object?.name||"",i=n?.name||u("shared_part_unknown",c);return{part:n,foreign:t,ownerName:d,label:d?`${i} (${d})`:i}}function f(e,r,s,c){let{part:t,label:a}=l(e,r,s,c),o=t&&t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:"",n=t?.storage_location?` \u2014 ${t.storage_location}`:"";return`${e.quantity}\xD7 ${a}${o}${n}`}function g(e,r,s,c){let a=(s.find(n=>n.entry_id===r)?.parts||[]).map(n=>({...n})),o=new Set(a.map(n=>_({part_id:n.id})));for(let n of e?.consumes_parts||[]){if(!n.entry_id||n.entry_id===r)continue;let d=_(n);if(o.has(d))continue;o.add(d);let{part:i,ownerName:p}=l(n,r,s,c);a.push({id:n.part_id,name:i?.name||u("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:n.entry_id,owner_name:p})}return a}export{_ as a,f as b,g as c};
|
import{n as u}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";function _(e){return`${e.entry_id??""}\0${e.part_id}`}function l(e,r,s,c){let t=!!e.entry_id&&e.entry_id!==r,a=t?e.entry_id:r,o=s.find(p=>p.entry_id===a),n=(o?.parts||[]).find(p=>p.id===e.part_id)||null,d=t&&o?.object?.name||"",i=n?.name||u("shared_part_unknown",c);return{part:n,foreign:t,ownerName:d,label:d?`${i} (${d})`:i}}function f(e,r,s,c){let{part:t,label:a}=l(e,r,s,c),o=t&&t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:"",n=t?.storage_location?` \u2014 ${t.storage_location}`:"";return`${e.quantity}\xD7 ${a}${o}${n}`}function g(e,r,s,c){let a=(s.find(n=>n.entry_id===r)?.parts||[]).map(n=>({...n})),o=new Set(a.map(n=>_({part_id:n.id})));for(let n of e?.consumes_parts||[]){if(!n.entry_id||n.entry_id===r)continue;let d=_(n);if(o.has(d))continue;o.add(d);let{part:i,ownerName:p}=l(n,r,s,c);a.push({id:n.part_id,name:i?.name||u("shared_part_unknown",c),unit:i?.unit,stock:i?.stock??null,storage_location:i?.storage_location,entry_id:n.entry_id,owner_name:p})}return a}export{_ as a,f as b,g as c};
|
||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
var r=class{constructor(s){this.usersCache=null;this.cacheTimestamp=0;this.CACHE_TTL_MS=6e4;this.hass=s}updateHass(s){this.hass=s}async getUsers(s=!1){let e=Date.now();if(!s&&this.usersCache&&e-this.cacheTimestamp<this.CACHE_TTL_MS)return this.usersCache;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/users/list"});return this.usersCache=t.users,this.cacheTimestamp=e,this.usersCache}catch(t){return console.error("Failed to fetch users:",t),this.usersCache||[]}}async assignUser(s,e,t){await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/assign_user",entry_id:s,task_id:e,user_id:t})}async getTasksByUser(s){return(await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/tasks/by_user",user_id:s})).tasks}getUserName(s){return!s||!this.usersCache?null:this.usersCache.find(t=>t.id===s)?.name||null}getUser(s){return!s||!this.usersCache?null:this.usersCache.find(e=>e.id===s)||null}getCurrentUserId(){return this.hass.user?.id||null}isCurrentUser(s){return s?s===this.getCurrentUserId():!1}clearCache(){this.usersCache=null,this.cacheTimestamp=0}};export{r as a};
|
var r=class{constructor(s){this.usersCache=null;this.cacheTimestamp=0;this.CACHE_TTL_MS=6e4;this.hass=s}updateHass(s){this.hass=s}async getUsers(s=!1){let e=Date.now();if(!s&&this.usersCache&&e-this.cacheTimestamp<this.CACHE_TTL_MS)return this.usersCache;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/users/list"});return this.usersCache=t.users,this.cacheTimestamp=e,this.usersCache}catch(t){return console.error("Failed to fetch users:",t),this.usersCache||[]}}async assignUser(s,e,t){await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/task/assign_user",entry_id:s,task_id:e,user_id:t})}async getTasksByUser(s){return(await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/tasks/by_user",user_id:s})).tasks}getUserName(s){return!s||!this.usersCache?null:this.usersCache.find(t=>t.id===s)?.name||null}getUser(s){return!s||!this.usersCache?null:this.usersCache.find(e=>e.id===s)||null}getCurrentUserId(){return this.hass.user?.id||null}isCurrentUser(s){return s?s===this.getCurrentUserId():!1}clearCache(){this.usersCache=null,this.cacheTimestamp=0}};export{r as a};
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
|
||||||
var o=["notes","cost","duration","photo","user"],t={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};export{o as a,t as b};
|
|
||||||
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,2 +1,2 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var s={name:"name",task_type:"maintenance_type",schedule_type:"schedule_type",interval_days:"interval_days",interval_anchor:"interval_anchor",warning_days:"warning_days",last_performed:"last_performed_optional",notes:"notes_optional",documentation_url:"documentation_url_optional",custom_icon:"custom_icon_optional",nfc_tag_id:"nfc_tag_id_optional",responsible_user_id:"responsible_user",entity_slug:"entity_slug",entity_id:"entity_id",area_id:"area_id_optional",manufacturer:"manufacturer_optional",model:"model_optional",serial_number:"serial_number_optional",installation_date:"installation_date_optional",warranty_expiry:"warranty_expiry_optional",checklist:"checklist_steps_optional",reason:"reason",feedback:"feedback",cost:"cost",duration:"duration",description:"description_optional",group_name:"name",group_description:"description_optional",environmental_entity:"environmental_entity_optional",environmental_attribute:"environmental_attribute_optional",trigger_above:"trigger_above",trigger_below:"trigger_below",trigger_for_minutes:"trigger_for_minutes"};function c(r,o){let e=s[r];if(!e)return r;let t=a(e,o);return t&&t!==e?t:r}function d(r){let e=r.match(/data\['([^']+)'\]/)?.[1],t;return(t=r.match(/length of value must be at most (\d+)/))?{field:e,rule:"too_long",param:t[1]}:(t=r.match(/length of value must be at least (\d+)/))?{field:e,rule:"too_short",param:t[1]}:(t=r.match(/value must be at most (\S+)/))?{field:e,rule:"value_too_high",param:t[1]}:(t=r.match(/value must be at least (\S+)/))?{field:e,rule:"value_too_low",param:t[1]}:/required key not provided/.test(r)?{field:e,rule:"required"}:(t=r.match(/expected (\w+)/))?{field:e,rule:"wrong_type",param:t[1]}:/value must be one of/.test(r)?{field:e,rule:"invalid_choice"}:/not a valid value/.test(r)?{field:e,rule:"invalid_value"}:{field:e,rule:"unknown"}}function g(r,o,e){if(e=e??a("action_error",o),typeof r=="string")return r;if(typeof r!="object"||r===null)return e;let t=r,_=t.message||t.error?.message||"";if(!_)return e;let i=d(_),l=i.field?c(i.field,o):"",n=u=>a(u,o).replace("{field}",l).replace("{n}",i.param??"");switch(i.rule){case"too_long":return n("err_too_long");case"too_short":return n("err_too_short");case"value_too_high":return n("err_value_too_high");case"value_too_low":return n("err_value_too_low");case"required":return n("err_required");case"wrong_type":return n("err_wrong_type").replace("{type}",i.param??"");case"invalid_choice":return n("err_invalid_choice");case"invalid_value":return n("err_invalid_value");default:return _||e}}export{g as a};
|
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var s={name:"name",task_type:"maintenance_type",schedule_type:"schedule_type",interval_days:"interval_days",interval_anchor:"interval_anchor",warning_days:"warning_days",last_performed:"last_performed_optional",notes:"notes_optional",documentation_url:"documentation_url_optional",custom_icon:"custom_icon_optional",nfc_tag_id:"nfc_tag_id_optional",responsible_user_id:"responsible_user",entity_slug:"entity_slug",entity_id:"entity_id",area_id:"area_id_optional",manufacturer:"manufacturer_optional",model:"model_optional",serial_number:"serial_number_optional",installation_date:"installation_date_optional",warranty_expiry:"warranty_expiry_optional",checklist:"checklist_steps_optional",reason:"reason",feedback:"feedback",cost:"cost",duration:"duration",description:"description_optional",group_name:"name",group_description:"description_optional",environmental_entity:"environmental_entity_optional",environmental_attribute:"environmental_attribute_optional",trigger_above:"trigger_above",trigger_below:"trigger_below",trigger_for_minutes:"trigger_for_minutes"};function c(r,o){let e=s[r];if(!e)return r;let t=a(e,o);return t&&t!==e?t:r}function d(r){let e=r.match(/data\['([^']+)'\]/)?.[1],t;return(t=r.match(/length of value must be at most (\d+)/))?{field:e,rule:"too_long",param:t[1]}:(t=r.match(/length of value must be at least (\d+)/))?{field:e,rule:"too_short",param:t[1]}:(t=r.match(/value must be at most (\S+)/))?{field:e,rule:"value_too_high",param:t[1]}:(t=r.match(/value must be at least (\S+)/))?{field:e,rule:"value_too_low",param:t[1]}:/required key not provided/.test(r)?{field:e,rule:"required"}:(t=r.match(/expected (\w+)/))?{field:e,rule:"wrong_type",param:t[1]}:/value must be one of/.test(r)?{field:e,rule:"invalid_choice"}:/not a valid value/.test(r)?{field:e,rule:"invalid_value"}:{field:e,rule:"unknown"}}function g(r,o,e){if(e=e??a("action_error",o),typeof r=="string")return r;if(typeof r!="object"||r===null)return e;let t=r,_=t.message||t.error?.message||"";if(!_)return e;let i=d(_),l=i.field?c(i.field,o):"",n=u=>a(u,o).replace("{field}",l).replace("{n}",i.param??"");switch(i.rule){case"too_long":return n("err_too_long");case"too_short":return n("err_too_short");case"value_too_high":return n("err_value_too_high");case"value_too_low":return n("err_value_too_low");case"required":return n("err_required");case"wrong_type":return n("err_wrong_type").replace("{type}",i.param??"");case"invalid_choice":return n("err_invalid_choice");case"invalid_value":return n("err_invalid_value");default:return _||e}}export{g as a};
|
||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
var o=["notes","cost","duration","photo","user"],t={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};export{o as a,t as b};
|
var o=["notes","cost","duration","photo","user"],t={notes:"notes_label",cost:"cost",duration:"duration",photo:"photo_label",user:"user_label"};export{o as a,t as b};
|
||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
var i=[{key:"name",labelKey:"name",required:!0},{key:"manufacturer",labelKey:"manufacturer"},{key:"model",labelKey:"model"},{key:"serial_number",labelKey:"serial_number_label"},{key:"installation_date",labelKey:"installed"},{key:"warranty_expiry",labelKey:"warranty"},{key:"area_id",labelKey:"area"},{key:"documentation_url",labelKey:"documentation_url_label"},{key:"notes",labelKey:"object_notes_label"},{key:"task_count",labelKey:"tasks"},{key:"actions",labelKey:"actions"}],s=i.map(n=>n.key),l=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function c(n){if(!Array.isArray(n))return[...l];let o=new Set,e=[];for(let a of n)typeof a=="string"&&s.includes(a)&&!o.has(a)&&(o.add(a),e.push(a));return e.length?(e.includes("name")||e.unshift("name"),e):[...l]}function u(n,o,e){let a=new Blob([n],{type:e}),r=URL.createObjectURL(a),t=document.createElement("a");t.href=r,t.download=o,t.target="_blank",t.rel="noopener",t.style.display="none",document.body.appendChild(t),t.dispatchEvent(new MouseEvent("click")),document.body.removeChild(t),setTimeout(()=>URL.revokeObjectURL(r),6e4)}function y(n,o){let e=document.createElement("a");e.href=n,e.download=o,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}export{i as a,l as b,c,u as d,y as e};
|
var i=[{key:"name",labelKey:"name",required:!0},{key:"manufacturer",labelKey:"manufacturer"},{key:"model",labelKey:"model"},{key:"serial_number",labelKey:"serial_number_label"},{key:"installation_date",labelKey:"installed"},{key:"warranty_expiry",labelKey:"warranty"},{key:"area_id",labelKey:"area"},{key:"documentation_url",labelKey:"documentation_url_label"},{key:"notes",labelKey:"object_notes_label"},{key:"task_count",labelKey:"tasks"},{key:"actions",labelKey:"actions"}],s=i.map(n=>n.key),l=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function c(n){if(!Array.isArray(n))return[...l];let o=new Set,e=[];for(let a of n)typeof a=="string"&&s.includes(a)&&!o.has(a)&&(o.add(a),e.push(a));return e.length?(e.includes("name")||e.unshift("name"),e):[...l]}function u(n,o,e){let a=new Blob([n],{type:e}),r=URL.createObjectURL(a),t=document.createElement("a");t.href=r,t.download=o,t.target="_blank",t.rel="noopener",t.style.display="none",document.body.appendChild(t),t.dispatchEvent(new MouseEvent("click")),document.body.removeChild(t),setTimeout(()=>URL.revokeObjectURL(r),6e4)}function y(n,o){let e=document.createElement("a");e.href=n,e.download=o,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}export{i as a,l as b,c,u as d,y as e};
|
||||||
+2
-2
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{a as t,b as a,c as i,f as l,g as p,i as r}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var e=class extends p{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1}_onInput(n){let o=n.target.value;this.value=o,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:o}}))}render(){return i`
|
import{a as t,b as a,c as i,f as l,g as p,i as r}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var e=class extends p{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1}_onInput(n){let o=n.target.value;this.value=o,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:o}}))}render(){return i`
|
||||||
<label class="field">
|
<label class="field">
|
||||||
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:l}</span>`:l}
|
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:l}</span>`:l}
|
||||||
<input
|
<input
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
|
||||||
import{n as a}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var s={name:"name",task_type:"maintenance_type",schedule_type:"schedule_type",interval_days:"interval_days",interval_anchor:"interval_anchor",warning_days:"warning_days",last_performed:"last_performed_optional",notes:"notes_optional",documentation_url:"documentation_url_optional",custom_icon:"custom_icon_optional",nfc_tag_id:"nfc_tag_id_optional",responsible_user_id:"responsible_user",entity_slug:"entity_slug",entity_id:"entity_id",area_id:"area_id_optional",manufacturer:"manufacturer_optional",model:"model_optional",serial_number:"serial_number_optional",installation_date:"installation_date_optional",warranty_expiry:"warranty_expiry_optional",checklist:"checklist_steps_optional",reason:"reason",feedback:"feedback",cost:"cost",duration:"duration",description:"description_optional",group_name:"name",group_description:"description_optional",environmental_entity:"environmental_entity_optional",environmental_attribute:"environmental_attribute_optional",trigger_above:"trigger_above",trigger_below:"trigger_below",trigger_for_minutes:"trigger_for_minutes"};function c(r,o){let e=s[r];if(!e)return r;let t=a(e,o);return t&&t!==e?t:r}function d(r){let e=r.match(/data\['([^']+)'\]/)?.[1],t;return(t=r.match(/length of value must be at most (\d+)/))?{field:e,rule:"too_long",param:t[1]}:(t=r.match(/length of value must be at least (\d+)/))?{field:e,rule:"too_short",param:t[1]}:(t=r.match(/value must be at most (\S+)/))?{field:e,rule:"value_too_high",param:t[1]}:(t=r.match(/value must be at least (\S+)/))?{field:e,rule:"value_too_low",param:t[1]}:/required key not provided/.test(r)?{field:e,rule:"required"}:(t=r.match(/expected (\w+)/))?{field:e,rule:"wrong_type",param:t[1]}:/value must be one of/.test(r)?{field:e,rule:"invalid_choice"}:/not a valid value/.test(r)?{field:e,rule:"invalid_value"}:{field:e,rule:"unknown"}}function g(r,o,e){if(e=e??a("action_error",o),typeof r=="string")return r;if(typeof r!="object"||r===null)return e;let t=r,_=t.message||t.error?.message||"";if(!_)return e;let i=d(_),l=i.field?c(i.field,o):"",n=u=>a(u,o).replace("{field}",l).replace("{n}",i.param??"");switch(i.rule){case"too_long":return n("err_too_long");case"too_short":return n("err_too_short");case"value_too_high":return n("err_value_too_high");case"value_too_low":return n("err_value_too_low");case"required":return n("err_required");case"wrong_type":return n("err_wrong_type").replace("{type}",i.param??"");case"invalid_choice":return n("err_invalid_choice");case"invalid_value":return n("err_invalid_value");default:return _||e}}export{g as a};
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
|
||||||
var i=[{key:"name",labelKey:"name",required:!0},{key:"manufacturer",labelKey:"manufacturer"},{key:"model",labelKey:"model"},{key:"serial_number",labelKey:"serial_number_label"},{key:"installation_date",labelKey:"installed"},{key:"warranty_expiry",labelKey:"warranty"},{key:"area_id",labelKey:"area"},{key:"documentation_url",labelKey:"documentation_url_label"},{key:"notes",labelKey:"object_notes_label"},{key:"task_count",labelKey:"tasks"},{key:"actions",labelKey:"actions"}],s=i.map(n=>n.key),l=["name","manufacturer","model","serial_number","installation_date","warranty_expiry","area_id","task_count","actions"];function c(n){if(!Array.isArray(n))return[...l];let o=new Set,e=[];for(let a of n)typeof a=="string"&&s.includes(a)&&!o.has(a)&&(o.add(a),e.push(a));return e.length?(e.includes("name")||e.unshift("name"),e):[...l]}function u(n,o,e){let a=new Blob([n],{type:e}),r=URL.createObjectURL(a),t=document.createElement("a");t.href=r,t.download=o,t.target="_blank",t.rel="noopener",t.style.display="none",document.body.appendChild(t),t.dispatchEvent(new MouseEvent("click")),document.body.removeChild(t),setTimeout(()=>URL.revokeObjectURL(r),6e4)}function y(n,o){let e=document.createElement("a");e.href=n,e.download=o,e.target="_blank",e.rel="noopener",e.style.display="none",document.body.appendChild(e),e.dispatchEvent(new MouseEvent("click")),document.body.removeChild(e)}export{i as a,l as b,c,u as d,y as e};
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
|
||||||
import{a as t,b as a,c as i,f as l,g as p,i as r}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var e=class extends p{constructor(){super(...arguments);this.label="";this.value="";this.placeholder="";this.type="text";this.required=!1;this.disabled=!1}_onInput(n){let o=n.target.value;this.value=o,this.dispatchEvent(new CustomEvent("input",{bubbles:!0,composed:!0,detail:{value:o}}))}render(){return i`
|
|
||||||
<label class="field">
|
|
||||||
${this.label?i`<span class="label">${this.label}${this.required?i`<span class="req">*</span>`:l}</span>`:l}
|
|
||||||
<input
|
|
||||||
.value=${this.value??""}
|
|
||||||
.type=${this.type}
|
|
||||||
?required=${this.required}
|
|
||||||
?disabled=${this.disabled}
|
|
||||||
placeholder=${this.placeholder}
|
|
||||||
step=${this.step??l}
|
|
||||||
min=${this.min??l}
|
|
||||||
max=${this.max??l}
|
|
||||||
pattern=${this.pattern??l}
|
|
||||||
@input=${this._onInput}
|
|
||||||
@change=${this._onInput}
|
|
||||||
/>
|
|
||||||
${this.helper?i`<span class="helper">${this.helper}</span>`:l}
|
|
||||||
</label>
|
|
||||||
`}};e.styles=a`
|
|
||||||
:host { display: block; }
|
|
||||||
.field {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
.label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--secondary-text-color, #888);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.req { color: var(--error-color, #f44336); margin-left: 2px; }
|
|
||||||
input {
|
|
||||||
padding: 8px 10px;
|
|
||||||
font-size: 14px;
|
|
||||||
background: var(--secondary-background-color, rgba(0,0,0,0.06));
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
border: 1px solid var(--divider-color, rgba(255,255,255,0.12));
|
|
||||||
border-radius: 6px;
|
|
||||||
font-family: inherit;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
input:focus {
|
|
||||||
border-color: var(--primary-color);
|
|
||||||
}
|
|
||||||
input:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
||||||
.helper {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
`,t([r()],e.prototype,"label",2),t([r()],e.prototype,"value",2),t([r()],e.prototype,"placeholder",2),t([r()],e.prototype,"type",2),t([r({type:Boolean})],e.prototype,"required",2),t([r({type:Boolean})],e.prototype,"disabled",2),t([r()],e.prototype,"step",2),t([r()],e.prototype,"min",2),t([r()],e.prototype,"max",2),t([r()],e.prototype,"pattern",2),t([r()],e.prototype,"helper",2);customElements.get("ms-textfield")||customElements.define("ms-textfield",e);
|
|
||||||
-292
@@ -1,292 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
|
||||||
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-7QFSK25W.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-4HD7ODUX.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,x as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var i=class extends v{constructor(){super(...arguments);this.entryId="";this.taskId="";this.taskName="";this.lang="en";this.checklist=[];this.adaptiveEnabled=!1;this.taskType="";this.readingUnit="";this.restockDefault=null;this.restockUnitCost=null;this.currencySymbol="";this.parts=[];this.consumesParts=[];this.consumesInfo=[];this.requiredFields=[];this._open=!1;this._notes="";this._cost="";this._duration="";this._loading=!1;this._error="";this._checklistState={};this._feedback="needed";this._photoDocId="";this._photoPreview="";this._photoUploading=!1;this._readingValue="";this._restockQty="";this._usedParts={};this.checklistPrefill={}}open(){this._open||(this._open=!0,this._notes="",this._cost="",this._duration="",this._error="",this._checklistState=Object.fromEntries(this.checklist.map((e,t)=>[String(t),!!this.checklistPrefill[e]]).filter(([,e])=>e)),this._feedback="needed",this._photoDocId="",this._photoPreview="",this._photoUploading=!1,this._readingValue="",this._restockQty=this.restockDefault!==null?String(this.restockDefault):"",this._usedParts=Object.fromEntries(this.consumesParts.map(e=>[_(e),{...e}])))}_toggleCheck(e){let t=String(e);this._checklistState={...this._checklistState,[t]:!this._checklistState[t]}}_setFeedback(e){this._feedback=e}async _onPhotoInput(e){let t=e.target,o=t.files?.[0];if(t.value="",!!o){this._photoUploading=!0,this._error="";try{let c=new FormData;c.append("entry_id",this.entryId),c.append("tags","photo"),c.append("file",o,o.name);let p=await fetch("/api/maintenance_supporter/document/upload",{method:"POST",headers:{Authorization:`Bearer ${this.hass.auth?.data?.access_token??""}`},body:c});if(!p.ok){this._error=p.status===413?r("doc_too_large",this.lang):r("doc_upload_failed",this.lang);return}let u=await p.json();u.id&&(this._photoDocId=u.id,this._photoPreview=URL.createObjectURL(o))}catch{this._error=r("doc_upload_failed",this.lang)}finally{this._photoUploading=!1}}}_removePhoto(){this._photoPreview&&URL.revokeObjectURL(this._photoPreview),this._photoDocId="",this._photoPreview=""}async _complete(){this._loading=!0,this._error="";try{let e={type:"maintenance_supporter/task/complete",entry_id:this.entryId,task_id:this.taskId};if(this._notes&&(e.notes=this._notes),this._cost){let t=parseFloat(this._cost);!isNaN(t)&&t>=0&&(e.cost=t)}if(this._duration){let t=parseInt(this._duration,10);!isNaN(t)&&t>=0&&(e.duration=t)}if(this.checklist.length>0&&(e.checklist_state=this._checklistState),this.adaptiveEnabled&&(e.feedback=this._feedback),this._photoDocId&&(e.photo_doc_id=this._photoDocId),this._readingValue!==""){let t=parseFloat(this._readingValue);isNaN(t)||(e.reading_value=t)}if(this.restockDefault!==null&&this._restockQty!==""){let t=parseFloat(this._restockQty);!isNaN(t)&&t>=1&&(e.restock_quantity=t)}this.parts.length>0&&(e.used_parts=Object.values(this._usedParts).filter(t=>Number.isFinite(t.quantity)&&t.quantity>0).map(t=>t.entry_id?{part_id:t.part_id,quantity:t.quantity,entry_id:t.entry_id}:{part_id:t.part_id,quantity:t.quantity})),await this.hass.connection.sendMessagePromise(e),this._open=!1,this.dispatchEvent(new CustomEvent("task-completed"))}catch(e){this._error=g(e,this.lang,r("save_error",this.lang))}finally{this._loading=!1}}get _missingRequired(){let e={notes:this._notes.trim()!=="",cost:this._cost.trim()!=="",duration:this._duration.trim()!=="",photo:this._photoDocId!=="",user:!!this.hass?.user};return this.requiredFields.filter(t=>!e[t])}_req(e){return this.requiredFields.includes(e)?a`<span class="req-mark" aria-hidden="true">*</span>`:d}_partsCostSuggestion(){if(this.restockDefault!==null){let o=parseFloat(this._restockQty);return this.restockUnitCost==null||!Number.isFinite(o)||o<=0?null:Math.round(this.restockUnitCost*o*100)/100}if(!this.parts.length)return null;let e=0,t=!1;for(let o of Object.values(this._usedParts)){let c=this.parts.find(p=>_({part_id:p.id,entry_id:p.entry_id})===_(o));c?.cost!=null&&(e+=c.cost*(o.quantity||1),t=!0)}return t?Math.round(e*100)/100:null}_renderCostSuggestion(e){if(this._cost.trim()!=="")return d;let t=this._partsCostSuggestion();if(t==null||t<=0)return d;let o=`${t.toFixed(2)}${this.currencySymbol?` ${this.currencySymbol}`:""}`;return a`<button
|
|
||||||
type="button"
|
|
||||||
class="cost-suggestion"
|
|
||||||
@click=${()=>this._cost=t.toFixed(2)}
|
|
||||||
>${r("cost_from_parts",e).replace("{amount}",o)}</button>`}_close(){this._open=!1}render(){if(!this._open)return a``;let e=this.lang||this.hass?.language||"en";return a`
|
|
||||||
<ha-dialog open @closed=${this._close}>
|
|
||||||
<div class="dialog-title">${r("complete_title",e)}${this.taskName}</div>
|
|
||||||
<div class="content">
|
|
||||||
${this._error?a`<div class="error">${this._error}</div>`:d}
|
|
||||||
${this.checklist.length>0?a`
|
|
||||||
<div class="checklist-section">
|
|
||||||
<label class="checklist-label">${r("checklist",e)}</label>
|
|
||||||
${this.checklist.map((t,o)=>a`
|
|
||||||
<label class="checklist-item" @click=${()=>this._toggleCheck(o)}>
|
|
||||||
<input type="checkbox" .checked=${!!this._checklistState[String(o)]} />
|
|
||||||
<span>${t}</span>
|
|
||||||
</label>
|
|
||||||
`)}
|
|
||||||
</div>
|
|
||||||
`:d}
|
|
||||||
${this.taskType==="reading"?a`
|
|
||||||
<label class="field">
|
|
||||||
<span class="field-label">${r("reading_value_label",e)}${this.readingUnit?` (${this.readingUnit})`:""}</span>
|
|
||||||
<input type="number" step="any" class="field-input"
|
|
||||||
.value=${this._readingValue}
|
|
||||||
@input=${t=>this._readingValue=t.target.value} />
|
|
||||||
</label>`:d}
|
|
||||||
${this.parts.length?a`<div class="used-parts">
|
|
||||||
<span class="field-label">${r("complete_parts_used",e)}</span>
|
|
||||||
${this.parts.map(t=>{let o=_({part_id:t.id,entry_id:t.entry_id}),c=this._usedParts[o],p=c!==void 0,u=t.entry_id?{part_id:t.id,quantity:1,entry_id:t.entry_id}:{part_id:t.id,quantity:1};return a`<div class="used-part-row">
|
|
||||||
<label class="used-part-check">
|
|
||||||
<input type="checkbox" .checked=${p}
|
|
||||||
@change=${f=>{let h={...this._usedParts};f.target.checked?h[o]=h[o]||u:delete h[o],this._usedParts=h}} />
|
|
||||||
<span
|
|
||||||
>${t.name}${t.owner_name?a`<span class="used-part-owner"> (${t.owner_name})</span>`:d}${t.stock!==null&&t.stock!==void 0?` (${t.stock}${t.unit?" "+t.unit:""})`:""}</span
|
|
||||||
>
|
|
||||||
</label>
|
|
||||||
${p?a`<input class="used-part-qty" type="number" min="0.01" max="999" step="0.01"
|
|
||||||
.value=${String(c.quantity)}
|
|
||||||
@input=${f=>{let h=parseFloat(f.target.value);this._usedParts={...this._usedParts,[o]:{...u,quantity:Number.isFinite(h)&&h>=.01?h:1}}}} />`:d}
|
|
||||||
</div>`})}
|
|
||||||
</div>`:this.consumesInfo.length?a`<div class="consumes-hint">
|
|
||||||
${this.consumesInfo.map(t=>a`<div>${t}</div>`)}
|
|
||||||
</div>`:d}
|
|
||||||
${this.restockDefault!==null?a`
|
|
||||||
<label class="field">
|
|
||||||
<span class="field-label">${r("restock_quantity_label",e)}</span>
|
|
||||||
<input type="number" step="0.01" min="0.01" class="field-input"
|
|
||||||
.value=${this._restockQty}
|
|
||||||
@input=${t=>this._restockQty=t.target.value} />
|
|
||||||
</label>`:d}
|
|
||||||
<!-- Native <input>s rather than <ha-textfield>: when this dialog
|
|
||||||
is opened from a Lovelace card via dialog-mount, ha-textfield
|
|
||||||
isn't yet registered (HA loads it lazily when its own panels
|
|
||||||
need it) so the elements render with zero height and the user
|
|
||||||
only sees the title + Cancel/Complete buttons — the original
|
|
||||||
bug report. Native inputs always render. -->
|
|
||||||
<label class="field">
|
|
||||||
<span class="field-label">${r("notes_optional",e)}${this._req("notes")}</span>
|
|
||||||
<input type="text" class="field-input"
|
|
||||||
.value=${this._notes}
|
|
||||||
@input=${t=>this._notes=t.target.value} />
|
|
||||||
</label>
|
|
||||||
<label class="field">
|
|
||||||
<span class="field-label">${r("cost_optional",e)}${this._req("cost")}</span>
|
|
||||||
<input type="number" step="0.01" min="0" class="field-input"
|
|
||||||
.value=${this._cost}
|
|
||||||
@input=${t=>this._cost=t.target.value} />
|
|
||||||
${this._renderCostSuggestion(e)}
|
|
||||||
</label>
|
|
||||||
<label class="field">
|
|
||||||
<span class="field-label">${r("duration_minutes",e)}${this._req("duration")}</span>
|
|
||||||
<input type="number" step="0.01" min="0" class="field-input"
|
|
||||||
.value=${this._duration}
|
|
||||||
@input=${t=>this._duration=t.target.value} />
|
|
||||||
</label>
|
|
||||||
<div class="field">
|
|
||||||
<span class="field-label">${r("completion_photo_optional",e)}${this._req("photo")}</span>
|
|
||||||
${this._photoPreview?a`
|
|
||||||
<div class="photo-preview">
|
|
||||||
<img src=${this._photoPreview} alt="" />
|
|
||||||
<button type="button" class="photo-remove" @click=${this._removePhoto}
|
|
||||||
title="${r("remove",e)}">✕</button>
|
|
||||||
</div>`:a`
|
|
||||||
<label class="photo-pick">
|
|
||||||
<ha-icon icon="mdi:camera"></ha-icon>
|
|
||||||
<span>${this._photoUploading?r("uploading",e):r("add_photo",e)}</span>
|
|
||||||
<input type="file" accept="image/*" capture="environment"
|
|
||||||
?disabled=${this._photoUploading}
|
|
||||||
@change=${this._onPhotoInput} />
|
|
||||||
</label>`}
|
|
||||||
</div>
|
|
||||||
${this.adaptiveEnabled?a`
|
|
||||||
<div class="feedback-section">
|
|
||||||
<label class="feedback-label">${r("was_maintenance_needed",e)}</label>
|
|
||||||
<div class="feedback-buttons">
|
|
||||||
<button
|
|
||||||
class="feedback-btn ${this._feedback==="needed"?"selected":""}"
|
|
||||||
@click=${()=>this._setFeedback("needed")}
|
|
||||||
>${r("feedback_needed",e)}</button>
|
|
||||||
<button
|
|
||||||
class="feedback-btn ${this._feedback==="not_needed"?"selected":""}"
|
|
||||||
@click=${()=>this._setFeedback("not_needed")}
|
|
||||||
>${r("feedback_not_needed",e)}</button>
|
|
||||||
<button
|
|
||||||
class="feedback-btn ${this._feedback==="not_sure"?"selected":""}"
|
|
||||||
@click=${()=>this._setFeedback("not_sure")}
|
|
||||||
>${r("feedback_not_sure",e)}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`:d}
|
|
||||||
</div>
|
|
||||||
<div class="dialog-actions">
|
|
||||||
<ha-button appearance="plain" @click=${this._close}>
|
|
||||||
${r("cancel",e)}
|
|
||||||
</ha-button>
|
|
||||||
<ha-button
|
|
||||||
@click=${this._complete}
|
|
||||||
.disabled=${this._loading||this._missingRequired.length>0}
|
|
||||||
title=${this._missingRequired.length?this._missingRequired.map(t=>r("err_required",e).replace("{field}",r(m[t]??t,e))).join(" \xB7 "):""}
|
|
||||||
>
|
|
||||||
${this._loading?r("completing",e):r("complete",e)}
|
|
||||||
</ha-button>
|
|
||||||
</div>
|
|
||||||
</ha-dialog>
|
|
||||||
`}};i.styles=[k,b`
|
|
||||||
.req-mark {
|
|
||||||
color: var(--error-color, #f44336);
|
|
||||||
margin-left: 2px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
/* #104: one-click cost suggestion from parts — quiet link-style chip. */
|
|
||||||
.cost-suggestion {
|
|
||||||
align-self: flex-start;
|
|
||||||
margin-top: 4px;
|
|
||||||
padding: 0;
|
|
||||||
border: none;
|
|
||||||
background: none;
|
|
||||||
color: var(--primary-color);
|
|
||||||
font-size: 12.5px;
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: underline dotted;
|
|
||||||
text-underline-offset: 2px;
|
|
||||||
}
|
|
||||||
.dialog-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 16px;
|
|
||||||
min-width: 300px;
|
|
||||||
}
|
|
||||||
.dialog-actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 8px;
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
.consumes-hint {
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
border-left: 3px solid var(--primary-color);
|
|
||||||
padding: 4px 8px;
|
|
||||||
margin: 4px 0 8px;
|
|
||||||
}
|
|
||||||
/* #99: editable per-completion parts selection */
|
|
||||||
.used-parts { margin: 4px 0 8px; display: flex; flex-direction: column; gap: 4px; }
|
|
||||||
.used-part-row { display: flex; align-items: center; gap: 8px; }
|
|
||||||
.used-part-check {
|
|
||||||
display: flex; align-items: center; gap: 6px; flex: 1;
|
|
||||||
font-size: 13px; cursor: pointer;
|
|
||||||
}
|
|
||||||
.used-part-check input { cursor: pointer; }
|
|
||||||
/* #111: whose stock this row draws on. Muted but never omitted — an
|
|
||||||
unlabelled foreign pool is indistinguishable from an own part. */
|
|
||||||
.used-part-owner { color: var(--secondary-text-color); }
|
|
||||||
.used-part-qty {
|
|
||||||
width: 76px; padding: 4px 6px; border-radius: 4px; font: inherit; font-size: 13px;
|
|
||||||
border: 1px solid var(--divider-color);
|
|
||||||
background: var(--card-background-color);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
}
|
|
||||||
.error {
|
|
||||||
color: var(--error-color, #f44336);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
/* .field/.field-label/.field-input come from nativeFieldStyles */
|
|
||||||
.photo-pick {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border: 1px dashed var(--divider-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
.photo-pick:hover { border-color: var(--primary-color); }
|
|
||||||
.photo-pick input[type="file"] { display: none; }
|
|
||||||
.photo-preview {
|
|
||||||
position: relative;
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
.photo-preview img {
|
|
||||||
max-width: 160px;
|
|
||||||
max-height: 160px;
|
|
||||||
border-radius: 8px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.photo-remove {
|
|
||||||
position: absolute;
|
|
||||||
top: -8px;
|
|
||||||
right: -8px;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: none;
|
|
||||||
background: var(--error-color, #db4437);
|
|
||||||
color: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.checklist-section {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 8px 0;
|
|
||||||
border-bottom: 1px solid var(--divider-color);
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
.checklist-label {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
.checklist-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 4px 0;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.checklist-item input[type="checkbox"] {
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.feedback-section {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 8px 0;
|
|
||||||
border-top: 1px solid var(--divider-color);
|
|
||||||
}
|
|
||||||
.feedback-label {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
.feedback-buttons {
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
.feedback-btn {
|
|
||||||
flex: 1;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border: 1px solid var(--divider-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
background: var(--card-background-color, #fff);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
font-size: 13px;
|
|
||||||
cursor: pointer;
|
|
||||||
text-align: center;
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
.feedback-btn:hover {
|
|
||||||
background: var(--secondary-background-color, #f5f5f5);
|
|
||||||
}
|
|
||||||
.feedback-btn.selected {
|
|
||||||
background: var(--primary-color);
|
|
||||||
color: var(--text-primary-color, #fff);
|
|
||||||
border-color: var(--primary-color);
|
|
||||||
}
|
|
||||||
`],s([n({attribute:!1})],i.prototype,"hass",2),s([n()],i.prototype,"entryId",2),s([n()],i.prototype,"taskId",2),s([n()],i.prototype,"taskName",2),s([n()],i.prototype,"lang",2),s([n({type:Array})],i.prototype,"checklist",2),s([n({type:Boolean})],i.prototype,"adaptiveEnabled",2),s([n()],i.prototype,"taskType",2),s([n()],i.prototype,"readingUnit",2),s([n({attribute:!1})],i.prototype,"restockDefault",2),s([n({attribute:!1})],i.prototype,"restockUnitCost",2),s([n()],i.prototype,"currencySymbol",2),s([n({attribute:!1})],i.prototype,"parts",2),s([n({attribute:!1})],i.prototype,"consumesParts",2),s([n({type:Array})],i.prototype,"consumesInfo",2),s([n({type:Array})],i.prototype,"requiredFields",2),s([l()],i.prototype,"_open",2),s([l()],i.prototype,"_notes",2),s([l()],i.prototype,"_cost",2),s([l()],i.prototype,"_duration",2),s([l()],i.prototype,"_loading",2),s([l()],i.prototype,"_error",2),s([l()],i.prototype,"_checklistState",2),s([l()],i.prototype,"_feedback",2),s([l()],i.prototype,"_photoDocId",2),s([l()],i.prototype,"_photoPreview",2),s([l()],i.prototype,"_photoUploading",2),s([l()],i.prototype,"_readingValue",2),s([l()],i.prototype,"_restockQty",2),s([l()],i.prototype,"_usedParts",2),s([n({attribute:!1})],i.prototype,"checklistPrefill",2);customElements.get("maintenance-complete-dialog")||customElements.define("maintenance-complete-dialog",i);export{i as MaintenanceCompleteDialog};
|
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NGMG4DEY.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-SD6IEJBA.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LJXSDCLS.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,x as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var i=class extends v{constructor(){super(...arguments);this.entryId="";this.taskId="";this.taskName="";this.lang="en";this.checklist=[];this.adaptiveEnabled=!1;this.taskType="";this.readingUnit="";this.restockDefault=null;this.restockUnitCost=null;this.currencySymbol="";this.parts=[];this.consumesParts=[];this.consumesInfo=[];this.requiredFields=[];this._open=!1;this._notes="";this._cost="";this._duration="";this._loading=!1;this._error="";this._checklistState={};this._feedback="needed";this._photoDocId="";this._photoPreview="";this._photoUploading=!1;this._readingValue="";this._restockQty="";this._usedParts={};this.checklistPrefill={}}open(){this._open||(this._open=!0,this._notes="",this._cost="",this._duration="",this._error="",this._checklistState=Object.fromEntries(this.checklist.map((e,t)=>[String(t),!!this.checklistPrefill[e]]).filter(([,e])=>e)),this._feedback="needed",this._photoDocId="",this._photoPreview="",this._photoUploading=!1,this._readingValue="",this._restockQty=this.restockDefault!==null?String(this.restockDefault):"",this._usedParts=Object.fromEntries(this.consumesParts.map(e=>[_(e),{...e}])))}_toggleCheck(e){let t=String(e);this._checklistState={...this._checklistState,[t]:!this._checklistState[t]}}_setFeedback(e){this._feedback=e}async _onPhotoInput(e){let t=e.target,o=t.files?.[0];if(t.value="",!!o){this._photoUploading=!0,this._error="";try{let c=new FormData;c.append("entry_id",this.entryId),c.append("tags","photo"),c.append("file",o,o.name);let p=await fetch("/api/maintenance_supporter/document/upload",{method:"POST",headers:{Authorization:`Bearer ${this.hass.auth?.data?.access_token??""}`},body:c});if(!p.ok){this._error=p.status===413?r("doc_too_large",this.lang):r("doc_upload_failed",this.lang);return}let u=await p.json();u.id&&(this._photoDocId=u.id,this._photoPreview=URL.createObjectURL(o))}catch{this._error=r("doc_upload_failed",this.lang)}finally{this._photoUploading=!1}}}_removePhoto(){this._photoPreview&&URL.revokeObjectURL(this._photoPreview),this._photoDocId="",this._photoPreview=""}async _complete(){this._loading=!0,this._error="";try{let e={type:"maintenance_supporter/task/complete",entry_id:this.entryId,task_id:this.taskId};if(this._notes&&(e.notes=this._notes),this._cost){let t=parseFloat(this._cost);!isNaN(t)&&t>=0&&(e.cost=t)}if(this._duration){let t=parseInt(this._duration,10);!isNaN(t)&&t>=0&&(e.duration=t)}if(this.checklist.length>0&&(e.checklist_state=this._checklistState),this.adaptiveEnabled&&(e.feedback=this._feedback),this._photoDocId&&(e.photo_doc_id=this._photoDocId),this._readingValue!==""){let t=parseFloat(this._readingValue);isNaN(t)||(e.reading_value=t)}if(this.restockDefault!==null&&this._restockQty!==""){let t=parseFloat(this._restockQty);!isNaN(t)&&t>=1&&(e.restock_quantity=t)}this.parts.length>0&&(e.used_parts=Object.values(this._usedParts).filter(t=>Number.isFinite(t.quantity)&&t.quantity>0).map(t=>t.entry_id?{part_id:t.part_id,quantity:t.quantity,entry_id:t.entry_id}:{part_id:t.part_id,quantity:t.quantity})),await this.hass.connection.sendMessagePromise(e),this._open=!1,this.dispatchEvent(new CustomEvent("task-completed"))}catch(e){this._error=g(e,this.lang,r("save_error",this.lang))}finally{this._loading=!1}}get _missingRequired(){let e={notes:this._notes.trim()!=="",cost:this._cost.trim()!=="",duration:this._duration.trim()!=="",photo:this._photoDocId!=="",user:!!this.hass?.user};return this.requiredFields.filter(t=>!e[t])}_req(e){return this.requiredFields.includes(e)?a`<span class="req-mark" aria-hidden="true">*</span>`:d}_partsCostSuggestion(){if(this.restockDefault!==null){let o=parseFloat(this._restockQty);return this.restockUnitCost==null||!Number.isFinite(o)||o<=0?null:Math.round(this.restockUnitCost*o*100)/100}if(!this.parts.length)return null;let e=0,t=!1;for(let o of Object.values(this._usedParts)){let c=this.parts.find(p=>_({part_id:p.id,entry_id:p.entry_id})===_(o));c?.cost!=null&&(e+=c.cost*(o.quantity||1),t=!0)}return t?Math.round(e*100)/100:null}_renderCostSuggestion(e){if(this._cost.trim()!=="")return d;let t=this._partsCostSuggestion();if(t==null||t<=0)return d;let o=`${t.toFixed(2)}${this.currencySymbol?` ${this.currencySymbol}`:""}`;return a`<button
|
import{b as m}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-RCMO6YCL.js";import{a as _}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-AIMCOREG.js";import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NU5DR7VT.js";import{a as s,b,c as a,f as d,g as v,i as n,j as l,n as r,x as k}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var i=class extends v{constructor(){super(...arguments);this.entryId="";this.taskId="";this.taskName="";this.lang="en";this.checklist=[];this.adaptiveEnabled=!1;this.taskType="";this.readingUnit="";this.restockDefault=null;this.restockUnitCost=null;this.currencySymbol="";this.parts=[];this.consumesParts=[];this.consumesInfo=[];this.requiredFields=[];this._open=!1;this._notes="";this._cost="";this._duration="";this._loading=!1;this._error="";this._checklistState={};this._feedback="needed";this._photoDocId="";this._photoPreview="";this._photoUploading=!1;this._readingValue="";this._restockQty="";this._usedParts={};this.checklistPrefill={}}open(){this._open||(this._open=!0,this._notes="",this._cost="",this._duration="",this._error="",this._checklistState=Object.fromEntries(this.checklist.map((e,t)=>[String(t),!!this.checklistPrefill[e]]).filter(([,e])=>e)),this._feedback="needed",this._photoDocId="",this._photoPreview="",this._photoUploading=!1,this._readingValue="",this._restockQty=this.restockDefault!==null?String(this.restockDefault):"",this._usedParts=Object.fromEntries(this.consumesParts.map(e=>[_(e),{...e}])))}_toggleCheck(e){let t=String(e);this._checklistState={...this._checklistState,[t]:!this._checklistState[t]}}_setFeedback(e){this._feedback=e}async _onPhotoInput(e){let t=e.target,o=t.files?.[0];if(t.value="",!!o){this._photoUploading=!0,this._error="";try{let c=new FormData;c.append("entry_id",this.entryId),c.append("tags","photo"),c.append("file",o,o.name);let p=await fetch("/api/maintenance_supporter/document/upload",{method:"POST",headers:{Authorization:`Bearer ${this.hass.auth?.data?.access_token??""}`},body:c});if(!p.ok){this._error=p.status===413?r("doc_too_large",this.lang):r("doc_upload_failed",this.lang);return}let u=await p.json();u.id&&(this._photoDocId=u.id,this._photoPreview=URL.createObjectURL(o))}catch{this._error=r("doc_upload_failed",this.lang)}finally{this._photoUploading=!1}}}_removePhoto(){this._photoPreview&&URL.revokeObjectURL(this._photoPreview),this._photoDocId="",this._photoPreview=""}async _complete(){this._loading=!0,this._error="";try{let e={type:"maintenance_supporter/task/complete",entry_id:this.entryId,task_id:this.taskId};if(this._notes&&(e.notes=this._notes),this._cost){let t=parseFloat(this._cost);!isNaN(t)&&t>=0&&(e.cost=t)}if(this._duration){let t=parseInt(this._duration,10);!isNaN(t)&&t>=0&&(e.duration=t)}if(this.checklist.length>0&&(e.checklist_state=this._checklistState),this.adaptiveEnabled&&(e.feedback=this._feedback),this._photoDocId&&(e.photo_doc_id=this._photoDocId),this._readingValue!==""){let t=parseFloat(this._readingValue);isNaN(t)||(e.reading_value=t)}if(this.restockDefault!==null&&this._restockQty!==""){let t=parseFloat(this._restockQty);!isNaN(t)&&t>=1&&(e.restock_quantity=t)}this.parts.length>0&&(e.used_parts=Object.values(this._usedParts).filter(t=>Number.isFinite(t.quantity)&&t.quantity>0).map(t=>t.entry_id?{part_id:t.part_id,quantity:t.quantity,entry_id:t.entry_id}:{part_id:t.part_id,quantity:t.quantity})),await this.hass.connection.sendMessagePromise(e),this._open=!1,this.dispatchEvent(new CustomEvent("task-completed"))}catch(e){this._error=g(e,this.lang,r("save_error",this.lang))}finally{this._loading=!1}}get _missingRequired(){let e={notes:this._notes.trim()!=="",cost:this._cost.trim()!=="",duration:this._duration.trim()!=="",photo:this._photoDocId!=="",user:!!this.hass?.user};return this.requiredFields.filter(t=>!e[t])}_req(e){return this.requiredFields.includes(e)?a`<span class="req-mark" aria-hidden="true">*</span>`:d}_partsCostSuggestion(){if(this.restockDefault!==null){let o=parseFloat(this._restockQty);return this.restockUnitCost==null||!Number.isFinite(o)||o<=0?null:Math.round(this.restockUnitCost*o*100)/100}if(!this.parts.length)return null;let e=0,t=!1;for(let o of Object.values(this._usedParts)){let c=this.parts.find(p=>_({part_id:p.id,entry_id:p.entry_id})===_(o));c?.cost!=null&&(e+=c.cost*(o.quantity||1),t=!0)}return t?Math.round(e*100)/100:null}_renderCostSuggestion(e){if(this._cost.trim()!=="")return d;let t=this._partsCostSuggestion();if(t==null||t<=0)return d;let o=`${t.toFixed(2)}${this.currencySymbol?` ${this.currencySymbol}`:""}`;return a`<button
|
||||||
type="button"
|
type="button"
|
||||||
class="cost-suggestion"
|
class="cost-suggestion"
|
||||||
@click=${()=>this._cost=t.toFixed(2)}
|
@click=${()=>this._cost=t.toFixed(2)}
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-ZK3W7TF6.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LJXSDCLS.js";import{a as r,b as _,c as l,f as o,g as p,i as d,j as s,n as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var e=class extends p{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return this.hass?.language??navigator.language.split("-")[0]??"en"}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(a,n){this._entryId=a,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(a){this._error=h(a,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(a=>a.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let a=this._lang,n=this._entryId?i("edit_object",a):i("new_object",a);return l`
|
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-VNISEOIC.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NU5DR7VT.js";import{a as r,b as _,c as l,f as o,g as p,i as d,j as s,n as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var e=class extends p{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return this.hass?.language??navigator.language.split("-")[0]??"en"}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(a,n){this._entryId=a,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(a){this._error=h(a,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(a=>a.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let a=this._lang,n=this._entryId?i("edit_object",a):i("new_object",a);return l`
|
||||||
<ha-dialog open @closed=${this._close}>
|
<ha-dialog open @closed=${this._close}>
|
||||||
<div class="dialog-title">${n}</div>
|
<div class="dialog-title">${n}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
-143
@@ -1,143 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
|
||||||
import"/maintenance_supporter_panelfiles/panel-chunks/chunk-BDAGEP22.js";import{a as h}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as r,b as _,c as l,f as o,g as p,i as d,j as s,n as i}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var e=class extends p{constructor(){super(...arguments);this.objects=[];this._open=!1;this._loading=!1;this._error="";this._name="";this._manufacturer="";this._model="";this._serialNumber="";this._areaId="";this._installationDate="";this._warrantyExpiry="";this._documentationUrl="";this._notes="";this._haDeviceId="";this._parentEntryId="";this._entryId=null}get _lang(){return this.hass?.language??navigator.language.split("-")[0]??"en"}openCreate(){this._entryId=null,this._name="",this._manufacturer="",this._model="",this._serialNumber="",this._areaId="",this._installationDate="",this._warrantyExpiry="",this._documentationUrl="",this._notes="",this._haDeviceId="",this._parentEntryId="",this._error="",this._open=!0}openEdit(a,n){this._entryId=a,this._name=n.name||"",this._manufacturer=n.manufacturer||"",this._model=n.model||"",this._serialNumber=n.serial_number||"",this._areaId=n.area_id||"",this._installationDate=n.installation_date||"",this._warrantyExpiry=n.warranty_expiry||"",this._documentationUrl=n.documentation_url||"",this._notes=n.notes||"",this._haDeviceId=n.ha_device_id||"",this._parentEntryId=n.parent_entry_id||"",this._error="",this._open=!0}async _save(){if(!this._loading&&this._name.trim()){this._loading=!0,this._error="";try{this._entryId?await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/update",entry_id:this._entryId,name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}):await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/object/create",name:this._name,manufacturer:this._manufacturer||null,model:this._model||null,serial_number:this._serialNumber||null,area_id:this._areaId||null,installation_date:this._installationDate||null,warranty_expiry:this._warrantyExpiry||null,documentation_url:this._documentationUrl.trim()||null,notes:this._notes.trim()||null,ha_device_id:this._haDeviceId||null,parent_entry_id:this._parentEntryId||null}),this._open=!1,this.dispatchEvent(new CustomEvent("object-saved"))}catch(a){this._error=h(a,this._lang,i("save_error",this._lang))}finally{this._loading=!1}}}_parentChoices(){return(this.objects||[]).filter(a=>a.entry_id!==this._entryId)}_close(){this._open=!1}render(){if(!this._open)return l``;let a=this._lang,n=this._entryId?i("edit_object",a):i("new_object",a);return l`
|
|
||||||
<ha-dialog open @closed=${this._close}>
|
|
||||||
<div class="dialog-title">${n}</div>
|
|
||||||
<div class="content">
|
|
||||||
${this._error?l`<div class="error">${this._error}</div>`:o}
|
|
||||||
<ms-textfield
|
|
||||||
label="${i("name",a)}"
|
|
||||||
required
|
|
||||||
.value=${this._name}
|
|
||||||
@input=${t=>this._name=t.target.value}
|
|
||||||
></ms-textfield>
|
|
||||||
<ms-textfield
|
|
||||||
label="${i("manufacturer_optional",a)}"
|
|
||||||
.value=${this._manufacturer}
|
|
||||||
@input=${t=>this._manufacturer=t.target.value}
|
|
||||||
></ms-textfield>
|
|
||||||
<ms-textfield
|
|
||||||
label="${i("model_optional",a)}"
|
|
||||||
.value=${this._model}
|
|
||||||
@input=${t=>this._model=t.target.value}
|
|
||||||
></ms-textfield>
|
|
||||||
<ms-textfield
|
|
||||||
label="${i("serial_number_optional",a)}"
|
|
||||||
.value=${this._serialNumber}
|
|
||||||
@input=${t=>this._serialNumber=t.target.value}
|
|
||||||
></ms-textfield>
|
|
||||||
<ms-textfield
|
|
||||||
label="${i("documentation_url_optional",a)}"
|
|
||||||
type="url"
|
|
||||||
.value=${this._documentationUrl}
|
|
||||||
@input=${t=>this._documentationUrl=t.target.value}
|
|
||||||
></ms-textfield>
|
|
||||||
<ha-area-picker
|
|
||||||
.hass=${this.hass}
|
|
||||||
label="${i("area_id_optional",a)}"
|
|
||||||
.value=${this._areaId}
|
|
||||||
@value-changed=${t=>this._areaId=t.detail.value||""}
|
|
||||||
></ha-area-picker>
|
|
||||||
<ms-textfield
|
|
||||||
label="${i("installation_date_optional",a)}"
|
|
||||||
type="date"
|
|
||||||
.value=${this._installationDate}
|
|
||||||
@input=${t=>this._installationDate=t.target.value}
|
|
||||||
></ms-textfield>
|
|
||||||
<ms-textfield
|
|
||||||
label="${i("warranty_expiry_optional",a)}"
|
|
||||||
type="date"
|
|
||||||
.value=${this._warrantyExpiry}
|
|
||||||
@input=${t=>this._warrantyExpiry=t.target.value}
|
|
||||||
></ms-textfield>
|
|
||||||
<ha-form
|
|
||||||
.hass=${this.hass}
|
|
||||||
.data=${{device:this._haDeviceId||void 0}}
|
|
||||||
.schema=${[{name:"device",selector:{device:{}}}]}
|
|
||||||
.computeLabel=${()=>i("link_device_optional",a)}
|
|
||||||
@value-changed=${t=>this._haDeviceId=t.detail.value?.device||""}
|
|
||||||
></ha-form>
|
|
||||||
${this._parentChoices().length?l`<label class="textarea-field">
|
|
||||||
<span class="textarea-label">${i("parent_object_optional",a)}</span>
|
|
||||||
<select
|
|
||||||
class="parent-select"
|
|
||||||
.value=${this._parentEntryId}
|
|
||||||
@change=${t=>this._parentEntryId=t.target.value}
|
|
||||||
>
|
|
||||||
<option value="" ?selected=${!this._parentEntryId}>
|
|
||||||
${i("parent_none",a)}
|
|
||||||
</option>
|
|
||||||
${this._parentChoices().map(t=>l`<option
|
|
||||||
value=${t.entry_id}
|
|
||||||
?selected=${this._parentEntryId===t.entry_id}
|
|
||||||
>${t.object.name}</option>`)}
|
|
||||||
</select>
|
|
||||||
</label>`:o}
|
|
||||||
<label class="textarea-field">
|
|
||||||
<span class="textarea-label">${i("object_notes_optional",a)}</span>
|
|
||||||
<textarea
|
|
||||||
rows="3"
|
|
||||||
.value=${this._notes}
|
|
||||||
@input=${t=>this._notes=t.target.value}
|
|
||||||
></textarea>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="dialog-actions">
|
|
||||||
<ha-button appearance="plain" @click=${this._close}>
|
|
||||||
${i("cancel",this._lang)}
|
|
||||||
</ha-button>
|
|
||||||
<ha-button
|
|
||||||
@click=${this._save}
|
|
||||||
.disabled=${this._loading||!this._name.trim()}
|
|
||||||
>
|
|
||||||
${this._loading?i("saving",this._lang):i("save",this._lang)}
|
|
||||||
</ha-button>
|
|
||||||
</div>
|
|
||||||
</ha-dialog>
|
|
||||||
`}};e.styles=_`
|
|
||||||
.dialog-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 16px;
|
|
||||||
min-width: 300px;
|
|
||||||
}
|
|
||||||
.dialog-actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 8px;
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
ms-textfield {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.textarea-field {
|
|
||||||
display: flex; flex-direction: column; gap: 4px;
|
|
||||||
}
|
|
||||||
.textarea-label {
|
|
||||||
font-size: 12px; color: var(--secondary-text-color, #888); font-weight: 500;
|
|
||||||
}
|
|
||||||
.textarea-field textarea {
|
|
||||||
padding: 8px 10px; font-size: 14px; font-family: inherit;
|
|
||||||
background: var(--secondary-background-color, rgba(0,0,0,0.06));
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
|
||||||
resize: vertical;
|
|
||||||
}
|
|
||||||
.textarea-field textarea:focus {
|
|
||||||
outline: none; border-color: var(--primary-color);
|
|
||||||
}
|
|
||||||
.parent-select {
|
|
||||||
padding: 8px 10px; font-size: 14px; font-family: inherit;
|
|
||||||
background: var(--secondary-background-color, rgba(0,0,0,0.06));
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
|
||||||
}
|
|
||||||
.error {
|
|
||||||
color: var(--error-color, #f44336);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
`,r([d({attribute:!1})],e.prototype,"hass",2),r([d({attribute:!1})],e.prototype,"objects",2),r([s()],e.prototype,"_open",2),r([s()],e.prototype,"_loading",2),r([s()],e.prototype,"_error",2),r([s()],e.prototype,"_name",2),r([s()],e.prototype,"_manufacturer",2),r([s()],e.prototype,"_model",2),r([s()],e.prototype,"_serialNumber",2),r([s()],e.prototype,"_areaId",2),r([s()],e.prototype,"_installationDate",2),r([s()],e.prototype,"_warrantyExpiry",2),r([s()],e.prototype,"_documentationUrl",2),r([s()],e.prototype,"_notes",2),r([s()],e.prototype,"_haDeviceId",2),r([s()],e.prototype,"_parentEntryId",2),r([s()],e.prototype,"_entryId",2);customElements.get("maintenance-object-dialog")||customElements.define("maintenance-object-dialog",e);export{e as MaintenanceObjectDialog};
|
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{a,b as v,c as n,f as g,g as b,i as m,j as c,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";function p(l){return l.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function x(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":p(l)}function $(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var r=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,o,s){this._entryId=e,this._taskId=i,this._objectName=o,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let o=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&o.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(o);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let o=i?.code,s=i?.message;this._error=o==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,o=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let h=this.lang||"en",d=p(i),u=p(o),_=!!this._completeResult,f=p(t("qr_action_view",h)),w=p(t("qr_action_complete",h));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
import{a,b as v,c as n,f as g,g as b,i as m,j as c,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";function p(l){return l.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function x(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":p(l)}function $(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var r=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,o,s){this._entryId=e,this._taskId=i,this._objectName=o,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let o=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&o.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(o);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let o=i?.code,s=i?.message;this._error=o==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,o=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let h=this.lang||"en",d=p(i),u=p(o),_=!!this._completeResult,f=p(t("qr_action_view",h)),w=p(t("qr_action_complete",h));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||||
<meta name="color-scheme" content="light">
|
<meta name="color-scheme" content="light">
|
||||||
<title>${d}</title>
|
<title>${d}</title>
|
||||||
<style>
|
<style>
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
|
||||||
import{a,b as v,c as n,f as g,g as b,i as m,j as c,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";function p(l){return l.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function x(l){return!l.startsWith("data:image/svg+xml,")&&!l.startsWith("data:image/png;base64,")?"":p(l)}function $(l){return l.replace(/[/\\:*?"<>|#%]+/g,"").replace(/\s+/g,"-").toLowerCase().substring(0,100)}var r=class extends b{constructor(){super(...arguments);this.lang="en";this._open=!1;this._loading=!1;this._error="";this._viewResult=null;this._completeResult=null;this._urlMode="companion";this._entryId="";this._taskId=null;this._objectName="";this._taskName="";this._generateSeq=0}openForObject(e,i){this._entryId=e,this._taskId=null,this._objectName=i,this._taskName="",this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}openForTask(e,i,o,s){this._entryId=e,this._taskId=i,this._objectName=o,this._taskName=s,this._urlMode="companion",this._error="",this._viewResult=null,this._completeResult=null,this._open=!0,this._generate()}async _generate(){let e=++this._generateSeq;this._loading=!0,this._error="",this._viewResult=null,this._completeResult=null;try{let i={type:"maintenance_supporter/qr/generate",entry_id:this._entryId,url_mode:this._urlMode};this._taskId&&(i.task_id=this._taskId);let o=[this.hass.connection.sendMessagePromise({...i,action:"view"})];this._taskId&&o.push(this.hass.connection.sendMessagePromise({...i,action:"complete"}));let s=await Promise.all(o);if(e!==this._generateSeq)return;this._viewResult=s[0],s.length>1&&(this._completeResult=s[1])}catch(i){if(e!==this._generateSeq)return;let o=i?.code,s=i?.message;this._error=o==="no_url"||typeof s=="string"&&s.includes("No Home Assistant URL")?t("qr_error_no_url",this.lang):t("qr_error",this.lang)}finally{e===this._generateSeq&&(this._loading=!1)}}_setUrlMode(e){this._urlMode!==e&&(this._urlMode=e,this._generate())}_print(){if(!this._viewResult)return;let e=this._viewResult,i=e.label.task_name?`${e.label.object_name} \u2014 ${e.label.task_name}`:e.label.object_name,o=[e.label.manufacturer,e.label.model].filter(Boolean).join(" "),s=window.open("","_blank","width=600,height=500");if(!s)return;let h=this.lang||"en",d=p(i),u=p(o),_=!!this._completeResult,f=p(t("qr_action_view",h)),w=p(t("qr_action_complete",h));s.document.write(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
|
||||||
<meta name="color-scheme" content="light">
|
|
||||||
<title>${d}</title>
|
|
||||||
<style>
|
|
||||||
/* Printable sheet \u2014 must not inherit the phone's dark theme. The QR images
|
|
||||||
carry their own white quiet zone and stay scannable either way, but the
|
|
||||||
labels below are explicit dark greys and would vanish on a WebView's dark
|
|
||||||
canvas. Same reasoning as helpers/report.ts. */
|
|
||||||
:root{color-scheme:light}
|
|
||||||
body{font-family:sans-serif;text-align:center;padding:20px;background:#fff;color:#1a1a1a}
|
|
||||||
h2{margin:0 0 4px}
|
|
||||||
.sub{color:#666;font-size:14px;margin-bottom:16px}
|
|
||||||
.qr-row{display:flex;justify-content:center;gap:24px;margin:12px 0}
|
|
||||||
.qr-col{display:flex;flex-direction:column;align-items:center;gap:6px}
|
|
||||||
.qr-col img{width:${_?"200px":"280px"}}
|
|
||||||
.qr-label{font-size:13px;font-weight:500;color:#333}
|
|
||||||
.url{font-size:10px;color:#999;word-break:break-all;margin-top:8px;max-width:480px}
|
|
||||||
</style></head><body>
|
|
||||||
<h2>${d}</h2>
|
|
||||||
${u?`<div class="sub">${u}</div>`:""}
|
|
||||||
<div class="qr-row">
|
|
||||||
<div class="qr-col">
|
|
||||||
<img src="${x(this._viewResult.svg_data_uri)}" alt="QR Info" />
|
|
||||||
<div class="qr-label">${f}</div>
|
|
||||||
</div>
|
|
||||||
${_?`<div class="qr-col">
|
|
||||||
<img src="${x(this._completeResult.svg_data_uri)}" alt="QR Complete" />
|
|
||||||
<div class="qr-label">${w}</div>
|
|
||||||
</div>`:""}
|
|
||||||
</div>
|
|
||||||
<div class="url">${p(this._viewResult.url)}</div>
|
|
||||||
<script>setTimeout(()=>window.print(),300)<\/script>
|
|
||||||
</body></html>`),s.document.close()}_downloadSvg(e,i){let o=decodeURIComponent(e.svg_data_uri.replace("data:image/svg+xml,","")),s=new Blob([o],{type:"image/svg+xml"}),h=URL.createObjectURL(s),d=document.createElement("a");d.href=h;let u=this._taskName?`${this._objectName}-${this._taskName}`:this._objectName;d.download=`qr-${$(u)}-${i}.svg`,d.click(),URL.revokeObjectURL(h)}_close(){this._open=!1,this._viewResult=null,this._completeResult=null,this._error="",this._loading=!1}render(){if(!this._open)return n``;let e=this.lang||this.hass?.language||"en",i=this._taskName?`${t("qr_code",e)}: ${this._objectName} \u2014 ${this._taskName}`:`${t("qr_code",e)}: ${this._objectName}`,o=!!this._viewResult;return n`
|
|
||||||
<ha-dialog open @closed=${this._close}>
|
|
||||||
<div class="dialog-title">${i}</div>
|
|
||||||
<div class="content">
|
|
||||||
${this._loading?n`<div class="loading">${t("qr_generating",e)}</div>`:this._error?n`<div class="error">${this._error}</div>`:o?n`
|
|
||||||
<div class="qr-pair">
|
|
||||||
<div class="qr-item">
|
|
||||||
<img
|
|
||||||
class="qr-image ${this._completeResult?"small":""}"
|
|
||||||
src="${this._viewResult.svg_data_uri}"
|
|
||||||
alt="QR Info"
|
|
||||||
/>
|
|
||||||
<div class="qr-item-label">${t("qr_action_view",e)}</div>
|
|
||||||
<button class="dl-btn"
|
|
||||||
@click=${()=>this._downloadSvg(this._viewResult,"info")}>
|
|
||||||
<ha-icon icon="mdi:download"></ha-icon>
|
|
||||||
${t("qr_download",e)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
${this._completeResult?n`
|
|
||||||
<div class="qr-item">
|
|
||||||
<img
|
|
||||||
class="qr-image small"
|
|
||||||
src="${this._completeResult.svg_data_uri}"
|
|
||||||
alt="QR Complete"
|
|
||||||
/>
|
|
||||||
<div class="qr-item-label">${t("qr_action_complete",e)}</div>
|
|
||||||
<button class="dl-btn"
|
|
||||||
@click=${()=>this._downloadSvg(this._completeResult,"complete")}>
|
|
||||||
<ha-icon icon="mdi:download"></ha-icon>
|
|
||||||
${t("qr_download",e)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
`:g}
|
|
||||||
</div>
|
|
||||||
<div class="url-display">${this._viewResult.url}</div>
|
|
||||||
`:g}
|
|
||||||
<div class="action-row">
|
|
||||||
<label>${t("qr_url_mode",e)}</label>
|
|
||||||
<div class="action-toggle">
|
|
||||||
<button class="toggle-btn ${this._urlMode==="companion"?"active":""}"
|
|
||||||
@click=${()=>this._setUrlMode("companion")}>${t("qr_mode_companion",e)}</button>
|
|
||||||
<button class="toggle-btn ${this._urlMode==="local"?"active":""}"
|
|
||||||
@click=${()=>this._setUrlMode("local")}>${t("qr_mode_local",e)}</button>
|
|
||||||
<button class="toggle-btn ${this._urlMode==="server"?"active":""}"
|
|
||||||
@click=${()=>this._setUrlMode("server")}>${t("qr_mode_server",e)}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dialog-actions">
|
|
||||||
<ha-button appearance="plain" @click=${this._close}>
|
|
||||||
${t("cancel",e)}
|
|
||||||
</ha-button>
|
|
||||||
<ha-button
|
|
||||||
@click=${this._print}
|
|
||||||
.disabled=${!o}
|
|
||||||
>
|
|
||||||
${t("qr_print",e)}
|
|
||||||
</ha-button>
|
|
||||||
</div>
|
|
||||||
</ha-dialog>
|
|
||||||
`}};r.styles=v`
|
|
||||||
.dialog-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 16px;
|
|
||||||
min-width: 300px;
|
|
||||||
}
|
|
||||||
.dialog-actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 8px;
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
.qr-pair {
|
|
||||||
display: flex;
|
|
||||||
gap: 20px;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.qr-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
.qr-image {
|
|
||||||
width: 240px;
|
|
||||||
height: 240px;
|
|
||||||
image-rendering: pixelated;
|
|
||||||
}
|
|
||||||
.qr-image.small {
|
|
||||||
width: 180px;
|
|
||||||
height: 180px;
|
|
||||||
}
|
|
||||||
.qr-item-label {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.dl-btn {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
background: none;
|
|
||||||
border: 1px solid var(--divider-color, #e0e0e0);
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
padding: 6px 14px;
|
|
||||||
border-radius: 18px;
|
|
||||||
transition: background 0.2s, border-color 0.2s;
|
|
||||||
}
|
|
||||||
.dl-btn:hover {
|
|
||||||
background: var(--secondary-background-color, #f5f5f5);
|
|
||||||
border-color: var(--primary-color);
|
|
||||||
}
|
|
||||||
.dl-btn ha-icon {
|
|
||||||
--mdc-icon-size: 18px;
|
|
||||||
}
|
|
||||||
.url-display {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
word-break: break-all;
|
|
||||||
text-align: center;
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
|
||||||
.loading {
|
|
||||||
padding: 40px 0;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
.error {
|
|
||||||
padding: 20px 0;
|
|
||||||
color: var(--error-color, #f44336);
|
|
||||||
}
|
|
||||||
.action-row {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 6px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.action-row label {
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
.action-toggle {
|
|
||||||
display: flex;
|
|
||||||
gap: 4px;
|
|
||||||
background: var(--divider-color, #e0e0e0);
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
.toggle-btn {
|
|
||||||
flex: 1;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 13px;
|
|
||||||
transition: all 0.2s;
|
|
||||||
line-height: 1.3;
|
|
||||||
}
|
|
||||||
.toggle-btn:hover {
|
|
||||||
background: rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
.toggle-btn.active {
|
|
||||||
background: var(--primary-color);
|
|
||||||
color: var(--text-primary-color, #fff);
|
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
`,a([m({attribute:!1})],r.prototype,"hass",2),a([m()],r.prototype,"lang",2),a([c()],r.prototype,"_open",2),a([c()],r.prototype,"_loading",2),a([c()],r.prototype,"_error",2),a([c()],r.prototype,"_viewResult",2),a([c()],r.prototype,"_completeResult",2),a([c()],r.prototype,"_urlMode",2);customElements.get("maintenance-qr-dialog")||customElements.define("maintenance-qr-dialog",r);export{r as MaintenanceQrDialog};
|
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{a as x,c as $,d as q}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-DV4UHMJC.js";import{a as T}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-I7J3AORE.js";import{a as l,b as w,c as r,e as k,f as p,g as E,i as b,j as d,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var S={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},j=m=>(..._)=>({_$litDirective$:m,values:_}),f=class{constructor(_){}get _$AU(){return this._$AM._$AU}_$AT(_,e,s){this._$Ct=_,this._$AM=e,this._$Ci=s}_$AS(_,e){return this.update(_,e)}update(_,e){return this.render(...e)}};var u=class extends f{constructor(_){if(super(_),this.it=p,_.type!==S.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(_){if(_===p||_==null)return this._t=void 0,this.it=_;if(_===k)return _;if(typeof _!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(_===this.it)return this._t;this.it=_;let e=[_];return e.raw=e,this._t={_$litType$:this.constructor.resultType,strings:e,values:[]}}};u.directiveName="unsafeHTML",u.resultType=1;var A=j(u);var H=["EUR","USD","GBP","JPY","CHF","CAD","AUD","NZD","CNY","INR","BRL","CZK","PLN","RUB","SEK","NOK","DKK","UAH"],c=class extends E{constructor(){super(...arguments);this.budget=null;this._settings=null;this._loading=!0;this._importCsv="";this._importLoading=!1;this._includeHistory=!0;this._toast="";this._testingNotification=!1;this._personTargets=[];this._testingUser="";this._users=[];this._savedViews=[];this._vacEnabled=!1;this._vacStart="";this._vacEnd="";this._vacBuffer=3;this._vacExempt=new Set;this._vacIsActive=!1;this._vacWindowEnd=null;this._vacAllTasks=[];this._vacPreview=[];this._vacPreviewLoading=!1;this._vacSaving=!1;this._qrObjects=[];this._qrSelectedEntries=new Set;this._qrActions=new Set(["view"]);this._qrUrlMode="companion";this._qrBatchLoading=!1;this._qrBatchResults=[];this._qrObjectsLoaded=!1;this._exportObjects=[];this._exportSelectedEntries=new Set;this._exportObjectsLoaded=!1;this._docArchiveLoading=!1;this._loaded=!1;this._userService=null;this._sendTestNotification=async e=>{e?this._testingUser=e:this._testingNotification=!0;try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/test_notification",...e?{user_id:e}:{}}),a=s.message||(s.success?t("test_notification_success",this._lang):t("test_notification_failed",this._lang));this._showToast(a)}catch{this._showToast(t("test_notification_failed",this._lang))}finally{e?this._testingUser="":this._testingNotification=!1}};this._allTemplates=[];this._templateCategories={};this._tplOpenGroups=new Set;this._templatesRequested=!1}get _lang(){return this.hass?.language||"en"}updated(e){super.updated(e),e.has("hass")&&this.hass&&!this._loaded?(this._loaded=!0,this._userService=new T(this.hass),this._loadSettings(),this._loadUsers()):e.has("hass")&&this.hass&&this._userService&&this._userService.updateHass(this.hass)}async _loadUsers(){if(this._userService){try{this._users=await this._userService.getUsers()}catch{this._users=[]}this._loadNotifyTargets()}}async _loadNotifyTargets(){try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/notify/user_targets"});this._personTargets=e.targets||[]}catch{this._personTargets=[]}}async _loadSettings(){this._loading=!0;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/settings"});this._settings=e,this._hydrateVacationFromSettings()}catch{}try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/views/list"});this._savedViews=e.views||[]}catch{}this._loading=!1}_hydrateVacationFromSettings(){let e=this._settings?.vacation;e&&(this._vacEnabled=e.enabled,this._vacStart=e.start||"",this._vacEnd=e.end||"",this._vacBuffer=e.buffer_days,this._vacExempt=new Set(e.exempt_task_ids||[]),this._vacIsActive=e.is_active,this._vacWindowEnd=e.window_end)}async _updateSetting(e,s){try{let a=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:{[e]:s}});this._settings=a,this._showToast(t("settings_saved",this._lang)),this.dispatchEvent(new CustomEvent("settings-changed"))}catch{this._showToast(t("action_error",this._lang))}}_showToast(e){this._toast=e,setTimeout(()=>{this._toast=""},3e3)}_downloadFile(e,s,a){q(e,s,a)}render(){let e=this._lang;return this._loading||!this._settings?r`<div class="settings-loading">Loading…</div>`:r`
|
import{a as x,c as $,d as q}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-T5QK5YQR.js";import{a as T}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-GKQ6LXK5.js";import{a as l,b as w,c as r,e as k,f as p,g as E,i as b,j as d,n as t}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var S={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},j=m=>(..._)=>({_$litDirective$:m,values:_}),f=class{constructor(_){}get _$AU(){return this._$AM._$AU}_$AT(_,e,s){this._$Ct=_,this._$AM=e,this._$Ci=s}_$AS(_,e){return this.update(_,e)}update(_,e){return this.render(...e)}};var u=class extends f{constructor(_){if(super(_),this.it=p,_.type!==S.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(_){if(_===p||_==null)return this._t=void 0,this.it=_;if(_===k)return _;if(typeof _!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(_===this.it)return this._t;this.it=_;let e=[_];return e.raw=e,this._t={_$litType$:this.constructor.resultType,strings:e,values:[]}}};u.directiveName="unsafeHTML",u.resultType=1;var A=j(u);var H=["EUR","USD","GBP","JPY","CHF","CAD","AUD","NZD","CNY","INR","BRL","CZK","PLN","RUB","SEK","NOK","DKK","UAH"],c=class extends E{constructor(){super(...arguments);this.budget=null;this._settings=null;this._loading=!0;this._importCsv="";this._importLoading=!1;this._includeHistory=!0;this._toast="";this._testingNotification=!1;this._personTargets=[];this._testingUser="";this._users=[];this._savedViews=[];this._vacEnabled=!1;this._vacStart="";this._vacEnd="";this._vacBuffer=3;this._vacExempt=new Set;this._vacIsActive=!1;this._vacWindowEnd=null;this._vacAllTasks=[];this._vacPreview=[];this._vacPreviewLoading=!1;this._vacSaving=!1;this._qrObjects=[];this._qrSelectedEntries=new Set;this._qrActions=new Set(["view"]);this._qrUrlMode="companion";this._qrBatchLoading=!1;this._qrBatchResults=[];this._qrObjectsLoaded=!1;this._exportObjects=[];this._exportSelectedEntries=new Set;this._exportObjectsLoaded=!1;this._docArchiveLoading=!1;this._loaded=!1;this._userService=null;this._sendTestNotification=async e=>{e?this._testingUser=e:this._testingNotification=!0;try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/test_notification",...e?{user_id:e}:{}}),a=s.message||(s.success?t("test_notification_success",this._lang):t("test_notification_failed",this._lang));this._showToast(a)}catch{this._showToast(t("test_notification_failed",this._lang))}finally{e?this._testingUser="":this._testingNotification=!1}};this._allTemplates=[];this._templateCategories={};this._tplOpenGroups=new Set;this._templatesRequested=!1}get _lang(){return this.hass?.language||"en"}updated(e){super.updated(e),e.has("hass")&&this.hass&&!this._loaded?(this._loaded=!0,this._userService=new T(this.hass),this._loadSettings(),this._loadUsers()):e.has("hass")&&this.hass&&this._userService&&this._userService.updateHass(this.hass)}async _loadUsers(){if(this._userService){try{this._users=await this._userService.getUsers()}catch{this._users=[]}this._loadNotifyTargets()}}async _loadNotifyTargets(){try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/notify/user_targets"});this._personTargets=e.targets||[]}catch{this._personTargets=[]}}async _loadSettings(){this._loading=!0;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/settings"});this._settings=e,this._hydrateVacationFromSettings()}catch{}try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/views/list"});this._savedViews=e.views||[]}catch{}this._loading=!1}_hydrateVacationFromSettings(){let e=this._settings?.vacation;e&&(this._vacEnabled=e.enabled,this._vacStart=e.start||"",this._vacEnd=e.end||"",this._vacBuffer=e.buffer_days,this._vacExempt=new Set(e.exempt_task_ids||[]),this._vacIsActive=e.is_active,this._vacWindowEnd=e.window_end)}async _updateSetting(e,s){try{let a=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:{[e]:s}});this._settings=a,this._showToast(t("settings_saved",this._lang)),this.dispatchEvent(new CustomEvent("settings-changed"))}catch{this._showToast(t("action_error",this._lang))}}_showToast(e){this._toast=e,setTimeout(()=>{this._toast=""},3e3)}_downloadFile(e,s,a){q(e,s,a)}render(){let e=this._lang;return this._loading||!this._settings?r`<div class="settings-loading">Loading…</div>`:r`
|
||||||
${this._renderFeatures(e)}
|
${this._renderFeatures(e)}
|
||||||
${this._renderPanelAccess(e)}
|
${this._renderPanelAccess(e)}
|
||||||
${this._renderGeneral(e)}
|
${this._renderGeneral(e)}
|
||||||
-1141
File diff suppressed because it is too large
Load Diff
-146
@@ -1,146 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
|
||||||
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-LJXSDCLS.js";import{a as l,b as m,c as i,f as h,g as v,i as u,j as d,n as p,p as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-C5W5B43R.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,f(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
|
|
||||||
<div class="overlay" @click=${this._close}>
|
|
||||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
|
||||||
<div class="title">${p("setups_title",t)}</div>
|
|
||||||
<div class="hint">${p("setups_hint",t)}</div>
|
|
||||||
${this._error?i`<div class="error">${this._error}</div>`:h}
|
|
||||||
|
|
||||||
${this._loading?i`<div class="loading">…</div>`:this._setups.length===0?i`<div class="empty">${p("setups_none",t)}</div>`:i`
|
|
||||||
<div class="list">
|
|
||||||
${this._setups.map(e=>{let r=this._selected.has(e.device_id),c=[e.integration_name,e.area_name].filter(Boolean).join(" \xB7 ");return i`
|
|
||||||
<label class="row">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
.checked=${r}
|
|
||||||
@change=${()=>this._toggle(e.device_id)}
|
|
||||||
/>
|
|
||||||
<div class="row-main">
|
|
||||||
<div class="row-top">
|
|
||||||
<span class="row-name">${e.device_name}</span>
|
|
||||||
</div>
|
|
||||||
<div class="row-sub">${c}</div>
|
|
||||||
<div class="row-target" @click=${s=>s.preventDefault()}>
|
|
||||||
→
|
|
||||||
${r&&this._objects.length>0?i`
|
|
||||||
<select
|
|
||||||
class="target-select"
|
|
||||||
@change=${s=>{let n=new Map(this._targets),o=s.target.value;o?n.set(e.device_id,o):n.delete(e.device_id),this._targets=n}}
|
|
||||||
>
|
|
||||||
<option value="" ?selected=${!this._targets.get(e.device_id)}>
|
|
||||||
${e.suggested_entry_id?e.suggested_object_name:p("setups_target_new",t).replace("{name}",e.suggested_object_name)}
|
|
||||||
</option>
|
|
||||||
${this._objects.filter(s=>s.entry_id!==e.suggested_entry_id).map(s=>i`<option
|
|
||||||
value=${s.entry_id}
|
|
||||||
?selected=${this._targets.get(e.device_id)===s.entry_id}
|
|
||||||
>
|
|
||||||
${s.name}
|
|
||||||
</option>`)}
|
|
||||||
</select>
|
|
||||||
`:i`${e.suggested_object_name}${e.suggested_entry_id?h:i` <span class="new-tag">${p("adopt_problem_new_object",t)}</span>`}`}
|
|
||||||
</div>
|
|
||||||
<div class="row-tasks">
|
|
||||||
${e.tasks.map(s=>i`<span class="chip" title=${s.entity_ids.join(", ")}>
|
|
||||||
<ha-icon icon="mdi:link-variant"></ha-icon>${s.task_name_localized||s.task_name}
|
|
||||||
</span>`)}
|
|
||||||
</div>
|
|
||||||
${r?e.tasks.filter(s=>s.direction==="usage_delta").map(s=>{let n=`${e.device_id} ${s.task_name}`;return i`
|
|
||||||
<div class="baseline-field" @click=${o=>o.preventDefault()}>
|
|
||||||
<span class="baseline-label"
|
|
||||||
>${s.task_name_localized||s.task_name} —
|
|
||||||
${p("setups_baseline_hint",t)}</span
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
step="any"
|
|
||||||
min="0"
|
|
||||||
.value=${this._baselines.get(n)??""}
|
|
||||||
@click=${o=>o.preventDefault()}
|
|
||||||
@input=${o=>{let _=new Map(this._baselines);_.set(n,o.target.value),this._baselines=_}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
`}):h}
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
`})}
|
|
||||||
</div>
|
|
||||||
`}
|
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<ha-button appearance="plain" @click=${this._close}>
|
|
||||||
${p("cancel",t)}
|
|
||||||
</ha-button>
|
|
||||||
<ha-button
|
|
||||||
@click=${this._adopt}
|
|
||||||
.disabled=${this._selected.size===0||this._adopting}
|
|
||||||
>
|
|
||||||
${p("setups_adopt",t)}
|
|
||||||
</ha-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`}};a.styles=m`
|
|
||||||
.overlay {
|
|
||||||
position: fixed;
|
|
||||||
inset: 0;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
background: var(--card-background-color, #fff);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 12px;
|
|
||||||
min-width: min(360px, calc(100vw - 24px));
|
|
||||||
max-width: 560px;
|
|
||||||
width: 90vw;
|
|
||||||
max-height: 80vh;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
.title { font-size: 18px; font-weight: 500; }
|
|
||||||
.hint { color: var(--secondary-text-color); font-size: 13px; }
|
|
||||||
.error { color: var(--error-color, #f44336); font-size: 13px; }
|
|
||||||
.loading, .empty { color: var(--secondary-text-color); font-size: 14px; padding: 12px 0; }
|
|
||||||
.list { display: flex; flex-direction: column; gap: 6px; overflow-y: auto; max-height: 50vh; }
|
|
||||||
.row {
|
|
||||||
display: flex; align-items: flex-start; gap: 10px; padding: 8px;
|
|
||||||
border: 1px solid var(--divider-color); border-radius: 6px; cursor: pointer;
|
|
||||||
}
|
|
||||||
.row input { margin-top: 2px; cursor: pointer; }
|
|
||||||
.row-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
|
|
||||||
.row-name { font-weight: 500; font-size: 13px; }
|
|
||||||
.row-sub, .row-target { color: var(--secondary-text-color); font-size: 12px; }
|
|
||||||
.new-tag { font-style: italic; }
|
|
||||||
.row-tasks { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
|
|
||||||
.chip {
|
|
||||||
display: inline-flex; align-items: center; gap: 4px;
|
|
||||||
font-size: 11px; padding: 2px 8px; border-radius: 10px;
|
|
||||||
background: var(--secondary-background-color, rgba(0, 0, 0, 0.06));
|
|
||||||
color: var(--primary-text-color); white-space: nowrap;
|
|
||||||
}
|
|
||||||
.chip ha-icon { --mdc-icon-size: 12px; color: var(--primary-color); }
|
|
||||||
.target-select {
|
|
||||||
font-size: 12px; padding: 2px 4px; max-width: 100%;
|
|
||||||
border: 1px solid var(--divider-color); border-radius: 4px;
|
|
||||||
background: var(--card-background-color, #fff);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
}
|
|
||||||
.baseline-field {
|
|
||||||
display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
|
|
||||||
margin-top: 4px; font-size: 12px; color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
.baseline-field input {
|
|
||||||
width: 110px; padding: 3px 6px; font-size: 12px;
|
|
||||||
border: 1px solid var(--divider-color); border-radius: 4px;
|
|
||||||
background: var(--card-background-color, #fff);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
}
|
|
||||||
.actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 8px; }
|
|
||||||
`,l([u({attribute:!1})],a.prototype,"hass",2),l([d()],a.prototype,"_open",2),l([d()],a.prototype,"_loading",2),l([d()],a.prototype,"_adopting",2),l([d()],a.prototype,"_error",2),l([d()],a.prototype,"_setups",2),l([d()],a.prototype,"_selected",2),l([d()],a.prototype,"_baselines",2),l([d()],a.prototype,"_targets",2),l([d()],a.prototype,"_objects",2);customElements.get("maintenance-suggested-setups-dialog")||customElements.define("maintenance-suggested-setups-dialog",a);export{a as MaintenanceSuggestedSetupsDialog};
|
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-XYTY2SBA.js";import{a as l,b as m,c as i,f as h,g as v,i as u,j as d,n as p,p as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NHOMCQWL.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,f(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
|
import{a as g}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-NU5DR7VT.js";import{a as l,b as m,c as i,f as h,g as v,i as u,j as d,n as p,p as f}from"/maintenance_supporter_panelfiles/panel-chunks/chunk-TSHS2WDI.js";var a=class extends v{constructor(){super(...arguments);this._open=!1;this._loading=!1;this._adopting=!1;this._error="";this._setups=[];this._selected=new Set;this._baselines=new Map;this._targets=new Map;this._objects=[];this._localeReady=!1;this._toggle=t=>{let e=new Set(this._selected);e.has(t)?e.delete(t):e.add(t),this._selected=e};this._adopt=async()=>{if(!(this._selected.size===0||this._adopting)){this._adopting=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/adopt",selections:[...this._selected].map(e=>{let r={device_id:e},c=this._targets.get(e);c&&(r.entry_id=c);let s=this._setups.find(n=>n.device_id===e);for(let n of s?.tasks??[]){let o=this._baselines.get(`${e} ${n.task_name}`),_=o?parseFloat(o):NaN;!isNaN(_)&&_>=0&&((r.baselines??={})[n.task_name]=_)}return r})});this.dispatchEvent(new CustomEvent("integration-setups-adopted",{bubbles:!0,composed:!0,detail:t})),this._open=!1}catch(t){this._error=g(t,this._lang)}finally{this._adopting=!1}}}}get _lang(){return this.hass?.language||"en"}updated(t){t.has("hass")&&this.hass&&!this._localeReady&&(this._localeReady=!0,f(this._lang).then(()=>this.requestUpdate()))}async open(){this._open=!0,this._loading=!0,this._error="",this._setups=[],this._selected=new Set;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/integration_setups/discover"});this._setups=t.setups||[],this._selected=new Set(this._setups.map(e=>e.device_id)),this._baselines=new Map,this._targets=new Map;try{let e=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/objects"});this._objects=(e.objects||[]).map(r=>({entry_id:r.entry_id,name:r.object?.name||r.entry_id})).sort((r,c)=>r.name.localeCompare(c.name))}catch{this._objects=[]}}catch(t){this._error=g(t,this._lang)}finally{this._loading=!1}}_close(){this._open=!1}render(){if(!this._open)return i``;let t=this._lang;return i`
|
||||||
<div class="overlay" @click=${this._close}>
|
<div class="overlay" @click=${this._close}>
|
||||||
<div class="card" @click=${e=>e.stopPropagation()}>
|
<div class="card" @click=${e=>e.stopPropagation()}>
|
||||||
<div class="title">${p("setups_title",t)}</div>
|
<div class="title">${p("setups_title",t)}</div>
|
||||||
-983
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
-125
@@ -1,125 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
|
||||||
import{a as v}from"./chunk-QCBC6YX3.js";import{a as u,b as o,d as h,e as b,f as y,g as l,h as g,i as r,k as m,t as p}from"./chunk-RNKC43AV.js";import{a as n}from"./chunk-LPNFL3AF.js";var x=80,s=class extends b{constructor(){super(...arguments);this._config={type:""};this._status=null;this._busy=!1;this._error="";this._localMonthly="";this._localYearly="";this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),m(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/budget_status"});this._status=t,this._localMonthly=t.monthly_budget?String(t.monthly_budget):"",this._localYearly=t.yearly_budget?String(t.yearly_budget):"",this._dirty=!1}catch(t){this._error=p(t,this._lang)}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=parseFloat(this._localMonthly),a=parseFloat(this._localYearly),i={};!isNaN(t)&&t>=0&&(i.budget_monthly=t),!isNaN(a)&&a>=0&&(i.budget_yearly=a),await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:i}),await this._load()}catch(t){this._error=p(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_budget"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,a=this._status;if(!a)return o`<ha-card><div class="loading">${r("loading",t)||"Loading\u2026"}</div></ha-card>`;let i=a.currency_symbol||g,_=a.alert_threshold_pct??x,f=[{label:r("budget_monthly",t)||"Monthly",spent:a.monthly_spent||0,budget:a.monthly_budget||0},{label:r("budget_yearly",t)||"Yearly",spent:a.yearly_spent||0,budget:a.yearly_budget||0}];return o`
|
|
||||||
<ha-card>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="header">
|
|
||||||
<div class="title">
|
|
||||||
<span class="emoji">💰</span>
|
|
||||||
<span>${this._config.title||r("settings_budget",t)||"Budget"}</span>
|
|
||||||
</div>
|
|
||||||
<span class="currency">${i}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
${this._error?o`<div class="error">${this._error}</div>`:h}
|
|
||||||
|
|
||||||
${f.map(e=>{if(!(e.budget>0))return o`
|
|
||||||
<div class="track spent-only">
|
|
||||||
<div class="track-label-row">
|
|
||||||
<label>${e.label}</label>
|
|
||||||
<span class="track-numbers ok">${e.spent.toFixed(0)} ${i}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;let d=Math.min(100,Math.max(0,e.spent/e.budget*100)),c=d>=100?"danger":d>=_?"warning":"ok";return o`
|
|
||||||
<div class="track">
|
|
||||||
<div class="track-label-row">
|
|
||||||
<label>${e.label}</label>
|
|
||||||
<span class="track-numbers ${c}">
|
|
||||||
${e.spent.toFixed(0)} / ${e.budget.toFixed(0)} ${i}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="bar"><div class="bar-fill ${c}" style="width:${d}%"></div></div>
|
|
||||||
</div>
|
|
||||||
`})}
|
|
||||||
|
|
||||||
${this._isAdmin?o`
|
|
||||||
<div class="inputs-row">
|
|
||||||
<div class="input-field">
|
|
||||||
<label>${r("budget_monthly_set",t)||"Set monthly"}</label>
|
|
||||||
<div class="input-wrap">
|
|
||||||
<input type="number" min="0" step="1"
|
|
||||||
.value=${this._localMonthly}
|
|
||||||
?disabled=${this._busy}
|
|
||||||
@input=${e=>{this._localMonthly=e.target.value,this._dirty=!0}} />
|
|
||||||
<span class="input-suffix">${i}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="input-field">
|
|
||||||
<label>${r("budget_yearly_set",t)||"Set yearly"}</label>
|
|
||||||
<div class="input-wrap">
|
|
||||||
<input type="number" min="0" step="1"
|
|
||||||
.value=${this._localYearly}
|
|
||||||
?disabled=${this._busy}
|
|
||||||
@input=${e=>{this._localYearly=e.target.value,this._dirty=!0}} />
|
|
||||||
<span class="input-suffix">${i}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="actions">
|
|
||||||
<button class="btn ${this._dirty?"primary":"muted"}"
|
|
||||||
@click=${this._save}
|
|
||||||
?disabled=${this._busy||!this._dirty}>
|
|
||||||
<ha-icon icon="${this._dirty?"mdi:content-save":"mdi:check"}"></ha-icon>
|
|
||||||
${this._dirty?r("save",t)||"Save":r("saved",t)||"Saved"}
|
|
||||||
</button>
|
|
||||||
<button class="btn link" @click=${this._onDeepLink}>
|
|
||||||
${r("budget_advanced",t)||"Currency, alerts\u2026"}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
`:o`
|
|
||||||
<button class="btn link" @click=${this._onDeepLink}>
|
|
||||||
${r("budget_open_panel",t)||"Open in panel"}
|
|
||||||
</button>
|
|
||||||
`}
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
`}};s.styles=[v,u`
|
|
||||||
.currency {
|
|
||||||
font-size: 14px; font-weight: 600;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
background: var(--secondary-background-color);
|
|
||||||
padding: 2px 10px; border-radius: 999px;
|
|
||||||
}
|
|
||||||
.track { display: flex; flex-direction: column; gap: 4px; }
|
|
||||||
.track-label-row {
|
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
|
||||||
}
|
|
||||||
.track-label-row label {
|
|
||||||
font-size: 12px; color: var(--secondary-text-color);
|
|
||||||
text-transform: uppercase; letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
.track-numbers { font-size: 13px; font-weight: 600; }
|
|
||||||
.track-numbers.ok { color: var(--primary-text-color); }
|
|
||||||
.track-numbers.warning { color: #ff9800; }
|
|
||||||
.track-numbers.danger { color: var(--error-color, #f44336); }
|
|
||||||
.bar {
|
|
||||||
height: 6px; background: var(--secondary-background-color);
|
|
||||||
border-radius: 3px; overflow: hidden;
|
|
||||||
}
|
|
||||||
.bar-fill { height: 100%; transition: width 0.3s; border-radius: 3px; }
|
|
||||||
.bar-fill.ok { background: var(--primary-color); }
|
|
||||||
.bar-fill.warning { background: #ff9800; }
|
|
||||||
.bar-fill.danger { background: var(--error-color, #f44336); }
|
|
||||||
.inputs-row {
|
|
||||||
display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
|
|
||||||
padding-top: 4px; border-top: 1px solid var(--divider-color);
|
|
||||||
}
|
|
||||||
.input-field { display: flex; flex-direction: column; gap: 4px; }
|
|
||||||
.input-field label {
|
|
||||||
font-size: 11px; color: var(--secondary-text-color);
|
|
||||||
text-transform: uppercase; letter-spacing: 0.3px;
|
|
||||||
}
|
|
||||||
.input-wrap { position: relative; display: flex; align-items: center; }
|
|
||||||
.input-wrap input {
|
|
||||||
flex: 1; padding: 6px 32px 6px 8px; font-size: 13px;
|
|
||||||
background: var(--secondary-background-color, #2c2c2c);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
|
||||||
font-family: inherit;
|
|
||||||
}
|
|
||||||
.input-suffix {
|
|
||||||
position: absolute; right: 8px;
|
|
||||||
color: var(--secondary-text-color); font-size: 13px;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.actions { display: flex; gap: 8px; align-items: center; }
|
|
||||||
`],n([y({attribute:!1})],s.prototype,"hass",2),n([l()],s.prototype,"_config",2),n([l()],s.prototype,"_status",2),n([l()],s.prototype,"_busy",2),n([l()],s.prototype,"_error",2),n([l()],s.prototype,"_localMonthly",2),n([l()],s.prototype,"_localYearly",2),n([l()],s.prototype,"_dirty",2);customElements.get("maintenance-budget-section-card")||customElements.define("maintenance-budget-section-card",s);window.customCards=window.customCards||[];window.customCards.push({type:"maintenance-budget-section-card",name:"Maintenance Supporter \u2014 Budget",description:"Inline monthly + yearly budget editor",preview:!1});export{s as MaintenanceBudgetSectionCard};
|
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{a as v}from"./chunk-XWMJNIQI.js";import{a as u,b as o,d as h,e as b,f as y,g as l,h as g,i as r,k as m,t as p}from"./chunk-TRW3CRLS.js";import{a as n}from"./chunk-UHANDS57.js";var x=80,s=class extends b{constructor(){super(...arguments);this._config={type:""};this._status=null;this._busy=!1;this._error="";this._localMonthly="";this._localYearly="";this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),m(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/budget_status"});this._status=t,this._localMonthly=t.monthly_budget?String(t.monthly_budget):"",this._localYearly=t.yearly_budget?String(t.yearly_budget):"",this._dirty=!1}catch(t){this._error=p(t,this._lang)}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=parseFloat(this._localMonthly),a=parseFloat(this._localYearly),i={};!isNaN(t)&&t>=0&&(i.budget_monthly=t),!isNaN(a)&&a>=0&&(i.budget_yearly=a),await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:i}),await this._load()}catch(t){this._error=p(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_budget"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,a=this._status;if(!a)return o`<ha-card><div class="loading">${r("loading",t)||"Loading\u2026"}</div></ha-card>`;let i=a.currency_symbol||g,_=a.alert_threshold_pct??x,f=[{label:r("budget_monthly",t)||"Monthly",spent:a.monthly_spent||0,budget:a.monthly_budget||0},{label:r("budget_yearly",t)||"Yearly",spent:a.yearly_spent||0,budget:a.yearly_budget||0}];return o`
|
import{a as v}from"./chunk-6INP67SU.js";import{a as u,b as o,d as h,e as b,f as y,g as l,h as g,i as r,k as m,t as p}from"./chunk-CWQRMTXS.js";import{a as n}from"./chunk-HQWGP2HE.js";var x=80,s=class extends b{constructor(){super(...arguments);this._config={type:""};this._status=null;this._busy=!1;this._error="";this._localMonthly="";this._localYearly="";this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),m(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/budget_status"});this._status=t,this._localMonthly=t.monthly_budget?String(t.monthly_budget):"",this._localYearly=t.yearly_budget?String(t.yearly_budget):"",this._dirty=!1}catch(t){this._error=p(t,this._lang)}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=parseFloat(this._localMonthly),a=parseFloat(this._localYearly),i={};!isNaN(t)&&t>=0&&(i.budget_monthly=t),!isNaN(a)&&a>=0&&(i.budget_yearly=a),await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/global/update",settings:i}),await this._load()}catch(t){this._error=p(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_budget"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,a=this._status;if(!a)return o`<ha-card><div class="loading">${r("loading",t)||"Loading\u2026"}</div></ha-card>`;let i=a.currency_symbol||g,_=a.alert_threshold_pct??x,f=[{label:r("budget_monthly",t)||"Monthly",spent:a.monthly_spent||0,budget:a.monthly_budget||0},{label:r("budget_yearly",t)||"Yearly",spent:a.yearly_spent||0,budget:a.yearly_budget||0}];return o`
|
||||||
<ha-card>
|
<ha-card>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{a as r}from"./chunk-RNKC43AV.js";var a=r`
|
import{a as r}from"./chunk-CWQRMTXS.js";var a=r`
|
||||||
ha-card { overflow: hidden; }
|
ha-card { overflow: hidden; }
|
||||||
.card-content {
|
.card-content {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
var s=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var t=(a,r,c,o)=>{for(var e=o>1?void 0:o?l(r,c):r,i=a.length-1,d;i>=0;i--)(d=a[i])&&(e=(o?d(r,c,e):d(e))||e);return o&&e&&s(r,c,e),e};var m={ok:"var(--success-color, #4caf50)",due_soon:"var(--warning-color, #ff9800)",overdue:"var(--error-color, #f44336)",triggered:"var(--deep-orange-color, #ff5722)",archived:"var(--disabled-color, #9e9e9e)",paused:"var(--info-color, #2196f3)"},v={ok:"mdi:check-circle",due_soon:"mdi:alert-circle",overdue:"mdi:alert-octagon",triggered:"mdi:bell-alert",archived:"mdi:archive-outline",paused:"mdi:pause-circle-outline",completed:"mdi:check-circle",skipped:"mdi:skip-next",missed:"mdi:calendar-remove",reset:"mdi:refresh"};export{t as a,m as b,v as c};
|
var s=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var t=(a,r,c,o)=>{for(var e=o>1?void 0:o?l(r,c):r,i=a.length-1,d;i>=0;i--)(d=a[i])&&(e=(o?d(r,c,e):d(e))||e);return o&&e&&s(r,c,e),e};var m={ok:"var(--success-color, #4caf50)",due_soon:"var(--warning-color, #ff9800)",overdue:"var(--error-color, #f44336)",triggered:"var(--deep-orange-color, #ff5722)",archived:"var(--disabled-color, #9e9e9e)",paused:"var(--info-color, #2196f3)"},v={ok:"mdi:check-circle",due_soon:"mdi:alert-circle",overdue:"mdi:alert-octagon",triggered:"mdi:bell-alert",archived:"mdi:archive-outline",paused:"mdi:pause-circle-outline",completed:"mdi:check-circle",skipped:"mdi:skip-next",missed:"mdi:calendar-remove",reset:"mdi:refresh"};export{t as a,m as b,v as c};
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
|
||||||
var s=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var t=(a,r,c,o)=>{for(var e=o>1?void 0:o?l(r,c):r,i=a.length-1,d;i>=0;i--)(d=a[i])&&(e=(o?d(r,c,e):d(e))||e);return o&&e&&s(r,c,e),e};var m={ok:"var(--success-color, #4caf50)",due_soon:"var(--warning-color, #ff9800)",overdue:"var(--error-color, #f44336)",triggered:"var(--deep-orange-color, #ff5722)",archived:"var(--disabled-color, #9e9e9e)",paused:"var(--info-color, #2196f3)"},v={ok:"mdi:check-circle",due_soon:"mdi:alert-circle",overdue:"mdi:alert-octagon",triggered:"mdi:bell-alert",archived:"mdi:archive-outline",paused:"mdi:pause-circle-outline",completed:"mdi:check-circle",skipped:"mdi:skip-next",missed:"mdi:calendar-remove",reset:"mdi:refresh"};export{t as a,m as b,v as c};
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
|
||||||
import{a as r}from"./chunk-TRW3CRLS.js";var a=r`
|
|
||||||
ha-card { overflow: hidden; }
|
|
||||||
.card-content {
|
|
||||||
padding: 16px;
|
|
||||||
display: flex; flex-direction: column;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
.header {
|
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
.title {
|
|
||||||
display: flex; align-items: center; gap: 8px;
|
|
||||||
font-size: 16px; font-weight: 500;
|
|
||||||
}
|
|
||||||
.emoji { font-size: 20px; }
|
|
||||||
|
|
||||||
/* Button family — primary action / muted-saved-state / link / icon-with-text */
|
|
||||||
.btn {
|
|
||||||
padding: 6px 12px; font-size: 13px;
|
|
||||||
border-radius: 6px; cursor: pointer;
|
|
||||||
border: 1px solid var(--divider-color);
|
|
||||||
background: var(--secondary-background-color, transparent);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
font-weight: 500;
|
|
||||||
display: inline-flex; align-items: center; gap: 4px;
|
|
||||||
}
|
|
||||||
.btn:hover { background: var(--state-icon-color, rgba(255,255,255,0.06)); }
|
|
||||||
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
|
|
||||||
.btn.primary {
|
|
||||||
background: var(--primary-color);
|
|
||||||
color: var(--text-primary-color, white);
|
|
||||||
border-color: var(--primary-color);
|
|
||||||
}
|
|
||||||
.btn.primary[disabled] { opacity: 0.6; }
|
|
||||||
.btn.muted {
|
|
||||||
background: transparent;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
border-style: dashed;
|
|
||||||
}
|
|
||||||
.btn.muted[disabled] { opacity: 1; cursor: default; }
|
|
||||||
.btn.muted ha-icon, .btn.primary ha-icon { --mdc-icon-size: 14px; }
|
|
||||||
.btn.link {
|
|
||||||
background: transparent; border: none; padding: 6px 4px;
|
|
||||||
color: var(--primary-color); margin-left: auto;
|
|
||||||
}
|
|
||||||
.btn.link:hover { background: transparent; text-decoration: underline; }
|
|
||||||
|
|
||||||
/* Error + loading states */
|
|
||||||
.error {
|
|
||||||
padding: 8px; border-radius: 6px;
|
|
||||||
background: rgba(211, 47, 47, 0.1);
|
|
||||||
color: var(--error-color, #d32f2f); font-size: 13px;
|
|
||||||
}
|
|
||||||
.loading {
|
|
||||||
padding: 24px; text-align: center;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
`;export{a};
|
|
||||||
+243
-212
File diff suppressed because one or more lines are too long
-2453
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{a as m}from"./chunk-XWMJNIQI.js";import{a as u,b as s,d as l,e as h,f as g,g as o,i,k as _,t as p}from"./chunk-TRW3CRLS.js";import{a}from"./chunk-UHANDS57.js";var e=class extends h{constructor(){super(...arguments);this._config={type:""};this._groups={};this._loaded=!1;this._busy=!1;this._error="";this._newName="";this._editingId=null;this._editingName="";this._hasInitiallyLoaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._hasInitiallyLoaded&&(this._hasInitiallyLoaded=!0,this._load(),_(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/groups"});this._groups=t.groups||{},this._loaded=!0}catch(t){this._error=p(t,this._lang)}}async _addGroup(){if(!this._isAdmin)return;let t=this._newName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/create",name:t}),this._newName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}_startEdit(t){this._editingId=t,this._editingName=this._groups[t]?.name||""}async _saveEdit(){if(!this._isAdmin||!this._editingId)return;let t=this._editingName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/update",group_id:this._editingId,name:t}),this._editingId=null,this._editingName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}async _deleteGroup(t,r){if(!this._isAdmin)return;let n=(i("group_delete_confirm",this._lang)||'Delete group "{name}"?').replace("{name}",r);if(window.confirm(n)){this._busy=!0;try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/delete",group_id:t}),await this._load()}catch(d){this._error=p(d,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_groups"),window.dispatchEvent(new CustomEvent("location-changed"))}_onKeyDown(t,r){t.key==="Enter"?(t.preventDefault(),r()):t.key==="Escape"&&(t.preventDefault(),this._editingId=null,this._editingName="")}render(){let t=this._lang;if(!this._loaded)return s`<ha-card><div class="loading">${i("loading",t)||"Loading\u2026"}</div></ha-card>`;let r=Object.keys(this._groups);return s`
|
import{a as m}from"./chunk-6INP67SU.js";import{a as u,b as s,d as l,e as h,f as g,g as o,i,k as _,t as p}from"./chunk-CWQRMTXS.js";import{a}from"./chunk-HQWGP2HE.js";var e=class extends h{constructor(){super(...arguments);this._config={type:""};this._groups={};this._loaded=!1;this._busy=!1;this._error="";this._newName="";this._editingId=null;this._editingName="";this._hasInitiallyLoaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._hasInitiallyLoaded&&(this._hasInitiallyLoaded=!0,this._load(),_(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/groups"});this._groups=t.groups||{},this._loaded=!0}catch(t){this._error=p(t,this._lang)}}async _addGroup(){if(!this._isAdmin)return;let t=this._newName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/create",name:t}),this._newName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}_startEdit(t){this._editingId=t,this._editingName=this._groups[t]?.name||""}async _saveEdit(){if(!this._isAdmin||!this._editingId)return;let t=this._editingName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/update",group_id:this._editingId,name:t}),this._editingId=null,this._editingName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}async _deleteGroup(t,r){if(!this._isAdmin)return;let n=(i("group_delete_confirm",this._lang)||'Delete group "{name}"?').replace("{name}",r);if(window.confirm(n)){this._busy=!0;try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/delete",group_id:t}),await this._load()}catch(d){this._error=p(d,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_groups"),window.dispatchEvent(new CustomEvent("location-changed"))}_onKeyDown(t,r){t.key==="Enter"?(t.preventDefault(),r()):t.key==="Escape"&&(t.preventDefault(),this._editingId=null,this._editingName="")}render(){let t=this._lang;if(!this._loaded)return s`<ha-card><div class="loading">${i("loading",t)||"Loading\u2026"}</div></ha-card>`;let r=Object.keys(this._groups);return s`
|
||||||
<ha-card>
|
<ha-card>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
-137
@@ -1,137 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
|
||||||
import{a as m}from"./chunk-QCBC6YX3.js";import{a as u,b as s,d as l,e as h,f as g,g as o,i,k as _,t as p}from"./chunk-RNKC43AV.js";import{a}from"./chunk-LPNFL3AF.js";var e=class extends h{constructor(){super(...arguments);this._config={type:""};this._groups={};this._loaded=!1;this._busy=!1;this._error="";this._newName="";this._editingId=null;this._editingName="";this._hasInitiallyLoaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._hasInitiallyLoaded&&(this._hasInitiallyLoaded=!0,this._load(),_(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/groups"});this._groups=t.groups||{},this._loaded=!0}catch(t){this._error=p(t,this._lang)}}async _addGroup(){if(!this._isAdmin)return;let t=this._newName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/create",name:t}),this._newName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}_startEdit(t){this._editingId=t,this._editingName=this._groups[t]?.name||""}async _saveEdit(){if(!this._isAdmin||!this._editingId)return;let t=this._editingName.trim();if(t){this._busy=!0,this._error="";try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/update",group_id:this._editingId,name:t}),this._editingId=null,this._editingName="",await this._load()}catch(r){this._error=p(r,this._lang)}finally{this._busy=!1}}}async _deleteGroup(t,r){if(!this._isAdmin)return;let n=(i("group_delete_confirm",this._lang)||'Delete group "{name}"?').replace("{name}",r);if(window.confirm(n)){this._busy=!0;try{await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/group/delete",group_id:t}),await this._load()}catch(d){this._error=p(d,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_groups"),window.dispatchEvent(new CustomEvent("location-changed"))}_onKeyDown(t,r){t.key==="Enter"?(t.preventDefault(),r()):t.key==="Escape"&&(t.preventDefault(),this._editingId=null,this._editingName="")}render(){let t=this._lang;if(!this._loaded)return s`<ha-card><div class="loading">${i("loading",t)||"Loading\u2026"}</div></ha-card>`;let r=Object.keys(this._groups);return s`
|
|
||||||
<ha-card>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="header">
|
|
||||||
<div class="title">
|
|
||||||
<span class="emoji">🏷️</span>
|
|
||||||
<span>${this._config.title||i("groups",t)||"Groups"}</span>
|
|
||||||
<span class="count">${r.length}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
${this._error?s`<div class="error">${this._error}</div>`:l}
|
|
||||||
|
|
||||||
${r.length===0?s`<div class="empty">${i("groups_empty",t)||"No groups yet."}</div>`:s`
|
|
||||||
<div class="group-list">
|
|
||||||
${r.map(n=>{let d=this._groups[n],v=d.task_refs?.length??0,b=this._editingId===n;return s`
|
|
||||||
<div class="group-row">
|
|
||||||
${b?s`
|
|
||||||
<input class="edit-input" type="text"
|
|
||||||
.value=${this._editingName}
|
|
||||||
?disabled=${this._busy}
|
|
||||||
@input=${c=>{this._editingName=c.target.value}}
|
|
||||||
@keydown=${c=>this._onKeyDown(c,this._saveEdit.bind(this))} />
|
|
||||||
<button class="btn small primary"
|
|
||||||
@click=${this._saveEdit}
|
|
||||||
?disabled=${this._busy||!this._editingName.trim()}>
|
|
||||||
${i("save",t)||"Save"}
|
|
||||||
</button>
|
|
||||||
<button class="btn small"
|
|
||||||
@click=${()=>{this._editingId=null}}>
|
|
||||||
${i("cancel",t)||"Cancel"}
|
|
||||||
</button>
|
|
||||||
`:s`
|
|
||||||
<span class="group-name">${d.name||"Unnamed"}</span>
|
|
||||||
<span class="task-count">${v}</span>
|
|
||||||
${this._isAdmin?s`
|
|
||||||
<button class="icon-btn"
|
|
||||||
title="${i("edit",t)||"Edit"}"
|
|
||||||
@click=${()=>this._startEdit(n)}
|
|
||||||
?disabled=${this._busy}>
|
|
||||||
<ha-icon icon="mdi:pencil"></ha-icon>
|
|
||||||
</button>
|
|
||||||
<button class="icon-btn danger"
|
|
||||||
title="${i("delete",t)||"Delete"}"
|
|
||||||
@click=${()=>this._deleteGroup(n,d.name||"Unnamed")}
|
|
||||||
?disabled=${this._busy}>
|
|
||||||
<ha-icon icon="mdi:delete"></ha-icon>
|
|
||||||
</button>
|
|
||||||
`:l}
|
|
||||||
`}
|
|
||||||
</div>
|
|
||||||
`})}
|
|
||||||
</div>
|
|
||||||
`}
|
|
||||||
|
|
||||||
${this._isAdmin?s`
|
|
||||||
<div class="add-row">
|
|
||||||
<input type="text"
|
|
||||||
placeholder="${i("group_new_placeholder",t)||"Add group\u2026"}"
|
|
||||||
.value=${this._newName}
|
|
||||||
?disabled=${this._busy}
|
|
||||||
@input=${n=>{this._newName=n.target.value}}
|
|
||||||
@keydown=${n=>this._onKeyDown(n,this._addGroup.bind(this))} />
|
|
||||||
<button class="btn primary"
|
|
||||||
@click=${this._addGroup}
|
|
||||||
?disabled=${this._busy||!this._newName.trim()}>
|
|
||||||
<ha-icon icon="mdi:plus"></ha-icon>
|
|
||||||
${i("add",t)||"Add"}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<button class="btn link" @click=${this._onDeepLink}>
|
|
||||||
${i("groups_manage_tasks",t)||"Manage task assignments\u2026"}
|
|
||||||
</button>
|
|
||||||
`:s`
|
|
||||||
<button class="btn link" @click=${this._onDeepLink}>
|
|
||||||
${i("groups_open_panel",t)||"Open in panel"}
|
|
||||||
</button>
|
|
||||||
`}
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
`}};e.styles=[m,u`
|
|
||||||
.count {
|
|
||||||
font-size: 12px; color: var(--secondary-text-color);
|
|
||||||
background: var(--secondary-background-color);
|
|
||||||
padding: 2px 8px; border-radius: 999px;
|
|
||||||
}
|
|
||||||
.empty {
|
|
||||||
padding: 16px; text-align: center;
|
|
||||||
color: var(--secondary-text-color); font-style: italic;
|
|
||||||
}
|
|
||||||
.group-list { display: flex; flex-direction: column; gap: 4px; }
|
|
||||||
.group-row {
|
|
||||||
display: flex; align-items: center; gap: 8px;
|
|
||||||
padding: 6px 8px; border-radius: 6px;
|
|
||||||
background: var(--secondary-background-color, rgba(255,255,255,0.03));
|
|
||||||
}
|
|
||||||
.group-name { flex: 1; font-size: 14px; }
|
|
||||||
.task-count {
|
|
||||||
font-size: 11px; color: var(--secondary-text-color);
|
|
||||||
background: var(--card-background-color, rgba(0,0,0,0.2));
|
|
||||||
padding: 1px 8px; border-radius: 999px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.edit-input {
|
|
||||||
flex: 1; padding: 4px 8px; font-size: 14px;
|
|
||||||
background: var(--card-background-color, #1c1c1c);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
border: 1px solid var(--primary-color); border-radius: 4px;
|
|
||||||
font-family: inherit;
|
|
||||||
}
|
|
||||||
.icon-btn {
|
|
||||||
background: transparent; border: none; cursor: pointer;
|
|
||||||
color: var(--secondary-text-color); padding: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.icon-btn:hover {
|
|
||||||
background: var(--state-icon-color, rgba(255,255,255,0.06));
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
}
|
|
||||||
.icon-btn.danger:hover { color: var(--error-color); }
|
|
||||||
.icon-btn ha-icon { --mdc-icon-size: 18px; }
|
|
||||||
.add-row {
|
|
||||||
display: flex; gap: 6px;
|
|
||||||
padding-top: 8px; border-top: 1px solid var(--divider-color);
|
|
||||||
}
|
|
||||||
.add-row input {
|
|
||||||
flex: 1; padding: 6px 8px; font-size: 13px;
|
|
||||||
background: var(--secondary-background-color, #2c2c2c);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
|
||||||
font-family: inherit;
|
|
||||||
}
|
|
||||||
/* Card-specific overrides on the shared .btn */
|
|
||||||
.btn.small { padding: 4px 8px; font-size: 12px; }
|
|
||||||
.btn ha-icon { --mdc-icon-size: 16px; }
|
|
||||||
`],a([g({attribute:!1})],e.prototype,"hass",2),a([o()],e.prototype,"_config",2),a([o()],e.prototype,"_groups",2),a([o()],e.prototype,"_loaded",2),a([o()],e.prototype,"_busy",2),a([o()],e.prototype,"_error",2),a([o()],e.prototype,"_newName",2),a([o()],e.prototype,"_editingId",2),a([o()],e.prototype,"_editingName",2);customElements.get("maintenance-groups-section-card")||customElements.define("maintenance-groups-section-card",e);window.customCards=window.customCards||[];window.customCards.push({type:"maintenance-groups-section-card",name:"Maintenance Supporter \u2014 Groups",description:"Inline group CRUD",preview:!1});export{e as MaintenanceGroupsSectionCard};
|
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*! maintenance_supporter frontend 2.56.0 */
|
/*! maintenance_supporter frontend 2.57.0 */
|
||||||
import{a as m}from"./chunk-XWMJNIQI.js";import{a as h,b as n,d as c,e as _,f as v,g as r,i as e,k as f,t as l}from"./chunk-TRW3CRLS.js";import{a as i}from"./chunk-UHANDS57.js";var a=class extends _{constructor(){super(...arguments);this._config={type:""};this._state=null;this._busy=!1;this._error="";this._localStart="";this._localEnd="";this._localBuffer=7;this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),f(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/state"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||"",this._localBuffer=t.buffer_days??7,this._dirty=!1}catch(t){this._error=l(t,this._lang)}}async _toggleEnabled(t){this._busy=!0,this._error="";try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",enabled:t});this._state=s}catch(s){this._error=l(s,this._lang)}finally{this._busy=!1}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",start:this._localStart||null,end:this._localEnd||null,buffer_days:this._localBuffer});this._state=t,this._dirty=!1}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}async _endNow(){if(this._isAdmin&&window.confirm(e("vacation_end_now_confirm",this._lang)||"End vacation immediately?")){this._busy=!0;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/end_now"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||""}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_vacation"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,s=this._state;if(!s)return n`<ha-card><div class="loading">${e("loading",t)||"Loading\u2026"}</div></ha-card>`;let p=s.is_active===!0,d=s.enabled===!0,u=s.exempt_task_ids?.length??0,b=p?e("vacation_status_active",t)||"Active now":d?e("vacation_status_scheduled",t)||"Scheduled":e("vacation_status_inactive",t)||"Inactive",g=p?"active":d?"scheduled":"inactive";return n`
|
import{a as m}from"./chunk-6INP67SU.js";import{a as h,b as n,d as c,e as _,f as v,g as r,i as e,k as f,t as l}from"./chunk-CWQRMTXS.js";import{a as i}from"./chunk-HQWGP2HE.js";var a=class extends _{constructor(){super(...arguments);this._config={type:""};this._state=null;this._busy=!1;this._error="";this._localStart="";this._localEnd="";this._localBuffer=7;this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),f(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/state"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||"",this._localBuffer=t.buffer_days??7,this._dirty=!1}catch(t){this._error=l(t,this._lang)}}async _toggleEnabled(t){this._busy=!0,this._error="";try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",enabled:t});this._state=s}catch(s){this._error=l(s,this._lang)}finally{this._busy=!1}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",start:this._localStart||null,end:this._localEnd||null,buffer_days:this._localBuffer});this._state=t,this._dirty=!1}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}async _endNow(){if(this._isAdmin&&window.confirm(e("vacation_end_now_confirm",this._lang)||"End vacation immediately?")){this._busy=!0;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/end_now"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||""}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_vacation"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,s=this._state;if(!s)return n`<ha-card><div class="loading">${e("loading",t)||"Loading\u2026"}</div></ha-card>`;let p=s.is_active===!0,d=s.enabled===!0,u=s.exempt_task_ids?.length??0,b=p?e("vacation_status_active",t)||"Active now":d?e("vacation_status_scheduled",t)||"Scheduled":e("vacation_status_inactive",t)||"Inactive",g=p?"active":d?"scheduled":"inactive";return n`
|
||||||
<ha-card>
|
<ha-card>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
-122
@@ -1,122 +0,0 @@
|
|||||||
/*! maintenance_supporter frontend 2.55.0 */
|
|
||||||
import{a as m}from"./chunk-QCBC6YX3.js";import{a as h,b as n,d as c,e as _,f as v,g as r,i as e,k as f,t as l}from"./chunk-RNKC43AV.js";import{a as i}from"./chunk-LPNFL3AF.js";var a=class extends _{constructor(){super(...arguments);this._config={type:""};this._state=null;this._busy=!1;this._error="";this._localStart="";this._localEnd="";this._localBuffer=7;this._dirty=!1;this._loaded=!1}setConfig(t){this._config=t}getCardSize(){return 2}get _lang(){return this.hass?.language||"en"}get _isAdmin(){return this.hass?.user?.is_admin??!0}updated(t){super.updated(t),t.has("hass")&&this.hass&&!this._loaded&&(this._loaded=!0,this._load(),f(this._lang).then(()=>this.requestUpdate()))}async _load(){try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/state"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||"",this._localBuffer=t.buffer_days??7,this._dirty=!1}catch(t){this._error=l(t,this._lang)}}async _toggleEnabled(t){this._busy=!0,this._error="";try{let s=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",enabled:t});this._state=s}catch(s){this._error=l(s,this._lang)}finally{this._busy=!1}}async _save(){if(this._isAdmin){this._busy=!0,this._error="";try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/update",start:this._localStart||null,end:this._localEnd||null,buffer_days:this._localBuffer});this._state=t,this._dirty=!1}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}async _endNow(){if(this._isAdmin&&window.confirm(e("vacation_end_now_confirm",this._lang)||"End vacation immediately?")){this._busy=!0;try{let t=await this.hass.connection.sendMessagePromise({type:"maintenance_supporter/vacation/end_now"});this._state=t,this._localStart=t.start||"",this._localEnd=t.end||""}catch(t){this._error=l(t,this._lang)}finally{this._busy=!1}}}_onDeepLink(){history.pushState(null,"","/maintenance-supporter?ms_action=open_vacation"),window.dispatchEvent(new CustomEvent("location-changed"))}render(){let t=this._lang,s=this._state;if(!s)return n`<ha-card><div class="loading">${e("loading",t)||"Loading\u2026"}</div></ha-card>`;let p=s.is_active===!0,d=s.enabled===!0,u=s.exempt_task_ids?.length??0,b=p?e("vacation_status_active",t)||"Active now":d?e("vacation_status_scheduled",t)||"Scheduled":e("vacation_status_inactive",t)||"Inactive",g=p?"active":d?"scheduled":"inactive";return n`
|
|
||||||
<ha-card>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="header">
|
|
||||||
<div class="title">
|
|
||||||
<span class="emoji">🏖️</span>
|
|
||||||
<span>${this._config.title||e("vacation_mode",t)||"Vacation mode"}</span>
|
|
||||||
</div>
|
|
||||||
<span class="status-pill ${g}">${b}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
${this._error?n`<div class="error">${this._error}</div>`:c}
|
|
||||||
|
|
||||||
${this._isAdmin?n`
|
|
||||||
<div class="row toggle-row">
|
|
||||||
<label>${e("enable",t)||"Enable"}</label>
|
|
||||||
<ha-switch
|
|
||||||
.checked=${d}
|
|
||||||
.disabled=${this._busy}
|
|
||||||
@change=${o=>this._toggleEnabled(o.target.checked)}
|
|
||||||
></ha-switch>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dates-row">
|
|
||||||
<div class="date-field">
|
|
||||||
<label>${e("vacation_start",t)||"Start"}</label>
|
|
||||||
<input type="date" .value=${this._localStart}
|
|
||||||
?disabled=${this._busy}
|
|
||||||
@input=${o=>{this._localStart=o.target.value,this._dirty=!0}} />
|
|
||||||
</div>
|
|
||||||
<div class="date-field">
|
|
||||||
<label>${e("vacation_end",t)||"End"}</label>
|
|
||||||
<input type="date" .value=${this._localEnd}
|
|
||||||
?disabled=${this._busy}
|
|
||||||
@input=${o=>{this._localEnd=o.target.value,this._dirty=!0}} />
|
|
||||||
</div>
|
|
||||||
<div class="date-field buffer">
|
|
||||||
<label>${e("vacation_buffer",t)||"Buffer days"}</label>
|
|
||||||
<input type="number" min="0" max="14"
|
|
||||||
.value=${String(this._localBuffer)}
|
|
||||||
?disabled=${this._busy}
|
|
||||||
@input=${o=>{this._localBuffer=parseInt(o.target.value,10)||0,this._dirty=!0}} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<button class="btn ${this._dirty?"primary":"muted"}"
|
|
||||||
@click=${this._save}
|
|
||||||
?disabled=${this._busy||!this._dirty}>
|
|
||||||
<ha-icon icon="${this._dirty?"mdi:content-save":"mdi:check"}"></ha-icon>
|
|
||||||
${this._dirty?e("save",t)||"Save":e("saved",t)||"Saved"}
|
|
||||||
</button>
|
|
||||||
${p?n`<button class="btn"
|
|
||||||
@click=${this._endNow}
|
|
||||||
?disabled=${this._busy}>
|
|
||||||
${e("vacation_end_now",t)||"End now"}
|
|
||||||
</button>`:c}
|
|
||||||
${u>0?n`<button class="btn link"
|
|
||||||
@click=${this._onDeepLink}>
|
|
||||||
${u} ${e("vacation_exempt_count",t)||"exempt"}…
|
|
||||||
</button>`:n`<button class="btn link"
|
|
||||||
@click=${this._onDeepLink}>
|
|
||||||
${e("vacation_advanced",t)||"Advanced\u2026"}
|
|
||||||
</button>`}
|
|
||||||
</div>
|
|
||||||
`:n`
|
|
||||||
<div class="readonly">
|
|
||||||
${d&&s.start&&s.end?n`<div>${s.start} → ${s.end}</div>`:c}
|
|
||||||
<button class="btn link" @click=${this._onDeepLink}>
|
|
||||||
${e("vacation_open_panel",t)||"Open in panel"}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
`}
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
`}};a.styles=[m,h`
|
|
||||||
.status-pill {
|
|
||||||
font-size: 11px; font-weight: 600;
|
|
||||||
padding: 3px 8px; border-radius: 999px;
|
|
||||||
text-transform: uppercase; letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
.status-pill.active {
|
|
||||||
background: rgba(76, 175, 80, 0.15);
|
|
||||||
color: #4caf50;
|
|
||||||
}
|
|
||||||
.status-pill.scheduled {
|
|
||||||
background: rgba(255, 152, 0, 0.15);
|
|
||||||
color: #ff9800;
|
|
||||||
}
|
|
||||||
.status-pill.inactive {
|
|
||||||
background: rgba(158, 158, 158, 0.15);
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
.row.toggle-row {
|
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
|
||||||
}
|
|
||||||
.row.toggle-row label {
|
|
||||||
font-size: 14px; color: var(--primary-text-color);
|
|
||||||
}
|
|
||||||
.dates-row {
|
|
||||||
display: grid; grid-template-columns: 1fr 1fr 100px; gap: 10px;
|
|
||||||
}
|
|
||||||
.date-field.buffer label { white-space: nowrap; }
|
|
||||||
.date-field { display: flex; flex-direction: column; gap: 4px; }
|
|
||||||
.date-field label {
|
|
||||||
font-size: 11px; color: var(--secondary-text-color);
|
|
||||||
text-transform: uppercase; letter-spacing: 0.3px;
|
|
||||||
}
|
|
||||||
.date-field input {
|
|
||||||
padding: 6px 8px; font-size: 13px;
|
|
||||||
background: var(--secondary-background-color, #2c2c2c);
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
|
||||||
font-family: inherit;
|
|
||||||
}
|
|
||||||
.date-field input:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
||||||
.actions {
|
|
||||||
display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.readonly { display: flex; flex-direction: column; gap: 8px; }
|
|
||||||
`],i([v({attribute:!1})],a.prototype,"hass",2),i([r()],a.prototype,"_config",2),i([r()],a.prototype,"_state",2),i([r()],a.prototype,"_busy",2),i([r()],a.prototype,"_error",2),i([r()],a.prototype,"_localStart",2),i([r()],a.prototype,"_localEnd",2),i([r()],a.prototype,"_localBuffer",2),i([r()],a.prototype,"_dirty",2);customElements.get("maintenance-vacation-section-card")||customElements.define("maintenance-vacation-section-card",a);window.customCards=window.customCards||[];window.customCards.push({type:"maintenance-vacation-section-card",name:"Maintenance Supporter \u2014 Vacation",description:"Inline vacation mode toggle + dates",preview:!1});export{a as MaintenanceVacationSectionCard};
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user