Drafts rebase onto the live settings; the review speaks in words

A draft started before someone else's Apply used to carry that older config and would have put
the newer changes back. Now every read of the draft replays only the draft's own changes onto the
live settings (base config from history), so the review lists exactly what you changed. Values
read in words (windows as days and hours), long ones fold open with was/now, commands are no
longer red, and warnings the live config already had are not repeated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 19:44:51 -04:00
co-authored by Claude Fable 5.1
parent edfd218ac9
commit 0eee778a92
6 changed files with 181 additions and 22 deletions
+4 -2
View File
@@ -676,11 +676,13 @@
return;
}
const r = await post("/api/validate", {});
const changes = r.changes.map((c) => `<li class="${c.command ? "command" : ""}">${esc(c.text)}${c.command ? ' <span class="pill">command</span>' : ""}</li>`).join("") + (r.atem_pending ? "<li>A new saved switcher file replaces the current one.</li>" : "");
const changes = r.changes.map((c) => c.before !== undefined || c.after !== undefined
? `<li><details><summary>${esc(c.text)}${c.command ? ' <span class="pill" data-hint="A command the watchdog will run; it never runs before Apply">command</span>' : ""}</summary>${c.before != null ? `<div class="small"><span class="muted">was</span> <span class="${c.command ? "mono" : ""}">${esc(c.before)}</span></div>` : ""}${c.after != null ? `<div class="small"><span class="muted">now</span> <span class="${c.command ? "mono" : ""}">${esc(c.after)}</span></div>` : ""}</details></li>`
: `<li>${esc(c.text)}</li>`).join("") + (r.atem_pending ? "<li>A new saved switcher file replaces the current one.</li>" : "");
const errors = r.errors.map((e) => `<li>${esc(e)}</li>`).join("");
const warnings = r.warnings.map((w) => `<li>${esc(w)}</li>`).join("");
const live = r.live && r.live.live ? `<div class="notice">Live now: ${esc(r.live.reason)}. Apply waits; your draft is saved. ${editing() ? '<button id="emergency" class="danger small">Apply anyway</button>' : ""}</div>` : "";
main.innerHTML = `<h1>Apply${hint("Your changes in words, and what will happen on the deck. Nothing is live until you press APPLY.")}</h1><p class="muted small">Started by ${esc(state.draft.started_by || state.draft.by || "?")}${state.draft.started ? " at " + esc(when(state.draft.started)) : ""}. ${state.draftStale ? "<b>The live settings changed since: look again before applying.</b>" : ""}</p>
main.innerHTML = `<h1>Apply${hint("Your changes in words, and what will happen on the deck. Nothing is live until you press APPLY.")}</h1>${state.draftStale ? "<p class='notice'>The live settings changed since this draft was started and could not be merged: look through the list before applying.</p>" : ""}
<div class="card">${changes ? `<ul class="changes">${changes}</ul>` : "<p class='muted'>No change yet.</p>"}
<p><b>Then:</b> ${esc(r.feel)}</p>
${errors ? `<div class="notice problem"><b>Not possible yet:</b><ul>${errors}</ul></div>` : ""}${warnings ? `<div class="notice grey"><ul>${warnings}</ul></div>` : ""}${live}