Dashboard Studio 2.2.1: sports match centre, Import JSON back, no double entities
- Sports card: crests in team colours, position and record, countdown, win-probability bar, live clock and last play, venue - Import JSON back in the builder's menu - Fixed: picking an entity with the keyboard added it twice; existing duplicates are removed when dashboards load Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -220,6 +220,12 @@
|
||||
|
||||
// Bring dashboards saved by older versions up to the current shape.
|
||||
function migrate(d) {
|
||||
// Before 2.2.1, picking an entity with the keyboard could add it twice: keep each entity once per list.
|
||||
const dedupe = (ws) => (ws || []).forEach((w) => {
|
||||
for (const [k, v] of Object.entries(w.cfg || {})) if (Array.isArray(v) && v.every((x) => typeof x === "string")) w.cfg[k] = [...new Set(v)];
|
||||
dedupe(w.cfg?.children);
|
||||
});
|
||||
(d.tabs || []).forEach((tb) => dedupe(tb.widgets));
|
||||
const t = d.theme || {};
|
||||
if (!t.preset) {
|
||||
t.preset = "Custom";
|
||||
@@ -1548,7 +1554,7 @@
|
||||
}
|
||||
if (path === "guest") {
|
||||
const g = current.guest;
|
||||
if (idx === "new") { if (!isChange || !v) return; mutate(() => { (g[k] ||= []).push(v); }, null, { rerender: false }); }
|
||||
if (idx === "new") { if (!isChange || !v || (g[k] || []).includes(v)) return; mutate(() => { (g[k] ||= []).push(v); }, null, { rerender: false }); }
|
||||
else mutate(() => { if (idx != null) g[k][Number(idx)] = v; else g[k] = v; }, `guest|${k}|${idx ?? ""}`, { rerender: false });
|
||||
checkGuest(true);
|
||||
if (isChange || t.tagName === "BUTTON") renderInspector();
|
||||
@@ -1572,6 +1578,7 @@
|
||||
|
||||
if (idx === "new") {
|
||||
if (!isChange || !v) return;
|
||||
if ((w.cfg[k] || []).includes(v)) { t.value = ""; return; } // already in the list
|
||||
mutate(() => { (w.cfg[k] ||= []).push(v); }, null);
|
||||
renderInspector();
|
||||
$(`#inspector [data-k="${k}"][data-idx="new"]`)?.focus();
|
||||
@@ -1628,6 +1635,8 @@
|
||||
|
||||
function onInspectorInput(e) {
|
||||
const t = e.target;
|
||||
// A field the inspector just replaced (picking an entity redraws it) can still report its change: ignore it.
|
||||
if (!t.isConnected) return;
|
||||
if (t.matches?.("[data-haptics]")) { if (e.type === "change") { lsSet("ds.haptics", t.checked ? "1" : "0"); haptic(); } return; }
|
||||
if (t.matches?.("[data-shortcut]")) {
|
||||
if (e.type !== "change") return;
|
||||
@@ -3343,7 +3352,7 @@
|
||||
return `<header class="adm-head"><div><h2>${tr("Dashboards")}</h2><p class="muted">${tr("Build a dashboard, then choose under People who sees it.")}</p></div>
|
||||
<div class="adm-actions"><button class="btn primary" data-a="new">${Icons.svg("plus")}${tr("New dashboard")}</button>
|
||||
<button class="btn" data-a="starter">${Icons.svg("sparkles")}${tr("From my devices")}</button>
|
||||
<button class="btn" data-a="import">${Icons.svg("plus")}${tr("Import file")}</button>
|
||||
<button class="btn" data-a="import">${Icons.svg("plus")}${tr("Import JSON…")}</button>
|
||||
<button class="btn" data-a="lovelace">${Icons.svg("import")}${tr("Import from Home Assistant")}</button></div></header>
|
||||
<div class="adm-cards">${cards}</div>`;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user