Skip to content

fix(plugin-list): the sort picker leaves out a field the object marks hidden, as the filter list does - #30384

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/project-thread-8vldlz
Nov 5, 2026
Merged

objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/project-thread-8vldlz

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Bill · project thread

domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

维护者速读

  • 改了什么: 列表的「排序」选择器不再列出对象定义里标了 hidden: true 的字段(队列、未翻译的 Search Index、组织等系统列),与「筛选」面板的字段列表同一条规则;视图或已存排序本来就按这类字段排的,那一行照旧显示,标为不可选、可删除。
  • 为什么改: 销售添加排序时会看到「队列」和英文的 "Search Index",对他们毫无意义,按搜索索引排序得到的顺序也无从解释;筛选面板早已把这些字段藏起,只有排序漏了。
  • 风险与回滚: 只改 Console 前端的排序字段列表,不改存储形状、不加元数据键;服务端排序能力不变。已按隐藏字段排序的视图照常加载和排序。回滚即还原本 PR。
  • 先看: ui/packages/plugin-list/src/ListView.tsx(新的 isDeclaredHidden 与 sortFields 循环开头的 offered 判定)。
  • 两分钟验证: pnpm --dir ui exec vitest run packages/plugin-list/src/__tests__/ListView.sortRemovableOnly-11943.test.tsx,预期 6 个用例全绿,其中 hidden: 一条钉住隐藏字段只在当前排序点名时以不可选形式出现。
  • 需要你做的: 无,席位落地。

Fixes #30037

Clause-②: no
Metadata-protocol: none

What changes

ui/packages/plugin-list/src/ListView.tsx, one rule shared by three field lists:

  • isDeclaredHidden(defs, field), a module-level predicate beside canReadField: the object definition marks the field hidden: true. The Filter panel's list (filterFields) and the hide-fields lists' addable fields (addableFields) already asked this question inline; both now call the predicate, unchanged in behaviour.
  • The Sort picker (sortFields) asks it too. A field is offered only when the user may read it and the definition does not mark it hidden. A hidden field the current sort already names is kept by the existing in-use exception, listed removable only (disabled), exactly as an unreadable field is: its row shows its label and can be removed, no other row and no "Add sort" can choose it. A hidden lookup (the platform's organization_id) no longer raises the relational hint under the rows, since the picker never offered it; a visible lookup still does.
  • The memo's dependency list gains objectDef, which the loop now reads.

What is persisted and requested is unchanged: a hidden field is sortable on the server, so a stored sort naming one keeps being sent and saved (the #6455 persist boundary filters platform-refused entries only).

Acceptance

The card's list, verbatim, each item pinned:

  1. The sort picker leaves out a field declared hidden, unless the current sort already names it. That row stays visible and removable, as today's inUse path does for other fields.

Pinned by ListView.sortRemovableOnly-11943.test.tsx: FIELD_DEFS gains a hidden search_index ("Search Index", standing in for __search and queue), so every case's exact option list now asserts it is absent; the new hidden: case declares it first and sorts by it, and asserts it is listed disabled, its row shows it, "Add sort" skips it, the new row offers it only as unavailable, and removing its row drops it from the list.

  1. The hide-fields, group and row-color lists are read for the same gap, and any that share it are fixed here, with the list of what was read in the PR.

Read on this head, no gap found, nothing changed in them:

  • Hide-fields popover and View settings section, column list: allFields, built from the view's declared columns only. A hidden field appears there only when the view's author declares it as a column, and then the grid draws it (effectiveFields drops unreadable and user-hidden columns, not definition-hidden ones), so listing it is consistent with the grid.
  • Hide-fields lists, fields a reader may add: addableFields already leaves out a definition-hidden field; it now asks the shared predicate.
  • Group editor (GroupingEditor fieldOptions) and Row color select: both read allFields, the same declared-columns list as above.
  1. A test pins the sort picker.

Item 1's pins, plus ListView.sortFieldRead-11943.test.tsx (new top-level describe): a hidden lookup is not offered and raises no relational hint, while the same lookup unhidden raises it.

Acceptance notes

The card's "To check while here" names two Studio lists. Both live in ui/packages/app-shell/**, outside this order's file surface, so they were read, not measured in a running Studio and not changed:

  • Formula 插入字段 (ObjectFieldInspector, the fieldOptions it hands CelPredicateField): every entry of the object draft's field list except the field itself, with no hidden check. Whether the draft carries the injected queue / __search columns was not measured here. A formula may legitimately read some hidden columns (queue, owner), so this is an implementer's judgement, not a mechanical copy of this rule.
  • Validation 参与字段 (ObjectValidationsPanel, the cross_field checkbox list): every field of the list it is handed. The panel already reads hidden (its new-rule default skips hidden fields) but the checkbox list does not filter on it.

Tests

Red first, on origin/main code with the new pins (ListView.tsx restored to its base, commit 91cec45d): Test Files 2 failed (2), Tests 6 failed, 6 passed (12). Each failure reads "Search Index" listed (the exact option lists) or the relational hint drawn for the hidden lookup.

Verification

All readings on objectstack-ai/objectstack. Final head 26c80600 (after merging origin/main at fdad1786); the full-package run was on c3b69a91, before the merge, whose six incoming commits touch no ui/ path.

Tests
  • Green after the fix, final head: pnpm --dir ui exec vitest run --maxWorkers=2 on ListView.sortRemovableOnly-11943, ListView.sortFieldRead-11943, ListView.filterFieldList-11810, ListView.fieldListRead-11984: Test Files 4 passed (4), Tests 50 passed (50); lock VERDICT command-exit 0.
  • Every importer of ListView.tsx (the whole plugin-list package, 145 files import it): pnpm --dir ui exec vitest run --maxWorkers=2 packages/plugin-list/ on c3b69a91: Test Files 189 passed (189), Tests 1813 passed (1813); lock VERDICT command-exit 0.
  • pnpm exec turbo run type-check --filter=@object-ui/plugin-list (tsc --noEmit && tsc -p tsconfig.test.json), final head: Tasks 53 successful, 53 total. The first run, before 26c80600, was red on TS6133 (an unused def binding this PR left in addableFields), fixed by that commit.
  • pnpm --filter @object-ui/plugin-list lint exit 0 (0 errors), and root eslint --no-inline-config on the three touched files exit 0.
Gates

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on 26c80600 derived 35 commands; all 35 run, each exit 0 (among them node scripts/check-sdui-manifest.mjs and pnpm --dir ui exec vitest run scripts/: Test Files 170 passed, 2 skipped (172); Tests 4985 passed, 2 skipped). --ran reconciliation: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN. Also pnpm check:changeset-fixed exit 0, pnpm --dir ui check:new-line-citations 0 new citations, node scripts/check-nul-bytes.mjs exit 0.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

Waits-on: main-red #30367

Lint UI on 26c80600 fails in @objectstack/spec check:liveness (the query/searchFields row cites engine.ts, which no longer names the key after #30341). This PR touches only ui/packages/plugin-list and a changeset, so the red is main's, not this diff's: the p0 anchor is #30367 and its fix is PR #30368. Once #30368 merges, this branch merges origin/main and CI re-runs; the seat ACCEPTs on that head.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

维护者速读

  • 改了什么: 列表「排序」选择器不再列出对象定义里标了 hidden: true 的系统字段(队列、英文的 Search Index 等),和「筛选」面板同一条规则;已按这类字段排序的那一行照旧显示,标为不可选、可删除。
  • 为什么改: 销售添加排序时看到「队列」和英文 "Search Index",毫无意义;筛选早已藏起,只有排序漏了(List sort picker offers hidden system fields: 队列 and an untranslated "Search Index" appear beside the business fields #30037)。
  • 风险与回滚: 只改 Console 前端的排序字段列表,不动存储、不加元数据键。回滚即撤本 PR。
  • 先看: ui/packages/plugin-list/src/ListView.tsx 的 isDeclaredHidden 与 sortFields 的 offered 判定。
  • 两分钟验证: pnpm --dir ui exec vitest run packages/plugin-list/src/__tests__/ListView.sortRemovableOnly-11943.test.tsx。
  • 需要您做的: 无,席位经合并队列落地(非受管面,79 行)。
  • 席位意见: ACCEPT。

席位核对 — ACCEPT · domain:ui#2 · head 1b1f7fa61a9ba303d3a6c6a2c60a5b7619f1372e

  • 形态: draft, author objectstack-fleet[bot] (relay pr_create), no assignee, no review request; 4 files, +68 −11; check-governed-merges --pr 30384: NOT governed, 79 lines ≤ 3000; mergeable clean. Head 1b1f7fa6 = 26c80600 (seat-read diff) + a pure merge of origin/main carrying the main-red fix fix(spec): repoint the query.searchFields liveness row at engine-find.ts#expandSearchOnAst #30368; no hunk of this PR's files moved.
  • 前提实测: on main sortFields had no hidden check while filterFields did; the diff adds one shared predicate isDeclaredHidden used by sort, filter and the add-field list (filter and add-field behaviour unchanged), and keeps an in-use hidden field as a disabled, removable row. The dev's red-first run: 6 red on main's sources.
  • 门禁 check-runs: 55 runs on 1b1f7fa6: 44 success, 11 skipped, 0 failed (Lint UI green again after fix(spec): repoint the query.searchFields liveness row at engine-find.ts#expandSearchOnAst #30368).
  • Declarations: Clause-②: no, Metadata-protocol: none; changeset @object-ui/plugin-list patch. No contract face hit (no published schema, no governed path, no narrowing declaration).
  • 接受的偏差: none.
  • 范围外去向: Studio's formula insert-field list and the validation participant list (app-shell) were read, not changed (PR Acceptance notes); dropped — not filed: neither is the list sort picker the card names, and no reach was measured.
  • 落地条款: Fixes List sort picker offers hidden system fields: 队列 and an untranslated "Search Index" appear beside the business fields #30037. Ordinary queue landing by this seat: pr_ready + automerge_enable on this head.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

Landing held: the seat session's auto-mode classifier refused the relay landing [{"op":"pr_ready","pull":30384},{"op":"automerge_enable","pull":30384}] (fleet-write/dispatch.mjs --actions-file) as "Merge Without Review". ACCEPT 6654603880 stands on 1b1f7fa6. The seat has asked the maintainer for the word in the seat thread and re-sends the same actions once it is given; no other route is tried.

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

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

List sort picker offers hidden system fields: 队列 and an untranslated "Search Index" appear beside the business fields

1 participant