diff --git a/manager/core/board.html b/manager/core/board.html index c3df5c1..a0766fa 100644 --- a/manager/core/board.html +++ b/manager/core/board.html @@ -309,6 +309,14 @@ font-family:var(--mono);font-size:11.5px;line-height:1.5;color:var(--muted); white-space:pre-wrap;overflow-x:auto; } + /* a well as a real disclosure: the summary IS the well, so its › is earned + — it rotates open instead of the fold's usual ▸ prefix */ + .fold.wellfold{max-width:none} + .fold.wellfold summary::before{content:none} + .fold.wellfold summary::-webkit-details-marker{display:none} + .fold.wellfold .lead{transition:transform .12s ease} + .fold.wellfold[open] .lead{transform:rotate(90deg)} + .fold.wellfold pre{max-height:300px;overflow-y:auto} .stopbtn:hover{border-color:var(--alarm);color:var(--alarm)} .f-empty{padding:30px 20px;font-size:12.5px;color:var(--dim)} @@ -857,11 +865,11 @@ function cardFor(task) { const last = run || (smeta && smeta.lastSummary ? { summary: smeta.lastSummary, ok: null } : null); if (last && last.summary) { const active = run || (smeta && smeta.status === 'active'); - liveLine = `
${esc(last.detail)}right + after the wellfold's summary, scrollable when long.""" + self.assertRegex(self.html, + r"
\$\{esc\(last\.detail\)\}",
+ "the wellfold must render last.detail in a ")
+ self.assertRegex(self.html, r"\.fold\.wellfold pre\{[^}]*max-height",
+ "long reports need a scroll bound on the fold's pre")
+
+ def test_open_state_is_keyed_not_dom_only(self):
+ """Focus re-renders every few seconds over SSE; the fold must be
+ re-created from S.openFolds and write back on toggle, exactly like
+ the Sessions timeline's folds."""
+ m = re.search(r"if \(last && last\.detail\) \{(.*?)\}\s*else",
+ self.html, re.S)
+ self.assertIsNotNone(m, "the Focus well no longer branches on detail")
+ for needle in ("data-key", "S.openFolds.has"):
+ self.assertIn(needle, m.group(1),
+ f"the wellfold lost {needle}: open state would "
+ "snap shut on the next re-render")
+ self.assertIn("#cgrid details.fold", self.html,
+ "renderFocus must re-attach toggle listeners so "
+ "toggles land back in S.openFolds")
+
+ def test_sessions_timeline_fold_unchanged(self):
+ """The timeline's own fold mechanism is the pattern being reused,
+ not replaced."""
+ self.assertIn("function fold(key, label, body)", self.html)
+ self.assertIn("ev.kind === 'report' ? 'the report'", self.html)
+ self.assertIn("#ftl details", self.html)
+
+
+if __name__ == "__main__":
+ unittest.main()