Repository navigation
Description
epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff
The maintainer: 「studio没有操作类型的元数据吗?除了批量操作,别的也需要配置的呀。」 (2026-11-04). Measured by the seat on main 63b86b385d. No domain:* label is set: triage routes this card.
The question
The platform needs no kernel work for bulk changes: a view's bulkActionDefs already produced 批量修改负责人 with no code (#30079). But that declaration can be written only in metadata. Should the person configuring a list in Studio be able to add one?
Governing text: packages/spec/src/ui/view.zod.ts:3576-3593 (rowActions, bulkActions, bulkActionDefs). ui/packages/app-shell/src/views/metadata-admin/inspectors/ActionDefaultInspector.tsx:1187-1190: "Selection placement is declared on the LIST VIEW". #30079: no kernel feature.
Measured
- An action's editor offers five placements and no selection-bar placement. An update action is not offered 列表工具栏, by design.
- Neither Studio view panel shows
bulkActions,bulkActionDefsorrowActions: no such section onsurface=view:…(Basics, Columns & filters, Table options, End-user controls, Navigation & sharing) and none on the object leaf's panel. There are no such keys inObjectListViewInspector.tsx. - So the action editor's note tells a person to declare it on the view, and the view editor has nowhere to do that.
Options
- A. A 批量操作 section in the view panel: pick existing actions for the selection bar (
bulkActions) and add a field update (bulkActionDefs: label, fields to ask, confirmation). The same section works on a customized view of an installed app. - B. Picking existing actions only: a field update still needs metadata.
- C. Leave it to metadata: developers and AI only.
Recommendation: A
四轴分析
实际业务需求。 哪些字段值得批量改,每个业务不一样:销售改负责人,工单改优先级。这是实施和运营配应用时的常规工作,今天只能找开发。
项目长远合理性。 这正符合你的意思:能力留在元数据,内核不写死任何业务字段。A 只是给已有的声明加编辑入口。动作编辑器已经在提示「到视图上声明」,补上后才前后一致。
防 AI 写错。 不新增键。编辑器按 spec 校验,字段和选项可以选,比手写更不容易错;声明后默认的删除会不会消失这类隐含行为,也要在界面上讲清楚。
创业阶段不扩散。 只加界面,服务端和 spec 不动。范围中等,可以排在 #30059 和页面、数据集入口之后。
| 棱 | A | B | C |
|---|---|---|---|
| 业务 | 强 | 中 | 弱 |
| 长远 | 强 | 中 | 中 |
| 防错 | 强 | 中 | 弱 |
| 不扩散 | 中 | 强 | 强 |
Not measured
Whether the default 删除 leaving the bar when a view declares bulkActionDefs is intended, and how a customized view of an installed app merges these keys beyond the one case tested.
Re-check
git grep -n "bulkActionDefs" origin/main -- ui/packages/app-shell/src/views/studio-design/ObjectListViewInspector.tsx
Activity
objectstack-fleet commentedon Nov 4, 2026
epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff
The maintainer, 2026-11-04: 「同意你的建议」, answering the seat's choice of option A on this card and closing #30079.
Ruling: option A. The view panel gains a 批量操作 section: pick existing actions for the selection bar (
bulkActions) and add a field update (bulkActionDefs: label, fields to ask, confirmation). It works on a customized view of an installed app as well. No kernel feature and no business field is built in, per #30079. Order it after #30059 and the page and dataset doors.needs-user-decisionis removed; triage routes this card.objectstack-fleet commentedon Nov 4, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 kept ·
domain:ui· 2026-11-04T13:57Z⛔ Not a claim.
bulkActionsand add a field-updatebulkActionDefs. This replaces [Decision] The list bulk bar offers only delete: should the platform offer bulk edit? #30079 (closed, not planned). p2 kept.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:ui#4 · os-support-ai · session_01WGufzinedUGSXteN45poyo
Claim: PM loop round 4
Session:
session_01WGufzhfh9quLdZYWtWEMLK(card thread executor; seat sessionsession_01WGufzinedUGSXteN45poyo)Account:
os-support-aiBranch:
claude/project-thread-0vx632(harness-pinned card thread branch; theclaude/issue-<n>-<slug>convention does not apply to a project card thread)Worktree:
objectstack-issue-30089Domain:
domain:uiSeat:
domain:ui#4File surface:
ui/packages/app-shell/src/views/studio-design/ObjectListViewInspector.tsx(a new 批量操作 section, additive region) and new studio-design helpers/tests for it,ui/packages/i18n/src/namespaces/studio/**strings, root.changeset/Container & model:
M–L,mode:thread,model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate; PM judgment call, default tier),effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: 6632518141
Premise: holds (seat read
origin/main4be973424: nobulkActions/bulkActionDefs/rowActionsunder studio-design; keys exist atpackages/spec/src/ui/view.zod.ts:3576-3593)Serial constraints cleared: ruling order met (#30059 merged; #30063, #30064 closed). Same file as #30177 (this seat, branch
claude/project-thread-ldhemo): region-level disjoint (#30177 editslistViewTargetOf, the switcher and the Create View seed; this card adds a new section), mergemainafter it lands. #30211 (#30088, action editor) is triage-serial: this card does not touchObjectActionsPanel.tsxorpairObjectActions.ts.objectstack-fleet commentedon Nov 5, 2026
domain:ui#4 · os-support-ai · session_01WGufzhfh9quLdZYWtWEMLK
os-dev-report
Stamp: 2026-11-05T06:28Z
{ "issue": 30089, "status": "done", "branch": "claude/project-thread-0vx632", "pr": "https://github.com/objectstack-ai/objectstack/pull/30339", "session": "session_01WGufzhfh9quLdZYWtWEMLK", "premise_still_valid": true, "summary": "Studio list-view panel (grid views) gains a Selection actions section (new ListViewBulkActionsSection.tsx, one additive mount in ObjectListViewInspector.tsx after Sort; no edit to listViewTargetOf, the switcher or the Create View seed). It picks object actions plus the built-in delete into bulkActions, and adds/edits/removes operation update defs in bulkActionDefs (label, one required param per field with select options / lookup object, optional confirmText), each checked with BulkActionDefSchema before write; emptied keys are removed. Writes go through the panel writeBody buffer, so a read-only base goes through the existing customization copy (pair draft with overrides). Not-measured items measured: default Delete leaves the bar once the view declares either key unless bulkActions names delete (shown as data-state default/kept/dropped, confirmed live); a customized view does not merge per key, the pair holds the whole view copy with overrides. One defect found live and fixed in this PR: a served confirmText comes back as the dialect/source envelope and read empty; now read and edited as its source.", "tests": "head d8c1f112: pnpm --dir ui exec vitest run (InterfacesPillar*, StudioDesignSurface*, ObjectListViewInspector* under studio-design): Test Files 149 passed, Tests 1036 passed, lock VERDICT command-exit 0. New file ObjectListViewInspector.bulkActions-30089.test.tsx 11/11 (real MetadataClient, PUT judged by spec view schema); customize-28562 harness new describe (pair copy, overrides, ifNoneMatch star, base untouched). Census suites 6 files 115 passed. type-check i18n + app-shell exit 0; eslint touched files 0 errors. Ablations via scripts/ablation-replace.mjs, src-resolved (no dist): writeNames no-op 2 failed/8 passed; writeDefs no-op 4 failed/32 passed (incl. pair-copy pin); envelope read blanked 1 failed/10 passed; each restored blob == HEAD, git diff HEAD empty. Browser: app-crm dev boot + console vite zh-CN, customized crm_lead.all, added 批量修改负责人 (assigned_to), published, selected 2 leads, ran: 成功 2/2, API shows assigned_to set on both; removed delete, republished: bar shows only the update button. Shots /mnt/project-files/ui-orders/30089-shots/ (10 files).", "gates": "dispatch-gates --commands on d8c1f112: 35 derived; all exit 0: node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0; node scripts/check-adr-0087-registration.mjs --self-test :: exit 0; node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0; node scripts/check-closing-keyword-parity.mjs :: exit 0; node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0; node scripts/check-comment-mask-corpus.mjs :: exit 0; node scripts/check-empty-changeset.mjs --base origin/main :: exit 0; node scripts/check-empty-changeset.mjs --self-test :: exit 0; node scripts/check-sdui-manifest.mjs :: exit 0; node scripts/check-sdui-manifest.mjs --self-test :: exit 0; node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0; node scripts/release-pending-publish.mjs --self-test :: exit 0; pnpm --dir ui exec vitest run scripts/ :: exit 0; pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0; pnpm check:changeset-gate-self-tests :: exit 0; pnpm check:closed-ceremony-text :: exit 0; pnpm check:cross-package-test-inputs :: exit 0; pnpm check:dispatcher-error-vocabulary :: exit 0; pnpm check:driver-memory-census :: exit 0; pnpm check:engine-double-contract :: exit 0; pnpm check:gitlink-declared :: exit 0; pnpm check:nul-bytes :: exit 0; pnpm check:published-files :: exit 0; pnpm check:query-options-erasure :: exit 0; pnpm check:refd-timer-probe :: exit 0; pnpm check:registry-log-declared :: exit 0; pnpm check:rest-log-spy-declared :: exit 0; pnpm check:skill-identifier-liveness :: exit 0; pnpm check:test-source-alias :: exit 0; pnpm check:tier-file-adoption :: exit 0; pnpm check:type-check-coverage :: exit 0; pnpm check:type-check-debt :: exit 0; pnpm check:undeclared-dep-imports :: exit 0; pnpm check:watch-hint-literal :: exit 0; pnpm check:where-matcher :: exit 0. --ran reconciliation: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN. Also ui check:new-line-citations 0 new, exit 0. CI check-runs on PR 30339: in_progress at report time.", "line_budget": "7 files, 1201 insertions (under the 1500 slice line): section, new test, customize harness +49, inspector +11, i18n en/zh +21 each, changeset 16", "files_changed": [ ".changeset/30089-studio-list-view-selection-actions.md", "ui/packages/app-shell/src/views/studio-design/ListViewBulkActionsSection.tsx", "ui/packages/app-shell/src/views/studio-design/ObjectListViewInspector.tsx", "ui/packages/app-shell/src/views/studio-design/ObjectListViewInspector.bulkActions-30089.test.tsx", "ui/packages/app-shell/src/views/studio-design/InterfacesPillar.customize-28562.test.tsx", "ui/packages/i18n/src/namespaces/studio/en.ts", "ui/packages/i18n/src/namespaces/studio/zh.ts" ], "deviations": "Section shown for grid views only (non-grid bars never render bulkActionDefs); params written required true. Main merged twice (0396b161, d8c1f112); #30177 not landed yet, merge again after it lands. PR opened without assignee/reviewer per order (session-context asks for both; order and os-dev.md win). No PR subscription by this thread (os-dev contract). Harness-written model-named trailer not used: commits carry the model-free pair.", "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "3: mcp__github__issue_read x3 (get, get_comments x2); no write tool", "api_writes": "2 relay writes: pr_create (PR 30339, read back identical 10841 bytes) and this os-dev-report comment via post-stamped; plus git push", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted in PR Acceptance notes: non-grid list views render bulkActions but not bulkActionDefs; a reading, not filed" ] }objectstack-fleet commentedon Nov 5, 2026
domain:ui#4 · os-support-ai · session_01WGufzinedUGSXteN45poyo
Landed · PR #30339
be9bfd04(the ACCEPTed change plus the main merge after #30315, re-verified by the dev)d99cd3b0cebc74ce87d8e858b455a6485f29b57bStatus: card closed as completed by the merge;
pm:dispatchedremoved.