Repository navigation
fix(app-shell): three designer inspectors read their words in the designer's locale (objectui#10586) - #10651
Conversation
…igner's locale (objectui#10586) DatasetDefaultInspector, FlowReferenceField (ReferenceCombobox) and ConditionBuilder route their labels, placeholders, hints, option labels and accessible names through the designer catalogue under engine.inspector.dataset.*, engine.inspector.reference.* and engine.inspector.condition.*, with en and zh rows. en renders unchanged. Claude-Session: https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy Co-authored-by: Claude <noreply@anthropic.com>
…e run lists the leaked English Claude-Session: https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy Co-authored-by: Claude <noreply@anthropic.com>
…spector-strings-i18n
…spector-strings-i18n
…spector-strings-i18n
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
CI red at
|
Contract reviewServed-tier: ① Derived judgmentsBinding texts. Triage Carve-out check (the amended claim's correction 1). Catalogue rows, zh-CN is real translation, not an English copy. Programmatic: 0 of the 113 zh rows equal their en row; 0 lack a CJK character. Spot-check, 21 rows across the three inspectors: dataset
en stays byte-identical (triage). Measured from the diff, not from the PR's harness. For the 25 ConditionBuilder and FlowReferenceField literals, each hand-extracted old string equals its new en row: 0 mismatches. For the 88 dataset rows, every en row was split on its Missing asks. None in PR 1's scope. The claim's 「re-measure the census first」 is in the PR body (H1). Every literal the base files carried is behind Done but not asked. Existing pins edited or deleted. None: the file list adds one test and edits no test. New pins can fail. ② Semver level
Changeset prose, sentence by sentence: (1) 「 The diff adds no docs or README prose. The two catalogue comments it adds (i18n.ts: 「 ③ Boundary flags
Implemented-by: VERDICT: PASS |
…ssue-10586-inspector-strings-i18n
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: ① Derived judgmentsRe-review frame (what moved since the PASSed head). The head Binding texts. Triage Carve-out (the amended claim's correction 1). Catalogue rows, zh-CN is real translation. Beyond the programmatic check, read: dataset
en stays byte-identical (triage). Measured from the diff, not from the PR's harness: each of the 113 new en rows was split on its Missing asks. None in PR 1's scope. The claim's 「re-measure the census first」 is in the PR body (H1) and reproduces here: the card's floor regex over the three base files gives Dataset 30 attribute hits plus 2 text-node hits and 0 Done but not asked. Existing pins edited or deleted. None: the file list is five source or changeset files plus one new test; no existing test is modified. The existing zh test on this surface, New pins can fail. ② Semver level
Changeset prose, sentence by sentence: (1) 「 The diff adds no docs or README prose. The comments it adds are true against the code: i18n.ts EN 806-808 (option labels keyed by the stored value; ③ Boundary flags
Implemented-by: VERDICT: PASS |
Part of #10586
Refs #10586 — PR 1 of 2. The card stays open: PR 2 carries
HookDefaultInspector.tsxandActionDefaultInspector.tsx, which seat 2's live claim on objectui#10585 edits today.Clause-②: no
The English literals of three designer inspectors move behind the designer catalogue's
t(), each with an en and a zh row, and en renders byte-identical. No schema, export or accept set moves.What changes
inspectors/DatasetDefaultInspector.tsxlocaleprop (MetadataDefaultInspectorProps.locale), the channelObjectDefaultInspectorandReportDefaultInspectorreadengine.inspector.dataset.*(88)engine.form.add,engine.form.searchFieldsinspectors/FlowReferenceField.tsx(ReferenceCombobox,RecordLookupCell,connectorsToOptions)useMetadataLocale(), already read there for the objectui#10448 flagengine.inspector.reference.*(10)inspectors/ConditionBuilder.tsxuseMetadataLocale(), through the existingtLocalengine.inspector.condition.*(15)metadata-admin/i18n.tsENGINE_STRINGS_ENandENGINE_STRINGS_ZH;pnpm check:i18n-driftreads "0 en value(s) changed (113 key(s) added, 0 removed)"{token}slots.tFormatfills plain values. A file-localwithSlotsfills React nodes (a code span, the emphasised tab name) with the split-and-interleave thatResourceEditPagealready uses forengine.edit.readOnlyBanner. The lookup mechanism is the existing one.…One/…Otherrow pairs, picked bycount === 1, which is the rule the en code applied. zh carries its single form in both rows.KeyedOption) and resolved at render, so stored values do not move. Deliberately left literal:≥/≤(symbols), currency codes with their signs, decimal digits.connectorsToOptions(connectors, locale?): the optional locale is for the· declarativeannotation. Without it the answer is en, soFlowReferenceField.connector.test.tsis unchanged.useConnectorListOptionskeys its effect on thelocalestring, a primitive (AGENTS.md rule 10).DatasetDefaultInspector'stris a plain function, and nothing keys on its identity.filterBuilder.and/filterBuilder.or, and its 搭建器 matchesengine.condition.advancedHint.Premise check: the dispatch's mechanism hypotheses, measured
e0f8202). The floor regex reproduces 32 literals / 0t()for the dataset inspector and 5 / 1 forFlowReferenceField. ForConditionBuildermy spelling of the regex reads 3 literals, because the two join text nodes, AND and OR, also match. The three files andi18n.tsare byte-identical betweene0f8202and this branch's base668dd59. Reading the files end to end gives the full set, which is what the pin lists: 77 rendered strings over the dataset fixtures, 10 for the reference picker and 15 for the condition builder. That includes lower-case option labels,aria-label/title/placeholdervalues and composed sentences the regex cannot see.t/tFormatfrom../i18n.jsand key intoengine.inspector.KIND.*/engine.form.*. This PR does the same.engine.inspector.*/engine.form.*rows do not live in the ten packs underpackages/i18n/src/locales/. They live in the module-local two-locale tablepackages/app-shell/src/views/metadata-admin/i18n.ts(en-US and zh-CN).packages/i18n/README.md, section "Scope — theengine.*carve-out" (objectui#4662), records that noengine.*key exists in any pack, by design. Writing them into the packs would add a second mechanism and contradict that ruling. So every new key goes into both locales that namespace has, en and zh, andpackages/i18nis untouched. The consequence is the carve-out's accepted price: the other eight shipped locales render these strings in English, like every otherengine.*string. File-surface consequence: the claim named the packs, and the keys went tometadata-admin/i18n.tsinstead. When this change was made, no open PR and no pushed claim branch (objectui#10585's included) touchedi18n.ts.pnpm check:i18n-designer-parity(EN/ZH rows and placeholders), and it is green. The pack gates are outside its subject and also green (packages/i18n/run below).en byte-identical: one-off measurement, not a committed test
A throwaway harness rendered the three inspectors under en-US in 21 fixture states and wrote
document.body.innerHTMLafter each. Those states were: dataset bound, unbound, create mode, advanced filter and open popover; every reference kind with a hint, the directory lookup and its manual-entry toggle; the condition builder empty, with rows, with both joins and in raw mode. It ran once on the base sources and once on the fix. Both dumps were 169917 bytes with sha256920a835809270db29527d4f0183a7ba518ec48cdcccf4d68c6256de6cab0b7c5, andcmpexited 0. The harness was deleted before the first commit.Pin: red on base, green on head
inspectors/inspectorStrings.i18n-10586.test.tsxhas 10 cases:aria-label,titleandplaceholder; then named zh samples are read back from the catalogue behind a not-the-key / not-the-en-row guard;ObjectDefaultInspector(thelocaleprop channel), the membership-tier flag and the raw CEL editor's label (theI18nProviderchannel).Measurements:
668dd59, the pin from head30171d2. ResultTests 4 failed | 6 passed (10), exit 1. The three zh sweeps list the English still rendered: dataset 77 of 77, reference 10 of 10, condition 15 of 15. The slot case readSample:. The 6 passes are the three en cases and the three lit controls, so the probe does see a translation where one exists.i18n.tsfrom head, the three inspectors from668dd59, at86d7ffe. ResultTests 4 failed | 6 passed (10), exit 1. The catalogue rows alone change nothing on screen.Tests 10 passed (10), re-run atae5c50c.git checkout HEAD --on the mutated paths, thengit diff HEADempty and each path'sgit hash-objectequal to its HEAD blob.Gates
The branch merged
origin/mainthree times:2803fac,4a3d500, thenf99f9cd. Final head isae5c50c.pnpm exec vitest run packages/app-shell/src/views/metadata-admin/, as 4 path-split runs (inspectors/;previews/+external/+__tests__/; the top-level files in two halves)d656ea6previews/again, after the second merge (which touchedpreviews/ToolPreview.tsx)50a3991pnpm exec vitest run packages/i18n/d656ea6studio-designtests and thecheck-i18n-call-site-keys,check-i18n-dead-keysandvite-dts-explicit-extensionsscript testsd656ea6pnpm turbo run type-check --filter @object-ui/app-shell --filter @object-ui/i18n --concurrency=2tsc --noEmitandtsc -p tsconfig.test.jsonran, and--listFilesshows the test project compiles the new testae5c50c--format json: 5 files, 0 errors, 20 warnings. The per-file warning counts equal base (0, 7, 3, 10; the new test 0)ae5c50ccheck:control-bytes,check:test-path-roots,check:vi-mock-specifiers,check:vi-mock-inherit,check:vi-mock-override-shape,check:new-line-citations(0 new),check:changeset-claims,check:pending-changeset-literals,check:i18n-keys,check:i18n-drift,check:i18n-designer-parity,check:i18n-dead-keys,check-changeset-presence(5 source files of 1 released package, 1 changeset),check-changeset-no-majorae5c50c.ts/.tsxfiles, which the config's**/*.{ts,tsx}block covers; the JSON output counts 5 files.eslint.config.jsconfigures no type-aware linting (noparserOptions.project/projectService), so this diff cannot move any untouched file's verdict.check:changeset-claimsreports 3 pending bodies that namei18n.ts:6310-designer-formula-key-retired,7125-dashboard-empty-state-keys-retiredand8632-malformed-picklist-option-loud. I read each paragraph, and all three still hold: the first two are about keys this PR does not touch, and the third restates the carve-out this PR follows.check:eager-locale-cataloguesexited 2 with PREREQUISITE NOT MET, because it reads a builtapps/consolebundle; the eager-closure budget needs the same build.performance-budget.ymlruns both. The repo-widepnpm lintand the fullpnpm testshards belong to CI.Round 2 (
89852f7): mergedorigin/main9d89c6f(conflict-free; the incoming diff isplugin-ganttand its changeset only). At89852f7, throughos-verify-lock: the pininspectorStrings.i18n-10586.test.tsxTests 10 passed (10), exit 0;check:i18n-designer-parityexit 0;pnpm turbo run type-check --filter @object-ui/app-shell30/30 tasks, exit 0 (app-shell cache miss, so it executed).Acceptance notes
engine.condition.celLabel/engine.condition.advancedHintstay underengine.condition.*. The new row-mode keys went underengine.inspector.condition.*, per the triage's namespaces. Moving the two older keys is outside this card.InspectorComboField's search and empty text, and theFilterBuilderinside the filter popover (the packs'filterBuilder.*).useDisplayLocale()(objectui#4575), unchanged. Only its "Sample:" lead-in moved to the catalogue.@object-ui/app-shell: patchonly. The dispatch asked for@object-ui/i18ntoo, but nothing inpackages/i18nchanges (H3).HookDefaultInspector.tsx,ActionDefaultInspector.tsx) completes the card.Session:
https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoyGenerated by Claude Code