Repository navigation
fix(plugin-grid): name bulk-confirm records by the declared nameField, never a derived field - #13112
Merged
objectstack-fleet[bot] merged 3 commits intoOct 20, 2026
Conversation
…, never a derived field The grid's own $select now asks for the object's declared nameField (a formula included), through the same declared-field and field-level read gates as its other harvests; it is fetched, not drawn. The bulk confirm step names a record of an object that declares a nameField by that field, or by the resolver's Record #id floor when the row lacks it, so the derive steps no longer substitute another text field (a contact's job title). Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB
…'s row pages Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB
Contributor
✅ 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
|
This was referenced Oct 20, 2026
objectstack-fleet
Bot
deleted the
claude/issue-13107-grid-select-namefield
branch
October 20, 2026 02:57
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.
Fixes #13107
Clause-②: no
What this changes
The bulk-action confirm step lists each affected record by the object's declared
nameField. Before this change, when no column of the view showed that field, the step listed another text field in its place. Measured on HotCRM's All Contacts list, it showed job titles instead of contact names.Two halves, both in
@object-ui/plugin-grid:ObjectGridgetSelectFields). The grid's own$selectnow asks for the object's declarednameField. It is read throughdeclaredNameField, the resolver's single spelling of that pointer. A formula field is requested by name, because the server serves formulas. It is fetched, not drawn: it joins the projection, not the columns. It goes through the same two gates as the grid's other extra fields:isProjectableField(the object must declare it) andpassesProjectionGate(the viewer may read it). It joins the existing union, so anameFieldthat is already a column is sent once. This is the projection a standaloneobject-gridsends, and the one every group row page of a server-grouped grid sends. The measured All Contacts view is grouped by account (grouping.fields: crm_account), so that is the path its rows take.BulkActionDialogconfirm step). A new module-localaffectedRecordNamedecides the name. An object with no declarednameFieldkeepsgetRecordDisplayName's full ladder, unchanged. For an object that declares one, the step uses the declared value, or the resolver's ownRecord #IDfloor when the row lacks it. The derive steps (4 and 4b) are never reached for such an object. Two cases leave the row without the value: the server did not answer it, or the viewer may not read it.No change to
getRecordDisplayName's global ladder in@object-ui/core(triage ruling). Nothing is added to the package entry: no export, prop or type member.Pins (
packages/plugin-grid/src/__tests__/bulkConfirmNameField-13107.test.tsx)Each pin drives the real ObjectGrid and BulkActionDialog. The data source honours
$selectthe way a server does: a row carries the selected keys only.full_nameasnameField, with columnsfirst_name/last_name/title. The$selectcarriesfull_name, the confirm step listsJohn SmithandMarcus Reed, and no column header is drawn for it.$selectcarriesfull_name.full_nameoff the answer: the step listsRecord #c1andRecord #c2, never the job titles.full_name: it is not requested, and the step listsRecord #ID.nameFieldthat is a column (the lead list shape) is sent once and listed as before.nameFieldasks for nothing more and keeps today's derive ladder. It lists the titles, as before.Ablations (one-off, via
scripts/ablation-replace.mjsin the objectstack checkout; no permanent test)Each mutation landed on disk with the anchor count going 1 to 0. Each was restored and checked: the blob equals HEAD and
git diff HEADis empty....nameFieldsremoved fromextraFields). Blobc025fe82f5a1became49fa09861016. 3 of 6 went red: both (a) pins and the first (b) pin, because that pin assertsfull_namein$select. Restored toc025fe82f5a1, the HEAD blob.affectedRecordNamecondition forced to the full ladder). Blob15c5e833e1ecbecame62e734d67541. Both (b) pins went red, and each receivedVP of EngineeringandDirector of Commercial Systems. That is the card's symptom, reproduced. Restored to15c5e833e1ec, the HEAD blob.Gates (final head
0d08662299; source last changed at85d07587eb, later commits are the test file and the changeset)pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-grid^...' build: exit 0.pnpm --filter @object-ui/plugin-grid run type-check(tsc --noEmitplustsc -p tsconfig.test.json; the new test is in that program by--listFilesOnly): exit 0 on0d08662299.--maxWorkers=1, run under the shared lock: the new file passes 6/6 on0d08662299. The families that touch these files ran on85d07587eb: 69 files, 1771 tests passed. That set is every plugin-grid test mentioning$selector the resolver, plus every test anywhere namingObjectGrid.tsxorBulkActionDialog. The fullpackages/plugin-grid/directory is declared to CI.eslinton the three changed source and test files: 0 errors. The warnings areno-explicit-anyin the test file, the same style as the precedentbulkConfirmRecordTitles-12332test.check:phantom-deps,self-import,unreferenced-sources,doc-example-readers,handler-key-reads,side-effects-array,element-data-source-declaration,spec-symbols,action-forward-parity,designer-field-key-parity,icon-record-names,i18n-keys,i18n-drift,i18n-designer-parity,control-bytes,new-line-citations,check-hand-rolled-comment-mask,check-changeset-fixedandcheck-changeset-presenceall exit 0.check:spec-floorsexits 1 withno-artifact, because the workspace is not fully built. This is a known state of main and is recorded, not acted on.Acceptance notes
plugin-list'sListView, which hands the rows to the grid. Its$selectharvest has no arm for the declarednameField. On such a list, anameFieldthat is not a column now reads asRecord #IDin the confirm step, not as a wrong name, but it is still not the name. The repair is a singleaddSpeculativecall for the declarednameFieldin that harvest.ListViewalready has the matching arms forrowColorandreferenceVia. That is plugin-list, outside the claim, so it is reported to the PM seat and not done here.changeset:@object-ui/plugin-gridpatch.The session that wrote this:
https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB.Generated by Claude Code