Skip to content

Commit 104cd1a

Browse files
feat(spec): list views offer Hide Fields by default — userActions.hideFields defaults to true (#29083)
<!-- claude-projects-attribution: {"github_login":"os-steve"} --> _Requested by **Steve** · [project thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9XsdB5Zc6oHVNgmxpWpMbSZ)_ Fixes #28912 Clause-②: yes (widening) Metadata-protocol: semantic ## 维护者速读 - 改了什么:列表视图的「隐藏字段」按钮改为默认显示;应用写 `userActions: { hideFields: false }` 才会关掉。spec 默认值、列表渲染器的读取、默认值变更台账三处同步。 - 为什么改:读者想去掉不需要的列却无处可点,CRM 示例和生成的应用都没打开这个开关。旧的默认关是照抄渲染器历史写法,不是产品选择;您已批准翻转。 - 风险与回滚:每个没声明该键的列表都会多一个按钮。隐藏只影响该读者自己(有 columns 的视图或保存视图存到其个人列表状态,系统视图仅本次会话),从不写共享视图。回滚即 revert 本 PR。 - 先看:`packages/spec/src/ui/view.zod.ts`(hideFields 默认值与上方注释)、`ui/packages/plugin-list/src/ListView.tsx`(`showHideFields` 一行)、`packages/spec/scripts/lib/default-changes.ts`(台账新行)。 - 两分钟验证:`cd ui && pnpm exec vitest run packages/plugin-list/src/__tests__/ListView.test.tsx -t "Hide fields"`,预期全部通过,其中含「未声明时显示」「声明 false 时不显示」两条新用例。 - 需要你做的:无,席位落地。 ## What changes - `packages/spec/src/ui/view.zod.ts`: `UserActionsConfigSchema.hideFields` goes from `.default(false)` to `.default(true)`. The describe and the block comment above the schema now say why (maintainer ruling on #28912) and where the reader's choice is kept. - `ui/packages/plugin-list/src/ListView.tsx`: `showHideFields: ua?.hideFields !== false` (was `=== true`), and the comment above it changes with it. - `packages/spec/scripts/lib/default-changes.ts`: the protocol-18 row `ui/UserActionsConfig:hideFields`, `false` to `true`, with the reason a build prints. - Regenerated: `content/docs/references/ui/{view,page}.mdx` (the default column and describe) and `packages/spec/authorable-defaults/ui.json` (one fingerprint line). - `.changeset/28912-hide-fields-default-on.md`: `@objectstack/spec` and `@object-ui/plugin-list`, minor. - Not touched, per the card: `persistHiddenFields` and the objectui#10694 session-only rule in `objectViewListRenderer.tsx`, and the record-details component's `hideFields` (a `string[]`). ## Tests Forced edits (they pinned the old default): - `packages/spec/src/ui/view.test.ts` "should apply default values": `hideFields` now expects `true`. - `packages/spec/src/ui/view.test.ts` the defaults-asymmetry pin: renamed to "pins the group-ON / hideFields-ON / rowColor-OFF defaults" and expects `true`. - `ui/packages/plugin-list/src/__tests__/ListView.test.tsx` "should keep the legacy show* flags working": a legacy `showHideFields: true` is now indistinguishable from silence, so the fold is pinned by `showHideFields: false` (control absent). New: - `view.test.ts` "hideFields defaults ON (maintainer ruling)": absent parses to `true` (schema and through `ListViewSchema`), explicit `false` stays `false`, no `userActions` block materialises none. - `ListView.test.tsx`: the control is drawn when `userActions` omits `hideFields`, and not drawn for `hideFields: false`. ## Acceptance notes - Premise check (run first, on `main` 135054e with `ListView.tsx` at `main`'s `=== true` read): `ObjectView.emptyColumnsNoProjection-10694.test.tsx` and `ObjectView.userListState-12418.test.tsx`, 43/43 passed. They drive the real ListView Display popover and its Hide Fields checkbox: the column goes; on a view that declares `columns` and on a saved view the choice is stored on the user's own list state and re-applied after a remount, and the view is not written; on a system view with no `columns` it is session-only and nothing is stored; another user sees the defaults. So the control works end to end and the flip does not spread a broken control. - Interface pages are unchanged on purpose: `InterfaceListPage.tsx` keeps its closed-by-default toolbar (`hideFields: userActions.hideFields === true`, like `filter`, `rowHeight`, `group`). A page `interfaceConfig.userActions` block that omits the key parses to `true`, but that page still draws the control only for an explicit `true`. The ledger reason and the changeset say so. - `ui/packages/core/src/utils/normalize-list-view.ts` around line 400 still says "hideFields/rowColor default OFF" in a comment. It is outside this card's file surface, so it is left for the seat. - No ADR-0087 D3 semantic migration entry is added: it is outside the claimed file surface. The three earlier UI default flips (`editInline`, `pageSize`, nav-group `expanded`) each carry one; see the report's open question. ## Verification Spec and plugin-list suites ran at d9c8c4e; the only later commit (5e51cfd) rewords the ledger reason and the changeset, touching no source or test. Gates and the app-shell set ran at 5e51cfd. <details><summary>Spec, consumers, generated artifacts</summary> - `pnpm --filter @objectstack/spec check:generated`: 14/14 artifacts up to date (after `gen:docs`). - `pnpm --filter @objectstack/spec test`: Test Files 789 passed, Tests 23328 passed, 1 todo. - `cd ui && pnpm exec vitest run packages/plugin-list`: Test Files 179 passed, Tests 1729 passed. - `cd ui && pnpm exec vitest run the 34 app-shell files that read hideFields, hiddenFields or userActions`: Test Files 34 passed, Tests 344 passed (head 5e51cfd). The full app-shell suite (2065 files) is left to CI's Test UI shards; a local full run was stopped after 64 minutes. - `check-empty-changeset` exit 0; `check-adr-0087-registration` exit 0 (non-breaking, no disposition owed); `check-changeset-no-major --event` on this body exit 0 (LEVEL AXIS reads `yes (widening)` + `semantic`). - `pnpm --filter @objectstack/spec typecheck` exit 0. `@object-ui/plugin-list type-check` NOT MEASURED locally (the ui package closure is unbuilt in this container); CI's Type Check UI carries it. - `dispatch-gates --ran` on head 5e51cfd: 108 derived, 108 run, 0 NOT-MEASURED, 0 UNRUN, every exit 0. </details> --- _Generated by [Claude Code](https://claude.ai/code/session_01ADHkmRSwH9oAqN1JrZZVoR)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent dedc350 commit 104cd1a

12 files changed

Lines changed: 214 additions & 32 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
'@objectstack/spec': minor
3+
'@object-ui/plugin-list': minor
4+
---
5+
6+
spec(ui): a list view lets readers hide and show columns by default — `userActions.hideFields` defaults to `true`
7+
8+
Clause-②: yes (widening)
9+
Metadata-protocol: semantic
10+
11+
A declared default moves. A list view whose `userActions` block says nothing about `hideFields` now offers the Hide Fields control, so a reader can remove a column they do not need without the app author having to turn the control on.
12+
13+
- **Before.** `UserActionsConfigSchema.hideFields` defaulted to `false`, and the list renderer drew the control only for an explicit `hideFields: true`. Generated apps and the CRM example never declared it, so their lists had no way to hide a column.
14+
- **Now.** The default is `true`, and the list renderer reads `hideFields !== false`, so the spec default and the renderer agree. A view with no `userActions` block parses with none, and the renderer reads the absent key as the new default.
15+
- **Interface pages.** A page `interfaceConfig.userActions` block that omits the key parses to `true` as well, but an interface page keeps its own closed-by-default toolbar, as it already does for `filter`, `rowHeight` and `group`: it draws the control only for an explicit `hideFields: true`.
16+
- **Where the choice is kept** does not change. The control only subtracts from the columns the view draws. On a view that declares `columns`, or a saved view, the choice is stored on the reader's own list state and survives a reload for that reader only. On a system view that declares no `columns`, it lasts for the session. It never writes the shared view.
17+
- **To withhold the control**, write `userActions: { hideFields: false }`. Every authored `hideFields` parses exactly as before, and a non-boolean is still refused.
18+
- **Compiled artifacts.** A document that serialised an earlier parse (an `os compile` artifact) carries the old written `false` and keeps withholding the control. Recompile it, or delete the key.
19+
- **Upgrade path.** The ADR-0087 D3 semantic entry `list-view-hide-fields-default-on` carries the change to `os migrate meta` and the upgrade guide. The default change is declared in the build's default-change ledger. No key is added or removed.

‎content/docs/references/ui/page.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ View filter rule
185185
| **group** | `boolean` | optional (default: `true`) | Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level `grouping` block. |
186186
| **addRecordForm** | `boolean` | optional (default: `false`) | Add records through a form instead of inline |
187187
| **editInline** | `boolean` | optional (default: `true`) | Allow users to edit records inline. On by default: a user who may update the object edits a cell in place with the field's type-aware widget (the same control the form uses), under the permission gate that already decides whether the object is editable at all. Declare `editInline: false` to make the list read-only in place. |
188-
| **hideFields** | `boolean` | optional (default: `false`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. Off by default: column hiding is opt-in. |
188+
| **hideFields** | `boolean` | optional (default: `true`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. On by default: a reader hides and shows columns for themselves; declare `hideFields: false` to withhold the control. |
189189
| **rowColor** | `boolean` | optional (default: `false`) | Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level `rowColor` block. Off by default: row colouring is opt-in. |
190190
| **buttons** | `string[]` | optional | Custom action button IDs to show in the toolbar |
191191

‎content/docs/references/ui/view.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ View filter rule
10901090
| **group** | `boolean` | optional (default: `true`) | Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level `grouping` block. |
10911091
| **addRecordForm** | `boolean` | optional (default: `false`) | Add records through a form instead of inline |
10921092
| **editInline** | `boolean` | optional (default: `true`) | Allow users to edit records inline. On by default: a user who may update the object edits a cell in place with the field's type-aware widget (the same control the form uses), under the permission gate that already decides whether the object is editable at all. Declare `editInline: false` to make the list read-only in place. |
1093-
| **hideFields** | `boolean` | optional (default: `false`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. Off by default: column hiding is opt-in. |
1093+
| **hideFields** | `boolean` | optional (default: `true`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. On by default: a reader hides and shows columns for themselves; declare `hideFields: false` to withhold the control. |
10941094
| **rowColor** | `boolean` | optional (default: `false`) | Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level `rowColor` block. Off by default: row colouring is opt-in. |
10951095
| **buttons** | `string[]` | optional | Custom action button IDs to show in the toolbar |
10961096

@@ -1469,7 +1469,7 @@ View filter rule
14691469
| **group** | `boolean` | optional (default: `true`) | Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level `grouping` block. |
14701470
| **addRecordForm** | `boolean` | optional (default: `false`) | Add records through a form instead of inline |
14711471
| **editInline** | `boolean` | optional (default: `true`) | Allow users to edit records inline. On by default: a user who may update the object edits a cell in place with the field's type-aware widget (the same control the form uses), under the permission gate that already decides whether the object is editable at all. Declare `editInline: false` to make the list read-only in place. |
1472-
| **hideFields** | `boolean` | optional (default: `false`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. Off by default: column hiding is opt-in. |
1472+
| **hideFields** | `boolean` | optional (default: `true`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. On by default: a reader hides and shows columns for themselves; declare `hideFields: false` to withhold the control. |
14731473
| **rowColor** | `boolean` | optional (default: `false`) | Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level `rowColor` block. Off by default: row colouring is opt-in. |
14741474
| **buttons** | `string[]` | optional | Custom action button IDs to show in the toolbar |
14751475

@@ -1641,7 +1641,7 @@ User action toggles for the view toolbar
16411641
| **group** | `boolean` | optional (default: `true`) | Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level `grouping` block. |
16421642
| **addRecordForm** | `boolean` | optional (default: `false`) | Add records through a form instead of inline |
16431643
| **editInline** | `boolean` | optional (default: `true`) | Allow users to edit records inline. On by default: a user who may update the object edits a cell in place with the field's type-aware widget (the same control the form uses), under the permission gate that already decides whether the object is editable at all. Declare `editInline: false` to make the list read-only in place. |
1644-
| **hideFields** | `boolean` | optional (default: `false`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. Off by default: column hiding is opt-in. |
1644+
| **hideFields** | `boolean` | optional (default: `true`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. On by default: a reader hides and shows columns for themselves; declare `hideFields: false` to withhold the control. |
16451645
| **rowColor** | `boolean` | optional (default: `false`) | Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level `rowColor` block. Off by default: row colouring is opt-in. |
16461646
| **buttons** | `string[]` | optional | Custom action button IDs to show in the toolbar |
16471647

‎packages/spec/authorable-defaults/ui.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
"ui/UserActionsConfig:editInline = true",
107107
"ui/UserActionsConfig:filter = true",
108108
"ui/UserActionsConfig:group = true",
109-
"ui/UserActionsConfig:hideFields = false",
109+
"ui/UserActionsConfig:hideFields = true",
110110
"ui/UserActionsConfig:refresh = true",
111111
"ui/UserActionsConfig:rowColor = false",
112112
"ui/UserActionsConfig:rowHeight = true",

‎packages/spec/scripts/lib/default-changes.ts‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,5 +716,31 @@ export const DEFAULT_CHANGES_BY_MAJOR: Readonly<Record<number, readonly Declared
716716
+ 'page, write `mode: \'page\'`. The `semantic` entry `ui-record-open-overlay-modes-retired` '
717717
+ 'carries the change to `os migrate meta` and the upgrade guide.',
718718
},
719+
{
720+
key: 'ui/UserActionsConfig:hideFields',
721+
from: 'false',
722+
to: 'true',
723+
reason:
724+
'A RULED default change (maintainer ruling on #28912: 「Fable 评估(核对后) 同意立卡」, '
725+
+ 'confirmed 「#28911 和 #28912 都保留,按卡上写的做。」): a list view lets a reader hide and '
726+
+ 'show its columns by default, and `userActions: { hideFields: false }` is the opt-out. The '
727+
+ 'old `false` was copied from the renderer\'s legacy `=== true` read, not chosen as product; '
728+
+ 'the renderer now reads `ua?.hideFields !== false`, so the spec default and the renderer '
729+
+ 'agree. What moves: a list view whose `userActions` block omits `hideFields` now parses to '
730+
+ '`true` where it parsed to `false`, and the console\'s list offers the Hide Fields control. '
731+
+ 'A view with NO `userActions` block parses with none on either side; the list renderer '
732+
+ 'reads an absent key as this default. A page `interfaceConfig.userActions` block parses to '
733+
+ '`true` too, but an interface page keeps its own closed-by-default toolbar (as it already '
734+
+ 'does for `filter`, `rowHeight` and `group`) and still draws the control only for an '
735+
+ 'explicit `hideFields: true`. The accept set does not move: '
736+
+ '`hideFields` is still a boolean, and every authored value parses exactly as before. The '
737+
+ 'control only subtracts from the columns the view draws, and the choice is the reader\'s '
738+
+ 'own: stored on their list state on a view that declares `columns` or a saved view, '
739+
+ 'session-only on a system view with no `columns`; it never writes the shared view. A '
740+
+ 'document that SERIALISED an earlier parse (an `os compile` artifact) carries a written '
741+
+ '`false` and keeps withholding the control: recompile it, or delete the key. To withhold '
742+
+ 'the control, write `userActions: { hideFields: false }`. To take the platform default, '
743+
+ 'change nothing. D3 entry: `list-view-hide-fields-default-on`.',
744+
},
719745
],
720746
};
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
import type { SemanticMigration } from '../../types.js';
4+
5+
// The declared default of `ListView.userActions.hideFields` moved from `false`
6+
// to `true` (maintainer ruling on #28912, 2026-11-02, verbatim:
7+
// 「Fable 评估(核对后) 同意立卡」, confirmed 「#28911 和 #28912 都保留,按卡上写的做。」).
8+
// A default move reaches every silent document with no parse error and nothing
9+
// in the author's diff, so the upgrade path carries it as a TODO: only the
10+
// deployment can say which list that never declared the key was relying on its
11+
// columns being fixed for every reader. The same class as
12+
// `list-view-edit-inline-default-on` and `view-pagination-page-size-default-50`:
13+
// no key is removed, so there is no tombstone and no RETIRED_KEYS_BY_MAJOR row,
14+
// and no D2 conversion exists — a mechanical pass writing `hideFields: false`
15+
// into every silent view would preserve the old posture and defeat the ruling,
16+
// and one writing `true` would add nothing the default does not already do.
17+
// Where the reader's choice is kept is objectui#10694's and objectui#12505's
18+
// rule in the console's list renderer, which this change leaves alone; the
19+
// citations live here, not in the printed guidance, which carries no tracker
20+
// number.
21+
export const entry: SemanticMigration = {
22+
id: 'list-view-hide-fields-default-on',
23+
surface: 'ui.UserActionsConfig.hideFields — an OMITTED hideFields inside a list view\'s '
24+
+ 'userActions block',
25+
replacement: 'nothing, to take the platform default: a reader can hide and show the list\'s '
26+
+ 'columns for themselves. To withhold the control on a list whose columns must stay as '
27+
+ 'authored for every reader, write it: `userActions: { hideFields: false }`',
28+
reason:
29+
'A RULED behaviour change on a default, so there is nothing to rewrite and nothing to '
30+
+ 'refuse: the maintainer\'s ruling of 2026-11-02 made the Hide Fields control available on a '
31+
+ 'list view by default, and the declared default of `UserActionsConfigSchema.hideFields` moved '
32+
+ 'from `false` to `true`. The old `false` was copied from the list renderer\'s legacy read, not '
33+
+ 'chosen as product; the renderer now reads an absent key as on. A `userActions` block that '
34+
+ 'omits `hideFields` now parses to `true`, and the console\'s list offers the control. A view '
35+
+ 'with no `userActions` block at all parses with none on either side; the renderer reads an '
36+
+ 'absent key as the spec default. The control only subtracts from the columns the view draws, '
37+
+ 'and the choice is the reader\'s own: stored on their own list state on a view that declares '
38+
+ '`columns` or on a saved view, kept for the session only on a system view that declares no '
39+
+ '`columns`, and never written into the shared view. An interface page keeps its own '
40+
+ 'closed-by-default toolbar and still draws the control only for an explicit `true`. Not '
41+
+ 'losslessly convertible because the question is intent, not text: only the deployment knows '
42+
+ 'which silent lists were relying on fixed columns. The accept set is unchanged — a boolean — '
43+
+ 'and every authored `hideFields` parses exactly as before. A document that serialised an '
44+
+ 'earlier parse (an `os compile` artifact) carries a written `false` and keeps withholding the '
45+
+ 'control; recompile it, or delete the key.',
46+
acceptanceCriteria:
47+
'An empty `userActions` block parses to `hideFields: true`, and a list view carrying '
48+
+ '`userActions: {}` parses to `userActions.hideFields` true; an authored '
49+
+ '`userActions: { hideFields: false }` still parses to `false`; a list view with no '
50+
+ '`userActions` block still parses with none. In the console, a grid view that declares no '
51+
+ '`hideFields` offers the Hide Fields control, and `userActions: { hideFields: false }` removes '
52+
+ 'it. Hiding a column on a view that declares `columns`, or on a saved view, survives a reload '
53+
+ 'for that reader only; on a system view with no `columns` it lasts for the session. Every list '
54+
+ 'whose columns must stay as authored declares `userActions: { hideFields: false }` and shows '
55+
+ 'no control.',
56+
};

‎packages/spec/src/ui/view.test.ts‎

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3435,7 +3435,7 @@ describe('UserActionsConfigSchema', () => {
34353435
expect(config.group).toBe(true);
34363436
expect(config.addRecordForm).toBe(false);
34373437
expect(config.editInline).toBe(true);
3438-
expect(config.hideFields).toBe(false);
3438+
expect(config.hideFields).toBe(true);
34393439
expect(config.rowColor).toBe(false);
34403440
expect(config.buttons).toBeUndefined();
34413441
});
@@ -3495,16 +3495,51 @@ describe('UserActionsConfigSchema', () => {
34953495
});
34963496
});
34973497

3498-
// The split is copied from the renderer's reads, not chosen by the spec
3499-
// (ruled A on objectui#5435): ListView.tsx computes `showGroup` as
3500-
// `ua?.group !== false` (absent ⇒ shown) but `showHideFields` / `showColor`
3501-
// as `ua?.hideFields === true` / `ua?.rowColor === true` (absent ⇒ hidden).
3502-
// Normalising the three to one default would silently flip a toolbar
3503-
// affordance on every view that never wrote the key.
3504-
it('pins the group-ON / hideFields-OFF / rowColor-OFF defaults asymmetry, copied from what the renderer reads', () => {
3498+
// Maintainer ruling on #28912: 「Fable 评估(核对后) 同意立卡」, confirmed on
3499+
// the card 「#28911 和 #28912 都保留,按卡上写的做。」 A reader can hide and
3500+
// show the view's columns by default; `hideFields: false` is the opt-out.
3501+
// The old OFF default was copied from the renderer's legacy `=== true` read;
3502+
// the renderer now reads `ua?.hideFields !== false`, so the two agree again.
3503+
describe('hideFields defaults ON (maintainer ruling)', () => {
3504+
it('an absent key parses to true', () => {
3505+
expect(UserActionsConfigSchema.parse({}).hideFields).toBe(true);
3506+
const view = ListViewSchema.parse({
3507+
name: 'accounts',
3508+
label: 'Accounts',
3509+
columns: [{ field: 'name' }],
3510+
userActions: {},
3511+
});
3512+
expect(view.userActions?.hideFields).toBe(true);
3513+
});
3514+
3515+
it('an explicit false stays false — the opt-out', () => {
3516+
expect(UserActionsConfigSchema.parse({ hideFields: false }).hideFields).toBe(false);
3517+
const view = ListViewSchema.parse({
3518+
name: 'accounts',
3519+
label: 'Accounts',
3520+
columns: [{ field: 'name' }],
3521+
userActions: { hideFields: false },
3522+
});
3523+
expect(view.userActions?.hideFields).toBe(false);
3524+
});
3525+
3526+
it('a view with no `userActions` block still materialises none', () => {
3527+
const view = ListViewSchema.parse({
3528+
name: 'accounts',
3529+
label: 'Accounts',
3530+
columns: [{ field: 'name' }],
3531+
});
3532+
expect(view.userActions).toBeUndefined();
3533+
});
3534+
});
3535+
3536+
// `group` is ON unless turned off (`ua?.group !== false`), `rowColor` is OFF
3537+
// unless turned on (`ua?.rowColor === true`) — the renderer's reads, ruled A
3538+
// on objectui#5435. `hideFields` left this pair by the ruling above.
3539+
it('pins the group-ON / hideFields-ON / rowColor-OFF defaults, matching what the renderer reads', () => {
35053540
const config = UserActionsConfigSchema.parse({});
35063541
expect(config.group).toBe(true);
3507-
expect(config.hideFields).toBe(false);
3542+
expect(config.hideFields).toBe(true);
35083543
expect(config.rowColor).toBe(false);
35093544
});
35103545

0 commit comments

Comments
 (0)