Repository navigation
fix(app-shell): draw a served object or list view label as served in the Console sidebar, recent list and object list header - #30388
Merged
Conversation
…the sidebar and recent list Claude-Session: https://claude.ai/code/session_01Utp6CZywtebM5fE7KZuMEM Co-authored-by: Claude <noreply@anthropic.com>
…r and recent list Claude-Session: https://claude.ai/code/session_01Utp6CZywtebM5fE7KZuMEM Co-authored-by: Claude <noreply@anthropic.com>
…page header and the app header Claude-Session: https://claude.ai/code/session_01Utp6CZywtebM5fE7KZuMEM Co-authored-by: Claude <noreply@anthropic.com>
…and the app header Claude-Session: https://claude.ai/code/session_01Utp6CZywtebM5fE7KZuMEM Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CZywtebM5fE7KZuMEM Co-authored-by: Claude <noreply@anthropic.com>
… fixture Claude-Session: https://claude.ai/code/session_01Utp6CZywtebM5fE7KZuMEM Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Nov 5, 2026
…l header fixtures AppHeader.objectCrumbPlural-11696, AppHeader.labelLessViewTitle-12805 and ObjectView.labelLessViewTab-12774 served the English object label and plural to a zh-CN session. Under the served-first label rule the header and the view tabs draw the served text, so those seven zh-CN cells read the English plural. The fixtures now serve each language's own answer, as the server does; no assertion changed. Claude-Session: https://claude.ai/code/session_01Utp6CZywtebM5fE7KZuMEM Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
|
domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG 维护者速读
席位核对 — ACCEPT · head 6583026
|
This was referenced Nov 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Bill · project thread
domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG
Refs #30311
Clause-②: no
Metadata-protocol: none
维护者速读
/data页标题,改为直接显示服务端返回的名字;只有服务端没给名字(客户端自己派生的视图、还没读到的对象、待发布草稿)时才查客户端词典。.custom里给已安装包的对象或列表视图改了名,服务端返回新名字,但 Console 拿服务端的名字再去查词典,基础包的旧译名又把它盖回去;实测 zh-CN 下对象页标题和最近访问仍显示「任务」「进行中」。ui/packages/app-shell/src/hooks/useNavTargetLabel.ts(object/view 分支与servedObjectPluralLabel);②ui/packages/app-shell/src/views/ObjectView.tsx的listTitleOf(标题、收藏、无标签视图同一来源);③ui/packages/app-shell/src/layout/AppHeader.tsx对象分支。pnpm --dir ui exec vitest run packages/app-shell/src/hooks/__tests__/useRecentItemLabel.test.tsx packages/app-shell/src/layout/__tests__/AppHeader.servedLabels-11295.test.tsx packages/app-shell/src/views/ObjectView.listTitlePlural-11696.test.tsx packages/app-shell/src/views/ObjectDataPage.listTitlePlural-11696.test.tsx,预期 4 个文件全部通过。What changes
/metaread or the app bundle served is already translated by the server, by its label order for an overridden item (i18n: an override's own label loses to the base's translation on page, dataset, app and book, and a translation in the .custom pair never wins on any type #30193), so it is drawn as given. The catalog key (useObjectLabel'sobjectLabel/objectPluralLabel/viewLabel) is asked only for text no server translated.useNavTargetLabel.tsobjecttarget (an unlabelled sidebar entry): the served object's label as given; a pending draft's label still goes through the catalog.viewtarget (an unlabelled sidebar entry, and a recent view row): a served view's label as given, decided byisServedView— the identity question the object page's view tabs already ask (objectui#11295, objectui#11336). A view the client derived (a container expansion) still goes throughviewLabel. By name, the served reads are the names-only scope's ownservedandviews, from the samereadObjectScopecallreadObjectsByNamemakes, so no new request.servedObjectPluralLabel(def, language, objectPluralLabel): what a served object's list is called — servedpluralLabel, else servedlabel, else the catalog under its name. Internal to app-shell (not in the package index).useRecentItemLabel.ts: the recent object row usesservedObjectPluralLabel.ObjectView.tsx: onelistTitleOffeeds the page header's object crumb (ObjectViewPageHeader), the list favorite's label and an unlabelled view's tab text, so the three still agree (the header compares the tab text with the plural).AppHeader.tsx: the object route's title, and the unlabelled-view fallback on a view route.ObjectDataPage.tsx: the/datapage title.ui/packages/i18n(useObjectLabelis published; changing its order is aClause-②question). The rest of the family — record pages, record forms, drawers, preview cards, and call sites outside app-shell — is listed in Acceptance notes for the seat's closing card.Tests
useRecentItemLabel.test.tsx(objectstack#30311 describe, 9 cases): renamed object and view in the recent list and inuseNavTargetLabel(whole-list and names-only-scope reads), served plural first, a view embedded in the served object document; controls: a client-derived view, an object the cache does not hold, a pending draft object, en.AppHeader.servedLabels-11295.test.tsx(4 cases),ObjectView.listTitlePlural-11696.test.tsx(2),ObjectDataPage.listTitlePlural-11696.test.tsx(2)./api/v1/i18n/translations/:localeanswer, and the server translates a served label with it):useRecentItemLabel.objectPlural-11733,ObjectView.listTitlePlural-11696,ObjectView.listLinksPlural-11733,ObjectView.labelLessViewTab-12774,ObjectDataPage.listTitlePlural-11696,AppHeader.objectCrumbPlural-11696,AppHeader.labelLessViewTitle-12805,StudioDesignSurface.standardNavEntries-11201(8 files) now serve the zh-CN answer in zh-CN. Every existing assertion is unchanged.ff3f83bbwithgit restore --source, marker count 0 on disk, restored withgit checkout HEAD --,git statusclean and blob hashes equal to HEAD after):Tests 9 failed | 63 passed (72). The 9 are exactly the renamed cells (object page title, app header en/zh,/datatitle, recent object, recent plural, recent/nav view, names-only scope, embedded view); every control stayed green.Test runs
Test Files 6 passed (6),Tests 72 passed (72),VERDICT command-exit 0.Test Files 1 failed | 562 passed (563),Tests 1 failed | 4324 passed (4325). The red wasStudioDesignSurface.standardNavEntries-11201(English served in zh-CN), fixed as above.origin/mainand rebuilding, head23114841): the 6 pin files plus 136 more test files that referenceObjectView,ObjectDataPageorAppHeader:Test Files 1 failed | 140 passed (141),Tests 2 failed | 1395 passed (1397). The 2 reds wereObjectView.listLinksPlural-11733's zh-CN cells (English served in zh-CN), fixed as above; that file thenTests 7 passed (7)atec3b0e69. This sweep ran 136 of the 298 test files its own reference search found, not all of them (see Acceptance notes).ec3b0e69red on 7 zh-CN cells inAppHeader.objectCrumbPlural-11696,AppHeader.labelLessViewTitle-12805andObjectView.labelLessViewTab-12774, reproduced locally, fixtures fixed at1553cdd6): everyAppHeader.*,ObjectView.*andObjectDataPage.*test in app-shell,Test Files 114 passed (114),Tests 929 passed (929); then all 298 files of sweep 2's reference search at6583026f(origin/mainmerged in, noui/file among the 37 it brought), in three locked runs:Test Files 97 passed (97)/101 passed (101)/100 passed (100),Tests 905/790/950 passed, eachVERDICT command-exit 0.eslint --no-inline-configon the changed TypeScript files (at23114841): 0 errors (104 warnings, all on lines this PR does not touch).pnpm exec turbo run type-check --filter=@object-ui/app-shell --concurrency=2atec3b0e69:Tasks 68 successful,VERDICT command-exit 0.Live (showcase
--fresh, zh-CN, Console fromui/src through Vite)Overrides written the way the platform takes them:
POST /api/v1/packages/com.example.showcase/ensure-customization(paircom.example.showcase.custom); the object through anobject_extension(PUT /api/v1/meta/object_extension/showcase_task?package=com.example.showcase.custom&mode=draftwithextend,label: Work Item (renamed-30311),pluralLabel: Work Items (renamed-30311), then publish — an objectoverridessave is refusedNOT_OVERRIDABLE, ADR-0146 D10); the view through a view override (showcase_task.in_progress,label: In flight (renamed-30311),overrides: { package: 'com.example.showcase', basedOn: '0.1.0' }, then publish).Served under
Accept-Language: zh-CNafter the overrides:/meta/object/showcase_task→Work Item (renamed-30311)/Work Items (renamed-30311);/meta/view/showcase_task.in_progress→In flight (renamed-30311); the app bundle/meta/app/showcase_app/bundlecarries the renamed object too. The zh-CN catalog keepsobjects.showcase_task.label= 任务 and_views.in_progress.label= 进行中.origin/mainui (ff3f83bbsources)Each leg restarted the Console's Vite (
--force) after switching the five sources and checked that the served modules carried (or lacked) the change before the run: the first after-run read a stale transform from Vite's watcher. Screenshots (1440×900 at 2×, before/after of the object page, the view page, the expanded sidebar recent group and Home) are in the project's files atui-seat3/30311-shots/; this channel cannot upload images to the PR body, so the table above is their text.The live leg did not reach an unlabelled sidebar entry: every showcase navigation entry carries its own label, so the sidebar's object/view rows draw those (unchanged). That path is pinned by the
useNavTargetLabelcases.Acceptance notes
origin/mainthe object page title also showed 任务. The seat folded the header into this PR and named the rest of the family for a closing card.objectLabel(/objectPluralLabel(over a served definition, at23114841): in app-shell,AppContent4,ActivityObjectLabel1,ConsoleLayout1,ObjectView3 more (import wizard, delete confirmations,objectLabelOf),ObjectDataPage1 (record drawer title),RecordDetailView11,RecordFormPage2,appReportIndex2,RecordPreviewCard1,recordDrawerStack2,PackagedActionsSection1,WidgetRefCellFaces1; outside app-shell:fieldsRecordHoverCard1,plugin-detail3,plugin-form2,plugin-gantt1,plugin-grid1. Some pass text no server translated ({ name, label: name }fallbacks, a widget ref's ownlabel), so each needs a per-site reading. The other way to close the class is to changeuseObjectLabel's own order, aClause-②card.labelalone keeps the served plural. The server translateslabelandpluralLabelseparately: an extension that renames onlylabelstill serves the base's translatedpluralLabel, so a list title (which reads the plural first) keeps it. That is the server's answer and Studio's; the live leg renamed both.ObjectView,ObjectDataPageorAppHeader; it ran 136 of the 298 its search found. Three of the 162 it skipped carried the same English-in-zh-CN fixture and went red in CI atec3b0e69. They are fixed at1553cdd6and the full 298 now pass (sweep 3).Refs.Verification
ec3b0e69the branch gained three test-fixture files (1553cdd6) and a merge oforigin/main(6583026f, noui/file).dispatch-gates --commandsat1553cdd6derives the same 35 commands; they were not re-run there.pnpm --filter @objectstack/spec check:livenessat6583026f: exit 0 (main red: spec check:liveness — query/searchFields cites engine.ts, which no longer mentions searchFields after #30341 #30367 fixed onmainby fix(spec): repoint the query.searchFields liveness row at engine-find.ts#expandSearchOnAst #30368).ec3b0e69:node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstacklists 35 commands (the same list as at23114841), each run with its exit code captured before any pipe, all 35 exit 0;--ranreconciliation: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN, exit 0.pnpm --dir ui exec vitest run scripts/ran underos-verify-lockwith--maxWorkers=2(Test Files 170 passed | 2 skipped (172)): its first run at23114841, with the showcase stack up, was SIGKILLed for memory.ui/scripts/check-new-cross-file-line-citations.mjsatec3b0e69: 0 new citations, exit 0..changeset/30311-served-object-view-labels.md,@object-ui/app-shellpatch, both declaration lines.Human Minimum
packages/specholds no runtime logic.eslinton the changed files reports 0 errors (the repo-widepnpm lintis CI's).main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed. (not touched)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01Utp6CZywtebM5fE7KZuMEM