Skip to content

record page: the Related tab gives an empty related list ("客户 0 暂无相关记录") a full row, and record:path squeezes two terminal stages ("× 已取消 客户未到") into one cell at the right edge #25895

Closed

Description

@os-steve

Filing gate ① a user-visible defect with a named landing site; two record-page polish items from one pass, split if triage prefers. Batch-of: 2026-10-25 browser pass on @objectstack/* 18.1.0 (23 cards: hotcrm 10, objectui 10, objectstack 3). Filed by the maintainer's account (os-steve) from the HotCRM pass driven in session session_01AwpXhq2nFKU6J7GmbCEmZu; ⛔ not a claim. Grade and routing are objectui triage's.

What is seen (HotCRM on @objectstack/console 18.1.0, 1440×900)

  1. Related tab, account Acme Corporation. Between 报价单 (2) and 活动 (7) sits a full-height row 「客户 0 · 暂无相关记录 · + 新建」 (child accounts), and after 活动 another 「线索 0 · 暂无相关记录 · + 新建」. With 26 related records in nine lists, two of the rows a reader scrolls past are empty. 50-account-related.png. Expected: empty lists fold to a one-line footer (「其他 2 个为空:客户、线索」) or sort last, keeping their 新建 action.
  2. record:path on an event. The stage bar has three stages 已计划 / 已举行 / 已取消 plus the terminal 客户未到; the last segment reads × 已取消 客户未到 in one narrow cell at the right edge while the first two stages take the width. 60-event-tall.png. The opportunity bar does the same with 成交 / × 失败, less visibly because it has seven stages. Expected: terminal states share the width equally or wrap, so each label is legible.

reach: the public UI, measured once as the dev admin.

Dedupe

MCP search_issues objectui "related tab empty related list with zero records still takes a row" → 6 hits (#13063, objectstack-ai/objectui#12870, objectstack-ai/objectui#12930, objectstack-ai/objectui#12245, objectstack-ai/objectui#11768, objectstack-ai/objectui#11613), none about empty-list layout; "record path stage bar terminal states cancelled no-show overlap cramped at the right" → 3 hits (#12965, objectstack-ai/objectui#5957, objectstack-ai/objectui#5916 — accessibility of the path, closed). Report: REPORT.md §4.2, §4.5.

Activity

  1. added
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    bugSomething isn't working
    and removed on Oct 25, 2026
  2. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    Contributor

    Triage: first grade — bug · priority:p3 · domain:ui · area:records · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-25T12:56Z

    ⛔ Not a claim, ⛔ not a dispatch. finding comes off.

    • Fold empty related lists (one line, or into the tab count), and give record:path's terminal stages their own cells.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    Contributor

    Transferred 2026-10-26T02:59Z from objectstack-ai/objectui#13519, with its comments and timeline; the old URL redirects here. objectui moved into this repository as the ui/ workspace (epic #25677) and is being archived (#25854). The body is left exactly as filed.

    Paths. The body names no file paths; the UI code it describes lives under ui/ here (the Console is ui/apps/console, the libraries ui/packages/*).

    References. The bare issue numbers in the body were written in objectui and now resolve against this repository by mistake; read them as objectstack-ai/objectui#5916, objectstack-ai/objectui#5957, objectstack-ai/objectui#11613, objectstack-ai/objectui#11768, objectstack-ai/objectui#12245, objectstack-ai/objectui#12870, objectstack-ai/objectui#12930, objectstack-ai/objectui#12965, objectstack-ai/objectui#13063.

    No stale pm:dispatched or assignee to strip.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 8 · 2026-10-27T00:54Z
    Session: session_01SMps7wq7rBTk53e8KTSEup
    Account: os-steve
    Branch: claude/issue-25895-related-empty-path-terminal
    Worktree: objectstack-issue-25895
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: ui/packages/plugin-detail/src/renderers/record-related-list.tsx and the Related-tab composition that stacks the lists (plugin-detail/src/synth/buildDefaultPageSchema.ts and/or app-shell/src/views/RecordDetailView.tsx, whichever owns the stack), ui/packages/plugin-detail/src/renderers/record-path.tsx, plugin-detail/src/useDetailTranslation.ts (fallback strings), tests beside them, scripts/sdui-manifest.sources/plugin-detail.json, root .changeset/. ⛔ DetailSection.tsx / HeaderHighlight.tsx (#25883, PR #26325), locale packs under ui/packages/i18n (on the i18n line behind #26326), ui/.github/**, root ci.yml.
    Container & model: M, mode:subagent, model: default tier, effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: a reader scrolling a record's Related tab, and a reader of a record's stage bar | RecordRelatedListComponent and RecordPathComponent rendering (no spec key) | every record page with related lists or a path
    Thread-read: none
    Premise: holds 2026-10-27T00:54Z at origin/main f02e644343, read from the card's two HotCRM shots: an empty related list takes a full row, and the path's terminal states share one narrow cell.
    Serial constraints cleared: seat 1's #26182 (PR #26277, record-related-list.tsx) MERGED 2026-10-27T00:52Z. No open PR touches these files. plugin-detail record: lands after #26325 (#25883).
    Writes: PR only via the relay op pr_create; comments only via the relay write tools; ⛔ no GitHub MCP writes.

    • Seat's route:
      • Item 1: on the Related tab, lists with zero records fold into one line after the non-empty lists, naming them and keeping each one's New action (the card's first expected shape). A list that loads later with rows unfolds. A page with only empty lists shows them as today.
      • Item 2: on the path bar, terminal states get legible width (share equally with the stages or wrap); each terminal label is readable at 1440 and at narrow widths.
      • New strings use useDetailTranslation's fallback defaults; locale-pack keys go to a follow-up after the i18n line drains. Say so in the PR.
      • Pin each item red-first. Fixes #25895.
  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 25895,
      "status": "done",
      "branch": "claude/issue-25895-related-empty-path-terminal",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26414",
      "head": "8271adf9d12b65cd5b740679c5187f6c27787866",
      "session": "session_01SMps7wq7rBTk53e8KTSEup",
      "premise_still_valid": true,
      "summary": "Item 1: record:related_list blocks that share a DOM container (the Related tab's page:tabs panel, or any authored container) coordinate through a small store in the new ui/packages/plugin-detail/src/RelatedListEmptyFold.tsx; once every list has answered and at least one has records, empty lists that offer only New are hidden in place (kept mounted) and the stack's last list draws one line naming them, each with its own New. RelatedList gains an optional onEmptyChange callback; the block keeps the last answer across a refetch. All-empty stacks, single lists and lists with add/toolbar actions/notices are unchanged; a folded list that gains a record unfolds. Item 2: record-path desktop rail groups grow by stage count from a zero basis and every stage is flex-1, so terminal stages get an equal share; terminal labels (won terminus and the alt group) wrap instead of truncating/nowrap. Seam chosen: the block itself, because the synthesizer (buildDefaultTabs) only emits children, page:tabs (components) draws them as plain siblings, and RecordDetailView only passes related; none knows row counts. No new i18n key: reuses detail.noRelatedRecords and detail.new; a dedicated count phrase is a follow-up for the locale packs.",
      "tests": "Red-first: tests committed aba3b5ca; red leg with the 3 impl files restored to base f02e6443 (markers counted 0): 9 failed / 3 passed (the 3 passing are CONTROL legs: all-empty stack, single list, ordinary forward stage); restore proven by blob hashes equal to HEAD; green leg 12/12. plugin-detail full suite at 5cf6e03e: 306 passed, 1 failed (spec-symbol-batch7: props type in renderers/ not spelled ...RendererProps) -> module moved to src/ in 47121545. Post-merge at 8271adf9 under the lock (VERDICT command-exit 0): spec build exit 0; spec-symbol-batch7 + all record-path*, record-related-list*, recordComponentAria*, RelatedList* tests: 59/59 files, 396/396 tests; plugin-detail type-check exit 0. Consumer set at 5cf6e03e (34 files under app-shell, apps/console, components that render record:related_list or empty related lists, incl. RecordDetailView related files, not the full app-shell suite): 34/34 files, 293/293 tests. gen-sdui-manifest at 5cf6e03e: sdui.manifest.json byte-unchanged (sha256 1f6e1ccb925a); the sources record it wrote was discarded per the seat (records retired by #26367).",
      "gates": "At head 8271adf9: dispatch-gates --commands --repo objectstack-ai/objectstack derived 35 families; all 35 run, each exit 0 (incl. node scripts/check-sdui-manifest.mjs and its --self-test); --ran reconciliation: 35 derived, 35 run, 0 NOT-MEASURED (derived zero, exit codes recorded). CI check-runs: in_progress / not yet read (draft just opened).",
      "line_budget": "7 files, +680 / -11 (691 changed lines) vs origin/main merge base b33dd25b; source +93 net in 3 existing files, new module 251 lines, tests 335 lines, changeset 13",
      "files_changed": [
        ".changeset/25895-related-empty-fold-path-terminal.md",
        "ui/packages/plugin-detail/src/RelatedList.tsx",
        "ui/packages/plugin-detail/src/RelatedListEmptyFold.tsx",
        "ui/packages/plugin-detail/src/renderers/record-path.tsx",
        "ui/packages/plugin-detail/src/renderers/record-related-list.tsx",
        "ui/packages/plugin-detail/src/renderers/__tests__/record-path.terminalWidth-25895.test.tsx",
        "ui/packages/plugin-detail/src/renderers/__tests__/record-related-list.emptyFold-25895.test.tsx"
      ],
      "deviations": [
        "File surface extended within plugin-detail: RelatedList.tsx (one optional prop onEmptyChange + one effect) and the new src/RelatedListEmptyFold.tsx; neither synth/buildDefaultPageSchema.ts nor app-shell is touched.",
        "No useDetailTranslation fallback strings were added: ui/scripts/check-i18n-call-site-keys.mjs refuses any t() key absent from the en pack (empty ratchet baseline; an inline defaultValue is explicitly not a fix), so a new key without the locale packs would red CI. Existing keys reused instead; the dedicated phrase is a follow-up.",
        "sdui sources re-record dropped per the seat's mid-run update (#26367 retired them); origin/main merged as merge commit 8271adf9."
      ],
      "dogfood_battery": "n/a - no ! in the PR title and Clause-2 is no with no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 - relay pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST issues/26414/assignees, one dispatch fw-20261027T025959Z-c3cbf6), and this os-dev-report comment (POST /repos/objectstack-ai/objectstack/issues/25895/comments via post-stamped). git push is not counted.",
      "open_questions": [
        {
          "question": "Fold line copy: reuse 'No related records found' + titles, or add a count phrase (e.g. 'N more with no records: A, B')?",
          "options": [
            "A keep the reused keys (no pack change)",
            "B add detail.relatedEmptyFold to all ten packs on the i18n line"
          ],
          "recommendation": "A now, B as the follow-up once the i18n line drains, because check:i18n-keys forbids a key the packs lack."
        }
      ],
      "out_of_scope_findings": [
        "class: none filed - RelatedList shows the empty state when its read FAILS (catch only logs), so a failed list also folds as empty; pre-existing read-path behaviour, noted in the PR Acceptance notes · carrier: none (承接者:无)"
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    Contributor

    Landed · seat 2 · 2026-10-27T05:02Z

    probe reading
    PR #26414 MERGED 2026-10-27T04:31Z, merge commit 775a0006, head 3fb46e57 (+680/−11, seat record on #26414)
    origin/main contains it (git merge-base --is-ancestor exit 0)
    queue branch gh-readonly-queue/main/pr-26414-*: none left (consumed)
    card closed (completed) by Fixes #25895 on #26414

    Status: on the Related tab, empty lists that offer only New fold into one line after the lists with records, each keeping its New; the path bar gives terminal stages an equal share with wrapping labels. A failed related read still shows as empty and now folds too: #26415. pm:dispatched removed.

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

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingdomain:uipriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions