Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Page element blocks draw English or bare-glyph placeholders while they load: element:repeater prints a hard-coded "Loading…" (no i18n key) and element:number prints "…" — a zh-CN control-plane home shows both on every load #12889

Closed

Description

@objectstack-fleet

Filing gate ①: a measured defect with named sites. Filed by repo:cloud seat 2 (seat post objectstack-ai/objectstack#24145, session session_01Cbdek8SKSHxddGqTPZXdqX) from the cloud#2915 dev's measured split (its report on objectstack-ai/cloud#2915; cloud PR objectstack-ai/cloud#2972 fixes cloud's half and adds no override for these). ⛔ Not a claim; no assignee. Grading is triage's.

Reader who acts: the lane that owns packages/components/src/renderers/basic/ (one dev round). Pull: objectstack-ai/cloud#2915 Target 1 (the maintainer's 2026-10-16 walk, zh-CN): "Loading placeholders in the page's language: the home hero's 'Loading…' becomes the translated string or a skeleton bar; '•••' becomes a skeleton of the number's width."

Dedupe: REST enumeration of this repository's issues updated since 2026-08-15 (735 issues, open and closed; control objectui#12294 found), grepped for data-list.tsx, repeater … Loading, elements.tsx:6xx, element:number … loading, UserFilters, raw field name, ConnectionStatus, 已连接. The nearest hits: objectui#11880 (page elements bind through node-level dataSource), #12345 (the repeater's retired flat spec), #12784 (the date-range chip's hard-coded From / To), #12295 (the chip never shows a mid-session outage) and the open parent #12308. None names this.

What happens (read at ef71a09f9e5f, cloud's objectui pin; the walk's screenshot cloud-home-loading-english.jpg on objectui d7be5db2e shows it)

  1. element:repeater: packages/components/src/renderers/basic/data-list.tsx:237 returns <p …>Loading…</p> — a literal with no t() and no key — while the repeater's find runs. The zh bundle already has common.loading: '加载中…' (packages/i18n/src/locales/zh.ts:96); the repeater does not read it. Same family on the same component: :240 prints 'No records' as the empty default and :219 'Failed to load'; packages/react/src/element-data-source/ElementDataSourceGate.tsx:665 prints 'Loading view…' while a named view resolves.
  2. element:number: packages/components/src/renderers/basic/elements.tsx:650 renders {loading ? '…' : formatValue(…)}: a U+2026 at the number's 24 px / 600 style, which reads as "•••" in the card.
  3. On cloud's home (packages/service-tenant/src/pages/welcome.page.ts): two repeaters under the hero (welcome_env_hostname, welcome_env_installs) and three numbers in the 成员 and 套餐与用量 cards (welcome_members_count, welcome_plan_ai_week, welcome_plan_storage). Cloud declares no loading text for any of them.

Wanted

The repeater's loading, empty and error defaults read from the i18n bundle (or the loading state is a skeleton, as CloudOnboardingNext.tsx:160-166 already draws); a loading element:number draws a skeleton of the number's width instead of a glyph. Done when a zh-CN render of a repeater and a number with a pending dataSource shows no English and no bare glyph, pinned by tests beside the two renderers.

Dedupe words: repeater Loading literal, data-list loading i18n, element:number loading ellipsis, metric placeholder skeleton, untranslated Loading…

Activity

  1. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: p2 · area:i18n · domain:ui · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-17T14:54Z

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch.

    • Fresh read on objectui origin/main d2b21a1225: every site holds, with lines shifted from ef71a09f9e5f:
      • packages/components/src/renderers/basic/data-list.tsx: :237 Loading…, :240 'No records' and :219 'Failed to load', none of them through t();
      • packages/components/src/renderers/basic/elements.tsx:674: {loading ? '…' : formatValue(…)};
      • packages/react/src/element-data-source/ElementDataSourceGate.tsx:665: Loading view&hellip;.
    • Grade p2. This is the objectui half of the maintainer's 2026-10-16 walk (cloud#2915, p2, closed with cloud's half in objectstack-ai/cloud#2972). It shows on every load of a zh-CN control-plane home.
    • Scope = the card's Wanted, as one round. It covers the whole family above, not only the two sites the walk saw.
      • The repeater's loading, empty and error defaults read the existing bundle keys (common.loading and the like), or the loading state draws a skeleton.
      • A loading element:number draws a skeleton of the number's width.
      • ⛔ No new widget. An authored emptyText still wins.
    • Lane: domain:ui (packages/components/src/renderers/basic/).

    Generated by Claude Code

  2. added
    area:i18nThe customer's own language, across UI, metadata and notifications
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Oct 17, 2026
  3. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 (priority:p2, triage scope 6235370635)
    Session: session_01XVp19E1MYUTFM3dnkwz8gB
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12889-element-loading-copy
    Worktree: objectui-issue-12889
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: packages/components/src/renderers/basic/data-list.tsx (the repeater's loading, empty and error defaults read existing bundle keys, or loading draws a skeleton; an authored emptyText still wins); packages/components/src/renderers/basic/elements.tsx (a loading element:number draws a skeleton of the number's width, not a glyph); packages/react/src/element-data-source/ElementDataSourceGate.tsx (the Loading view… literal reads the bundle); packages/i18n/src/locales/*.ts (new keys only if no existing key fits, all ten packs); tests beside the renderers; one .changeset/12889-*.md. ⛔ No new widget. Stop on breach; explain in the report.
    Container & model: S, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui reads no path-derived mandate)
    Clause-②: no
    Responsibility: objectui's own page-element renderers, which print English literals and a bare glyph while loading | the i18n bundle already carries common.loading | every zh-CN viewer of a page with a repeater or number element, today (the control-plane home)
    Thread-read: 6235370635
    Serial constraints cleared: no open objectui PR touches these three files, and no pm:dispatched claim names them (read at claim). This seat's objectui#12890 (packages/plugin-list) and objectui#12892 (apps/console) are disjoint.
    Claimed at: 2026-10-17T16:06Z

  4. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12889,
      "status": "done",
      "branch": "claude/issue-12889-element-loading-copy",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12909",
      "session": "session_01XVp19E1MYUTFM3dnkwz8gB — the parent's id (mode:subagent)",
      "premise_still_valid": true,
      "summary": "All five sites on origin/main c999d4c017 held as the card described. The work was done as one round, and all three files read copy through useObjectTranslation from @object-ui/i18n. elements.tsx already used that hook for element.number.noObject; ElementDataSourceGate.tsx used it for view.malformedFilter and view.noObject; the components package also uses it in record-picker.tsx. The repeater now reads common.loading, common.noData and list.loadErrorTitle. An authored emptyText still wins and a thrown message is still shown as thrown. A loading element:number draws the Skeleton primitive (role=status, aria-label = common.loading) instead of the bare ellipsis glyph. ElementDataSourceLoadingPanel reads common.loading instead of 'Loading view…'. All four keys already existed in all ten packs, so no new key, prop, widget or export was added. Two English strings changed: the repeater's empty text went from 'No records' to 'No data', and the view placeholder went from 'Loading view…' to 'Loading…'. Three existing 'No records' assertions were updated to match.",
      "tests": "All runs at head 74a80e8e2f. Closure build: pnpm --workspace-concurrency=2 --filter '@object-ui/components^...' run build, VERDICT command-exit 0 (8 of 47 projects). Type-check: --filter @object-ui/components --filter @object-ui/react run type-check, exit 0; both packages' tsconfig.test.json include src/**/*.test.tsx. Targeted vitest (2 new + 3 edited files): 5 files, 33/33 passed. packages/react/ whole dir: 114 files, 1429 tests passed. packages/components/ whole dir: NOT MEASURED, reason: 405 files is more than the foreground limit allows under the shared lock (the lock queue was over 20 min behind an orphaned apps/console vitest holder, pid 25188). Declared narrowing instead: all of renderers/basic plus every repo test file naming the touched renderers or the panel, 84 files and 3552 tests passed; the full dir is left to CI. Ablation: I put the repeater's Loading literal back with objectstack's scripts/ablation-replace.mjs (wrapped mode). It landed (blob fe0a34049038 -> bb1a25003189) and pin (a) went red: 'expected Loading… to be 加载中…', 1 failed | 7 passed. Restore proven: blob == HEAD fe0a34049038 and git diff HEAD empty, re-checked with git hash-object. The first ablation attempt was a no-op that the tool refused before any test ran, because the replacement count could not rise. Lint: eslint --no-inline-config --format json over the 8 changed ts/tsx files gave 8 files, 0 errors; the 39 warnings all predate this change. Config has no parserOptions.project or projectService, so linting is not type-aware and untouched files' verdicts are invariant. Battery, all exit 0: check:phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, i18n-dead-keys, control-bytes; check-hand-rolled-comment-mask, check-changeset-fixed and check-changeset-presence. check:spec-floors was not run (named as may-red-on-main; not in the required list). CI: in_progress at report time.",
      "mcp_calls": "0",
      "api_writes": "2 — 1 relay stroke pr_create (POST /repos/objectstack-ai/objectui/pulls + POST issues/12909/assignees) via fleet-write dispatch (POST /repos/objectstack-ai/objectstack/dispatches); 1 os-dev-report comment (POST /repos/objectstack-ai/objectui/issues/12889/comments) via the same relay. Plus 2 git pushes (not REST). Labels: zero writes, because the dispatch named none and objectui path labels belong to labeler.yml.",
      "gates": {"build_closure": 0, "type-check": 0, "vitest_targeted": 0, "vitest_react_dir": 0, "vitest_components_dir": "NOT MEASURED (narrowed: 84 files / 3552 tests exit 0)", "eslint_changed_files": 0, "check:phantom-deps": 0, "check:self-import": 0, "check:unreferenced-sources": 0, "check:doc-example-readers": 0, "check:handler-key-reads": 0, "check:side-effects-array": 0, "check:element-data-source-declaration": 0, "check:spec-symbols": 0, "check:action-forward-parity": 0, "check:designer-field-key-parity": 0, "check:icon-record-names": 0, "check:i18n-keys": 0, "check:i18n-drift": 0, "check:i18n-designer-parity": 0, "check:i18n-dead-keys": 0, "check:control-bytes": 0, "check-hand-rolled-comment-mask": 0, "check-changeset-fixed": 0, "check-changeset-presence": 0},
      "files_changed": [".changeset/12889-element-loading-copy.md", "packages/components/src/renderers/basic/data-list.tsx", "packages/components/src/renderers/basic/elements.tsx", "packages/react/src/element-data-source/ElementDataSourceGate.tsx", "packages/components/src/renderers/basic/__tests__/element-loading-copy-12889.test.tsx", "packages/react/src/element-data-source/__tests__/ElementDataSourceLoadingPanel.i18n-12889.test.tsx", "packages/components/src/renderers/basic/__tests__/data-list.contractEnvelope-6726.test.tsx", "packages/components/src/renderers/basic/__tests__/data-list.elementDataSource-11880.test.tsx", "packages/components/src/renderers/basic/__tests__/element-number.contractEnvelope-6726.test.tsx"],
      "deviations": ["Three existing test files beside the renderer were edited: two 'No records' assertions became 'No data', and one stale code comment about the old glyph was updated. These are tests beside the renderers, inside the surface, but they are edits to existing tests, not only new ones.", "No locales file was touched (no new key was needed)."],
      "line_budget": "not applicable (no skills/** or governed ledger touched)",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a · reach: public door — element:record_picker renders English under zh-CN. The existing pin record-picker-empty-text-i18n.test.tsx 'keeps the No records default for an ABSENT key' renders 'No records' under zh-CN. record-picker.tsx also prints the input placeholder 'Loading…' / 'Failed to load' as literals · same family as this card; outside the claimed file surface · dedupe: record_picker No records literal, record picker loading placeholder i18n, Failed to load placeholder",
        "carrier: whoever next touches packages/components/src/renderers/basic/elements.tsx (answer if none: 承接者:无) · element:number's error fallback 'aggregate failed' and the error-panel title 'This metric’s data source could not be resolved' are English literals; same family, not in this card's ruling · noted, not filed",
        "carrier: whoever next touches packages/components/src/renderers/basic/data-list.tsx (answer if none: 承接者:无) · element:definition-list's empty state 'No details' is an English literal; same family, not in this card's ruling · noted, not filed"
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT — objectui PR #12909 · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-17T17:38Z

    Reviewed on GitHub at head 74a80e8, against the card's Wanted, the triage scope (6235370635) and the claim (6236319631).

    • Shape: the body says Fixes #12889; the second line is Clause-②: no. The changeset is @object-ui/components and @object-ui/react: patch. No key, prop, widget or export is added.

    • The change, one round over the whole family, every site reading through useObjectTranslation (A1: elements.tsx and ElementDataSourceGate.tsx already used it):

      • element:repeater (data-list.tsx):
        • loading reads common.loading;
        • empty reads common.noData, and an authored emptyText still wins;
        • a failure without a message reads list.loadErrorTitle, and a thrown message is still shown as thrown.
      • element:number (elements.tsx): while loading it draws the Skeleton primitive, a status region named by common.loading, instead of the bare … glyph.
      • The saved-view placeholder (ElementDataSourceLoadingPanel): it reads common.loading instead of "Loading view…".
      • Two English strings move: the repeater's empty default goes from "No records" to "No data" (reusing the existing key, as ruled), and the view placeholder goes from "Loading view…" to "Loading…". Three existing assertions on "No records" move with it.
    • Pins: element-loading-copy-12889 and ElementDataSourceLoadingPanel.i18n-12889 cover:

      • under zh, the repeater's loading, empty and error defaults read the zh pack;
      • a loading number draws the skeleton and no glyph;
      • the gate's pending view reads the zh pack;
      • CONTROL: an authored emptyText wins, and en reads sensibly.

      Ablation: restoring the repeater's "Loading…" literal turns the zh loading case red; the restore was proven by blob hash. packages/react (114 files, 1429 tests) is green. packages/components was narrowed and declared: all of renderers/basic plus every test naming the touched renderers or the panel (84 files, 3552 tests); its full directory is CI's. Type-check and the i18n gates exit 0.

    • Out-of-scope findings: element:record_picker's "No records" / "Loading…" / "Failed to load", element:number's error copy and element:definition-list's "No details" are filed as one family close-out card, objectui#12910 (class (a): the picker's empty default reaches a zh-CN page).

    • Trailers: the commit carries only the model-free pair.

    • CI at head: 33 success, 3 skipped, 0 failures (filter=latest, 36 runs), including the full packages/components directory across the test shards and Bundle Analysis (performance budget PASS). Not governed (path audit).

    Next: pr_ready + automerge_enable.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-17T17:51Z

    PR #12909 merged through the merge queue as 9753811, which is on main; Fixes #12889 closed this card. Verified by content: all 9 of the PR's files on main are blob-identical to the accepted head 74a80e8. The merge commit's message names no model.

    What landed:

    • element:repeater's loading, empty and error defaults read common.loading, common.noData and list.loadErrorTitle; an authored emptyText still wins.
    • A loading element:number draws a skeleton bar (a status region named by common.loading) instead of a bare ….
    • The saved-view placeholder reads common.loading instead of "Loading view…".
    • Released as @object-ui/components and @object-ui/react: patch.

    The family's remaining English defaults (element:record_picker, element:number's error copy, element:definition-list's empty state) are objectui#12910. For objectstack-ai/cloud#2915 Target 1: cloud sees this once its .objectui-sha covers the merge commit above. This seat now removes pm:dispatched.


    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

Labels

area:i18nThe customer's own language, across UI, metadata and notificationsdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions