UX-13 P2 review fixes (PR #145, comment 1880)
1. Discard reloads /config/model: after a stale save the page kept the
new fingerprint with the old values, so Discard + Save overwrote the
other surface's change without a 409.
2. Removing cards back to one restores the stored inverter shape, so a
flat site stays flat after add + remove.
3. A choice the page can only keep ("Other time windows") stays offered
while it is the stored value.
4. A load locks every locked value again.
5. at_zero() needs an accepted 0 W write; before the first one Home says
"Going to 0 W" (the heartbeat writes every heartbeat_s, so it clears).
6. A field with a unit drops the translation's "(W)" from its label: the
peak limit read "Peak limit (W)" beside a kW value.
7. A mirrored choice lists the mirrored field's keys, so a search for
static_profile finds the contract on a fixed-price site.
8. test_settings: a save refused by ui_to_options writes nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -87,8 +87,10 @@
|
||||
}
|
||||
|
||||
/* ---------------- controls ---------------- */
|
||||
function choicesOf(f, cur) {
|
||||
const out = (f.choices || []).filter((c) => !c[2] || same(c[0], cur));
|
||||
// A choice the page can only keep stays offered while it is the stored value.
|
||||
function choicesOf(f, card) {
|
||||
const cur = get(f, card), was = valueIn(ORIG, f, card);
|
||||
const out = (f.choices || []).filter((c) => !c[2] || same(c[0], cur) || same(c[0], was));
|
||||
if (cur != null && cur !== "" && !out.some((c) => same(c[0], cur))) out.push([cur, String(cur)]);
|
||||
return out;
|
||||
}
|
||||
@@ -106,7 +108,7 @@
|
||||
function radios(f, card, lid, cards) {
|
||||
const cur = get(f, card);
|
||||
const g = h("div", { class: cards ? "choices" : "seg", role: "radiogroup", "aria-labelledby": lid });
|
||||
const items = choicesOf(f, cur);
|
||||
const items = choicesOf(f, card);
|
||||
const buttons = items.map(([v, label], i) => {
|
||||
const on = same(v, cur);
|
||||
const hint = cards && f.hints ? f.hints[v] : "";
|
||||
@@ -132,7 +134,7 @@
|
||||
function select(f, card, lid) {
|
||||
const cur = get(f, card);
|
||||
const s = h("select", { class: "sel", "aria-labelledby": lid });
|
||||
for (const [v, label] of choicesOf(f, cur)) s.append(h("option", { value: JSON.stringify(v), selected: same(v, cur) }, label));
|
||||
for (const [v, label] of choicesOf(f, card)) s.append(h("option", { value: JSON.stringify(v), selected: same(v, cur) }, label));
|
||||
for (const [v, label] of f.later || []) s.append(h("option", { value: JSON.stringify(v), disabled: true }, label));
|
||||
s.addEventListener("change", () => put(f, card, JSON.parse(s.value), true));
|
||||
const preset = f.presets && f.presets[cur];
|
||||
@@ -324,7 +326,10 @@
|
||||
const box = h("div", { class: "inv" }, h("div", { class: "hd" },
|
||||
h("span", { class: "grow" }, c.name || W.inverter + " " + (i + 1)), h("span", { class: "key" }, f.key + "[" + i + "]"),
|
||||
cards.length > 1 ? h("button", { type: "button", class: "btn link tiny", onclick: () => {
|
||||
V[f.key].splice(i, 1); V[f.count] = V[f.key].length; put(f, null, V[f.key], true);
|
||||
V[f.key].splice(i, 1); V[f.count] = V[f.key].length;
|
||||
// Back to one card, the stored shape returns: a flat inverter stays flat.
|
||||
if (V[f.key].length === 1) for (const k in f.grow) V[k] = clone(ORIG[k]);
|
||||
put(f, null, V[f.key], true);
|
||||
} }, W.remove) : null));
|
||||
for (const s of f.fields) box.append(fieldRow(s, i, gid));
|
||||
wrap.append(box);
|
||||
@@ -496,6 +501,7 @@
|
||||
return;
|
||||
}
|
||||
M = m; V = clone(m.ui); ORIG = clone(m.ui); FP = m.fingerprint; MSG = []; DEVICE = "";
|
||||
UNLOCKED.clear();
|
||||
$("#set-search").hidden = false;
|
||||
FILLED = {};
|
||||
LIST = null;
|
||||
@@ -541,9 +547,9 @@
|
||||
finally { btn.disabled = false; btn.textContent = W.savebar.save; }
|
||||
}
|
||||
$("#sb-save").addEventListener("click", save);
|
||||
$("#sb-discard").addEventListener("click", () => {
|
||||
V = clone(ORIG); UNLOCKED.clear(); render(); validate(); toast(W.toast.discarded);
|
||||
if ($("#set-banner .b-bad")) banner();
|
||||
// Discard reloads what is stored: after a stale save ORIG is no longer it.
|
||||
$("#sb-discard").addEventListener("click", async () => {
|
||||
await load(); toast(W.toast.discarded);
|
||||
});
|
||||
addEventListener("beforeunload", (e) => { if (V && dirtyCount()) { e.preventDefault(); e.returnValue = ""; } });
|
||||
document.addEventListener("ux13:tab", (e) => {
|
||||
|
||||
Reference in New Issue
Block a user