Uh oh!
There was an error while loading. Please reload this page.
fix(grid,types): 对象声明的批量 action 能真正跑在选中记录上 (#3002) - #3031
Merged
Conversation
…d records (#3002) `bulkActions: ['push_down']` dispatched the action NAME in the runner's `type` slot, so it never ran — and the object had nothing to declare a bulk action with, since `bulkActionDefs` was passed through from view JSON verbatim rather than derived from `objectDef.actions`. No spec change needed: `ActionSchema.bulkEnabled` ("whether this action can be applied to multiple selected records") is already the declaration; it just had no consumer. `ObjectGrid` — the single convergence point of the three list callers — now folds three sources into the selection bar via the new pure `resolveBulkActions`: inline-authored defs, object actions flagged `bulkEnabled`, and legacy names resolved against `objectDef.actions`. A derived def carries the source action under `actionDef`; `useBulkExecutor` dispatches it through the action runner once per record with the row attached as `_rowRecord`, reusing BulkActionDialog's params → confirm → progress → result model so params/confirmation are collected once. Failures are attributed per record instead of counted as successes. Also: the bar rendered legacy string buttons only when no defs existed, so a view mixing both silently lost half its buttons. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Jul 30, 2026
os-zhuang added a commit
that referenced
this pull request
Jul 30, 2026
…stone (#3002) (#3053) Follow-up to #3031. `@objectstack/spec` 17.0.0 retired `action.bulkEnabled` in the #3896 audit close-out (framework#4054), which landed while #3031 was in flight — the spec source still carried the key when its design was settled. It is now a retiredKey() tombstone, so it is not merely ignored: defineStack HARD-REJECTS a config that sets it and the backend refuses to boot. The derivation branch could never run, and #3031's changeset pointed authors at a key that breaks their app. Browser verification against a real showcase backend is what surfaced it. The tombstone prescribes the surviving path — "declare the action in the view's `bulkActions` instead" — which is #3031's other half, and the half the end-to-end run exercised: naming `showcase_mark_done` in the view issued one POST /api/v1/actions/showcase_task/showcase_mark_done per selected record (10/10 → done: true, progress: 100 server-side). Everything downstream of the fold is unchanged. A stale `bulkEnabled: true` is now inert rather than a second path into the bar. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This was referenced Jul 30, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#3002.
结论先行:spec 不用改
issue 的前提是「spec 的
locations枚举里没有 bulk 这一档,对象 action 无法声明『我是一个批量操作』」,所以这是跨仓库的、动手前得先定设计。查下来这个前提不成立:
ActionSchema一直有bulkEnabled——缺的从来不是声明,而是消费方。framework 自己的 property-liveness 审计逐字记着这件事:
所以本 PR 纯 objectui 改动,framework/spec 一行没动。
对 issue 四个设计问题的回答
list_bulk/mass_action这一档吗? 不加。列表选择栏是唯一「记录被多选」的界面,这正是bulkEnabled已经命名的东西;再加一档 location 等于承认bulkEnabled表达不了它。locations保持正交——它安放的是 action 的单条入口,一个 action 可以两者都带(locations: ['list_item'] + bulkEnabled: true= 行菜单点一条、选择栏跑 N 条)。bulkActionDefs要不要像rowActionDefs一样推导? 要,且推导点放在ObjectGrid——它是三个列表调用方(app-shellObjectView、plugin-viewObjectView、plugin-listListView)的唯一收敛点,和 fix(grid): a legacy string row action runs instead of green-toasting a no-op (#2960) #2996 的选择一致,改一处覆盖三处。params/recordIdParam/visible)本来就是逐记录的,服务端「一次收全量 id」需要自己的 spec key + endpoint 契约,那是新功能不是修 bug。bulkActions: string[]保留还是废弃? 保留为 view 级覆盖:名字先拿去和objectDef.actions解析,解析得到就提升成真 def;解析不到仍按名字派发(消费方可能用该名字注册过 runner handler)。改动
① 新增纯函数
resolveBulkActions(resolveLegacyRowActions的批量孪生),把三路词汇折叠成一份 def 列表:bulkActionDefs—— 原样保留,同名永远它赢;objectDef.actions里bulkEnabled: true的 —— 推导出来,这就是「在对象上声明一个批量 action」的新含义;bulkActions里的名字 —— 按名字解析到对象 action 后提升成该 def,于是带上 label / icon /visible谓词 / 确认文案 / 参数(字符串形式一个都带不了)。已在栏上的同名项直接丢弃,不再渲染死副本。② 执行接进现有
BulkActionDialog(params → confirm → progress → result,issue 里点名要求的)。推导出的 def 带operation: 'custom'+actionDef(源 action);useBulkExecutor按这个 key 分流,逐记录经 action runner 派发,行记录挂在_rowRecord上——和list_item行 action 完全同一个键,所以recordIdParam注入行为一模一样。参数和确认由对话框收一次再交给 runner,runner 不会逐条再弹;逐条 toast 静音,对话框的聚合结果是唯一报告;失败的记录进错误列表 / 错误 CSV,而不是被记成成功(那正是 #2960 的批量版)。不带actionDef的customdef 语义不变(consumer 自己 wireonComplete)。③ 顺带修:
BulkActionBar过去只在没有任何 def 时才渲染 legacy 字符串按钮,于是同时写了两者的 view 会静默丢掉一半按钮。折叠之后两个列表互斥,两边都渲染。验证
resolveBulkActions.test.ts(13 条纯函数)、objectBulkActionDispatch.test.tsx(6 条,驱动真实 ObjectGrid + 真实 ActionProvider + 真实对话框,断言fetch真的按选中记录数发出、每条带自己的记录、失败被逐条归因)。plugin-grid42 文件 / 342 测试全绿;app-shell+plugin-list+plugin-view257 文件 / 2325 测试全绿;types+core/actions+react/hooks35 文件 / 537 测试全绿。types/core/plugin-grid/app-shell及其依赖 32 个任务全过。bulkEnabled的对象 action,而上面的 DOM 测试已经驱动真实 grid/runner/对话框并断言真实fetch,覆盖同一条链路。🤖 Generated with Claude Code