Commit 6ae818e
Column field identity was resolved twice with two different precedences over
the same `schema.columns` array, and the two halves disagreed:
request path ListView's `$expand` / `$select` builders and
ObjectGrid.getSelectFields read `f?.field` and ONLY that.
render path the FLS gate, the hidden-field filter, `fieldOrder`, both
export branches and the hide-fields popover read
`f.name || f.fieldName || f.field` — name FIRST.
So `{field:'account', name:'account_name'}` fetched `account` while the
renderer keyed off `account_name`, and `{name:'account'}` rendered a column
the request dropped entirely. That is the mechanism behind the "relation
column shows a bare id / column is empty / sort does nothing / export is
missing a column" defect class.
Per AGENTS.md #0.1 the fix is not another `?? name` at the read sites. Legacy
acceptance moves to the boundary that already folds this view's vocabulary:
`normalizeListViewSchema` now canonicalizes each column's identity too,
running after the `fields` -> `columns` rename so a doubly-legacy view is
fixed on both axes in one pass.
New in @object-ui/core (`utils/column-identity.ts`):
columnIdentity() the single reader, canonical-first
normalizeColumnIdentity(-ies)() the fold
hasConflictingColumnIdentity() true when a column's keys disagree
The fold MIRRORS rather than deletes the legacy key, unlike the other folds in
normalizeListViewSchema. Deleting works in-repo (every name-first read falls
through to `field`), but `columns` entries cross the package boundary into host
renderers and dropping `name` from under them is a breaking change with no
inventory. An absent legacy key is never invented, and an already-canonical
column is returned by reference so ListView's useMemo deps stay stable.
`accessorKey` is deliberately untouched: it is TanStack Table's column key
(`TableColumn.accessorKey`), not ObjectStack metadata identity.
Tests:
- ListView.columnIdentity.test.tsx — the repro through the real ListView.
`checkField` is the observable: BOTH paths call it, so a column whose keys
disagree checks two different field names. Now exactly one.
- column-identity.ratchet.test.ts — the 34-site inventory with a per-site
precedence and verdict; a new dual read, or an extra one in a listed file,
fails. Shrinking fails too, so the tree and the record cannot drift.
The inventory corrects the issue's framing in two places: resolveActionParams
(3) and dashboard-filters (1) carry BOTH orders legitimately — `name` and
`field` are separately declared there and mean different things, so those are
two layers, not two spellings. The real pollution is worse than "two orders
coexist": ListView and ObjectGrid each disagree with themselves.
Behaviour is unchanged for any column carrying a single identity key. The
entries whose resolution moves are exactly the ones where two sites already
disagreed.
Refs: objectstack#4115, #3090 (playbook), #2598 (chokepoint precedent)
Claude-Session: https://claude.ai/code/session_01C2pdPmf2yZSd4wFDs1NHY5
Co-authored-by: Claude <noreply@anthropic.com>
1 parent bac266c commit 6ae818e
8 files changed
Lines changed: 970 additions & 1 deletion
File tree
- .changeset
- content/docs/guide
- packages
- core/src
- utils
- __tests__
- plugin-list/src/__tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
282 | 282 | | |
283 | 283 | | |
284 | 284 | | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
285 | 329 | | |
286 | 330 | | |
287 | 331 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| 21 | + | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
| |||
0 commit comments