mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
fix: roll back rejected general settings save
Issue: #439 User-Visible: yes
This commit is contained in:
committed by
claude[bot]
parent
5f90eaf4ef
commit
d5ad0371aa
@@ -1,125 +1,125 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "e5edb95a1f5817c9035c6418ea0f9cb86cde238466f1f5c3174fb5246662c8ec",
|
||||
"fingerprint": "a1c6b7fa80c55b69f45f0b0975bcde7eb67d53a02f75f5b7c61d66f220e78ed9",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js",
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 291069,
|
||||
"initialViewGzipBytes": 291175,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/de-D_5HnJeM.js",
|
||||
"houseplan-assets/editor-CqQRQq4C.js",
|
||||
"houseplan-assets/fr-DpKqMyVB.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-D0JYjEs4.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C-SJxeJ_.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/de-B-zT3Bet.js",
|
||||
"houseplan-assets/editor-DJZS-SMT.js",
|
||||
"houseplan-assets/fr-DhlZhAWs.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-S0bYVW5I.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DJriHHug.js"
|
||||
],
|
||||
"lazyGzipBytes": 215495,
|
||||
"lazyGzipBytes": 215559,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/editor-CqQRQq4C.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-D0JYjEs4.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/editor-DJZS-SMT.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-S0bYVW5I.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 159809,
|
||||
"lazyEditorGzipBytes": 159876,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C-SJxeJ_.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DJriHHug.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 14126,
|
||||
"lazyOnboardingGzipBytes": 14133,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-D_5HnJeM.js",
|
||||
"houseplan-assets/fr-DpKqMyVB.js"
|
||||
"houseplan-assets/de-B-zT3Bet.js",
|
||||
"houseplan-assets/fr-DhlZhAWs.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 48734,
|
||||
"lazyLocaleGzipBytes": 48727,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"sha256": "b67eb5e04c63007ff8ca7ff5623a7dcae44ff3c6f3ca5528ac7f1d389f75c4ec",
|
||||
"path": "houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"sha256": "b556cef2823ea5e4f7c142ee5f4cee8dbbed71311dd101291faf30a0d38d6805",
|
||||
"rawBytes": 20996,
|
||||
"gzipBytes": 7174,
|
||||
"gzipBytes": 7177,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-D_5HnJeM.js",
|
||||
"sha256": "ad2dde1407ae850f963cf81a8c0218c0e6646a86cf3bceb61a305cd54f60dad9",
|
||||
"path": "houseplan-assets/de-B-zT3Bet.js",
|
||||
"sha256": "2ee98742a517ac754434e5627f958a20def03cd1c3907dd7ec3e394104c850a1",
|
||||
"rawBytes": 81632,
|
||||
"gzipBytes": 24639,
|
||||
"gzipBytes": 24635,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-CqQRQq4C.js",
|
||||
"sha256": "5007144deff010072eb0a6a6d3e5565064a60575baa173a0250cec89b1478823",
|
||||
"path": "houseplan-assets/editor-DJZS-SMT.js",
|
||||
"sha256": "3cda88a32916d4a3256cb0f76570d72f58308ad9ee6a28c9496d5c9e2c613aa4",
|
||||
"rawBytes": 3826,
|
||||
"gzipBytes": 1580,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-DpKqMyVB.js",
|
||||
"sha256": "3c03580d357a96678d80b012923e7e28e989fe6a612fe0342d5d041e2d37d4f1",
|
||||
"path": "houseplan-assets/fr-DhlZhAWs.js",
|
||||
"sha256": "f37aecbd6a5aaa1fbc5c3be0854464b949cbdcefd453906b268c46d76760772d",
|
||||
"rawBytes": 83754,
|
||||
"gzipBytes": 24095,
|
||||
"gzipBytes": 24092,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-o7i25aVl.js",
|
||||
"sha256": "9b3942532fe83c5d49791859c419fb6f35a8db86c01a09ddccb1a2ec186bfbd3",
|
||||
"rawBytes": 1033268,
|
||||
"gzipBytes": 290274,
|
||||
"path": "houseplan-assets/houseplan-card-D9kogu9G.js",
|
||||
"sha256": "65622583b77e3ff11a34ff2c2ceb65748cb1f607412794141375841fcea818bb",
|
||||
"rawBytes": 1033646,
|
||||
"gzipBytes": 290380,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-D_5HnJeM.js",
|
||||
"houseplan-assets/editor-CqQRQq4C.js",
|
||||
"houseplan-assets/fr-DpKqMyVB.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-D0JYjEs4.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C-SJxeJ_.js"
|
||||
"houseplan-assets/de-B-zT3Bet.js",
|
||||
"houseplan-assets/editor-DJZS-SMT.js",
|
||||
"houseplan-assets/fr-DhlZhAWs.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-S0bYVW5I.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DJriHHug.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-D0JYjEs4.js",
|
||||
"sha256": "b2a69132a223d6c5b06b8d4a11b19416d33582bae2d39b2448ecc41f44ba98b2",
|
||||
"rawBytes": 576032,
|
||||
"gzipBytes": 151055,
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-S0bYVW5I.js",
|
||||
"sha256": "c1935afb94bfe01cc7ee1302492c6c9a76faac8bd60ddc1db98eded52c7d9d65",
|
||||
"rawBytes": 576162,
|
||||
"gzipBytes": 151119,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-C-SJxeJ_.js",
|
||||
"sha256": "1324b8003d727c99c6ce6d9e48598032b29782f8c8c7b783c1b1073e9b79d9f2",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-DJriHHug.js",
|
||||
"sha256": "20b122261b8ce7484806fbaaf17aafb5f59c1864648b1a31fa226dc861d7cbd2",
|
||||
"rawBytes": 28088,
|
||||
"gzipBytes": 6952,
|
||||
"gzipBytes": 6956,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "d6c8be124ce907703e76f24a5e9fedb3abd945213d7befb1f97d1635d82f4830",
|
||||
"sha256": "ac14b26a8d45a1747833be382ab3b0b816332156a59ed7125fa3eba598cd940d",
|
||||
"rawBytes": 1183,
|
||||
"gzipBytes": 795,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+5
-5
@@ -1,14 +1,14 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="e5edb95a1f5817c9035c6418ea0f9cb86cde238466f1f5c3174fb5246662c8ec";import{b as e,l as o,t,dg as s,A as a,dh as i,di as l,dj as n,E as r,c}from"./houseplan-card-o7i25aVl.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="a1c6b7fa80c55b69f45f0b0975bcde7eb67d53a02f75f5b7c61d66f220e78ed9";import{b as e,l as o,t,di as s,A as a,dj as i,dk as l,dl as n,E as r,c}from"./houseplan-card-D9kogu9G.js";class f extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,f={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},h=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
.computeLabel=${e=>h[e.name]||e.name}
|
||||
.computeLabel=${e=>f[e.name]||e.name}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>`;return c`
|
||||
${d(f.slice(0,3))}
|
||||
${d(h.slice(0,3))}
|
||||
${_?c`<div class="default-floor-error" role="alert"
|
||||
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
|
||||
${t(s,"editor.default_floor_missing",{id:_})}
|
||||
</div>`:a}
|
||||
${d(f.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
|
||||
${d(h.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+18
-18
File diff suppressed because one or more lines are too long
+74
-74
File diff suppressed because one or more lines are too long
+3
-3
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="e5edb95a1f5817c9035c6418ea0f9cb86cde238466f1f5c3174fb5246662c8ec";try{await import("./houseplan-assets/houseplan-card-o7i25aVl.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale entry: the main chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="a1c6b7fa80c55b69f45f0b0975bcde7eb67d53a02f75f5b7c61d66f220e78ed9";try{await import("./houseplan-assets/houseplan-card-D9kogu9G.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale entry: the main chunk is unavailable",e)}
|
||||
|
||||
@@ -26,6 +26,68 @@ const result = await page.evaluate(async () => {
|
||||
await card.updateComplete;
|
||||
out.defaultRoomTip = card._tip?.room === true && !!root().querySelector('.tip');
|
||||
|
||||
const originalCallWS = card.hass.callWS;
|
||||
const beforeRejectedSave = structuredClone(card._serverCfg);
|
||||
const beforeRejectedFingerprint = card._cfgContentFingerprint;
|
||||
card._openSettingsDialog();
|
||||
card._settingsDialog = {
|
||||
...card._settingsDialog,
|
||||
colors: {
|
||||
...card._settingsDialog.colors,
|
||||
light_on: { c: '#123456', a: 0.4 },
|
||||
},
|
||||
glowRadius: 4,
|
||||
bgColor: '#234567',
|
||||
northDeg: 45,
|
||||
bgMode: 'static',
|
||||
sunRays: true,
|
||||
showRoomTooltip: false,
|
||||
};
|
||||
card.hass = { ...card.hass, callWS: async (message) => {
|
||||
if (message.type === 'houseplan/config/set') throw new Error('offline');
|
||||
return originalCallWS(message);
|
||||
} };
|
||||
await card._saveSettingsDialog();
|
||||
await card.updateComplete;
|
||||
out.rejectedSettingsRolledBack = JSON.stringify(card._serverCfg)
|
||||
=== JSON.stringify(beforeRejectedSave);
|
||||
out.rejectedFingerprintRolledBack = card._cfgContentFingerprint
|
||||
=== beforeRejectedFingerprint;
|
||||
out.rejectedDraftKept = card._settingsDialog?.showRoomTooltip === false
|
||||
&& card._settingsDialog?.bgColor === '#234567'
|
||||
&& card._settingsDialog?.colors.light_on.c === '#123456';
|
||||
out.rejectedBusyCleared = card._settingsDialog?.busy === false;
|
||||
card._tip = null;
|
||||
room().dispatchEvent(mouse('pointermove', 185, 185));
|
||||
await card.updateComplete;
|
||||
out.rejectedRuntimeUsesServerSettings = card._tip?.room === true;
|
||||
|
||||
const authoritative = structuredClone(beforeRejectedSave);
|
||||
authoritative.settings = { ...authoritative.settings, bg_color: '#345678' };
|
||||
const authoritativeRev = card._cfgRev + 5;
|
||||
card._openSettingsDialog();
|
||||
card._settingsDialog = {
|
||||
...card._settingsDialog, bgColor: '#abcdef', showRoomTooltip: false,
|
||||
};
|
||||
card.hass = { ...card.hass, callWS: async (message) => {
|
||||
if (message.type === 'houseplan/config/set') {
|
||||
throw Object.assign(new Error('conflict'), { code: 'conflict' });
|
||||
}
|
||||
if (message.type === 'houseplan/config/get') {
|
||||
return { config: structuredClone(authoritative), rev: authoritativeRev, can_write: true };
|
||||
}
|
||||
return originalCallWS(message);
|
||||
} };
|
||||
await card._saveSettingsDialog();
|
||||
await card.updateComplete;
|
||||
out.conflictKeepsAuthoritative = card._serverCfg.settings.bg_color === '#345678'
|
||||
&& !Object.hasOwn(card._serverCfg.settings, 'show_room_tooltip')
|
||||
&& card._cfgRev === authoritativeRev;
|
||||
out.conflictDraftKept = card._settingsDialog?.bgColor === '#abcdef'
|
||||
&& card._settingsDialog?.showRoomTooltip === false
|
||||
&& card._settingsDialog?.busy === false;
|
||||
card.hass = { ...card.hass, callWS: originalCallWS };
|
||||
|
||||
card._openSettingsDialog();
|
||||
card._settingsDialog = { ...card._settingsDialog, showRoomTooltip: false };
|
||||
await card._saveSettingsDialog();
|
||||
@@ -70,6 +132,13 @@ checkAll(result, {
|
||||
defaultOn: true,
|
||||
cancelKeepsAbsentDefault: true,
|
||||
defaultRoomTip: true,
|
||||
rejectedSettingsRolledBack: true,
|
||||
rejectedFingerprintRolledBack: true,
|
||||
rejectedDraftKept: true,
|
||||
rejectedBusyCleared: true,
|
||||
rejectedRuntimeUsesServerSettings: true,
|
||||
conflictKeepsAuthoritative: true,
|
||||
conflictDraftKept: true,
|
||||
falsePersists: true,
|
||||
visibleRoomTipCleared: true,
|
||||
disabledRoomTip: true,
|
||||
|
||||
Vendored
+55
-55
@@ -1,125 +1,125 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "e5edb95a1f5817c9035c6418ea0f9cb86cde238466f1f5c3174fb5246662c8ec",
|
||||
"fingerprint": "a1c6b7fa80c55b69f45f0b0975bcde7eb67d53a02f75f5b7c61d66f220e78ed9",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js",
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 291069,
|
||||
"initialViewGzipBytes": 291175,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/de-D_5HnJeM.js",
|
||||
"houseplan-assets/editor-CqQRQq4C.js",
|
||||
"houseplan-assets/fr-DpKqMyVB.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-D0JYjEs4.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C-SJxeJ_.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/de-B-zT3Bet.js",
|
||||
"houseplan-assets/editor-DJZS-SMT.js",
|
||||
"houseplan-assets/fr-DhlZhAWs.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-S0bYVW5I.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DJriHHug.js"
|
||||
],
|
||||
"lazyGzipBytes": 215495,
|
||||
"lazyGzipBytes": 215559,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/editor-CqQRQq4C.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-D0JYjEs4.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/editor-DJZS-SMT.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-S0bYVW5I.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 159809,
|
||||
"lazyEditorGzipBytes": 159876,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C-SJxeJ_.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DJriHHug.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 14126,
|
||||
"lazyOnboardingGzipBytes": 14133,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-D_5HnJeM.js",
|
||||
"houseplan-assets/fr-DpKqMyVB.js"
|
||||
"houseplan-assets/de-B-zT3Bet.js",
|
||||
"houseplan-assets/fr-DhlZhAWs.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 48734,
|
||||
"lazyLocaleGzipBytes": 48727,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"sha256": "b67eb5e04c63007ff8ca7ff5623a7dcae44ff3c6f3ca5528ac7f1d389f75c4ec",
|
||||
"path": "houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"sha256": "b556cef2823ea5e4f7c142ee5f4cee8dbbed71311dd101291faf30a0d38d6805",
|
||||
"rawBytes": 20996,
|
||||
"gzipBytes": 7174,
|
||||
"gzipBytes": 7177,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-D_5HnJeM.js",
|
||||
"sha256": "ad2dde1407ae850f963cf81a8c0218c0e6646a86cf3bceb61a305cd54f60dad9",
|
||||
"path": "houseplan-assets/de-B-zT3Bet.js",
|
||||
"sha256": "2ee98742a517ac754434e5627f958a20def03cd1c3907dd7ec3e394104c850a1",
|
||||
"rawBytes": 81632,
|
||||
"gzipBytes": 24639,
|
||||
"gzipBytes": 24635,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-CqQRQq4C.js",
|
||||
"sha256": "5007144deff010072eb0a6a6d3e5565064a60575baa173a0250cec89b1478823",
|
||||
"path": "houseplan-assets/editor-DJZS-SMT.js",
|
||||
"sha256": "3cda88a32916d4a3256cb0f76570d72f58308ad9ee6a28c9496d5c9e2c613aa4",
|
||||
"rawBytes": 3826,
|
||||
"gzipBytes": 1580,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-DpKqMyVB.js",
|
||||
"sha256": "3c03580d357a96678d80b012923e7e28e989fe6a612fe0342d5d041e2d37d4f1",
|
||||
"path": "houseplan-assets/fr-DhlZhAWs.js",
|
||||
"sha256": "f37aecbd6a5aaa1fbc5c3be0854464b949cbdcefd453906b268c46d76760772d",
|
||||
"rawBytes": 83754,
|
||||
"gzipBytes": 24095,
|
||||
"gzipBytes": 24092,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-o7i25aVl.js",
|
||||
"sha256": "9b3942532fe83c5d49791859c419fb6f35a8db86c01a09ddccb1a2ec186bfbd3",
|
||||
"rawBytes": 1033268,
|
||||
"gzipBytes": 290274,
|
||||
"path": "houseplan-assets/houseplan-card-D9kogu9G.js",
|
||||
"sha256": "65622583b77e3ff11a34ff2c2ceb65748cb1f607412794141375841fcea818bb",
|
||||
"rawBytes": 1033646,
|
||||
"gzipBytes": 290380,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-D_5HnJeM.js",
|
||||
"houseplan-assets/editor-CqQRQq4C.js",
|
||||
"houseplan-assets/fr-DpKqMyVB.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-D0JYjEs4.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C-SJxeJ_.js"
|
||||
"houseplan-assets/de-B-zT3Bet.js",
|
||||
"houseplan-assets/editor-DJZS-SMT.js",
|
||||
"houseplan-assets/fr-DhlZhAWs.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-S0bYVW5I.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DJriHHug.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-D0JYjEs4.js",
|
||||
"sha256": "b2a69132a223d6c5b06b8d4a11b19416d33582bae2d39b2448ecc41f44ba98b2",
|
||||
"rawBytes": 576032,
|
||||
"gzipBytes": 151055,
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-S0bYVW5I.js",
|
||||
"sha256": "c1935afb94bfe01cc7ee1302492c6c9a76faac8bd60ddc1db98eded52c7d9d65",
|
||||
"rawBytes": 576162,
|
||||
"gzipBytes": 151119,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-C-SJxeJ_.js",
|
||||
"sha256": "1324b8003d727c99c6ce6d9e48598032b29782f8c8c7b783c1b1073e9b79d9f2",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-DJriHHug.js",
|
||||
"sha256": "20b122261b8ce7484806fbaaf17aafb5f59c1864648b1a31fa226dc861d7cbd2",
|
||||
"rawBytes": 28088,
|
||||
"gzipBytes": 6952,
|
||||
"gzipBytes": 6956,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-Dg2Uytel.js",
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/backdrop-pick-BEQcDs80.js",
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "d6c8be124ce907703e76f24a5e9fedb3abd945213d7befb1f97d1635d82f4830",
|
||||
"sha256": "ac14b26a8d45a1747833be382ab3b0b816332156a59ed7125fa3eba598cd940d",
|
||||
"rawBytes": 1183,
|
||||
"gzipBytes": 795,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-o7i25aVl.js"
|
||||
"houseplan-assets/houseplan-card-D9kogu9G.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+5
-5
@@ -1,14 +1,14 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="e5edb95a1f5817c9035c6418ea0f9cb86cde238466f1f5c3174fb5246662c8ec";import{b as e,l as o,t,dg as s,A as a,dh as i,di as l,dj as n,E as r,c}from"./houseplan-card-o7i25aVl.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="a1c6b7fa80c55b69f45f0b0975bcde7eb67d53a02f75f5b7c61d66f220e78ed9";import{b as e,l as o,t,di as s,A as a,dj as i,dk as l,dl as n,E as r,c}from"./houseplan-card-D9kogu9G.js";class f extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,f={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},h=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
.computeLabel=${e=>h[e.name]||e.name}
|
||||
.computeLabel=${e=>f[e.name]||e.name}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>`;return c`
|
||||
${d(f.slice(0,3))}
|
||||
${d(h.slice(0,3))}
|
||||
${_?c`<div class="default-floor-error" role="alert"
|
||||
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
|
||||
${t(s,"editor.default_floor_missing",{id:_})}
|
||||
</div>`:a}
|
||||
${d(f.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
|
||||
${d(h.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+18
-18
File diff suppressed because one or more lines are too long
+74
-74
File diff suppressed because one or more lines are too long
+3
-3
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="e5edb95a1f5817c9035c6418ea0f9cb86cde238466f1f5c3174fb5246662c8ec";try{await import("./houseplan-assets/houseplan-card-o7i25aVl.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale entry: the main chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="a1c6b7fa80c55b69f45f0b0975bcde7eb67d53a02f75f5b7c61d66f220e78ed9";try{await import("./houseplan-assets/houseplan-card-D9kogu9G.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale entry: the main chunk is unavailable",e)}
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- If Home Assistant rejects a General settings save, the plan now returns to
|
||||
the last server-confirmed state instead of displaying an unsaved local draft;
|
||||
the entered values remain in the open dialog for another attempt
|
||||
([#439](https://github.com/Matysh/houseplan-card/issues/439)).
|
||||
|
||||
## v1.71.0-beta.2 — 2026-09-03
|
||||
|
||||
- Custom background images now recover cleanly after interrupted uploads,
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
|
||||
## Не выпущено
|
||||
|
||||
- Если Home Assistant отклоняет сохранение общих настроек, план снова показывает
|
||||
последнее подтверждённое сервером состояние вместо несохранённого локального
|
||||
черновика; введённые значения остаются в открытом диалоге для повторной
|
||||
попытки ([#439](https://github.com/Matysh/houseplan-card/issues/439)).
|
||||
|
||||
## v1.71.0-beta.2 — 2026-09-03
|
||||
|
||||
- Пользовательские картинки подложки теперь корректно восстанавливаются после
|
||||
|
||||
@@ -242,7 +242,7 @@ import {
|
||||
canonicalizePosition,
|
||||
formatLatticeShiftCm,
|
||||
} from './coordinate-canonicalization';
|
||||
import { enqueueSerializedWrite } from './serialized-write-queue';
|
||||
import { enqueueSerializedWrite, optimisticAttempt, rollbackOptimistic, type OptimisticAttempt } from './serialized-write-queue';
|
||||
import { hasTranslation, langOf, t, type I18nKey } from './i18n';
|
||||
import { supportT, type SupportI18nKey } from './i18n/support';
|
||||
import {
|
||||
@@ -10228,6 +10228,7 @@ public _updateDecorStyle(next: DecorStyle): void {
|
||||
const d = this.host._settingsDialog;
|
||||
if (!d || d.busy) return;
|
||||
this.host._settingsDialog = { ...d, busy: true };
|
||||
let attempt: OptimisticAttempt<ServerConfig> | null = null;
|
||||
try {
|
||||
const cfg = this.host._serverCfg!;
|
||||
const isDefault = JSON.stringify(d.colors) === JSON.stringify(DEFAULT_FILL_COLORS);
|
||||
@@ -10239,8 +10240,7 @@ public _updateDecorStyle(next: DecorStyle): void {
|
||||
else delete settings.glow_radius_cm;
|
||||
if (d.bgColor) settings.bg_color = d.bgColor;
|
||||
else delete settings.bg_color;
|
||||
// Sun background compatibility is explicit: legacy absence means static,
|
||||
// while new installations and spaces materialise daynight.
|
||||
// Legacy absence means static; new installations/spaces materialise daynight.
|
||||
if (d.northDeg !== null && Number.isInteger(d.northDeg) && d.northDeg >= 0 && d.northDeg <= 359)
|
||||
settings.north_deg = d.northDeg;
|
||||
else delete settings.north_deg;
|
||||
@@ -10249,21 +10249,22 @@ public _updateDecorStyle(next: DecorStyle): void {
|
||||
else delete settings.sun_rays;
|
||||
if (d.showRoomTooltip) delete settings.show_room_tooltip;
|
||||
else settings.show_room_tooltip = false;
|
||||
// Legacy compatibility: old configs may still contain this accepted
|
||||
// field, but weather no longer affects sunlight and the UI no longer
|
||||
// exposes it. Saving general settings cleans the obsolete value up.
|
||||
// Old configs may still contain this accepted field, but weather no
|
||||
// longer affects sunlight; saving general settings cleans it up.
|
||||
delete settings.weather_entity;
|
||||
this.host._serverCfg = { ...cfg, settings };
|
||||
const nextConfig = { ...cfg, settings };
|
||||
attempt = optimisticAttempt(cfg, nextConfig, this.host._cfgContentFingerprint,
|
||||
this.host._cfgRev, contentFingerprint);
|
||||
this.host._serverCfg = nextConfig;
|
||||
await this._saveConfigNow();
|
||||
if (!d.showRoomTooltip && this.host._tip?.room) this.host._tip = null;
|
||||
this.host._settingsDialog = null;
|
||||
this.host.requestUpdate();
|
||||
this.host._showToast(this.host._t('gs.saved'));
|
||||
} catch (e: any) {
|
||||
// audit L3: the dialog may have been closed (Esc) while the save was
|
||||
// in flight — spreading null yields a truthy husk and the renderer
|
||||
// then crashes, blanking the whole card. The toast below is the
|
||||
// only remaining signal, so it must still fire.
|
||||
// Esc may close the dialog in flight; the toast must still fire (audit L3).
|
||||
// Never overwrite an authoritative conflict reload or newer edit (#439).
|
||||
if (attempt) rollbackOptimistic(this.host, attempt, contentFingerprint);
|
||||
if (this.host._settingsDialog) this.host._settingsDialog = { ...this.host._settingsDialog, busy: false };
|
||||
this.host._showToast(this.host._t('toast.error', { err: this.host._errText(e) }));
|
||||
}
|
||||
|
||||
@@ -9,3 +9,52 @@ export function enqueueSerializedWrite(
|
||||
): Promise<void> {
|
||||
return previous.catch(() => undefined).then(write);
|
||||
}
|
||||
|
||||
export interface OptimisticAttempt<T> {
|
||||
previous: T;
|
||||
previousFingerprint: string;
|
||||
revision: number;
|
||||
attempted: T;
|
||||
attemptedFingerprint: string;
|
||||
}
|
||||
|
||||
/** Capture the server-backed value before exposing a write candidate locally. */
|
||||
export function optimisticAttempt<T>(
|
||||
previous: T,
|
||||
attempted: T,
|
||||
previousFingerprint: string,
|
||||
revision: number,
|
||||
fingerprint: (value: T) => string,
|
||||
): OptimisticAttempt<T> {
|
||||
return {
|
||||
previous: JSON.parse(JSON.stringify(previous)) as T,
|
||||
previousFingerprint,
|
||||
revision,
|
||||
attempted,
|
||||
attemptedFingerprint: fingerprint(attempted),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back only the failed candidate represented by this attempt. A conflict
|
||||
* reload or a newer edit owns a different revision/content and must win.
|
||||
*/
|
||||
export function rollbackOptimistic<T>(
|
||||
host: {
|
||||
_serverCfg: T | null;
|
||||
_cfgRev: number;
|
||||
_cfgContentFingerprint: string;
|
||||
requestUpdate: () => unknown;
|
||||
},
|
||||
attempt: OptimisticAttempt<T>,
|
||||
fingerprint: (value: T) => string,
|
||||
): boolean {
|
||||
const current = host._serverCfg;
|
||||
if (!current || host._cfgRev !== attempt.revision
|
||||
|| (current !== attempt.attempted
|
||||
&& fingerprint(current) !== attempt.attemptedFingerprint)) return false;
|
||||
host._serverCfg = attempt.previous;
|
||||
host._cfgContentFingerprint = attempt.previousFingerprint;
|
||||
host.requestUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { enqueueSerializedWrite } from '../test-build/serialized-write-queue.js';
|
||||
import {
|
||||
enqueueSerializedWrite,
|
||||
optimisticAttempt,
|
||||
rollbackOptimistic,
|
||||
} from '../test-build/serialized-write-queue.js';
|
||||
|
||||
function deferred() {
|
||||
let resolve;
|
||||
@@ -51,3 +55,48 @@ test('a failed write does not poison the next queued edit (#224)', async () => {
|
||||
await recovered;
|
||||
assert.deepEqual(seen, ['failed', 'recovered']);
|
||||
});
|
||||
|
||||
test('a rejected optimistic write restores only its own candidate (#439)', () => {
|
||||
const fingerprint = (value) => JSON.stringify(value);
|
||||
const previous = { settings: { enabled: true } };
|
||||
const attempted = { settings: { enabled: false } };
|
||||
const attempt = optimisticAttempt(previous, attempted, 'server-fingerprint', 7, fingerprint);
|
||||
let updates = 0;
|
||||
const host = {
|
||||
_serverCfg: attempted,
|
||||
_cfgRev: 7,
|
||||
_cfgContentFingerprint: fingerprint(attempted),
|
||||
requestUpdate: () => { updates += 1; },
|
||||
};
|
||||
|
||||
assert.equal(rollbackOptimistic(host, attempt, fingerprint), true);
|
||||
assert.deepEqual(host._serverCfg, previous);
|
||||
assert.notEqual(host._serverCfg, previous, 'the rollback snapshot is isolated from later mutations');
|
||||
assert.equal(host._cfgContentFingerprint, 'server-fingerprint');
|
||||
assert.equal(updates, 1);
|
||||
});
|
||||
|
||||
test('a conflict reload or newer mutation wins over a rejected candidate (#439)', () => {
|
||||
const fingerprint = (value) => JSON.stringify(value);
|
||||
const previous = { settings: { value: 'server-before' } };
|
||||
const attempted = { settings: { value: 'draft' } };
|
||||
const attempt = optimisticAttempt(previous, attempted, 'before', 3, fingerprint);
|
||||
const authoritative = { settings: { value: 'server-after' } };
|
||||
let updates = 0;
|
||||
const host = {
|
||||
_serverCfg: authoritative,
|
||||
_cfgRev: 4,
|
||||
_cfgContentFingerprint: fingerprint(authoritative),
|
||||
requestUpdate: () => { updates += 1; },
|
||||
};
|
||||
|
||||
assert.equal(rollbackOptimistic(host, attempt, fingerprint), false);
|
||||
assert.equal(host._serverCfg, authoritative);
|
||||
assert.equal(updates, 0);
|
||||
|
||||
host._cfgRev = 3;
|
||||
host._serverCfg = { settings: { value: 'newer-local-edit' } };
|
||||
assert.equal(rollbackOptimistic(host, attempt, fingerprint), false);
|
||||
assert.equal(host._serverCfg.settings.value, 'newer-local-edit');
|
||||
assert.equal(updates, 0);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user