Repository navigation
Commit a364093
fix(plugin-detail): on a desktop the enlarged related tab draws the child object's list grid (#28902)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbC5yRMtRXouSfKD16A2gwFn)_
Fixes #28865
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:记录页放大的相关列表页签,在桌面端改为渲染子对象列表页同款的 `object-grid`(手机端自 #28484
起已是如此),不再是通用 `data-table`。行高、密度、名称链接、行操作都与列表页一致;全部芯片已显示数量时,工具栏下方不再重复显示「N
条」。
- **为什么改**:#27524 第 9 项规定放大页签就是「子对象的列表面」;实测桌面端行高约 65 px(列表页 41
px)、名称是纯文本点不开、数量显示两次。
- **风险与回滚**:中低。分页、排序仍由相关列表自己掌控(服务端 `$top/$skip/$orderby` 不变),通过 grid
的宿主属性传入;行操作仍经宿主的 `onRowAction`
派发到子对象。唯一行为差异:筛选框有文字时,查找类列的表头不再提供排序(与所有列表页一致)。回滚即 revert 本 PR。
- **先看**:① `ui/packages/plugin-detail/src/RelatedList.tsx` 的
`viewSchema` 放大分支与 `enlargedGridHost`;② 同文件 `enlargedGridActions`(把 grid
的行操作派发路由回宿主);③ 新测试 `RelatedList.enlargedListGrid-28865.test.tsx`。
- **两分钟验证**:`pnpm dev:crm` 后打开 客户 Acme Corp → 商机列表 页签(1440
px):行高与商机列表页相同,名称是蓝色链接、点开即打开记录抽屉,数量只在「全部 4」芯片上出现一次。
- **需要你做的**:无,席位落地。
## What changes
`RelatedList`'s enlarged face (the record page's active related tab) now
renders `object-grid` on every width, the branch the phone has taken
since #28484. On a desktop it fell through to the generic `data-table`.
- **One branch, phone and desktop.** `viewSchema` returns `object-grid`
over the page of rows this list already read (`data: { provider:
'value', items }`), with the list's columns, the grid's own pager and
search off (`showPagination: false`, `showSearch: false`). Under 768 px
the grid draws the phone list's card rows, as before.
- **The list stays the source of truth.** Its window, page and sort
reach the grid on the grid's host channel: React props spread on
`SchemaRenderer` (`manualPagination`, `rowCount`, `page`, `pageSize`,
`onPageChange`, `sort`, `onSortChange`), the same ones `plugin-list`'s
`ListView` hands the grid. Paging and sort stay the server's `$top` /
`$skip` / `$orderby`; the list's own pager stays the one pager, because
it also answers a window whose total the server did not send
(`hasMore`). `objectFields` rides along so no column paints withheld
while the grid reads the definition (objectui#10657).
- **Row actions come from the grid.** The host's localized row actions
(`list_item`, and `record_related` inside a parent record) ride to the
grid's row menu as `rowActionDefs`, the non-author host key the
console's object page uses. Row Edit is the host's `onRowEdit`; row
Delete is this list's confirm-then-delete.
- **Row-action dispatch stays the host's.** The grid runs a row action
def through the surrounding action runner with the row under
`params._rowRecord` and no object of its own; on the record page that
runner's object is the parent's, and nothing would tell the list to read
its rows again. `RelatedList` provides the grid an action context
(`enlargedGridActions`) that sends a dispatch carrying one of its own
row action defs and a row to the host's `onRowAction` (child object, row
context, and the related-changed signal that refetches the list), and
every other dispatch to the surrounding runner unchanged.
- **One count.** While the 全部 chip is on and nothing narrows the rows,
the line under the toolbar no longer repeats the chip's count; it keeps
the page line when there is one. A narrowing chip (我的 / 逾期) or filter
text keeps the line's count, which is then a different number.
- Compact panels in the right column and lists that are not enlarged are
unchanged. No change to `plugin-grid`.
## Why
#27524 item 9: the enlarged tab is "the full-width table (all columns,
paging, sort, inline edit where the FK allows — **the child object's
list face**)". Measured on `main` before this PR (account Acme Corp →
商机, 1440 px, `examples/app-crm`): rows 65 px against the opportunity
list page's 41 px, the name as plain text, and the count shown twice
(「全部 4」 and 「4 条」).
## Tests
- New `RelatedList.enlargedListGrid-28865.test.tsx` (11 tests): the
desktop branch is `object-grid` over the read rows with the grid's pager
and search off; the host channel carries the window, page and sort and
none of it rides as node keys; a header sort from the grid becomes one
server `$orderby` from page 1; a page from the grid reads the next
window (`$skip` 25); the pinned deviation below; the count shows once on
全部 and a narrowing chip keeps its own count; a grid row-action dispatch
reaches `onRowAction` with the def and the row, and (control) any other
dispatch does not; row Edit is the host's and row Delete asks first;
control: a list that is not enlarged keeps the `data-table` with no host
props.
- `RelatedList.enlargedPhoneCards-28484.test.tsx`: its desktop control
now asserts the same `object-grid` branch.
- `RelatedList.enlargedToolbar-27524.test.tsx`: registers a stand-in
`object-grid` (this package cannot import `plugin-grid`, which depends
on it) and asserts the status line is not drawn when the 全部 chip carries
the count.
- `app-shell`
`RecordDetailView.childWriteRefreshesParent-12244.test.tsx`: the
enlarged tab's row menu is now the grid's, so the test opens it by
`row-action-trigger`. The delete still re-reads the parent.
Ablations (each through `scripts/ablation-replace.mjs`, restored to
`HEAD` byte-identical):
- desktop branch gated back to the phone (`enlargedFace && isMobile &&
…`): 7 of 11 red in the new file;
- the routed dispatch sent to the surrounding runner instead of
`onRowAction`: 1 red (the routing test);
- the one-count rule switched off: 2 red (the new count test and the
27524 toolbar test).
## Acceptance notes
- **Deviation (pinned):** while the filter box has text the list sorts
its in-memory rows itself; the grid is still handed that sort on the
host channel, and under a host sort the grid offers no header sort on a
relational column (its stored value is an id), as on every list page.
The `data-table` sorted such a column by its label in that one state.
Pinned in the new test file.
- Screenshots (1440 px, zh-CN, `examples/app-crm`, fresh boot) are in
the project folder `issue-28865/`; the seat links them here:
`before-account-opportunities-1440.png`,
`after-account-opportunities-1440.png`, and for comparison
`opportunity-list-page-1440.png`; also
`after-name-opens-record-1440.png`, `after-sorted-amount-desc-1440.png`,
`after-leads-row-actions-1440.png` and the phone face
`after-account-opportunities-390.png`.
- Measured in the running app after the change: rows 41 px on the tab
and on the list page; a header click sends `sort=amount` then `amount
desc` and the rows follow; the name opens the record drawer stepping 1 /
4; the 全部 chip says 4 and no line repeats it; on the leads tab the row
menu holds 编辑, 删除 and Convert Lead, and Convert Lead posts
`actions/crm_lead/crm_convert_lead` and the list then re-reads
`crm_lead`.
- The 操作 header over a column with no visible buttons is the grid's own
behaviour, the same as on the list page (#28871); it is not changed
here.
## Verification
At head `47c53a5a` (this branch with `origin/main` `7fa9873f` merged in;
4 later commits on main touch none of the changed files):
- `pnpm exec vitest run packages/plugin-detail/` (from `ui/`,
`--maxWorkers=2`, under `os-verify-lock`): 361 files passed, 1 skipped;
3200 tests passed, 18 skipped (run before the main merge; the merge
touched no file under `plugin-detail`, `plugin-grid` or `react`).
- 30 `app-shell` / `console` / `plugin-view` / `plugin-grid` test files
that name `RelatedList`, the enlarged face or `?related=`: 30 / 30
files, 496 / 496 tests after the row-menu update above.
- The touched test files again at the final head: the three
`plugin-detail` files plus the 30 above, 33 / 33 files, 516 / 516 tests.
- `pnpm --filter @object-ui/plugin-detail run type-check`: exit 0.
`eslint` on `RelatedList.tsx`: 0 errors, 99 warnings, the same count as
`main`.
- Derived gates (`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`, 34 commands, run at `47c53a5a`): 34 / 34
exit 0, reconciled by `--ran` (34 derived, 34 run, 0 NOT-MEASURED, every
line with its exit code); `pnpm --dir ui run check:spec-symbols` exit 0.
`node scripts/check-sdui-manifest.mjs`: exit 0 (manifest present and
intact, 106 components).
- `check-changeset-no-major.mjs --base origin/main` with this body as
`GITHUB_EVENT_PATH`: exit 0 (`Metadata-protocol: none`, patch);
`check-adr-0087-registration`, `check-closing-keyword-parity` and
`check-partof-closing-keyword` on this body: exit 0.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes.
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: not touched.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01QsR2jV95ABcxitqSGp6kmv
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QsR2jV95ABcxitqSGp6kmv)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 3ac22c9 commit a364093
6 files changed
Lines changed: 437 additions & 30 deletions
File tree
- .changeset
- ui/packages
- app-shell/src/views
- plugin-detail/src
- __tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
279 | 279 | | |
280 | 280 | | |
281 | 281 | | |
282 | | - | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
283 | 285 | | |
284 | 286 | | |
285 | 287 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
| 34 | + | |
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
83 | 86 | | |
84 | 87 | | |
85 | 88 | | |
| |||
408 | 411 | | |
409 | 412 | | |
410 | 413 | | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
411 | 434 | | |
412 | 435 | | |
413 | 436 | | |
| |||
2728 | 2751 | | |
2729 | 2752 | | |
2730 | 2753 | | |
| 2754 | + | |
| 2755 | + | |
| 2756 | + | |
| 2757 | + | |
| 2758 | + | |
| 2759 | + | |
| 2760 | + | |
| 2761 | + | |
| 2762 | + | |
| 2763 | + | |
| 2764 | + | |
| 2765 | + | |
| 2766 | + | |
| 2767 | + | |
| 2768 | + | |
| 2769 | + | |
| 2770 | + | |
| 2771 | + | |
| 2772 | + | |
| 2773 | + | |
| 2774 | + | |
| 2775 | + | |
| 2776 | + | |
| 2777 | + | |
| 2778 | + | |
| 2779 | + | |
| 2780 | + | |
| 2781 | + | |
| 2782 | + | |
| 2783 | + | |
| 2784 | + | |
| 2785 | + | |
| 2786 | + | |
2731 | 2787 | | |
2732 | 2788 | | |
2733 | 2789 | | |
2734 | 2790 | | |
2735 | 2791 | | |
2736 | 2792 | | |
2737 | | - | |
2738 | | - | |
2739 | | - | |
2740 | | - | |
2741 | | - | |
2742 | | - | |
2743 | | - | |
2744 | | - | |
2745 | | - | |
2746 | | - | |
2747 | | - | |
2748 | | - | |
2749 | | - | |
2750 | | - | |
2751 | | - | |
2752 | | - | |
2753 | 2793 | | |
2754 | 2794 | | |
2755 | 2795 | | |
| |||
2827 | 2867 | | |
2828 | 2868 | | |
2829 | 2869 | | |
| 2870 | + | |
| 2871 | + | |
| 2872 | + | |
| 2873 | + | |
| 2874 | + | |
| 2875 | + | |
| 2876 | + | |
| 2877 | + | |
| 2878 | + | |
| 2879 | + | |
| 2880 | + | |
| 2881 | + | |
| 2882 | + | |
| 2883 | + | |
| 2884 | + | |
| 2885 | + | |
| 2886 | + | |
| 2887 | + | |
| 2888 | + | |
| 2889 | + | |
| 2890 | + | |
| 2891 | + | |
| 2892 | + | |
| 2893 | + | |
| 2894 | + | |
| 2895 | + | |
| 2896 | + | |
| 2897 | + | |
| 2898 | + | |
| 2899 | + | |
| 2900 | + | |
| 2901 | + | |
| 2902 | + | |
| 2903 | + | |
| 2904 | + | |
| 2905 | + | |
| 2906 | + | |
| 2907 | + | |
| 2908 | + | |
| 2909 | + | |
| 2910 | + | |
| 2911 | + | |
| 2912 | + | |
| 2913 | + | |
| 2914 | + | |
| 2915 | + | |
| 2916 | + | |
| 2917 | + | |
| 2918 | + | |
| 2919 | + | |
| 2920 | + | |
| 2921 | + | |
| 2922 | + | |
| 2923 | + | |
| 2924 | + | |
| 2925 | + | |
| 2926 | + | |
| 2927 | + | |
| 2928 | + | |
| 2929 | + | |
| 2930 | + | |
| 2931 | + | |
| 2932 | + | |
| 2933 | + | |
| 2934 | + | |
| 2935 | + | |
| 2936 | + | |
| 2937 | + | |
| 2938 | + | |
| 2939 | + | |
| 2940 | + | |
| 2941 | + | |
| 2942 | + | |
| 2943 | + | |
2830 | 2944 | | |
2831 | 2945 | | |
2832 | 2946 | | |
| |||
3165 | 3279 | | |
3166 | 3280 | | |
3167 | 3281 | | |
| 3282 | + | |
| 3283 | + | |
| 3284 | + | |
| 3285 | + | |
| 3286 | + | |
| 3287 | + | |
3168 | 3288 | | |
3169 | 3289 | | |
3170 | 3290 | | |
| |||
3308 | 3428 | | |
3309 | 3429 | | |
3310 | 3430 | | |
3311 | | - | |
3312 | | - | |
3313 | | - | |
3314 | | - | |
| 3431 | + | |
| 3432 | + | |
| 3433 | + | |
| 3434 | + | |
| 3435 | + | |
| 3436 | + | |
| 3437 | + | |
| 3438 | + | |
3315 | 3439 | | |
3316 | | - | |
| 3440 | + | |
| 3441 | + | |
| 3442 | + | |
| 3443 | + | |
| 3444 | + | |
| 3445 | + | |
| 3446 | + | |
3317 | 3447 | | |
3318 | 3448 | | |
3319 | 3449 | | |
| |||
0 commit comments