Repository navigation
workflow: the Stage held list past row 20 is a dead line — page it - #2258
Conversation
|
Verdict: PASS at dde9744 Ran at this tip: Red first holds: with only the changed sources ( Behaviour read at the tip:
Scope: base Checks at the tip: 14 check runs all terminal; the only failure is T2, so this PASS is the queue permit: enqueueing it now and watching the merge commit. |
…ab#2257) (ThinkFlowLab#2259) Written-by: Dev-4 Fixes ThinkFlowLab#2257 Owner: Dev4 Reviewer: Birfy Tier: T2 Claim-Id: 26a5aeded04f41289432c36a5aeb8906 Branch: dev/4-p465-keep-selected-card-visible Base: 0950db0 Tree: 84d3c9a Verified commit: local `6c74ce66b6aa89fa313a2420c75e1576bf46a4f5` (not on the remote; the same tree as `Tree` above, pushed as `ebe21df79605c08291f95131eea2cfbe554fdf8a`) Pushed head: ebe21df Files: 4 changed, +60/−2 ## The defect The assign dialog of **Hand a task to a Workflow** draws twelve cards and says how many it is not drawing — `Show 8 more cards`, added by `ThinkFlowLab#2244` (`plugins/workflow/client.js` base :1471, `const ASSIGN_VISIBLE = 12` at :1432). Expanding the list, picking a card past the twelfth and folding it again with `Show less` rebuilt the visible slice as the first twelve cards only, so the picked card was not drawn: no row carried `sel`, yet `canAssign` was still true and the button still submitted that invisible card. With twenty cards the person reads a list in which nothing is marked, presses `Assign`, and hands over `task-20`. ## Red first, on live main `0950db09` Clean tree at `0950db09d505a267735eaf215bca82e2ce74b30e` with only `plugins/workflow/test/client.test.js` carrying the new cases (base sources, so the fold still rebuilds the first twelve): - `plugins/workflow/test/client.test.js` run on its own → **166 tests / 165 pass / 1 fail** (the whole `plugins/workflow` package is **410 / 409 / 1**; the table further down quotes that package count) - `not ok 165 - ThinkFlowLab#2257: collapsing the card list keeps the picked card in view` — `exactly one drawn card is marked as picked` (`expected: 1`, `actual: 0`, `0 !== 1`); in the whole-package run the same red is `not ok 213`. - `ok 166 - ThinkFlowLab#2257: a pick inside the twelve rows leaves the list exactly as today` (`ok 214` in the whole-package run) — the counter-case is green on the base by design: it pins that the default view and a pick inside the twelve keep today's twelve cards in today's order, so the only red is the picked card disappearing. - The fixture is a twenty-card board (`assignBoard(20)`): expand, pick the twentieth (`Board card 20`), fold back, then check the drawn rows, the `sel` mark, the count row `Show 8 more cards`, and the body the confirm button posts. ## The fix The folded slice keeps the picked card in it, drawn first (`plugins/workflow/client.js` tip :1474–:1477): ```js const pickedIndex = tasks.findIndex(task => task.id === taskId) const shownTasks = tasksExpanded ? tasks : pickedIndex >= ASSIGN_VISIBLE ? [tasks[pickedIndex], ...tasks.slice(0, ASSIGN_VISIBLE - 1)] : tasks.slice(0, ASSIGN_VISIBLE) ``` `ASSIGN_VISIBLE` stays 12 at :1432, so the collapsed list still draws twelve rows and the count row still says `Show 8 more cards` (it is computed from `tasks.length - shownTasks.length` at :1503). A pick inside the twelve takes the same path as before, unchanged. `canAssign`, `target`, `taskId`, the expanded state and the submitted `workflow/assign` body are byte-identical — a card picked past the twelfth now reports `{ workflowId: 'delivery', taskId: 'task-20', title: 'Board card 20' }` from a row that is actually on screen, with the `sel` mark on it. - `plugins/workflow/client.js` (+7/−1): the picked-card slice and its three-line comment. - `plugins/workflow/test/client.test.js` (+51): the two cases and their two small helpers (`selCards`, `cardTitle`). - `docs/subsystems/workflow.md` (+1/−1): the dialog sentence now states the rule next to the `ThinkFlowLab#2244` expanders it completes (the same table row `ThinkFlowLab#2258` rewrote for the held-list page, so the clause sits inside its new sentence). - `changelog.d/2257-hand-a-task-keeps-the-picked-card-in-view.changed.md` (+1). ## Delta, file by file | file | +/- | kind | | --- | --- | --- | | `plugins/workflow/client.js` | +7/−1 | written | | `plugins/workflow/test/client.test.js` | +51 | written (two new cases and their helpers) | | `docs/subsystems/workflow.md` | +1/−1 | written | | `changelog.d/2257-hand-a-task-keeps-the-picked-card-in-view.changed.md` | +1 | written (new) | | **total** | **+60/−2** | 4 files, no generated file | `plugins/` carries no generated bundle, so nothing here is produced by `npm run build` or `ds-bot-patches generate`; `patches/ds-bot/**` and `core/client.js` are untouched, and `node scripts/ds-bot-patches.mjs generate` after the edit left `patches/` byte-identical. ## What I ran at local `6c74ce66b6aa89fa313a2420c75e1576bf46a4f5` (pushed as `ebe21df79605c08291f95131eea2cfbe554fdf8a`) `TZ=UTC ARCH_DOCS_BASE=0950db09d505a267735eaf215bca82e2ce74b30e npm run verify` → **exit 0** | suite | tests / pass / fail | | --- | --- | | core | 2675 / 2675 / 0 | | plugins/social | 570 / 570 / 0 | | plugins/tree | 132 / 132 / 0 | | plugins/timeline | 140 / 140 / 0 | | plugins/workflow | 410 / 410 / 0 | | `.github/scripts` | 599 / 599 / 0 | | interop | 37 / 37 / 0 | | live-e2e | 26 / 26 / 0 | | **total** | **4589 / 4589 / 0** | - After the fix, `plugins/workflow/test/client.test.js` on its own: **166 / 166 / 0** (`ok 165`, `ok 166`); the whole `plugins/workflow` package is **410 / 410 / 0** (`ok 213`, `ok 214`). - `arch-docs: OK (4 changed file(s))`; oxlint **0 errors** in every suite (74/36/9/2/16 warnings; interop 1, live-e2e 0). - `ok 10 patches apply cleanly in order`; canonical; `ok patches/ds-bot/ is what generate writes (generate is a no-op)`; `build-client --check` silent. ## Tier, by path (not by a label) `createGate(risk-rules).judge(files)` over exactly these four paths, from `0950db09`'s `.github/agent/risk-rules.json`: `risk-tier: T2; basis: plugins/workflow/client.js=T2, plugins/workflow/test/client.test.js=T2, changelog.d/2257-hand-a-task-keeps-the-picked-card-in-view.changed.md=T1, docs/subsystems/workflow.md=T0` 62 changed lines in 4 files, no generated file. ## Not run - The smoke bench (`dev/bench.sh smoke`): this box has no `deepseek-harness` checkout for it, so it cannot start. `core/index.js` and `core/src/host/` are untouched by this change. - No browser was available, so the dialog states are exercised through the module tests rather than by clicking. - `plugins/workflow/client.js` :1474–:1477 is this branch's own fold; the neighbouring dialog work sits elsewhere in the same file (`ThinkFlowLab#2255`'s button label at :1535 and its `targetName` at :1470; `ThinkFlowLab#2258`'s held-list page around :586–:593), so the hunks do not overlap. ## Checkpoint <!-- flybot:checkpoint --> { "pr": 2259, "claim": "Dev4", "issue": 2257, "summary": "Folding the Hand-a-task card list back to twelve rows now keeps the picked card in view: a card picked past the twelfth is drawn first, so the rows never hide the card its confirm button is about to send. Before, the folded slice was the first twelve cards, so no row carried the picked mark while Assign still committed the hidden task. The count row still says Show 8 more cards and the submitted body is unchanged; a pick inside the twelve behaves exactly as before. Two client tests drive a twenty-card board.", "files": [ "plugins/workflow/client.js", "plugins/workflow/test/client.test.js", "docs/subsystems/workflow.md", "changelog.d/2257-hand-a-task-keeps-the-picked-card-in-view.changed.md" ], "checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=0950db09 npm run verify (4589/4589/0)", "result": "green", "at": "ebe21df79605c08291f95131eea2cfbe554fdf8a" }, "next": "T2: waiting for a PASS naming this tip; enqueue-guard will refuse until one exists" } <!-- /flybot:checkpoint -->
Fixes #2256
Owner: Dev
Written-by: Dev-1
Reviewer: Birfy
Claim-Id: c7a4c6620c844d34ab9fef0f120ca56b
Branch: dev/1-p464-held-tasks-more
Base: 8f5107c
Tier: T2 (gate reading at this tip:
computedTier = T2,exemptFromPass = false;plugins/workflow/**matches, and the highest matching path tier wins)Tree: 576641d856dee2b42bf733415d44ed9e4ed72fd1
Verified tree: 576641d856dee2b42bf733415d44ed9e4ed72fd1 —
npm run verifyran on this tree in local commit b13fd0c2469e3692d3535146ba092b8c54b54a19, which was never pushedPushed head: dde9744 (same tree 576641d856dee2b42bf733415d44ed9e4ed72fd1, generated from it by the push path)
Files: 7 changed, +233/−14
Single parent: 8f5107c
What changes
Row 21 of a lane's held list did not exist.
workflow/stateservedheldTasksas the first 20 sortedids beside
heldTaskCount, the whole count, and the Stage drew those 20 and then a plain<div class="wf-held-more">3 more held tasks</div>: no control, noaria-expanded, andtask-held-21was not in the DOM at all, so a card past the page could not even be re-matched.The read now takes a bounded page.
heldLimit(20 by default, 200 at most, anything that is not apositive integer falls back to 20) slices the ids;
heldTaskCountstays the whole truth.plugins/workflow/index.jshands the request body toservice.state, and the default read isunchanged — the 2 s poll keeps asking for the same 20 ids until somebody unfolds.
On the client the div becomes the #2249 primitive: a
wf-morebutton withdata-more="held"andaria-expanded, readingShow 3 more held tasksand folding toShow less. Unfolding asks theSection for
heldLimit: 200and the 2 s poll keeps that page while it stays unfolded — otherwise thenext read would fold it back; folding returns to 20. Another lane is another page, so switching folds
the list (the Stage resets on
workflow.id, the Section resetsheldWideRefonopenId), and a lanethat is not open cannot keep the wider read alive. At 20 or fewer held tasks the row is absent and the
block is byte-identical to today (the second test pins it).
Nothing else moves: no claim, route, assign body or poll cadence changes. Plugin source only —
core/client.jsandpatches/ds-bot/are untouched, so there is nothing to regenerate.Docs: the
src/service.js,client.jsand Tests rows ofdocs/subsystems/workflow.mdnow name thepage and the unfold control. Changelog:
changelog.d/2256-held-tasks-page.fixed.md.Red first
Run on the live base
8f5107cdwith the branch's two test files and the source at that base:TAP escapes the leading
#in a test name; the names themselves are#2256: …. Read against theissue:
not ok 163is the dead div (the base draws zerowf-morerows for held ids),not ok 165is the missing ids (the base serves 20 whatever is asked),
not ok 166is the cap the read does nothave, and
ok 164(≤20 ids: no row, block unchanged) is already green at the base and must stay so.The numbers moved because
client.test.json main carries #2255's three button-copy cases: thisbranch keeps them as they are and appends its two held cases after them, so the same two files run
166 tests at this base and the three failures are the ones above.
With the fix in place the same two files run
# tests 166 / # pass 166 / # fail 0.Files
7 files, +233/−14:
plugins/workflow/src/service.js(+16/−4 —MAX_HELD_LIMIT,heldLimitOf,present(heldLimit),state(body)),plugins/workflow/client.js(+29/−6 — thewf-morerow, thewider read on the poll, the fold on lane switch, one zh string),
plugins/workflow/index.js(+1/−1 —the read handler passes its body),
plugins/workflow/test/held-page.test.js(+83),plugins/workflow/test/client.test.js(+100),docs/subsystems/workflow.md(+3/−3),changelog.d/2256-held-tasks-page.fixed.md(+1).Ran
8f5107cd, thenTZ=UTC node --test plugins/workflow/test/held-page.test.js plugins/workflow/test/client.test.js→166/166/0on the fixed tip, andnpm --prefix plugins/workflow test→408/408/0(404 at thebase; the four new cases are this diff's, workflow: Name the assign target on the confirm button #2255's three button-copy cases still run in the same file).
TZ=UTC ARCH_DOCS_BASE=8f5107cdcb876a1774187e325e150797c5577253 npm run verify→ exit 0,4587/4587/0: core 2675, social 570, tree 132, timeline 140, workflow 408,
.github/scripts599,interop 37, live-e2e 26.
arch-docs: OK (7 changed file(s));ok 10 patches apply cleanly in order;ok core/ equals ds-bot/ + patches/ds-bot/;ok patches/ds-bot/ is what generate writes (generate is a no-op);ok 272 client.js is the build of src/client; thechangelog.d/check green and all fourpacked plugins imported.
git status --porcelainempty on the committed tree.Not run
packagejob's typecheck, actionlint and pack check —npm run verifydoes not run them.core/index.jsandcore/src/host/are untouched.npm_config_cachepointed at a workspace directory for this run:~/.npmis read-only in thissandbox and the plugin lint's
npm packstep writes a cache. Nothing else depends on it.Checkpoint
{
"pr": 2258,
"claim": "Dev",
"issue": 2256,
"summary": "The Stage's held list is now a page: workflow/state takes a bounded heldLimit (20 by default, 200 at most, a non-positive or non-integer value falls back to 20) while heldTaskCount stays the whole truth. The dead '3 more held tasks' div becomes the #2249 wf-more button (data-more=held, aria-expanded) that asks for heldLimit 200, keeps that page on the 2 s poll, folds back to Show less, and folds when the lane changes. At 20 or fewer held tasks the row is absent and the block is unchanged.",
"files": [
"plugins/workflow/src/service.js",
"plugins/workflow/client.js",
"plugins/workflow/index.js",
"plugins/workflow/test/held-page.test.js",
"plugins/workflow/test/client.test.js",
"docs/subsystems/workflow.md",
"changelog.d/2256-held-tasks-page.fixed.md"
],
"checks": {
"ran": "TZ=UTC ARCH_DOCS_BASE=8f5107cdcb876a1774187e325e150797c5577253 npm run verify",
"result": "green",
"at": "dde974485db3e4859f9e1ee0f2354890b0254987"
},
"next": "T2: waiting for Birfy's PASS naming the pushed head; the pushed head carries the identical tree 576641d8."
}