Skip to content

[Decision] Selection-bar actions cannot be configured in Studio: should the view panel offer them? #30089

Closed

Description

@objectstack-fleet

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, bulkActionDefs or rowActions: no such section on surface=view:… (Basics, Columns & filters, Table options, End-user controls, Navigation & sharing) and none on the object leaf's panel. There are no such keys in ObjectListViewInspector.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

  1. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Nov 4, 2026
  2. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    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-decision is removed; triage routes this card.

  3. removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Nov 4, 2026
  4. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p2 kept · domain:ui · 2026-11-04T13:57Z

    ⛔ Not a claim.


    Generated by Claude Code

  5. added
    domain:uiDomain lane — seat card indexed by label:pm:seat
    enhancementNew feature or request
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 4, 2026
  6. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-support-ai · session_01WGufzinedUGSXteN45poyo

    Claim: PM loop round 4
    Session: session_01WGufzhfh9quLdZYWtWEMLK (card thread executor; seat session session_01WGufzinedUGSXteN45poyo)
    Account: os-support-ai
    Branch: claude/project-thread-0vx632 (harness-pinned card thread branch; the claude/issue-<n>-<slug> convention does not apply to a project card thread)
    Worktree: objectstack-issue-30089
    Domain: domain:ui
    Seat: domain:ui#4
    File 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: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6632518141
    Premise: holds (seat read origin/main 4be973424: no bulkActions/bulkActionDefs/rowActions under studio-design; keys exist at packages/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 edits listViewTargetOf, the switcher and the Create View seed; this card adds a new section), merge main after it lands. #30211 (#30088, action editor) is triage-serial: this card does not touch ObjectActionsPanel.tsx or pairObjectActions.ts.

  7. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    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"
     ]
    }
  8. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-support-ai · session_01WGufzinedUGSXteN45poyo

    Landed · PR #30339

    Reading Value
    PR #30339 state merged 2026-11-05T12:30Z via merge queue, head be9bfd04 (the ACCEPTed change plus the main merge after #30315, re-verified by the dev)
    merge commit on main d99cd3b0cebc74ce87d8e858b455a6485f29b57b

    Status: card closed as completed by the merge; pm:dispatched removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:uiDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions