Skip to content

fix(console): a nav entry with no icon draws its object's icon, record labels in one style, a small count axis fits, a failed entry load retries (#30126) - #30573

Merged
objectstack-fleet[bot] merged 11 commits into
mainfrom
claude/project-thread-cfhyia
Nov 5, 2026
Merged

objectstack-fleet[bot] merged 11 commits into
mainfrom
claude/project-thread-cfhyia

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Sales · project thread

Part of #30126

Clause-②: yes (widening)
Metadata-protocol: none

维护者速读

  1. What: the console rows of Console and CLI polish from the real-user walkthrough #30126 that still reproduce on main and are fixed in ui/**: rows 4, 6, 11 and 14. Rows 5 and 10 do not reproduce (readings below). Row 8 reproduces, but its fix is a server object definition, outside this PR.
  2. Row 4: an object nav entry with no icon draws the icon its object declares, in the sidebar and in the nav:menu block. It reads the object by name from metadata the console already holds, adds no request and writes nothing to the navigation.
  3. Row 6: a record section's field labels drop the uppercase transform, so REPAIR COST no longer reads in capitals beside 负责人. They now use the highlights strip's label class.
  4. Row 11: a count axis whose largest value is 1 to 3 tops out at that value, so one record's bar is full height (362×71 → 362×282 px).
  5. Row 14: an entry script that fails to load before mount makes the page reload itself, backing off from 1 s and doubling (1/2/4/8/16 s), at most 5 times per tab. Before, the splash stayed forever.
  6. Contract: @object-ui/layout gains resolveNavItemIcon, NavIconTarget, NavTargetIconResolver and an optional resolveTargetIcon prop on NavigationRenderer, which mirrors resolveTargetLabel. That is a widening, so Clause-②: yes (widening) (the claim said no, and the seat corrects it). No metadata key, no i18n key, nothing under packages/**.

What changes

  • ui/packages/layout/src/NavigationRenderer.tsx: resolveNavItemIcon(item, resolver) returns the authored icon; failing that, for an object entry, the resolver's answer; otherwise undefined (the generic icon). The leaf row, including rows inside groups, draws it.
  • ui/packages/app-shell/src/hooks/useNavTargetIcon.ts (new): the console's resolver. It reads readObjectsByName from the metadata cache, the same by-name read the entry's label already makes. It is wired into UnifiedSidebar (app arm) and nav-menu-renderer, and added to the openPathObjectReaders-12811 census as a byName reader.
  • ui/packages/plugin-detail/src/DetailSection.tsx: the field label class goes from text-xs font-medium text-muted-foreground uppercase tracking-wide to text-xs font-medium text-muted-foreground (the HeaderHighlight label class).
  • ui/packages/plugin-charts/src/normalizeChartSchema.ts + AdvancedChartImpl.tsx: wholeNumberTickCount(axis, values) gives max + 1 ticks when every value is a non-negative integer, 1 ≤ max ≤ 3, and the axis has no authored min/max/stepSize. Otherwise it returns undefined, and the axis is drawn as before. This is not exported from the package index.
  • ui/apps/console/index.html: the boot splash adds a capture error listener for a failed type=module entry script before mount. It keeps a per-tab retry count in sessionStorage (os-boot-entry-retries, max 5), backs off 1/2/4/8/16 s, clears the count on mount, and does not retry where storage is blocked. The splash still ships no copy.

Row readings (real stack, origin/main c045c341, showcase app, zh, 1440×900 unless noted)

row before after
4 sidebar icons all 6 Walkthrough rows file-text (shot) folder-kanban / check-square / building / receipt, the dashboard row stays file-text (shot)
5 Setup collapsed sidebar not reproduced: hovering a collapsed icon shows its tooltip, both collapsed by hand at 1440 (shot) and on the auto rail at 1280 (shot, tooltip Users). The Setup labels are English in zh, which belongs to #30504. no change
6 record labels Field Zoo: 负责人 beside EMAIL / PHONE (shot); en project record: OWNER EMAIL, SPENT, START DATE in capitals (shot) one style, as authored (shot)
8 inbox topic reproduces: the sys_inbox_message view mine shows the raw topic notify (list, popover). The column list is in packages/services/service-messaging/src/objects/inbox-message.object.ts, outside ui/**, so it is left for the server lane. no change
10 toast over assignee not reproduced: 1440 page: toast y53–107, assignee y249–291 (shot); 1440 drawer: toast x340, drawer from x720 (shot); 1024 drawer: toast y136–190, assignee y249 (shot) no change
11 one-bar count axis 0–4, bar 362×71 in a 510×350 plot (shot) axis 0–1, bar 362×282 (shot)
14 entry fails backend down after the HTML loads already reads "无法连接到服务器" + 重试 (shot); an entry module that fails to load left the splash forever (shot) 2 aborted entry loads: recovered on load 3, about 15 s (shot); every load aborted: gives up after 6 loads, splash stays (shot)

Row 14 was emulated with a Playwright route abort on the entry chunk, not with a real os dev restart.

Tests

  • ui/packages/layout/src/__tests__/NavigationRenderer.iconInheritsObject-30126.test.tsx (5): the resolver's precedence and controls, plus rows at the top level and in a group.
  • ui/packages/app-shell/src/views/__tests__/nav-icon-inherits-object-30126.render.test.tsx (3): both surfaces against one MetadataCtx. It checks that an authored icon stays, an object with no icon and a dashboard entry keep the generic glyph, and a changed object icon shows on rerender with the navigation unchanged.
  • ui/packages/plugin-detail/src/__tests__/DetailSection.labelStyle-30126.test.tsx (2): Latin and CJK labels share one class with no uppercase, and match the highlights strip.
  • ChartRenderer.integerMeasureTicks-11681.test.tsx: plus 6 tests for the small-count axis and its controls (fractional, count ≥ 4, authored max).
  • apps/console/src/__tests__/bootSplash.test.ts: plus 5 tests for the retry, back-off, cap, reset on mount, and storage blocked.
  • Ablations, each reverted with the restore diff at 0 lines, and each turned its tests red: the sidebar leaf back to item.icon, the nav:menu row back to item.icon, uppercase restored on the section label, the axis tickCount spread dropped, the splash's location.reload() removed, and the reset of the retry count on mount removed.

Verification

  • Type-check exit 0: @object-ui/layout, plugin-detail, plugin-charts, app-shell (re-run after the main merge), console.
  • eslint on the 14 changed source/test files: 0 errors (warnings pre-existing; the one new any warning in bootSplash.test.ts fixed).
  • node scripts/pm/dispatch-gates.mjs --commands: 36 derived families plus pnpm --dir ui run check:new-line-citations, all exit 0. pnpm --dir ui exec vitest run scripts/ was OOM-killed beside the loop and passed run alone: 170 files passed (2 skipped), 4985 tests.
  • After merging origin/main (f33b094f): vitest run packages/layout/ packages/plugin-detail/ packages/plugin-charts/ apps/console/src/__tests__/ packages/app-shell/src/layout/ packages/app-shell/src/views/__tests__/ packages/app-shell/src/hooks/ + the openPathObjectReaders-12811 census: 923 files passed (1 skipped), 8557 tests passed (27 skipped).
  • Evidence: shots at a0ade7b6 (evidence/30126/, removed from the tree by the next commit).

Acceptance notes

  • Open question for the seat (row 11): the one bar is still 362 px wide. Capping maxBarSize would change every bar chart, so it was left alone.
  • Row 8's fix (columns of view mine) and rows 9, 12, 13, 15, 16 stay on the card.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L6bhgVUJuSB1qgbeFwydba

claude added 10 commits November 5, 2026 15:07
…d field labels in one style

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6bhgVUJuSB1qgbeFwydba
…he next commit)

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6bhgVUJuSB1qgbeFwydba
@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 5, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#4 · os-sales · session_01L6bhgVfPeFZkN1FP93imKU

维护者速读

  • 改了什么:Console and CLI polish from the real-user walkthrough #30126 的四行控制台问题。第 4 行:没写 icon 的 object 导航项改画它对象自己的图标,侧边栏和 nav:menu 都是。第 6 行:记录页分区字段标签去掉大写变换,中文旁的英文标签不再全大写。第 11 行:计数图最大值是 1 到 3 时纵轴顶到这个数,一条值为 1 的柱子画满高度,不再停在 0–4 轴的四分之一。第 14 行:入口脚本在挂载前加载失败时页面自己重载,从 1 秒起翻倍,每个标签页最多 5 次,挂载后清零。
  • 为什么改:Console and CLI polish from the real-user walkthrough #30126 的维护者走查。第 5、10 行实测不复现,第 8 行能复现但改法在 packages/services/service-messaging,不在 ui。
  • 风险与回滚:图标只读控制台已有的元数据缓存,不加请求、不写导航;手写的 icon 永远优先。计数轴只在没有手写 min/max/stepSize、值全是非负整数且最大值 1–3 时改。重载只在 sessionStorage 可用时进行,读不到就不重试,最多 5 次后照旧停在加载画面。@object-ui/layout 新增导出 resolveNavItemIcon、类型 NavIconTarget 与 NavTargetIconResolver,NavigationRenderer 新增可选 prop resolveTargetIcon(Clause-② yes,加宽),五个包 changeset 都是 patch。回滚即撤本 PR。
  • 先看:ui/packages/layout/src/NavigationRenderer.tsx 的 resolveNavItemIcon;ui/packages/app-shell/src/hooks/useNavTargetIcon.ts;ui/apps/console/index.html 的重试监听;ui/packages/plugin-charts/src/normalizeChartSchema.ts 的 wholeNumberTickCount。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/layout/src/__tests__/NavigationRenderer.iconInheritsObject-30126.test.tsx packages/app-shell/src/views/__tests__/nav-icon-inherits-object-30126.render.test.tsx packages/plugin-detail/src/__tests__/DetailSection.labelStyle-30126.test.tsx,预期 10 passed。
  • 需要你做的:无,席位落地。
  • 席位意见:可合。

席位核对 — ACCEPT · head e6792b4

  • 形态:15 文件 +736/−10(源码 8 个文件 +198/−10:NavigationRenderer.tsx +55/−1、useNavTargetIcon.ts +40、nav-menu-renderer.tsx +6/−1、UnifiedSidebar.tsx +3、DetailSection.tsx +4/−1、normalizeChartSchema.ts +26、AdvancedChartImpl.tsx +15/−5、index.html +49/−2;测试与对象读取普查一行;changeset 一份,@object-ui/layout、app-shell、plugin-detail、plugin-charts、console 各 patch)。check-governed-merges --pr 30573:NOT governed,746 行 ≤ 3000。Part of #30126,draft,目标 main,标题无 !。证据截图提交 a0ade7b6 已由 d3e5ad7b 移除,树上没有 evidence/。
  • 复核面:TIER_DEFAULT(声明面:Clause-②: yes (widening),@object-ui/layout 经 export * from './NavigationRenderer' 新增一个函数、两个类型,NavigationRendererProps 新增可选 resolveTargetIcon;没有 packages/spec 路径、没有受管路径、没有收窄;Metadata-protocol: none),由本席在此写出。认领行已由修正 6663386410 改为 yes,文件面不变。
  • 席位逐行读:resolveNavItemIcon 先认手写 icon(非空串),再对 object 项问 resolver,答空就回 undefined,由 resolveIcon 画通用图标;分隔符直接 undefined。useNavTargetIcon 用 readObjectsByName 从壳已有的元数据缓存按名读,与同一项取标签走同一条读,对象读取普查 openPathObjectReaders-12811 已按 byName 登记。侧边栏与 nav:menu 都接上,两处不会给同一项两种图标。DetailSection 只删 uppercase tracking-wide,与上方 highlights 同款。wholeNumberTickCount 在有手写轴、有负数或小数、无数据、最大值 ≥ 4 时都返回 undefined,即 recharts 原样。index.html 的捕获阶段 error 监听只认挂载前失败的 type=module 带 src 脚本;计数存在 sessionStorage,读不到返回 null 就不重试;间隔 1000 * 2^tries;首次挂载由已有的 MutationObserver 清零。
  • 前提实测:dev 报告 6663325262。每行先在 origin/main c045c341 真栈(showcase objectstack dev --seed-admin + console vite,zh,1440×900)实测:第 4 行改前 6 行全是 file-text,改后各画对象图标,dashboard 行仍通用;第 6 行 负责人 旁的 EMAIL 改前全大写;第 11 行改前轴 0–4、柱高 71,改后轴 0–1、柱高 282;第 14 行用 Playwright 模拟入口加载失败,改前停在加载画面。第 5 行(收起的 Setup 侧边栏悬停有提示)与第 10 行(提示与指派人不重叠)读数在报告里,未改。新测试:图标 5 + 3、标签 2、计数轴 +6、启动画面 +5;消融六腿(侧边栏退回 item.icon 4 红、nav:menu 退回、恢复大写 3 红、去掉 tickCount、去掉 location.reload、去掉挂载清零)各自转红后还原。合并 main 后相关目录 923 文件 8557 例绿;派生门禁 36 条全部 exit 0;五个包 type-check exit 0。
  • 门禁 check-runs:head 上 55 个(按名取最新一次),42 success,13 skipped,0 红;check-expected-skips --pr 30573:13 个跳过全在 main 的名册里(ui-only diff 的预期跳过,exit 0)。Build & E2E UI、Live E2E UI、Lint UI、Test UI 16 片与汇总、Type Check UI 与各 Type Check 均绿,Check Changeset 与 PR-body guards 在本席改正文后 success。mergeable_state clean。
  • 接受的偏差:changeset 与 PR 正文原把重试间隔写成从 2 秒起,代码是 1、2、4、8、16 秒;changeset 由卡线程在 e6792b40 改正,正文两处由本席经中继改正。openPathObjectReaders-12811.test.ts 加一行是新读者必须登记的普查。
  • 范围外去向:第 11 行单根柱子仍宽 362px:该行的建议「Axis fits the data」已满足,全局限制 maxBarSize 会改所有柱图,不立卡,落地评论记作余项。第 8 行(收件箱 mine 视图显示原始 topic notify)的改法是 packages/services/service-messaging/src/objects/inbox-message.object.ts 的视图列,归 domain:server,落地时在卡上写明。第 9、12、13、15、16 行本来就不在这次派单里,留在卡上。
  • 落地条款:中继 pr_ready + automerge_enable。合并后 Part of 不关卡,席位同一笔在 Console and CLI polish from the real-user walkthrough #30126 留落地评论写明交付了什么、余项归谁,并调整 pm:dispatched。

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 5, 2026 16:53
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 5, 2026
Merged via the queue into main with commit 4128213 Nov 5, 2026
60 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-cfhyia branch November 5, 2026 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant