diff --git a/manager/core/board.html b/manager/core/board.html index 67c2327..4cd0d44 100644 --- a/manager/core/board.html +++ b/manager/core/board.html @@ -2303,16 +2303,18 @@ async function unarchiveLast() { /* Where a lane sits in the stack: a halt first, because it is the one thing on this page waiting on a person and it must not be below the - fold; then a run in flight; then the phases nobody has started; then the - ones that are over. Every phase card draws a lane — a phase whose - members are all merged and which is waiting on its own PR still owns - them, and a lane that vanished exactly when it needed merging would be - a view you could not trust. */ + fold; then a run in flight; then a run a person held, which is still + theirs to resume and so belongs above the phases nobody has started; + then the ones that are over. Every phase card draws a lane — a phase + whose members are all merged and which is waiting on its own PR still + owns them, and a lane that vanished exactly when it needed merging + would be a view you could not trust. */ function laneRank(task) { const snap = (S.state.phases || {})[task.file]; if (snap && snap.halted) return 0; if (snap && snap.running) return 1; - return task.stage === 'done' ? 3 : 2; + if (snap && snap.stopped) return 2; + return task.stage === 'done' ? 4 : 3; } function lanePhases() { diff --git a/tests/test_phases_view.py b/tests/test_phases_view.py index 57d7ecc..e46b996 100644 --- a/tests/test_phases_view.py +++ b/tests/test_phases_view.py @@ -202,6 +202,27 @@ class OneLanePerPhase(LaneCase): self.assertEqual(self.lanes(phases=self.snapshot()), ["40-the-site.md", "39-earlier.md"]) + def test_a_held_run_sorts_above_a_phase_nobody_has_started(self): + """A person held it, so it is theirs to resume — it belongs near the + top, not lumped in with the phases nobody has started.""" + self.a_phase_of_three() + self.write("41-the-docs.md", card("41 — Ship the docs", kind="Phase", + cards="- 33 — The landing page\n", + status="In Progress"), "in-progress") + self.write("39-earlier.md", card("39 — An earlier phase", kind="Phase", + cards="- 33 — The landing page\n", + status="To Do"), "to-do") + phases = self.snapshot() + phases["41-the-docs.md"] = {"file": "41-the-docs.md", "members": [], + "running": False, "started": True, + "halted": "", "haltedAt": None, + "haltedWhy": None, "stopped": True, + "stoppedBy": "held by ronald"} + + self.assertEqual(self.lanes(phases=phases), + ["40-the-site.md", "41-the-docs.md", "39-earlier.md"], + "running, then the held run, then the unstarted one") + def test_a_finished_phase_sorts_last(self): self.a_phase_of_three(phase_stage="done") self.write("41-the-docs.md", card("41 — Ship the docs", kind="Phase",