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 12aad14
Browse filesBrowse the repository at this point in the historyBrowse files
fix(plugin-list, app-shell): "Reset to view default" clears the stored list setting instead of copying the view into it (#29044)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbKSY5upS6CYM6fGkDbsN2GK)_Fixes#28948
Clause-②: yes (widening)
Metadata-protocol: none
## 维护者速读
-
**改了什么**:列表「显示」里的「恢复视图默认设置」和排序面板里的「恢复视图默认排序」,现在清除读者自己存下的那部分偏好(行高、隐藏列、排序),不再把视图当时的默认值当成读者的选择写进去。条目清空后整条删除,⋯
里的「重置视图」随之消失。
- **为什么改**:原来恢复默认会把旧默认值存成读者的选择,管理员之后修改视图的行高、隐藏列或排序,这位读者仍停在旧值上,⋯
也一直显示「重置视图」。
- **风险与回滚**:只动 `ui/` 的 `plugin-list`(`ListView` 新增宿主属性
`onRestoreViewDefaults`,`viewDefaults` 多一个 `sort`)和
`app-shell`(对象页接上这两个属性,恢复时把对应部分置空)。不动 spec、服务端和元数据。读者主动的「不排序」(`sort:
[]`)和「显示全部列」(`hiddenFields: []`)照旧保存。不接新属性的宿主行为不变。回滚 = revert 本 PR。
- **先看**:`ui/packages/plugin-list/src/ListView.tsx` 的
`resetDisplayToViewDefault` 与
`handleResetSort`;`ui/packages/app-shell/src/views/objectViewListRenderer.tsx`
的 `restoreViewDefaults`;新测试
`ListView.restoreViewDefaults-28948.test.tsx`。
- **两分钟验证**:`pnpm --dir ui exec vitest run
packages/plugin-list/src/__tests__/ListView.restoreViewDefaults-28948.test.tsx
packages/app-shell/src/views/ObjectView.userListState-12418.test.tsx`,应
2 个文件全部通过(6 + 32 个用例);或在 Console 线索列表改行高后点「恢复视图默认设置」,该用户的
`sys_user_preference` 条目里不再有 `rowHeight`。
- **需要你做的**:无,席位落地。
## What changes
**`@object-ui/plugin-list` — `ListView`**
- New host prop `onRestoreViewDefaults(parts)`, where `parts` is drawn
from `'sort' | 'hiddenFields' | 'rowHeight'`. When a host wires it, the
Display control's "Reset to view default" and the sort popover's "Reset
to view default" call it with the parts they returned to the view's own,
in one call, and no longer write the view's values through
`onHiddenFieldsChange`, `schema.onDensityChange` or `onSortChange` for
those parts. The list puts the view's sort and hidden fields back at
once; the table density follows `schema.rowHeight` once the host's clear
lays the view's own back there.
- `viewDefaults` gains `sort` (a pick of `ListViewSchema`'s
`hiddenFields`, `rowHeight` and `sort`). The sort popover's reset
compares against it (enabled state, whether it is drawn) and restores
it. As with the other two members, a passed `viewDefaults` is the whole
baseline: an absent `sort` means the view declares none.
- Without `onRestoreViewDefaults` (and without `viewDefaults`), both
resets behave exactly as before. Layout, grouping, row color, row
numbers, inline edit and the gallery card size reset as before in every
case.
**`@object-ui/app-shell` — the object page's list**
- Hands `viewDefaults.sort` (the view's own sort, under the link's or
user's stored sort that the `sort` rung lays over it) and wires
`onRestoreViewDefaults` to `restoreViewDefaults`, which patches each
named part to `null` on the user's list state (`listPrefs.patchView`).
`patchViewPreference` already treats `null` as a clear and removes a
view left with nothing, so "Reset view" disappears with the last part. A
sort reset also takes the sort off the URL (`writeListUrlState({ sort:
null })`).
- `ListPreferencesProvider`: docblock only — `ListViewPreferencePatch`
now names the list's per-part reset as the second way back to the view's
own.
## Tests
-
`ui/packages/plugin-list/src/__tests__/ListView.restoreViewDefaults-28948.test.tsx`
(new, 6 cases): the Display reset names `hiddenFields` and calls no
`onHiddenFieldsChange`; names `rowHeight`, calls no `onDensityChange`,
and follows the host's re-rendered `schema.rowHeight`; both differ ⇒ one
call naming both; the sort reset returns to `viewDefaults.sort` (server
`$orderby` moves from the user's to the view's), names `sort`, calls no
`onSortChange`; CONTROL: removing the last sort level still emits
`onSortChange([])`; CONTROL: row numbers reset without naming anything.
-
`ui/packages/app-shell/src/views/ObjectView.userListState-12418.test.tsx`
— new describe at the host seam (real `ObjectView`, real
`ListPreferencesProvider`, recorded list-state family), 6 cases: the
list is wired and handed the view's sort; a Display reset leaves neither
density nor hidden fields in the saved row; after it, a changed view
`rowHeight` / `hiddenFields` reaches the user on the next open; a sort
reset with nothing else stored saves `{}` and the ⋯ "Reset view" entry
goes; after it, a changed view sort reaches the user; CONTROL: a
deliberate `sort: []` and `hiddenFields: []` are saved and survive a
reload. The three `viewDefaults` equality pins now include `sort`; the
old "the list's reset writes through the doors" case is renamed to what
it pins (a choice equal to the view's own is stored as a choice).
<details><summary>Ablation (scripts/ablation-replace.mjs,
source-resolved, no dist)</summary>
- Sort reset back to the door (`if (onRestoreViewDefaults)
onRestoreViewDefaults(['sort']); else emitSortChange(restored);` to
`emitSortChange(restored);`): 1 failed (the sort reset case), 5 passed.
Restored, blob equal to HEAD, `git diff HEAD` empty.
- Density leg removed (the `else if (onRestoreViewDefaults)` branch
dropped, so the density goes through `density.setMode`): 2 failed (the
density case, the both-parts case), 4 passed. Restored, blob equal to
HEAD, `git diff HEAD` empty.
- Host stores the view's values instead of clearing (`patch[part] =
null` to the view's value per part): 4 failed in the host file (both
"leaves nothing stored" cases and both "follows the view on the next
open" cases), 28 passed. Restored, blob equal to HEAD, `git diff HEAD`
empty.
</details>
## Acceptance notes
- The sort popover's reset in the console used to return to the sort the
list OPENED with (a link's sort, or the user's stored sort), per the
`sort` rung's old comment. It now returns to the view's own sort, which
is what its label says and what a reload shows once the stored sort is
cleared; "Reset view" already did this.
- A display reset under `onRestoreViewDefaults` does not set the density
locally; it waits for the host to clear `rowHeight`. A host wiring the
prop must clear what it is named, which the docblock says.
- Not pinned: the URL `sort` param removal on a sort reset (the
harness's `MemoryRouter` URL is not read by these tests).
- #28950 (the 已个性化 marker) builds on these reset paths and is out of
scope here.
## Verification
All on the final head `eda72c06` (base `origin/main` `fed3a51b`), after
`pnpm install --frozen-lockfile` and `turbo run build
--filter='@object-ui/app-shell^...'
--filter='@object-ui/plugin-list^...'` plus formula, sdui-parser, lint
and client (64 tasks, exit 0), under `scripts/pm/os-verify-lock.sh`.
- The whole `packages/plugin-list/` vitest suite plus 16 app-shell /
console / plugin-view test files that name the touched modules or props
(`git grep -l` of `objectViewListRenderer`, `ListPreferencesProvider`,
`viewDefaults`, `listPrefs`, `patchView`, `onHiddenFieldsChange`,
`onDensityChange`, the two reset test ids), `--maxWorkers=2`: 196 files,
1907 tests passed. A declared narrowing for app-shell; CI's Test UI runs
the rest.
- `pnpm --filter @object-ui/plugin-list run type-check` and `pnpm
--filter @object-ui/app-shell run type-check` (the test programs
included): exit 0.
- ESLint on the five changed tsx files: exit 0, 0 errors (existing
warnings only).
- Derived gates (`node scripts/pm/dispatch-gates.mjs --commands`): 35 of
35 run, each exit 0 (`check:type-check-debt` and `pnpm --dir ui exec
vitest run scripts/` under the lock; the latter 169 files passed, 2
skipped), including `node scripts/check-sdui-manifest.mjs` and the
PR-body gates with this body as `GITHUB_EVENT_PATH`. `--ran` reconciles
35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN.
`check-partof-closing-keyword` with `PR_BODY`: exit 0. `ui`
`check:new-line-citations`: 0 new citations.
- `origin/main` moved to `ab085a04` since the base; none of its commits
touch the five changed files, so no merge was taken before opening.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01QsR2jTivKAK8N8dfW5mn9D
---------
Co-authored-by: Claude <noreply@anthropic.com>
fix(plugin-list, app-shell): "Reset to view default" clears the user's stored list setting instead of storing the view's value as their choice
7
+
8
+
Clause-②: yes (widening)
9
+
Metadata-protocol: none
10
+
11
+
In the console, a list's density, hidden fields and sort are the signed-in user's own preference. The Display control's "Reset to view default" and the sort popover's "Reset to view default" used to write the view's values back through the controls, so the console stored them as the user's choice: the user stayed on the old value after the view's author changed it, and the header ⋯ kept offering "Reset view".
12
+
13
+
-**`ListView` gains `onRestoreViewDefaults(parts)`**, a host prop. When a host wires it, those two resets call it with the parts they returned to the view's own (`'sort'`, `'hiddenFields'`, `'rowHeight'`) and no longer call `onSortChange`, `onHiddenFieldsChange` or `schema.onDensityChange` for them. The list shows the view's sort and hidden fields at once; the density follows `schema.rowHeight` once the host clears it. Without the prop, the resets write through the controls exactly as before.
14
+
-**`viewDefaults` gains `sort`.** A host that lays the user's own sort over the view's in `schema` hands the view's here, and the sort popover's reset compares against it and returns to it. As with the other two members, an absent `sort` in a passed `viewDefaults` means the view declares none.
15
+
-**The console clears the stored parts.** The object page wires both: a reset removes those parts from the user's stored entry for the view (and the sort from the URL), and a view left with nothing is removed, so "Reset view" disappears with it. A deliberate choice is unchanged: removing every sort level (`sort: []`) or showing every column (`hiddenFields: []`) is still stored.
16
+
-**Unchanged:** the other Display settings (layout, grouping, row color, row numbers, inline edit, gallery card size) reset as before.
0 commit comments