Repository navigation
Description
epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff
Filed by the record-page epic seat from a review of list personalization under epic #26676. An independent reviewer read the code and tested on examples/app-crm, and the seat re-read the evidence. The maintainer: 「把「恢复默认清除偏好」、「账号偏好字段校验」、「个性化标记与统一重置」立卡,并收窄 #28912 的验收。命名个人视图暂不做。」 (2026-11-02). Code readings below are on main a36409337b. No domain:* label is set: triage routes this card.
Business reason
A reader can't tell they are looking at a personalized list, so "why is my list different from my colleague's" has no answer on screen. When they want to go back, there are two similarly named entries with different scopes, and neither restores everything.
Measured and read
| Entry | Where | Restores | Leaves |
|---|---|---|---|
| 「重置视图」 | header ⋯, only when the view has a stored entry | sort, filters, column layout, density, hidden fields | search term, grouping, Display-only settings |
| 「恢复视图默认设置」 | bottom of the Display popover | layout, grouping, row color, hidden fields, density, row numbers, inline edit | sort, filters, column layout, search term |
- The reviewer measured that after 「重置视图」 the URL still carried
uf__search=Alanand the cached term remained. - The tooltip
console.objectView.resetViewTitle(ui/packages/i18n/src/locales/zh.ts:2375) names sort, filters and column width only.resetViewPreference(ListPreferencesProvider.tsx, around line 253) also clears density and hidden fields. - The Display badge counts Display settings only (
ListView.tsx, around line 5442), so a list with a changed sort and filter shows 0. - Header entry:
objectViewListUrlState.ts:159-164,objectViewPageHeader.tsx, around line 223. Display entry:ViewSettingsPopover.tsx:668-679.
Target
- A small marker beside the list title appears while the reader's list differs from the view. Opening it says what differs: sort, filters, columns, density, hidden fields, grouping, search.
- The marker holds one reset that returns the whole list to the view. That covers everything in the table above, the search term and URL state included.
- The two existing entries go, or point to this one. The claiming seat states which in the PR. One way back stays.
- Copy says exactly what the reset covers, across the ten packs.
- These are not part of the reset, because they are not this view's list state: the record-open preference, pinned views and favorites.
- No new metadata key and no new option. The marker is not configurable.
Not in this card: named personal views (the maintainer: 「命名个人视图暂不做」, tracked by #28971) and admin-side reset.
Run after #28948, because both touch the same reset paths. Also check #28912 and #28915, which touch the Display popover.
Acceptance
- Change a sort: the marker appears and names it. Reset: the marker disappears, the list equals the view, and the URL has no
uf_*state of the reader's. - On a list with nothing changed, there is no marker.
- A narrow window and the phone keep the marker reachable without pushing out the view name.
- Screenshots at 1440 and 390 px are linked from the PR, so the epic seat can check the marker's look.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: priority:p2 · domain:ui · pm:queue · 2026-11-02T05:00Z
⛔ Not a claim.
ListPreferencesProvider.tsx,objectViewListUrlState.ts,objectViewPageHeader.tsx,ViewSettingsPopover.tsx,ListView.tsx) that adds no metadata key, so it is a user-visible feature at p2 indomain:ui. The maintainer's quoted ruling orders the card, so there is nothing to decide and it goes topm:queue. It was filed under epic epic: record page v2 — one default open mode per object (drawer by default, page by declaration; modal / split / popover retired as metadata); the drawer and the page are one page at two widths; related records open in place #26676 but is not a sub-issue, and the body hands routing to triage. It runs after List personalization: 「恢复视图默认」 clears the reader's stored setting instead of copying the default into it — today the reader stays on the old value after the view changes #28948, which shares the reset paths.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu
Claim: PM loop round 19 · 2026-11-02T08:01Z
Session:
session_01QsR2jQki8itS3sC2eZCj7J(card thread, os-dev); dispatched by seat sessionsession_01QsR2jUJ19MstFvFhjgiYTuAccount:
zhuangjianguoBranch:
claude/project-thread-o05ndx(platform-assigned to the card thread; it can push only this branch)Worktree:
objectstack-issue-28950Domain:
domain:uiSeat:
domain:ui#1File surface:
ui/packages/plugin-list/src/ListView.tsx(a new optional host proponPersonalizationChange); underui/packages/app-shell/src/views/:objectViewListUrlState.ts,objectViewPageHeader.tsx,objectViewHeaderChrome.tsx,ObjectView.tsx,objectViewListRenderer.tsxand a newListPersonalizedMarker.tsx; newconsole.objectViewkeys in the ten@object-ui/i18nlocale packs (none removed); their tests; onecontent/docspage; and a root.changeset. Shape:/mnt/project-files/issue-28950/shape.md(stop on breach; explain in the report)Container & model: M,
mode:thread,model: default tier (dispatch-gates --tier: no path-derived mandate),effort: highClause-②: yes (widening)
Metadata-protocol: none
Responsibility: one 已个性化 marker listing what differs and one reset that restores the whole list (sort, filters and chips, search, grouping, columns, display) and strips the uf_* params; the header 重置视图 entry and the Display popover reset go; per-control resets stay
Thread-read: 6569470218
Premise: holds (at
origin/maina4015ab4: the card measures two reset entries covering different parts; measured by code reading at a4015ab: the header entry leaves search and uf_* chip params, which re-seed on reload; the Display reset restores Display settings only)Serial constraints cleared: #28911 landed as
f67bbeca(PR #29054). Seat 4 cleared starting against draft PR #29108 (#28915); merge main after #29108 and PR #29047 (#28908) land.objectstack-fleet commentedon Nov 2, 2026
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu
os-dev-report
{ "issue": 28950, "status": "done", "branch": "claude/project-thread-o05ndx", "pr": "https://github.com/objectstack-ai/objectstack/pull/29266", "head": "b2d090d8", "session": "session_01QsR2jQki8itS3sC2eZCj7J", "premise_still_valid": true, "summary": "One Personalized marker beside the list title (PageHeader badge slot, both header faces; icon-only beside the phone title) names what differs and holds the one Reset to view. ListView gains one optional host prop, onPersonalizationChange(parts), reporting sort, filters (panel, chips, queue toggle), search, grouping, hiddenFields, density, layout, rowColor, rowNumbers, inlineEdit; the host adds columns from the stored entry. With the prop wired ListView passes no onReset to the Display popover (ViewSettingsPopover.tsx untouched); hosts without it keep the Display reset. viewDefaults also accepts grouping. The reset drops the stored entry, clears the cached search, strips the whole uf_* family (withoutListStateParams) and seeds from storage on the remount, so a reload or an opened link cannot bring the old list back. The header ⋯ Reset view and the folded bar's object_view_reset_view action are gone; ⋯ keeps favorites. Sort popover reset and Filter Clear all stay. Copy in all ten packs, no key removed. Clause-② yes (widening), Metadata-protocol none, as claimed. Premise held with one correction from measurement: on main the header reset already restored grouping and Display settings through the remount, and was never offered for a URL-only personalization.", "tests": "New plugin-list ListView.personalization-28950 (12) and app-shell ObjectView.listPersonalized-28950 (5); 12418's ⋯ Reset view pins moved to the marker (32/32). Ablations via ablation-replace.mjs, each restored to HEAD: dropping `&& !reset` from the seed condition reds the reload test (1 of 5); unconditional Display onReset reds the no-Display-reset test (1 of 12). On merged head b2d090d8: turbo type-check plugin-list + app-shell + i18n 67/67; pnpm build 117/117; plugin-list 183 files 1759 passed; app-shell ObjectView*/objectView* set 88 files 735 passed (narrowed on purpose, CI Test UI runs the rest); i18n 95 files 1443 passed 13 skipped; eslint touched files 0 errors. Live (app-crm + console dev): link with uf__sort + uf__search draws the marker (Search, Sort); reset leaves location.search empty, reload keeps it empty, marker gone, at 1440 and 390. 16 before/after shots in /mnt/project-files/issue-28950/shots/.", "gates": "dispatch-gates --commands derived 66 families on b2d090d8; all 66 exit 0 (incl. check-sdui-manifest, vitest run scripts/). --ran: 66 derived, 66 run, 0 NOT-MEASURED (derived zero). PR-body gates on the final body (check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword): exit 0. PR at report time: draft, mergeable_state blocked (checks pending), 13 completed / 20 in progress.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — fleet-write relay pr_create (#29266, run 41430900576, body read back identical, no assignees); this os-dev-report comment via post-stamped on #28950", "merges": "main merged twice (e3c09093 after #29047, b2d090d8 after #29108 = ea150b7f), both clean; merge-tree against main 67ee171a clean at report time", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed — lists outside ObjectView (InterfaceListPage, ObjectDataPage, embedded ListView) do not wire onPersonalizationChange, so they draw no marker and keep the Display-only reset; giving them the marker is a card of its own. reach: hosts of @object-ui/plugin-list ListView other than app-shell ObjectView; dedupe words: personalized marker other hosts, onPersonalizationChange InterfaceListPage" ] }objectstack-fleet commentedon Nov 2, 2026
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu
Landed · 2026-11-02T11:51Z · PR #29266 merged through the merge queue as
8c93af7fat 2026-11-02T11:50Z (GitHub's clock). ACCEPT 6575463518 at headb2d090d8. Clause-② yes (widening), contract self-review passed in that ACCEPT.8c93af7f~1)origin/main)onPersonalizationChangeinui/packages/plugin-list/src/ListView.tsxui/packages/app-shell/src/views/ListPersonalizedMarker.tsxexistspersonalizinui/packages/i18n/src/locales/en.tsFixes #28950closed this card.pm:dispatchedcomes off in the same stroke as this note. No seat card waited on this PR.