Repository navigation
feat(ui): kanban board draws only the declared lanes, in their order - #28291
Conversation
Both object-kanban producers (ListView and ObjectView) map kanban.lanes onto the node's columns through one @object-ui/core helper, kanbanDeclaredLanes: the author's order, option labels as titles, a lost lane collapsed. An unlisted value still lands in Uncategorized. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibymteTr9Zsy1aSkJPt
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibymteTr9Zsy1aSkJPt
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibymteTr9Zsy1aSkJPt
📓 Docs Drift Check
What this run could not see
Coarse fallback — 168 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
|
domain:ui#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz Contract-review-claim: |
|
domain:ui#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz Contract reviewServed-tier: Inputs: card #28211 (body and all five comments: triage 6530215469 with its one-file cross-domain exception, the seat's claim 6537960788, amendment 6537973671 which moves the surface from ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Verdict reasoning. The PR delivers the card's effect through the mechanism the seat amended before any edit, with Implemented-by: VERDICT: PASS |
|
domain:ui#1 · os-tesla · session_01L9qibzC6RxMfB59EsgAoNN 席位核对ACCEPT · seat 席位意见:看板视图声明了
|
Requested by Tesla · project thread
Fixes #28211
Refs #28018
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
kanban.lanes只画作者列出的泳道、按作者的顺序;两条生成看板的路径(列表视图与 object-view 元素)都把它映射到看板已有的columns键上。lanes的看板完全不变;未列出取值的记录落进「未分类」泳道,不会被藏起来。回滚即撤销本 PR。ui/packages/core/src/utils/kanban-declared-lanes.ts(映射规则),ui/packages/plugin-list/src/ListView.tsx的case 'kanban',ui/packages/plugin-view/src/ObjectView.tsx的case 'kanban'。pnpm --dir ui exec vitest run packages/plugin-kanban/src/ObjectKanban.declaredLanes-28211.test.tsx,预期 3 个用例全绿(只画列出的泳道、顺序对、未列出的进「未分类」)。What changes
@object-ui/core: newkanbanDeclaredLanes(lanes, options). It turns a list view'skanban.lanesinto theobject-kanbannode'scolumns, in the author's order. Each lane is titled with its option's label, or with the value itself while the definition is still loading. A lane whose option haskind: 'lost'getscollapsed: true, keeping the Stage path and kanban read the select option's lifecycle kind: terminal options drawn apart from the steps, lost ones marked, instead of guessing from closed_won / closed_lost spelling #26612 behaviour. Nolanesreturnsundefined.@object-ui/plugin-list(ListView,case 'kanban') and@object-ui/plugin-view(ObjectView#generateViewSchema,case 'kanban'): both producers of the node readkanban.lanesby name and emitcolumnsonly when lanes are declared.generateViewSchemanow also depends onobjectSchema, so the titles follow the definition once it lands.ObjectKanban.tsxis unchanged. Its explicit-columns branch already drawscolumnsin order and localizes each title. A record whose value matches no lane already lands inUncategorized, both when loaded rows are bucketed and when lanes page on their own:pagedLaneIdsKeyreads declared columns first, and the uncolumned lane's query is "not in the listed ids".packages/spec/liveness/view.json: only thekanbanrow changes. Its note moveslanesfrom planned to live and cites the readers by symbol..changeset/28211-kanban-declared-lanes.md, with every package atpatch.Why the producers and not
ObjectKanban: the node's face,ComponentPropsMap['object-kanban'], declares nolanes, and both producers forward only named block keys. Mapping onto the existingcolumnskey needs no spec edit. The seat's claim amendment records this surface.Tests
ui/packages/core/src/utils/__tests__/kanban-declared-lanes-28211.test.ts(4 cases): order and labels, no lanes, author order over lifecycle order with lost collapsed, value title before options load.ui/packages/plugin-kanban/src/ObjectKanban.declaredLanes-28211.test.tsx(3 cases): the real board draws only the listed lanes in order, an unlisted value lands inUncategorized, and a listed lost lane starts collapsed.ui/packages/plugin-list/src/__tests__/ListView.kanbanDeclaredLanes-28211.test.tsxandui/packages/plugin-view/src/__tests__/ObjectView.kanbanDeclaredLanes-28211.test.tsx(2 cases each): the generated node carries the declaredcolumns, and a control shows that nolanesmeans nocolumns.columnsspread was deleted withscripts/ablation-replace.mjsin each producer, and restore was proven by blob hash. Predicted and observed: thecolumnscase of that producer's test goes red (1 failed | 1 passed) and its control stays green.Acceptance notes
checkKanbanLanesdocblock line) does not ride. That module ispackages/lint/src/validate-list-view-field-refs.ts, outside the liveness file. TheKanbanConfigSchema.lanesTSDoc inpackages/spec/src/ui/view.zod.tsstill says it "Lands ahead of its reader", which is now false. Both are spec-source edits that the seat files as adomain:specfollow-up after merge.ListView.tsx, one hunk sits outsidecase 'kanban': the@object-ui/coreimport line gainskanbanDeclaredLanes. That matters for the serial overlap with seat 4's lint/types: 14,366 no-explicit-any warnings can never red CI — make it an error on packages/types/src, delete the vestigial (schema as any) reads, and type ComponentRendererProps with unknown #25918 in the same file. When this branch was cut,origin/mainhad no change to that file.lanes. Membership and repeats are judged at authoring (list-view-kanban-lane-unknown/-repeatedin@objectstack/lint).AGENTS.md✨ Set up Copilot instructions #2 (docs-driven) is not covered: no README orcontent/docs/frontend/page is touched, because both are outside the claimed surface. The spec key's own docs already describe the behaviour.Verification
Head
8f4d9c61, base6285203d.Package suites and type-checks
pnpm --dir ui exec vitest run --maxWorkers=2 packages/core/ packages/plugin-kanban/: 306 files, 4723 passed, 27 skipped.pnpm --dir ui exec vitest run --maxWorkers=2 packages/plugin-view/: 78 files, 716 passed.pnpm --dir ui exec vitest run --maxWorkers=2 packages/plugin-list/in two shards: 85 files / 794 passed, then 89 files / 908 passed.pnpm run type-checkinui/packages/core,plugin-kanban,plugin-listandplugin-view: all exit 0, after a real dts build of their closure.eslint --no-inline-configon the changed TS files: exit 0 (0 errors).Derived gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 67 commands. Every one was run with stdin closed. Reconciliation with--ran: 67 accounted for, 66 run and 1 NOT MEASURED.pnpm check:dual-build-cjs-loadsexited 3 (PREREQUISITE NOT MET: needs a full workspace dist). NOT MEASURED locally; CI runs it.node scripts/check-plugin-teardown-shape.mjs --self-testfirst exited 3 because the shallow clone lacked its pinned fixture commit. Aftergit fetch origin 621a4876… --depth=1it exited 0 (48 cases).node scripts/check-sdui-manifest.mjs,pnpm --filter @objectstack/spec run check:liveness,pnpm check:doc-authoring,pnpm check:test-source-aliasandpnpm --dir ui exec vitest run scripts/.🤖 Generated with Claude Code
https://claude.ai/code/session_01L9qibymteTr9Zsy1aSkJPt
Generated by Claude Code