Repository navigation
fix(plugin-list)!: a non-grid view's selection bar draws only actions the object declares (#30394) - #30498
Conversation
…the object declares The bar ListView draws itself for kanban, calendar, gallery and the other non-grid views mapped every bare `bulkActions` name to a button. It now folds the names through plugin-grid's `resolveBulkActions`, the grid's own fold: a declared name draws under its declared label, the built-in `delete` keeps its own path, and any other name draws nothing and is named once in development by plugin-grid's `useUndeclaredActionNamesWarning`. plugin-grid exports the two (and their types) for this, and the warning's address gains an optional `component`, defaulting to `ObjectGrid` so the grid's message is unchanged. plugin-list declares plugin-grid as a peer and dev dependency. Co-Authored-By: Claude <[email protected]> Claude-Session: https://claude.ai/code/session_01L6bhgVzvtWN68zb2r9z2zy
…t's warn spy Co-Authored-By: Claude <[email protected]> Claude-Session: https://claude.ai/code/session_01L6bhgVzvtWN68zb2r9z2zy
…arrows Co-Authored-By: Claude <[email protected]> Claude-Session: https://claude.ai/code/session_01L6bhgVzvtWN68zb2r9z2zy
… arm Co-Authored-By: Claude <[email protected]> Claude-Session: https://claude.ai/code/session_01L6bhgVzvtWN68zb2r9z2zy
|
domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif Contract reviewServed-tier: 输入:卡 #30394 正文与全部评论(triage 6655193895、认领 6658430589、认领修正 6658495307 = plan A 裁定、os-dev-report 6659349029);PR #30387 正文、文件表与其达档复核 6654355327(点名本面为后续卡);PR #30498 正文、文件表、相对 ① Derived judgments逐条列 diff 蕴含的 accept-set 与公开面变化,各判对错:
② Semver level
③ Boundary flagsos-dev-report 6659349029 与认领修正 6658495307 的每面旗:
④ Design judgment逐
无 must-fix。should-fix 三条(②-a、④-a、④-b)各是一两行,不阻塞落地;③ 第 2 条由席位立卡,③ 第 3 条由席位记录读数。若在本分支上补这些再推,新 head 另欠一张记录。 本 head 的 check-runs(其结论即门的判决,读于本记录写成时): Implemented-by: VERDICT: PASS |
|
domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif 维护者速读
席位核对 — ACCEPT · domain:ui#5 · head
|
Requested by Sales · project thread
domain:ui#5 · os-sales · session_01L6bhgVzvtWN68zb2r9z2zy
Fixes #30394
Clause-②: yes (narrowing) —
@object-ui/plugin-gridnow exportsresolveBulkActionsanduseUndeclaredActionNamesWarning(with theActionLabelResolver,NamedActionDef,UndeclaredActionNameKey,UndeclaredActionNamesAddressandUndeclaredActionNamesBasistypes), so@object-ui/plugin-listreuses the grid's fold and warning instead of a second copy. The warning's address gains an optionalcomponent, defaulting toObjectGrid, so the grid's message is byte-identical. This PR both widens (those exports) and narrows (the non-grid bar no longer draws an undeclared bare name), so the arm is(narrowing): seat patch round on the Check Changeset red, after claim amendment 6658495307 had written(widening). Owes aTIER_DEFAULTreview for the export widening and aCONTRACT_REVIEW_TIERreview for the narrowing below.Metadata-protocol: narrowed (an undeclared bare
bulkActionsname no longer draws in a non-grid view, matching #30387 on the grid)Skills-docs: none owed —
skills/**teaches no handler-only bulk action name (searchedskills/forbulkActionsexamples);content/docs/ui/**already names only declared actions.维护者速读
bulkActions里的裸名字,只有对象声明了同名操作才画按钮,用声明的标签;删除照旧走自己的路径;没声明的名字不画,开发态控制台打一行警告点名。ui/packages/plugin-list/src/ListView.tsx(nonGridBulkBar折叠与选择栏渲染)→ui/packages/plugin-grid/src/undeclaredActionNames.ts(可选component)→ui/packages/plugin-grid/src/index.tsx(两个新导出)。pnpm --dir ui exec vitest run packages/plugin-list/src/__tests__/ListView.nonGridBulkDeclared-30394.test.tsx,预期 4 条全过;去掉折叠(消融)时其中 3 条转红。What changes
ListView draws its own selection bar for every view but the grid (kanban, calendar, gallery, timeline, …). That bar mapped each
bulkActionsmember straight to a button labelled by the humanized name, declared or not. #30169 (ruling C, comment 6651753071) made the grid draw only actions the object declares; this applies the same rule to the other bar, through the grid's own code.ListView.tsx. A newnonGridBulkBarmemo foldspermittedBulkActions(the existing delete gate is untouched) through plugin-grid'sresolveBulkActions, with the canonicaldeleteheld out of the fold exactly asObjectGridholds it out. The bar draws, in authored order,delete(its own path, gate and per-recordvisibleWhensubset, unchanged) and each name the served object declares, under the declared label resolved through the app's i18n bundle (the grid'slocalizeLabel). Any other name draws nothing. A bar with nothing left to draw is not rendered.useUndeclaredActionNamesWarningnames the undrawn names once in development, only while a non-grid view is on screen (the grid warns for itself) and only once the object schema read has settled; with no schema in hand (nogetObjectSchema, or the read failed) the names are reported as unread, never as undeclared, the grid's reading.plugin-grid/src/undeclaredActionNames.ts.UndeclaredActionNamesAddressgains an optionalcomponentthat heads the message; omitted, it isObjectGrid, so every grid message is byte-identical. ListView passesListViewand the view on screen asblockType:[ObjectUI] ListView bulkActions: kanban (objectName: 'lead') — 1 name matches no action the object declares, ….plugin-grid/src/index.tsx. ExportsresolveBulkActions,useUndeclaredActionNamesWarningand the types their signatures name.plugin-list/package.json. Declares@object-ui/plugin-gridas a peer (workspace:^) and dev (workspace:*) dependency, following its@object-ui/plugin-detailprecedent. No cycle: plugin-grid does not depend on plugin-list. plugin-list's build externalizes@object-ui/*, so its dist does not bundle the grid.pnpm-lock.yamlmoves by the three lines that declaration adds.ListView.bulkDeleteVisibleWhen.test.tsxandListView.permissions.test.tsxusedarchiveas their non-delete control without the object declaring it; both fixtures now declare{ name: 'archive', label: 'Archive' }, so the control still draws (moved pins, assertions unchanged).Why
Same defect as #30169, one more surface: after PR #30387 a list shown as a grid hides a name the object does not declare (for example an action a disabled package withholds), but the same list switched to kanban or gallery still drew a button for it, and pressing it toasted "not executable". The card asks for the grid's resolver to be reused rather than copied; plugin-list could not reach it (no dependency, not exported), measured and reported to the seat before plugin-grid was touched.
Tests
ui/packages/plugin-list/src/__tests__/ListView.nonGridBulkDeclared-30394.test.tsx(gallery view, selection stubbed the wayListView.bulkDeleteVisibleWhen.test.tsxdoes): a declared name draws under its declared label and dispatches by name,deletedraws in authored order, an undeclared name draws nothing and is named in oneListViewwarning; all-undeclared draws no bar; nogetObjectSchemareports the names as unread; all-declared warns nothing.ui/packages/plugin-grid/src/__tests__/undeclaredActionNames.test.ts: the message heads withObjectGridby default and with the address'scomponentwhen given.Acceptance notes
sideEffects: true, it registersobject-gridon import) did not disturb plugin-list's mocked registrations: the full plugin-list suite is green (below), which was the measured risk in the claim amendment's plan B.onBulkAction(name, rows); promoted defs' params, confirm text andvisibleare not consulted on this bar (they never were). Unchanged by this PR.Verification
Heads
38d91dbeand4d680aaachange only the changeset overfbecf332: the Clause-② arm ((widening)→(narrowing)), then the summary's!; on itcheck-changeset-no-major(fed this body as the event) exits 0 where the(widening)body exits 1 with the level-axis contradiction, andcheck-adr-0087-registration,check-empty-changeset,check:changeset-fixedexit 0 on4d680aaa. The(narrowing)arm owes the full dogfood battery on the final head; its reading goes to the seat. Everything below is onfbecf332unless stated; the build closure waspnpm exec turbo run build --filter='@object-ui/plugin-list^...'(53/53 tasks).Package suites and type-check
pnpm --filter @object-ui/plugin-list teston85a03128(the fix commit;fbecf332changes only the changeset marker and the new test's spy typing):Test Files 190 passed (190),Tests 1817 passed (1817), lockVERDICT command-exit 0.pnpm --filter @object-ui/plugin-grid test:Test Files 278 passed (278),Tests 2389 passed (2389),VERDICT command-exit 0.pnpm exec vitest run packages/plugin-list/src/__tests__/ListView.nonGridBulkDeclared-30394.test.tsx:Tests 4 passed (4).pnpm --filter @object-ui/plugin-grid --filter @object-ui/plugin-list run type-check: plugin-grid Done; plugin-list green after typing the new test's spy (fbecf332).pnpm --dir ui run check:spec-symbols:: exit 0 (1807 files scanned against 5743 spec export names; ... 0 untriaged collisions).Ablation (one, on the tested behaviour)
node scripts/ablation-replace.mjs --file ui/packages/plugin-list/src/ListView.tsx --anchor ".filter((a) => a.toLowerCase() === 'delete' || labels.has(a))" --replacement ".filter(() => true /* ABLATION-30394 */)" -- …vitest run …nonGridBulkDeclared-30394.test.tsxc5b3c47fb594→5ddccdf4efbb.Tests 3 failed | 1 passed (4); the passing one is the all-declared control, which the mutation cannot move.c5b3c47fb594== HEAD,git diff HEADempty.Derived gates (dispatch-gates --commands, 57 families)
--ranwith an exit code on every line: "a DERIVED zero").node scripts/check-adr-0087-registration.mjs --base origin/main:: exit 1 on85a03128(thenarrowedkind requires a disposition), exit 0 onfbecf332after the changeset gainednot-required (no-migration-prescription);pnpm check:dual-build-cjs-loads:: exit 3 (PREREQUISITE NOT MET, dists missing) then exit 0 (116 published require entry point(s) across 71 package(s) load).fbecf332:check-changeset-no-major0,check-empty-changeset0,check:changeset-fixed0,check-closing-keyword-parity0.Human Minimum
packages/specholds no runtime logic. (not touched)pnpm lintis CI's.main, one pull request.packages/spectouched: n/a.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code