Repository navigation
fix(fields,plugin-detail,plugin-grid,app-shell,i18n): read-only booleans, the boolean list face and the Home greeting follow the locale (objectui#11689) - #11731
Conversation
…1689) `BooleanField`'s readonly branch, a boolean `FormulaField` and the lookup column's plain-text fallback spelled 'Yes' / 'No' in code. They now read `common.yes` / `common.no` through one hook, `useBooleanValueLabel`, whose provider-less defaults keep the English words. Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju Co-authored-by: Claude <noreply@anthropic.com>
…ing follow the locale (objectui#11689) The record-detail highlights strip spelled its boolean chip 'Yes' / 'No' as JSX text; it now reads `useBooleanValueLabel` from `@object-ui/fields`. The Home greeting joined the greeting and the name with an ASCII ', ' and closed with '.'. The joiners are two new keys in all ten packs, `home.greetingSeparator` and `home.greetingEnd`, so zh-CN writes the full-width comma and full stop and en is unchanged. Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju Co-authored-by: Claude <noreply@anthropic.com>
Brings in objectui#11721 (the tree's cell faces through `BooleanCellRenderer`), whose zh pin this branch re-judges once the badge word is translated. Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju Co-authored-by: Claude <noreply@anthropic.com>
…olumn label follow the locale (objectui#11689) The family sites recorded on the card (claim amendment 6019561490): - `BooleanCellRenderer` spelled its status badge's "Off" and the completion indicator's "Completed" / "Not completed" accessible names in English. They are three new keys under `fields.boolean` in all ten packs, read through `useFieldTranslation` with en defaults. - `ObjectGrid` handed the cell face the authored field label while the header printed the translated one. Each schema-backed path now hands the face the header's own resolved label. The tree's zh pin from objectui#11721 is re-judged to the translated word. Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju Co-authored-by: Claude <noreply@anthropic.com>
…sites Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju Co-authored-by: Claude <noreply@anthropic.com>
|
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
|
Contract reviewServed-tier: Reviewed: PR objectui#11731 ( ① Derived judgmentsPublic surface, Public surface, Published behaviour, read against the head tree.
Accept sets. None move: the diff changes which words and marks are drawn, not what any surface accepts or returns as data. RIGHT (the changeset claims no accept-set change). The three behaviour bullets, sentence by sentence.
Card Done-when. The boolean words and the joiners come from keys present in every locale (five new in ten packs; File surface against the claim as amended and accepted. 25 files. Claim ② Semver levelChangeset
Clause-②: yes (widening) ③ Boundary flagsDev report
Six Check-runs on Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #11689
Clause-②: yes
Read-only boolean values, the boolean list face and the Home greeting now take their words and punctuation from the language packs. Under zh-CN the record-detail highlights strip read the English word beside a translated label (the card's "Email Verified" sighting), the list face's status badge read "LABEL — Off", and Home joined the night greeting to the name with an ASCII comma and period. All of them now read in the session language; en is unchanged.
The file surface is the claim's, widened by claim amendment 6019561490 (the two family sites seat 1 recorded in 6019099345), plus the producer the measurement found (see "Where the sighting came from").
Read-only boolean words: the existing
common.yes/common.noBooleanFieldreadonly branch'Yes'/'No'useBooleanValueLabel()FormulaFieldwithreturnType: 'boolean'useBooleanValueLabel()renderLookupColumnValueplain-text fallbackBooleanValueText(same hook; the function cannot call a hook itself, and both callers render what it returns)HeaderHighlight,@object-ui/plugin-detail)Yes/NouseBooleanValueLabel(), exported from@object-ui/fieldsWhy
common.yes/common.noand no new key. The packs carry threeyesrows.common.yes/common.nois the pair whose meaning is "the value of a boolean": its one existing reader, app-shell's audit-history display, draws a boolean field's old and new value with it.grid.yes/grid.nobelong toObjectGrid's own toolbar bundle (group header, bulk-action dialog), andlookup.yesis the record picker's filter-checkbox caption with nonohalf. No confirm dialog readscommon.yes.One rule, one home.
useBooleanValueLabel(new filepackages/fields/src/widgets/booleanValueLabel.tsx) is the only place that maps a boolean to its key; every drawer above calls it.useFieldTranslation's defaults table carries both rows with the en values, so a field rendered without anI18nProviderstill says Yes / No.Where the sighting came from.
sys_userlistsemail_verifiedamong itshighlightFields, and the highlights chip spelled the words as JSX text, which is why a plain'Yes'grep inpackages/fieldsandpackages/componentsdid not find it. The record body's own row draws a boolean throughBooleanCellRenderer(a checkbox, no word). So the fix also lands in@object-ui/plugin-detail, as the order allows for a producer found elsewhere.The boolean list face (
BooleanCellRenderer): three new keys underfields.booleanfalseon a status-named columnfields.boolean.offBadge{{label}} — Off{{label}} — 已关闭true(accessible name)fields.boolean.completedCompleted已完成false(accessible name)fields.boolean.notCompletedNot completed未完成The badge is one interpolated sentence, so a locale can reorder the label and the word. Read through the same hook and defaults table as the Yes / No words (
useFieldTranslation). Reuse was considered and refused:packagedAutomation.offis a console page's switch state,dashboard.config.refresh.offthe auto-refresh setting,chatbot.toolState.completedan AI tool call's state. None of them names a field value. The zh value follows the pack's existing word for off (packagedAutomation.off).The grid hands the face the header's label
ObjectGridhanded the cell face the authored field label while its header printed the translated one (resolveFieldLabel). So under a non-en pack the badge sat under a translated header and named the column in the authored language. Every schema-backed path now hands the face theheaderit already resolved, with no second copy of the label rule: object-shaped columns, string columns, inline-data columns, and the columns generated from the schema. The last is not one of the three sites the amendment names; it is the same one-line label handoff. The authored-label guard stays, so an unlabelled field keeps the face's own fallback.Greeting joiners: two new keys
home.greetingSeparator(the comma before the name, rendered only when there is a name) andhome.greetingEnd(the closing mark). I chose a joiner pair overTranscomponent interpolation: the markup stays as it is, so the name keeps its owntext-primaryspan and the closing mark its muted one, and no pack carries component markup.,。、。،.,.zh-CN now reads "夜深了,Dev Admin。"; en still reads "Working late, Dev Admin.".
Public surface (the
Clause-②reading)@object-ui/i18ndist/locales/en.d.ts, basec910630against head550037f: five members added, nothing else moved. They arefields.booleanwithoffBadge: "{{label}} — Off",completed: "Completed"andnotCompleted: "Not completed", plushome.greetingSeparator: ", "andhome.greetingEnd: ".". TheTranslationKeystype derived fromengains the same five.@object-ui/fields: one new export,useBooleanValueLabel, with its typeBooleanValueLabel.BooleanValueTextstays internal..changeset/11689-boolean-greeting-locale.md:minorfor fields, plugin-detail, plugin-grid, app-shell and i18n.Pins (all under a real
I18nProviderover the real packs; en and provider-less are the controls)packages/fields/src/__tests__/booleanValueLabel.locale-11689.test.tsxhas two parts. The three drawers: zh 是 / 否, en Yes / No, every pack's owncommon.yes/common.no, provider-less Yes / No. ThenBooleanCellRenderer: zh badge启用 — 已关闭, zh accessible names, en unchanged, every pack, provider-less.packages/plugin-detail/src/__tests__/HeaderHighlight.booleanLocale-11689.test.tsx: zh chips 是 / 否, en and provider-less Yes / No.packages/app-shell/src/console/home/__tests__/HomePage.greetingLocale-11689.test.tsx: the realHomePageat 02:30 local. zh heading夜深了,Dev Admin。, enWorking late, Dev Admin., the name keeps its coloured span, and with no name only the closing mark appears.packages/plugin-grid/src/__tests__/ObjectGrid.cellFaceLabel-11689.test.tsx: object-shaped, string and generated columns. zh badge启用 — 已关闭under a启用header, enActive — Off.packages/plugin-tree/src/ObjectTree.cellFaces-11686.test.tsx(from objectui#11721, merged here ata58626c): its zh pin is re-judged to the whole translated badge,启用 — 已关闭.Ablation (one-shot, at
550037f, four legs, each restore proven)Each leg went through
ablation-replace.mjs, which checks the anchor hit, the marker count and that the blob changed, then restores and proves blob == HEAD with an emptygit diff HEAD. After all four legs,git status --porcelainwas empty. The tests resolve the packages through the vitest source alias, so nodiststep was involved.useBooleanValueLabelreturns the English literals', 'BooleanCellRendererbadge back to the literal— OffActive — 已关闭received)Local verification (head
550037f; CI runs the full farm)pnpm --filter X type-checkfor i18n, fields, plugin-detail, plugin-grid, plugin-tree, app-shell (after a dependency-closure build of the app-shell and plugin-tree closures)pnpm exec vitest run packages/fields/pnpm exec vitest run packages/plugin-detail/ packages/i18n/pnpm exec vitest run packages/plugin-grid/ packages/plugin-tree/scripts/__tests__: defaults-population-parity-7904, check-i18n-call-site-keys, check-i18n-en-drift, check-i18n-dead-keys, placeholder-spelling-parityconsole/home/, the defaults-maps mirror, audit-history display, the threeAppContentsuites that mountHomePage, andRecordDetailView.lookupDependsOn-7190check:i18n-keys,check:i18n-drift,check:i18n-dead-keys(report-only),check:i18n-designer-paritycheck:new-line-citations(0 new),check:control-bytes,check:changeset-claims(report-only; the one paragraph it names, in the 11659 changeset, stays true),check:pending-changeset-literals,check-changeset-no-major,check-changeset-presencecheck:test-path-roots,check:phantom-deps,check:esm-specifiers,check:unreferenced-sources,check:self-import,check-vi-mock-override-shapecheck-governed-queue-guard.mjs --testover the diffpnpm --filter X lint(eslint .) for the six packageslint.ymlsets no--max-warnings)The app-shell run is a declared narrowing: the full package has more than a thousand test files, and CI runs them sharded.
Acceptance notes (observed, not changed here, nothing filed)
ObjectGantt's tooltip boolean branch,PropertyEditor's boolean caption (plugin-designer), andderiveMasterDetail'soptionsForlabels for a boolean column (plugin-form). Rawtrue/falsetext also appears inConcurrentUpdateDialogandHistoryTimeline(plugin-detail) and inrecord-picker(components).FormulaFieldstill read the value by truthiness, so a null boolean highlight draws the "No" chip. That is the defect class the readonlyBooleanFieldandBooleanCellRendererwere ruled on; it is not judged here.common.no아니오andgrid.no아니요.resolveFieldLabel. The face now matches that header.namenever reaches the boolean face's status and completion name tests.common.yes/common.noselection through itsctx.t, with its own truthiness.Generated by Claude Code