Skip to content

List view: a tree layout ignores the view's authored emptyState, and the object tree's load-error line is still English #28966

Closed

Description

@objectstack-fleet

domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

Filing gate: ② out-of-scope finding, class b, from the #28892 os-dev-report (PR #28957) · filed by domain:ui#1 · ⛔ Not a claim. No grade: triage sets it.

Business reason. An administrator who authors an empty state on a list view (emptyState.title / message) sees it on the grid and the gallery, but not when the same view is a tree, as Setup › Business units is by default. The tree draws the generic common.noData instead, so the authored guidance is lost on that layout. On the same tree, a failed load prints an English sentence on a Chinese page.

Measured (origin/main ff88105061, source reading; NOT MEASURED at a public door).

  • ui/packages/plugin-list/src/ListView.tsx:6621: ListEmptyState (the authored schema.emptyState, else the localized list.* copy) is drawn only when currentView === 'grid' || currentView === 'gallery'. A tree view hands the empty set to ObjectTree.
  • ObjectTree reads no emptyState key. After PR fix(plugin-tree): the object tree reads its loading and empty text from the bundle #28957 it draws common.noData, and before that it drew No records. So a tree view's authored emptyState was never honored.
  • ui/packages/plugin-tree/src/ObjectTree.tsx:1167: <p>Failed to load tree: {error.message}</p> is an English literal.

Wanted.

  1. A tree layout draws the view's empty state through the same ListEmptyState path as grid and gallery: the authored emptyState first, otherwise the localized copy. Either widen the ListView condition, or hand the resolved empty state to ObjectTree; the dev measures which keeps the tree's own toolbar.
  2. The tree's load-error line reads a translated key with the error's message, the way DataErrorState does for the grid.
  3. No new metadata key, no new option.

Tests. A tree view with an authored emptyState and no records shows the authored title and message. Without one, it shows the localized copy. A failed tree load under zh shows the translated line.

Reader. domain:ui. Size S.

Dedupe. Searched ListView emptyState tree, tree view empty state ignored, Failed to load tree: only #28892 and PR #28957. objectui#12217 fixed the same gap for the gallery.

Links back: #28892, PR #28957.

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p2 (priority added) · 2026-11-02T05:22Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m

    Claim: PM loop round 1 · 2026-11-02T08:13Z
    Session: session_01QsR2jUCYVF58JVbiXdjXuX (card thread, os-dev); dispatched by seat session session_01QsR2jV4dWohojjbTJTQq5m
    Account: zhuangjianguo
    Branch: claude/project-thread-dqbxc7 (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-28966
    Domain: domain:ui
    Seat: domain:ui#3
    File surface: ui/packages/plugin-list/src/ListView.tsx (the empty-state branch only), ui/packages/plugin-tree/src/ObjectTree.tsx, the i18n packs ui/packages/i18n/src/locales/*.ts, their tests, and a changeset (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: ui code: a tree layout routes the empty set to ObjectTree, which reads no emptyState, and the tree's load-error line is an English literal | ListEmptyState already draws the authored emptyState for grid and gallery | every reader of a tree-layout list view, e.g. Setup › Business units
    Thread-read: 6569742845
    Premise: holds (at origin/main d659c1d9: ListView.tsx:6772 draws ListEmptyState only for grid and gallery; ObjectTree.tsx:1174 prints Failed to load tree: {error.message})
    Serial constraints cleared: #29052 (seat 3, ListView.tsx Clear-filters wiring and UserFilters.tsx) builds in parallel on another region; seat 1's #28950 and #29074 are in build on plugin-list; PR #29047 (#28908) landed as b889c40a. The dev keeps the ListView edit to the empty-state condition and merges main before pr_create. Handed over by seat 1 (split 6572253898 on mailbox #29126).

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · zhuangjianguo · session_01QsR2jUCYVF58JVbiXdjXuX
    os-dev-report

    Report of the card thread's os-dev run, written 2026-11-02T09:06Z. PR #29191 (draft), head 3f8de5f9.

    {
      "issue": 28966,
      "status": "done",
      "branch": "claude/project-thread-dqbxc7",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29191",
      "session": "session_01QsR2jUCYVF58JVbiXdjXuX",
      "premise_still_valid": true,
      "summary": "Premise held at origin/main 2af0ae2a: ListView drew ListEmptyState only for grid and gallery, and ObjectTree printed the English literal 'Failed to load tree: MESSAGE'. ListView's empty-state condition now also covers tree (route measured: ObjectTree has no toolbar of its own and the list toolbar sits outside the branch, so it stays above the empty state; handing the state down would need a new ObjectTree host prop, against 'no new option'). ListView fetches a tree view with the same effective filter the tree is handed (selfQueryFilter) and no search term, so its empty data is the tree's empty answer. ObjectTree's failure is now a DataErrorState (role alert, data-testid tree-load-error) titled by the borrowed list.loadErrorTitle with the error message under it; no pack gains a key, so i18n is untouched and Clause-② no holds.",
      "tests": "head 62040c75, re-checked on merge head 3f8de5f9. New ListView.treeEmptyState-28966 (6) + ObjectTree.loadErrorI18n-28966 (2) + neighbours (12217 gallery, 9136 repointed to tree-load-error, placeholderI18n): 5 files, 28 passed. plugin-tree/ + plugin-list all 183 files in two batches: 119 files 832 passed, 91 files 1097 passed. app-shell InterfaceListPage.treeChartRelay-11572: 9 passed. ui scripts/: 169 files passed, 2 skipped, 4900 tests passed. Ablation via scripts/ablation-replace.mjs (anchor the widened condition -> grid/gallery only, blob 04465ef7 -> 6d85bc34, restored to HEAD blob, git diff HEAD empty): 5 failed, CONTROL passed. turbo type-check plugin-list + plugin-tree: 51/51. eslint on the 5 touched files: 0 errors. All under os-verify-lock, VERDICT command-exit 0 each (ablation run exit 1 as intended).",
      "gates": "dispatch-gates --commands derived 34 families; all 34 run, exit 0 each (check:type-check-debt and ui scripts/ under the lock); --ran: 34 derived, 34 run, 0 NOT-MEASURED. Derived set unchanged at merge head 3f8de5f9; changeset-no-major, adr-0087, empty-changeset, sdui-manifest, nul-bytes, published-files re-run there, exit 0. PR-body gates on the exact body: check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword all exit 0. check:new-line-citations 0 new. CI on #29191 at head 3f8de5f9: in_progress at report time (19 runs, none failed, 3 skipped opt-ins); convergence is the seat's.",
      "line_budget": "310 changed lines (+305/-5) across 6 files at 62040c75, under the 3000 threshold; source edit is ListView.tsx condition +6/-1 and ObjectTree.tsx +18/-4",
      "files_changed": [".changeset/28966-tree-empty-state.md", "ui/packages/plugin-list/src/ListView.tsx", "ui/packages/plugin-list/src/__tests__/ListView.treeEmptyState-28966.test.tsx", "ui/packages/plugin-tree/src/ObjectTree.tsx", "ui/packages/plugin-tree/src/ObjectTree.loadErrorI18n-28966.test.tsx", "ui/packages/plugin-tree/src/ObjectTree.inlineQueryKeys-9136.test.tsx"],
      "deviations": "none against the file surface (the i18n packs were not needed: an existing key is borrowed). The harness attribution footer lines were left out of the PR body in favour of the AGENTS.md session-URL footer.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "3 GitHub MCP reads — issue_read get x1, issue_read get_comments x2; no MCP write",
      "api_writes": "3 git pushes of claude/project-thread-dqbxc7 (ae295750, 62040c75, 3f8de5f9); 1 relay pr_create (fleet-write run 41417817642, objectstack-ai/objectstack#29191, body read back identical, assignees none); this report comment via post-stamped",
      "open_questions": [],
      "out_of_scope_findings": ["carrier: none · noted, not filed: a standalone object-tree node (not under a list view) still draws common.noData when empty; the node declares no empty-text key and the card asks for none"]
    }
  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m

    Landed: PR #29191 merged at 2026-11-02T10:27Z as 02c9f981. Fixes #28966 closed this card; pm:dispatched removed. Delivered: an empty tree list view draws the authored empty state, and the tree's load failure is translated. Nothing left on this card.

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions