Skip to content

finding(app-shell): view-column-io's colLabel/colFieldName still read the retired accessorKey/header aliases, so the column LIST re-shows an identity the column inspector just stopped showing #5725

Description

@os-zhuang

Found while implementing #5344 (retiring the READ tolerance in ViewColumnInspector). Filed unassigned, not claiming. Out of that card's granted file surface (ViewColumnInspector.tsx + its tests only), so recorded rather than fixed.

The fact

packages/app-shell/src/views/metadata-admin/previews/view-column-io.ts carries the same undeclared-alias read that #5344 just retired one file over:

// :29 — colLabel()
return String(o.label ?? o.header ?? o.field ?? o.accessorKey ?? `col ${i + 1}`);
// :39 — colFieldName()
const v = o.field ?? o.accessorKey;

Its sole importer is previews/FieldsListEditor.tsx, which supplies the row labels for the column manager — and FieldsListEditor renders inside ViewColumnInspector's own panel (it is rendered by both ViewVariantInspector and ViewColumnInspector; see that file's header docblock).

Why it is worth recording now

After #5344 the two surfaces disagree within one panel. Measured on the #5344 branch, mounting the real component with a stored column {accessorKey: 'name', header: 'Name'}:

  • the inspector's Field key control shows '' and its Header control shows '' — the ruled behaviour, since ListColumn refuses both keys by name (unrecognized_keys ["accessorKey","header"]);
  • the column list row one line above still reads Name, because colLabel consults o.header.

So the ruling's observable requirement — "the inspector stops presenting a spec-refused spelling as a valid column identity" — is met by the identity controls and not by the list rendered beside them. A pin for exactly this is committed in ViewColumnInspector.identityRead.test.tsx (the test named "records the residue this card is fenced out of"), which asserts getAllByText('Name') has length 1 and carries a comment saying the expectation flips when this is fixed.

Two details worth having before triage

  1. colLabel's precedence is not merely tolerant, it is inverted. The chain is label ?? header ?? field ?? accessorKeyheader is preferred overfield. A perfectly canonical column that also happens to carry a stray header key displays header's value rather than its declared label/field. That is a different (and stronger) defect than the plain ?? accessorKey alias.
  2. colFieldName feeds more than a label. It backs usedFieldNames(), which is what the Add-field picker uses to decide which object fields are already taken. Reading accessorKey there means a spec-refused column still reserves a field name in the picker.

Scope note

Same family as #5068 (renderer), #5120 (packages/components / plugin-dashboard), #5340 (bridgeListView), and #5344 (the column inspector, now fixed). This is the sixth site and the second editor-side one. Whether it should be retired the same way #5344 was, or whether the list deliberately wants a best-effort human label for a column it cannot otherwise name, is a judgement this finding does not take — note the two surfaces are not symmetric: an empty field-key box invites re-authoring, an empty list row would leave the author with nothing to click.

Reproduce

sed -n '1,45p' packages/app-shell/src/views/metadata-admin/previews/view-column-io.ts
grep -rn "view-column-io" packages/app-shell/src --include=*.tsx # sole importer

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions