Repository navigation
fix(plugin-grid, plugin-detail): a returnType currency formula reads as money in list cells and on the record page - #27689
Merged
Conversation
The three configured-column paths rebuilt the cell's field bag from a picked key list that carried currencyConfig and scale but not returnType, so a returnType 'currency' formula drew the number face. Claude-Session: https://claude.ai/code/session_01Utp6CYFYwzxE4fR2Vr1sQo Co-authored-by: Claude <noreply@anthropic.com>
Adds returnType to ENRICHED_FIELD_METADATA_KEYS, with tests for the grid and the detail section, and a changeset. Claude-Session: https://claude.ai/code/session_01Utp6CYFYwzxE4fR2Vr1sQo Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CYFYwzxE4fR2Vr1sQo Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
|
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC 席位核对ACCEPT · head
Generated by Claude Code |
This was referenced Oct 29, 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.
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC
Requested by Bill · project thread
Fixes #27494
Clause-②: no
Metadata-protocol: none
维护者速读
returnType一并传给单元格;returnType: 'currency'的公式(如演示应用的「Budget Remaining」)按货币显示$180,000.00,与旁边的货币列一致。currencyConfig、scale等键,漏了returnType,单元格以为是未声明类型的数字,显示成裸数字180,000.00。number或未声明的公式照旧显示数字。回滚即 revert 本 PR。ui/packages/plugin-grid/src/objectGridGenerateColumns.tsx(三处fieldMeta.returnType)→ui/packages/plugin-detail/src/fieldEnrichment.ts(ENRICHED_FIELD_METADATA_KEYS加returnType)→ 新测试gridFormulaCurrency-27494.test.tsx。pnpm --dir ui exec vitest run packages/plugin-grid/src/__tests__/gridFormulaCurrency-27494.test.tsx packages/plugin-detail/src/__tests__/formulaReturnTypeRelay-27494.test.tsx,预期 13/13 通过。What changes
FormulaCellRenderer(the table face) andFormulaField(the form face) already draw a formula declaringreturnType: 'currency'through the currency field's own faces (CurrencyCellRenderer/CurrencyField,formatCurrency), reading the formula's owncurrencyConfig. The renderers were never reached with that key: the hosts that rebuild a field bag from a picked key list carriedcurrencyConfigandscalebut notreturnType. The cell then saw an undeclared formula holding a JS number and drew the number face atscale: 2, which is the90,000.00the card reports beside$150,000.00.plugin-grid,objectGridGenerateColumns.tsx. The three configured-column paths (ListColumn objects, a string column list, inline rows with afieldsprojection) now copyreturnTypeverbatim besidecurrencyConfiginto the cell'sfieldMeta. The auto-generated (object-schema) path already hands the whole def and is unchanged.plugin-detail,fieldEnrichment.ts.ENRICHED_FIELD_METADATA_KEYS, shared byDetailSection,HeaderHighlightand the summary chips, gainsreturnType, so a section entry naming the field ({ name }) reaches the formula cell with its declared type. A view entry that declares its ownreturnTypestill wins (the list's existing fill-the-gaps rule). The list is not exported from the package entry, so no published surface moves.returnTypeandcurrencyConfigare the spec's existing formula keys (spec: a formula field cannot declare a currency result —returnTypeisnumber | text | boolean | date, so a formula over money renders as a bare number #22727).Tests
ui/packages/plugin-grid/src/__tests__/gridFormulaCurrency-27494.test.tsx, under a EUR tenant so the$can only come from the formula's own fixedcurrencyConfig: on each of the three configured paths, the currency formula reads$90,000.00beside the currency field's$150,000.00; controls, areturnType: 'number'formula atscale: 2reads1,234.50and an undeclared formula reads4,321; every formula cell reads what the whole-defFormulaCellRendererreads; the auto-generated columns are the reference face.ui/packages/plugin-detail/src/__tests__/formulaReturnTypeRelay-27494.test.tsx: the fixture is a spec-valid formula def (FieldSchema.safeParse);enrichDetailFieldcopiesreturnTypeand a view-entry one wins;DetailSectiondraws$90,000.00beside$150,000.00, and a number formula stays1,234.50.Acceptance notes
examples/app-showcaseboot,GET /api/v1/meta/object/showcase_projectreturnedbudget_remainingas{ type: 'formula', returnType: 'currency', currencyConfig: { currencyMode: 'fixed', defaultCurrency: 'USD' }, scale: 2 }. (b) The renderers: the list cell isFormulaCellRendererreached fromobjectGridGenerateColumns' configured-column paths; the related-list cell isFormulaCellRendererreached fromRelatedList'smakeCellbag; the record page's field isFormulaCellRendererreached throughenrichDetailField. None goes throughFormulaField, and none needed a renderer change.RelatedList.tsx'smakeCellbuilds the same picked-key bag and dropsreturnTypethe same way; the one-line fix is areturnTypespread beside itscurrencyConfig: def.currencyConfigspread. That file is being rewritten by an open PR (perf(plugin-detail,app-shell): the record page's related column loads counts first, then rows only for the cards in view, and never blocks the details #27636), so the seat holds it until that lands; this PR does not pin the related list. Rows 2 to 4 of console analytics: a formula declared returnType currency renders as a bare number, a KPI tile cannot show its description, percent fields always draw a progress bar, and report charts cannot split a series by a second dimension #27430 are not touched.RecordDetailPanel'sbuildRecordDetailFields(the quick-look overlay) also builds its field from a picked list (currencyConfig,scale, …) withoutreturnType. Reported to the seat with the related-list site; not changed here.DetailSectiontest only.Verification
Live console, Showcase → Projects (fresh boot, 1440×900)
Branch console (
ui/apps/consolevite) against the branch'sobjectstack dev --seed-admin --fresh. Rows read from the list's table, columns Budget / Budget Remaining:fieldMeta.returnTypecopies renamed throughablation-replace --hold):$600,000.00/180,000.00,$50,000.00/2,000.00,$200,000.00/200,000.00$600,000.00/$180,000.00,$50,000.00/$2,000.00,$200,000.00/$200,000.00Restored after the reading: blob == HEAD,
git diff HEADempty.Ablation (each fix removed, then restored)
@object-ui/*resolves to source in ui vitest, so no rebuild between legs.node scripts/ablation-replace.mjs --file ui/packages/plugin-grid/src/objectGridGenerateColumns.tsx --anchor "fieldMeta.returnType = " --expect 3 --replacement "fieldMeta.ablated27494 = " -- …gridFormulaCurrency-27494.test.tsx. Landed: anchor 3 → 0, blob90f02baa3e9c→6aac6616f1bb. Red:Tests 6 failed | 4 passed (10), the three "reads as money" cases and the three agreement cases, with grid cells["1Open","Tower","$150,000.00","90,000.00","1,234.50","4,321"]; the four controls and the reference stayed green, as predicted. Restored: blob == HEAD,git diff HEADempty.--file ui/packages/plugin-detail/src/fieldEnrichment.ts --anchor " 'returnType'," --replacement " 'ablated27494',". Landed: anchor 1 → 0, blob910282667aac→35f03459ed4a. Red:Tests 2 failed | 1 passed (3)(expected undefined to be 'currency'; section text…remaining90,000.00…). Restored: blob == HEAD,git diff HEADempty.A first grid leg was refused by the tool (
ANCHOR AMBIGUOUS, nothing written) and re-run with--expect 3; the reading above is the second run.Tests, type-check and gates
All on the merged head
0191a4f9(origin/main merged once, no file ofplugin-grid,plugin-detailorfieldsmoved by it;@objectstack/specrebuilt after the merge).pnpm --dir ui exec vitest run --maxWorkers=2 packages/plugin-grid/ packages/plugin-detail/→Test Files 595 passed | 1 skipped (596),Tests 5347 passed | 18 skipped (5365)(lock VERDICT command-exit 0).pnpm --filter @object-ui/plugin-grid run type-check→ exit 0;pnpm --filter @object-ui/plugin-detail run type-check→ exit 0 (each runstsc --noEmit && tsc -p tsconfig.test.json).node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack): 34 derived, 34 run, every one exit 0, reconciled with--ran(0 NOT-MEASURED, 0 UNRUN).node scripts/check-sdui-manifest.mjsand its--self-testare among them.pnpm check:type-check-debtfirst answered exit 3 (PREREQUISITE NOT MET: its closure build queued behind this branch's own test run on the shared lock) and was re-run alone under the lock: exit 0, 0 ledger entries above their recorded number.pnpm --dir ui exec vitest run scripts/→Test Files 169 passed | 2 skipped (171).pnpm check:new-line-citations(ui) → 0 new citations.Lint UI,Test UI,Build & E2E UI) are this PR's check-runs.Generated by Claude Code