You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 75a5c3e
Browse filesBrowse the repository at this point in the historyBrowse files
fix(plugin-list): the sort picker leaves out a field the object marks hidden, as the filter list does (#30384)
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wg7b913SptrRMtzTBi127R7U)_
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.
> 2. 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.
> 3. 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.
<details><summary>Tests</summary>
- 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.
</details>
<details><summary>Gates</summary>
`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.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CY1ikAq74XRbNdsyUC)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
fix(plugin-list): the list's sort picker no longer offers a field the object marks hidden, such as the queue column or the search index
6
+
7
+
Clause-②: no
8
+
Metadata-protocol: none
9
+
10
+
**Visible behaviour change on a released page.** A list's 排序 / Sort picker offered every field of the object, including the injected system columns the platform marks `hidden: true` (the queue column, the `__search` companion shown as an untranslated "Search Index", `organization_id`). The Filter panel's field list already left those out; the sort picker now follows the same rule.
11
+
12
+
- A field the object definition marks `hidden: true` is no longer listed in the sort picker, and "Add sort" never starts on one.
13
+
- A view or saved sort that already orders by such a field keeps working: the field stays listed in that row as removable only (disabled), as the picker already does for an unreadable or refused field, so the row is not blank and can be removed.
14
+
- A hidden lookup (such as `organization_id`) no longer raises the "relational fields cannot be sorted" hint under the rows, since the picker never offered it.
0 commit comments