Repository navigation
Add an entry to the Project board and make its rows readable (#1701) - #1726
Conversation
|
Verdict: PASS at c38ebe5 Ran at this tip: Scope. One commit Red first. Restoring only the four changed client sources to their base blobs keeps the new test file and turns 5/5 green assertions red on behaviour (title/priority/board on a row, the Green at tip. 29/29 serial over the entry/view/kanban/project-board/i18n/client-bundle files. A parallel run of the same set flakes on this host under OS-thread pressure ( Checks at the tip: Design. The overlay's read is still four host reads once (no polling, no per-Bot read), the row/task join is one Not run: no browser pass and no live-instance smoke (client overlay needs a bound Project on a running host); the unit tests cover the pane, the hash consumers and the button. |
c38ebe5 to
64d9f27
Compare
|
Verdict: PASS at 64d9f27 Ran at this tip: Scope. One commit Red first. Restoring only the four changed client sources to their Green at tip. 30/30 serial over the entry/view/kanban/project-board/i18n/client-bundle files (the class added one baseline case over the 29 seen at the old tip). A parallel run of the same set flakes on this host under OS-thread pressure, not on assertions; Checks at the tip: Design. The overlay's read is still four host reads once (no polling, no per-Bot read), the row/task join is one Not run: no browser pass and no live-instance smoke (the client overlay needs a bound Project on a running host); the unit tests cover the pane, the hash consumers and the button. |
Replay onto main d5ae145 so the branch carries the Project board actor rule (#1723), the thinking-row clip (#1718) and the board entry view (#1726). Conflicts were resolved in core/src/host/store.js (the Project Assistant memory and main's actor argument both kept) and docs/subsystems/core-host.md (both paragraphs); client.js and patches/ds-bot/ were regenerated from the merged core/.
Fixes #1701
Owner: Dev2
Reviewer: Birfy
Written-by: Dev-2
supersedes #1714 (absorbed by #1715 @ f0159ea); rebased once onto
703bead3after #1725 and #1721 landed.What changed
#1715merged the Project board and nothing could reach it:git grep '#project'on main found only readers, so the board opened by hand-editing the address bar. A row said@assigneeand nothing else, so three cards held by the same person were indistinguishable, and therole="button"on a row went nowhere —#task=had no consumer anywhere in the tree. This branch adds the reachable slice only; the board itself is#1715's.Entry.
KanbanDialog's header draws a Project board button when the selected Bot or group carries aprojectId(the roster already ships it). It writes#project=<id>and closes the Tasks dialog, leaving theshell.overlayboard to take over. No rail row and no second board, and the per-Bot board is untouched.The overlay now re-reads the hash. Its read was
useEffect(…, []), so a hash written while the overlay was already mounted opened nothing — writing#project=from the new entry would have failed on its own. It subscribes tohashchangeand reads#project=<id>from that state.Rows are readable.
projectBoardView({ project, rows, canManage, tasks })joins the ordinary task read byidin oneMappass — the row itself still carries only{id, source, column, assignee, updatedAt, runId?, nodeId?}, so nothing is copied and no membership is re-decided here. A row takestitle, falls back tonote, and only then to@assignee/—; it also carriespriority(data-priority). The board a row leads to follows the host's ownsource:group→ the task'sorigin.roomId,bot→ itsownerBotId, and aworkflowrow has no board of its own. A row with a board is a real button (role,tabIndex, Enter/Space); a row without one is not a button at all.A row's exit. Clicking a row writes
#task=<kind>:<id>and callsactions.openBoard()(the overlay is mounted with the shellfacenow, so it hasactions).KanbanDialogconsumes that hash once on mount, moves its scope to that Bot or group and clears it, so a reload does not reopen the same board. There is no task-detail surface anywhere in the tree, so this is the equivalent path the issue allows: the row lands on the board the task lives on.#task=<kind>:<id>names a board, not a dialog.Labels.
not-started,in-progressanddonewere missing from the zh dictionary ini18n.js, sot()fell back to the raw key and a zh board readin-progress. The three keys are added.Not changed: the board is not moved into the Tasks dialog or the rail, no 24h window, no per-Bot board change, and no client-side
projectScopemapping — attribution stays the host's.project-bindis owner-only since#1715; nothing here writes a binding. The rebase moved no logic:git diff f0159ea8 703bead3 -- core/src/client/{kanban,project-board,i18n,index}.jsis empty, so the source hunks are the same ones reviewed before, and#1725'staskVisiblefiltering plus#1721's thinking-row work are untouched.docs/subsystems/core-client.mdnow documents the entry, the row join, the hash consumer and the read bound.Red first
On the new base
703bead3, withcore/srcreverted to base and onlycore/test/project-board-entry.test.jskept,node --test test/project-board-entry.test.jsread 5 tests / 0 pass / 5 fail, each on behaviour rather than a missing export:the row says what the task is— expected'Ship the board', actualundefined.the row repeats the assignee instead of the title: in-progress@Dev4.expected 1 / actual 0(data-open-projectcount) — a bound Bot had no entry.+ 'not-started' / - '未开始'—t()returned the raw key.#task=consumer — nothing moved the Tasks board to that scope.At this tip the file is 5/5 green, and
project-board-view.test.js(5),project-board.test.js(7),kanban.test.js(9) andprojects.test.js(9) stay green (30/30 across those four files; 35/35 counting this branch's five).Read bound
Opening the pane is four host reads, once, no polling and no per-Bot read:
projects(1) →Promise.all([project-read (1), project-board (1), tasks {} (1)]). The row/task join is a singleMapbuilt over that onetaskslist; it adds no request. A row click adds no read of its own — the Tasks dialog it opens then loads through its existinguseBoardTasks(active list + archive page, 15 s poll), which this branch does not change.Verification at the tip
Tip:
64d9f27449a8af6cc351a16854c75ae0610df423Tree:
6af1429dc0d2883b3357942f68cfb4038ab8c6bcBase / merge-base:
703bead3565af4d097bb7832b7eaa5e1a90f12b4(live main when this rebase was cut; single-parent commit, 13 files, +833/−176)Ran:
DSH_HARNESS=… TZ=UTC ARCH_DOCS_BASE=703bead3565af4d097bb7832b7eaa5e1a90f12b4 npm run verify→ exit 0. Counts: core 2034, social 539, tree 125, timeline 129, workflow 279,.github549, interop 37, live-e2e 24 — 0 failures in each. oxlint: 0 errors.arch-docs: OK (13 changed file(s)).node scripts/ds-bot-patches.mjs check→ three green lines (ds-bot/pinned at2b10c70, 10 patches apply in order,core/equalsds-bot/plus the patches).Not run: no live-instance smoke (client-only change; the overlay needs a running host and a bound Project, which unit tests can't stand up here), and no browser pass (no layout change beyond one header button and one chip).
Patches (generator gate)
core/client.jswas rebuilt withnode core/scripts/build-client.mjsand the mirrors withnode scripts/ds-bot-patches.mjs generate; no hunk body was hand-written. Then each file follows the stored form main already has, not a reformat of it:Mirrors this branch does not carry —
0002,0005,0014→ byte-identical to new main, zero diff.#1725rewrote main's0002(thetaskVisibleslice); that content is kept as main has it, whole, not merged hunk by hunk.Mirrors it does carry —
0001,0003,0008→ content fromgenerate, and every hunk this branch does not touch is main's own line, copied verbatim:0001-core-fixes.patch0003-flybot-api-client.patchinject: faceline, +3/−2)0008-client-bundle.patchfiles/src/client/kanban.jsfiles/src/client/project-board.jsfiles/test/project-board-entry.test.js0008keeps main's 381-hunk cut.generateon this tree would write the same content as 312 hunks; the four re-emitted hunks above are main's own boundaries with this branch's lines inside them, so the review sees the bundle's delta, not a re-cut of 19k lines. Both cuts reproducecore/client.js(check), and no hunk boundary was changed to make a number look small.Why "restore the old base's bytes" is not the rule here: on a clean checkout of
703bead3with no source change,generatealready rewrites000190,000348,000526,00086433,00144 — hunk-header hints and the bundle's cut, not content (checkgreen both before and after). Chasing those bytes would be the noise, so the stored form follows main and the bodies followgenerate.Round-trip evidence for the mirrors: with hunk-header hint text ignored, this branch's
0001/0002/0003/0005/0014are identical togenerate's output on this tree (same hunk numbers, same bodies), and0008's four re-emitted hunks are the only difference.build-client --checkpasses as part ofverify, and on a clean703bead3worktreebuild-clientleavesclient.jsunchanged (0 lines), so the committed bundle is exactly the build of these sources.Conclusion: 承载本单的三个镜像只有本单那几行差异(
00011 个 hunk、00031 个、00084 个),不承载的三个与 main 逐字节相同;check三行绿,且忽略 hunk 头文本后与 generate 输出逐字节一致。Checkpoint
{ "pr": 1726, "claim": "Dev2", "issue": 1701, "summary": "The Project board #1715 shipped was unreachable, since nothing wrote #project=. A Project board button in the Tasks dialog header now opens it for the selected Bot or group that carries a Project. A row joins the ordinary task read by id, so it says the task's title (note, then @assignee), carries its priority and knows the board its task lives on, and a click lands the Tasks board on that Bot or group. Three column keys were missing from the zh dictionary.", "files": ["core/src/client/project-board.js", "core/src/client/kanban.js", "core/src/client/index.js", "core/src/client/i18n.js", "core/test/project-board-entry.test.js", "docs/subsystems/core-client.md"], "checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=703bead3 npm run verify; node scripts/ds-bot-patches.mjs check", "result": "green", "at": "64d9f27449a8af6cc351a16854c75ae0610df423" }, "next": "Waiting for the single named Verdict at this tip; nothing else is planned on this branch." }