Repository navigation
fix(fields): a text field that declares options reads the option label in its record cell - #28817
Merged
Merged
Conversation
…first) Claude-Session: https://claude.ai/code/session_01FEkQ5kmCTHo1Zn4w3D8EBp Co-authored-by: Claude <noreply@anthropic.com>
A field that declares a non-empty options list now reads the matching option label in the read-only text cell, the test analytics dimension labels and grid group headers already apply on any field type. The stored value is untouched, an unmatched value reads as itself, and a field without a list is unchanged. The select cell's matcher moves to a module function both cells call. Claude-Session: https://claude.ai/code/session_01FEkQ5kmCTHo1Zn4w3D8EBp Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEkQ5kmCTHo1Zn4w3D8EBp Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
|
domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo 席位核对ACCEPT · The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」.
Generated by Claude Code |
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 Leehom · project thread
Fixes #28792
Clause-②: no
Metadata-protocol: none
维护者速读
text、textarea等走文本单元格的类型)如果声明了非空的options,列表和详情里的只读单元格现在显示匹配选项的标签(如Backlog),不再显示存储值backlog;存储值不变,匹配不到的值照原样显示,没有options的字段完全不变。options声明,图表维度和分组表头早就按标签显示,只有单元格显示原值,一个声明读出两种样子。席位路线是对齐(enforce),不是禁止声明。options,现有界面零变化。回滚即撤销本 PR。ui/packages/fields/src/index.tsx(TextCellRenderer的选项分支,和从SelectCellRenderer提出来共用的findDeclaredOption);ui/packages/fields/src/__tests__/TextCellRenderer.declaredOptions-28792.test.tsx。pnpm --dir ui exec vitest run packages/fields/src/__tests__/TextCellRenderer.declaredOptions-28792.test.tsx,预期 7/7 通过(main 上两条标签用例红:显示backlog而不是Backlog)。What changes
The seam.
optionsis a spec key on every field type (FieldSchema.options). Two faces already honour a declared non-empty list on any type, on purpose: analytics dimension labels (service-analyticsdimension-labels.ts, "the condition is the declared list itself, never the field's type") and grid group headers (plugin-gridobjectGridGrouping.ts). The read-only text cell ignored it, sotext+options: [{ value: 'backlog', label: 'Backlog' }]readbacklogin a list or detail cell andBacklogin a chart or group header.TextCellRenderer(ui/packages/fields/src/index.tsx). When the field carries a non-emptyoptionsarray (the same test analytics applies,Array.isArray(options) && options.length > 0) and the stored value is a string or number, the cell draws the matching option's label through core'soptionDisplayLabel. The full-text hovertitlecarries the same label. Every type this cell draws gets the same reading (text,textarea,code,qrcode,time,auto_number, the widget faces registered to it, and the fallback for undeclared types).SelectCellRenderer's output.SelectCellRenderer's body into a module function,findDeclaredOption, which both cells call. No second matcher was written. The grid grouping's matcher lives inside aplugin-gridhook and is not importable from@object-ui/fields.generateColumnsinplugin-grid,DetailSectioninplugin-detail) runstranslateOptionsover a non-emptyoptionslist whatever the field's type.optionsreaches the cell. Through the existingfieldprop ofCellRendererProps; no published prop or type was widened. The per-type metadata (TextFieldMetadata) does not nameoptions, so the cell reads it structurally,(field as { options?: unknown }).options, the wayLookupCellRendererreads its static options, and guards it withArray.isArray..changeset/28792-text-cell-declared-option-label.md:patchon@object-ui/fields, with both declaration lines.Clause-② measured: no. The diff touches no
packages/specpath, no published export (findDeclaredOptionis module-private;TextCellRenderer's signature is unchanged) and no wire shape. It changes what one console cell draws for metadata the spec already accepts. Metadata-protocol: none: no key, accepted value or meaning an author writes moved.Tests
Field.X({...})calls and{ type: 'X', ... }literals with anoptionskey that is not an empty array literal) over the tree at basec064d3a2:packages/platform-objects: 88 files, 8optionsdeclarations, 0 on a non-option type.examples/**: 161 files, 53 declarations, 0 on a non-option type.packages/apps(account, connector-github, connector-stripe, setup, studio): 16 files, 0 declarations, 0.packages/plugins+packages/services: 773 files, 32 declarations, 0.src/,apps/, ata598256): 302 files, 80 declarations, 0 fields (8 hits are dashboard widgets of typetable/area, not fields).Field.text({ options: [...] })and{ type: 'textarea', options: OPTS }is reported as 2 hits, and aField.selectbeside them is not.bb5573c2, cell file at base):TextCellRenderer.declaredOptions-28792.test.tsxfailed 2 of 7,expected 'backlog' to be 'Backlog'andexpected 'in_progress' to be 'In progress'(the textarea case). The five controls were green on base.32dc0196: the file passes 7/7. With it,cell-truncation.test.tsx,formulaFaces.textFace-12357.test.tsx,fieldFaceSeam-13216.test.tsxandselect-label-association-e2e.test.tsx: 5 files, 39/39.otherreadsother; an emptyoptions: []reads the stored value; a field with no options renders exactlyspan.block.max-w-full.truncatewithtitle="backlog"and textbacklog;SelectCellRendererwith the same list still readsBacklog;TextField(the edit input) of a text field with options holds the rawbacklog.@object-ui/fieldssuite at7e05456b:pnpm --dir ui exec vitest run --maxWorkers=2 packages/fields/: Test Files 292 passed, 1 skipped (293); Tests 4399 passed, 7 skipped (4406). Lock VERDICT command-exit 0.ui/packages/fieldspnpm run type-check(tsc --noEmit && tsc -p tsconfig.test.json; the test config includessrc/**/*.test.tsx, so the new test is compiled): exit 0, after building the@object-ui/fields^...closure.react-refresh/only-export-componentson the barrel's existing exports; the new function is not exported).Ablation (one-off, from committed HEAD 32dc019)
node scripts/ablation-replace.mjsreplaced the cell's final return (theTruncatedTextelement whosetextisoption ? optionDisplayLabel(option) : String(safe)) with one whosetextisString(safe), plus a marker comment, inui/packages/fields/src/index.tsx: anchor 1 → 0, marker 0 → 1 (alsogrep -c= 1 on disk before the run), blob630a20cf9f49→5fee7b9df6c0.TextCellRenderer.declaredOptions-28792.test.tsx: 2 failed, 5 passed, exactly the two label cases; every control stayed green. Restored: blob after restore630a20cf9f49equals HEAD,git diff HEADempty. The ui suite imports the cell from source (../index), so no build sat between the mutation and the run.Acceptance notes
TextField'sreadonlybranch (a read-only form field, not the cell) still prints the stored value. The order put edit inputs and forms out of scope;DetailSection's read-only rows draw through the cell and do align. A record view whose read-only face is the form widget would still readbacklog. Noted, not filed: no shipped field declares the list (count above).BACKLOGnames thebacklogoption in the cell, as it does in a select cell; analytics and grid grouping match exactly, so that value readsBacklogin the cell andBACKLOGin a group header. Same split the select cell already has; noted, not filed.sys_notification.topic.Verification
objectstack-ai/objectstackat 21:2x UTC; every code PR's head was fetched and diffed against its merge base. None touchesui/packages/fields/src/index.tsx; the only one touchingui/packages/fields/is the Dependabot group bump (chore(deps)(deps-dev): Bump the development-dependencies group with 2 updates #28499,package.jsononly).origin/mainmoved fromc064d3a2to70bf4343while this ran (31 files); none underui/packages/fields/orui/packages/core/src/evaluator/, so the branch was not merged forward.Local derived gate loop, head 7e05456 (34 of 34, all exit 0)
node scripts/pm/dispatch-gates.mjs --commandsderived 34 families for this diff; each was run with its exit code captured before any pipe;--ranreconciliation: "34 derived famil(ies) accounted for — 34 run, 0 NOT-MEASURED (a DERIVED zero — all 34 recorded an exit code and none of them is 3)". Record:pm-orders/server/28792-gates-ran.txtin the project folder. Families includecheck-adr-0087-registration(plus self-test),check-changeset-no-major,check-empty-changeset(plus self-test),check-sdui-manifest(plus self-test),check-comment-mask-corpus,ui vitest scripts/,check:nul-bytes,check:published-files,check:test-source-alias,check:type-check-coverage,check:type-check-debt,check:undeclared-dep-imports,check:cross-package-test-inputs. Every family CI runs is read from this PR's check-runs, not re-run here.Generated by Claude Code