Skip to content

console record page: the related column loads counts first, then the first three rows of only the visible cards, and never blocks the details — one batched request, viewport-lazy cards, a measured budget #27056

Open

Description

@objectstack-fleet

epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff

Unblocked 2026-10-29T09:06Z — upstream #27055 closed (the record page v3 layout and its round 2 are on main at 273137d227; #27053's tabs retirement and #26679's drawer are there too). Back in the ui lane queue; re-read the card's Source against current main at dispatch — the v3 files it names moved in PR #27310 / #27473.

Part of the record-page-v3 epic #26676 (v3 child 3 of 8). Runs after #27055 (the compact cards it loads).

Source (origin/main 7bb8084590)

Every record:related_list node mounts RelatedList, which runs its own query on mount (pageSize default 10, the child's list columns); the column tier (#26758) mounts all of them at once, so a record with N related lists opens with N concurrent queries racing the record's own read (ruling 3). The folded rail in the two-column tier reads nothing until opened.

Target

  1. Counts first: on open, ONE request answers the count of every related list for this parent (one aggregate per child object's FK, batched through the data source's batch door if main has one, else the aggregate API per list in one Promise.all behind a single loading state — measure which exists). Card headers render from counts; a count of 0 folds the card to one line and skips its rows.
  2. Rows on demand: a card fetches at most 3 rows (limit) with a projection of the name field plus one status / date field (from relatedListColumns when declared, else the first status-like or date field), ordered by the inherited sort; only cards in the viewport fetch (IntersectionObserver), primary cards first; a folded 「动态」 card fetches nothing until opened.
  3. Details first: the details column renders from the record read alone; the related column shows skeleton cards until counts land, then rows; the page's interactive moment does not wait on related data.
  4. Prefetch on step: in the drawer, ↑ ↓ (console record drawer v2: the bar is ↑ ↓ · ⤢ · ✕ (no object name, no counter); a related row or a lookup opens its record in place with a trail, ← / Esc go back one level; ⤢ carries the trail into the page; on the record page a related row opens a drawer over the page #26679) prefetches the next record's counts.
  5. Budget, measured in the PR body on HotCRM (fresh DB, an account with ≥ 8 related lists): details interactive ≤ 300 ms after the record read returns; all card headers ≤ 500 ms; total related requests on open ≤ 2 round trips. Numbers from the browser's network panel, pasted.

File surface

ui/packages/plugin-detail/src/RelatedList.tsx (lazy + limit + projection), relatedListCompact.ts, a related-counts hook beside it, ui/packages/app-shell/src/views/RecordDetailView.tsx (the counts request and skeleton gating), the data-source batch call if present (ui/packages/data-objectstack), tests beside, changesets; ⛔ packages/spec/** (no new key: limit is an existing node prop).

Acceptance

  1. Tests: a record with 6 related lists issues one counts call and rows only for the 2 cards in view; a 0-count card never queries rows; the details render before any related response resolves.
  2. The measured budget table in the PR body; screenshots not required.

Rulings (maintainer, chat in the filing session, 2026-10-28 — verbatim, not re-decidable here)

  1. Record-page model (2026-10-27): 「1. 一个对象一个默认打开方式:默认抽屉(带展开整页),page 只给显式声明的对象,modal 退役,split / popover 变成用户个人偏好;抽屉和整页是同一张页在两个宽度。」
  2. On the resident timeline column: 「时间线是不是太突出了,这个只适合部分对象吧?适合做所有业务对象的默认布局吗」 and then 「时间线是否显示,是否可以切换,比如当前版本的 Claude code,顶部有很多切换图标」 — the column's presence is a per-user toggle with an object-derived default, never metadata.
  3. On the related column's cost: 「关联都放在右侧,记录打开时是不是会很慢,因为需要加载所有的关联子表。」 — the related column loads counts first, rows on demand, and never blocks the details.
  4. On mobile: 「还要考虑手机端的效果。」
  5. On the definition surfaces: the PM's keep / narrow / retire table was put to the maintainer (keep object roles, relationship flags, six slotted slots and kind: full; retire the tabs slot and the dead BuildPageOptions hints; fold the quick-look path into the one record page) and approved with the instruction in the footer.

Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff on 2026-10-28 under epic #26676 (record page v2 → v3), from the record-page definition-surface inventory on objectstack main 7bb8084590 and the maintainer's rulings in that session. The maintainer's instruction to file and dispatch, verbatim: 「同意,以上界面相关的需要我确认的你负责立卡派发,如果有可能可以启动云会话,开发完你来确认。」 Design evidence: the design canvas boards 「记录页 v3」 row (RecordPageV3, RecordPageV3NoTimeline, RecordPageRef, RecordDrawerV3, RecordMobile) — exported to the never-merged branch named in the epic parent once this batch is filed.

Activity

  1. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff

    Unlock scan 2026-10-29T09:07Z: every Blocked-by: upstream of this card is closed — #27055 by PR #27310 (merged by the maintainer) and PR #27473 (the seat landed it through the queue), #26679 by PR #27038, #27053 by PR #27219. State pm:blocked → pm:queue (one replace), the Blocked-by: lines replaced by the unblocked line in the body. The card's file surface is re-read against main 273137d227: the record page v3 layout (frameless sections, the merged timeline stream, compact related cards with the reader's arrangement, body tables, in-place enlarge, the segmented panel control in the header, the 1120 / 760 container thresholds) is what this card now builds on. Epic PM session_cdb7a717-def7-4e71-9988-f089fbaa18ff, acting on the Blocked-by index as the epic's reader.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:uienhancementNew feature or requestpm:queuepriority:p1High: required for production / M2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions