Removable reference curves, audit fixes across pages, shaded Academy art
Test and deploy / test-and-deploy (push) Successful in 1m8s
Test and deploy / test-and-deploy (push) Successful in 1m8s
The planner's Artisan .alog drawer now shows what's attached with a "Remove reference curve" control (re-rendered per drawer open), so adding a reference curve is no longer a one-way door; /api/alog shares the 8 MB body cap so real-sized logs parse instead of failing with "bad_request". Deep-evaluation fixes: editing a brew of an archived bean no longer silently detaches the bean; the roasts pending-review poll no longer wipes in-progress after-roast edits; roasters gain an Edit (rename/model) action; the gear page refuses to autosave over a failed load; duplicating a plan carries its custom name; cupping sessions can attach a plan after creation (ownership-checked PUT + selector); admin user deletion also refreshes plans/audit; cupping cup-count subtitle stays live; roasts error-row colspan corrected. Regression tests cover the new cupping PUT and the /api/alog body cap. Academy scenes drop the flat paper-cutout look: shared defs provide radial-gradient shading on every bean/half-bean/particle, flame gradients with radiant halos, soft ground shadows, and a warm-lit stage background; fill-shift animations now ride a partial-opacity tint overlay so shading survives the color change. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
+33
-2
@@ -21,6 +21,38 @@ export function initAlogPanel({
|
||||
resultEl = document.getElementById("alog-result"),
|
||||
actualInput = document.getElementById("actual-alog-file"),
|
||||
actualResultEl = document.getElementById("actual-alog-result");
|
||||
// A plan keeps its attached reference curve until explicitly removed — show what's
|
||||
// attached (including on page load) with a Remove control, so adding a curve is
|
||||
// never a one-way door.
|
||||
function renderReference(summary) {
|
||||
const ref = state.plan.reference;
|
||||
if (!ref?.roast) {
|
||||
resultEl.replaceChildren();
|
||||
return;
|
||||
}
|
||||
const node = document.createElement("p");
|
||||
node.textContent =
|
||||
summary ??
|
||||
`Attached: ${ref.roast.title || "reference curve"} — ${ref.roast.roastDate || "no date"}.`;
|
||||
const removeBtn = document.createElement("button");
|
||||
removeBtn.type = "button";
|
||||
removeBtn.className = "ghost-btn small";
|
||||
removeBtn.style.marginLeft = "8px";
|
||||
removeBtn.textContent = "Remove reference curve";
|
||||
removeBtn.addEventListener("click", () => {
|
||||
state.plan.reference = null;
|
||||
recompute();
|
||||
setText(resultEl, "Reference curve removed.");
|
||||
});
|
||||
node.append(removeBtn);
|
||||
resultEl.replaceChildren(node);
|
||||
}
|
||||
renderReference();
|
||||
// Re-render on every drawer open: the user may have switched plans since init, and the
|
||||
// summary must always describe the plan currently loaded.
|
||||
document
|
||||
.getElementById("nav-alog")
|
||||
?.addEventListener("click", () => renderReference());
|
||||
fileInput.addEventListener("change", async (e) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
@@ -135,8 +167,7 @@ export function initAlogPanel({
|
||||
}
|
||||
state.plan.reference = body;
|
||||
recompute();
|
||||
setText(
|
||||
resultEl,
|
||||
renderReference(
|
||||
`${body.roast.title} — ${body.roast.roastDate || "no date"}; first crack ${fmt(body.derived?.firstCrackS)}; development ${fmt(body.derived?.developmentS)}; drop ${fmt(body.derived?.dropS)}; DTR ${body.derived?.dtrPct ?? "—"}%.`,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user