Skip to content

ObjectGrid: accessorKey-format columns bypass type inference — raw dates, no badges, no progress bars #902

Description

@hotlong

Summary

The ObjectGrid rendering pipeline completely skips type inference and cell renderer injection when columns use accessorKey format (data-table format) instead of field format (ListColumn format). This causes all type-aware rendering to break — dates show raw ISO strings, status/priority show plain text, progress shows raw numbers, and user fields show raw IDs.

image1

Root Cause

In ObjectGrid.generateColumns(), the accessorKey branch returns columns as-is with no processing:

// packages/plugin-grid/src/ObjectGrid.tsx L506-514if('accessorKey'infirstCol){returncols;// ← BUG: skips entire inference + renderer pipeline}

Meanwhile the field (ListColumn) branch correctly runs inferColumnType()getCellRenderer() → cell renderer injection. This is a platform-level rendering pipeline gap that affects any view using accessorKey-format column definitions.

Symptoms (all caused by the same root cause)

Column TypeCurrent (broken)Expected
Date (start_date, end_date)2024-02-01T00:00:00.000ZFeb 1, 2024 via DateCellRenderer
Status (status)in_progress (plain text)Colored <Badge> via SelectCellRenderer
Priority (priority)high / critical (plain text)Semantic colored badge (orange/red)
Progress (progress)75 (raw number)Mini progress bar + 75% via PercentCellRenderer
Assignee (assignee)2 (raw ID)Avatar + name via UserCellRenderer

Required Changes

1. [P0] Apply inference to accessorKey-format columns

File:packages/plugin-grid/src/ObjectGrid.tsxgenerateColumns() L506-514

When columns are in accessorKey format, iterate and apply inferColumnType() + getCellRenderer() for columns that don't already have a cell renderer:

if('accessorKey'infirstCol){return(colsasany[]).map((col,colIndex)=>{if(col.cell)returncol;// already has custom rendererconstsyntheticCol={field: col.accessorKey,label: col.header,type: col.type};constinferredType=inferColumnType(syntheticCol);if(!inferredType)returncol;constCellRenderer=getCellRenderer(inferredType);constfieldMeta={name: col.accessorKey,type: inferredType};if(inferredType==='select'){constuniqueValues=Array.from(newSet(data.map(row=>row[col.accessorKey]).filter(Boolean)));fieldMeta.options=uniqueValues.map(v=>({value: v,label: humanizeLabel(String(v))}));}return{
...col,headerIcon: getTypeIcon(inferredType),cell: (value,row)=><CellRenderervalue={value}field={fieldMeta}/>,};});}

2. [P1] Auto-humanize snake_case select labels

File:packages/fields/src/index.tsxSelectCellRenderer

Add and export a humanizeLabel() utility, use as fallback when no option.label exists:

exportfunctionhumanizeLabel(value: string): string{returnvalue.replace(/[_-]/g,' ').replace(/\b\w/g,c=>c.toUpperCase());}// In SelectCellRenderer:constlabel=option?.label||humanizeLabel(String(value));

Also apply in ObjectGrid.generateColumns() when auto-generating options from data values.

3. [P1] PercentCellRenderer value normalization for progress fields

File:packages/fields/src/index.tsxPercentCellRenderer

Use field name to disambiguate 0-1 fraction vs 0-100 whole number:

constisWholePercentField=/progress|completion/.test(field?.name?.toLowerCase()||'');constbarValue=isWholePercentField
? numValue
: (numValue>-1&&numValue<1) ? numValue*100 : numValue;

Affected Packages

  • packages/plugin-grid/src/ObjectGrid.tsx — core fix
  • packages/fields/src/index.tsxSelectCellRenderer, PercentCellRenderer, humanizeLabel()

Acceptance Criteria

  • accessorKey-format columns receive type inference via inferColumnType()
  • Inferred types get appropriate getCellRenderer() cell renderers applied
  • Columns with existing cell renderer are NOT overridden
  • snake_case select values display as Title Case (e.g., in_progressIn Progress)
  • Explicit option.label still takes priority over humanized fallback
  • progress field with value 75 renders as 75% with correctly filled bar
  • probability field with value 0.75 renders as 75%
  • All existing tests pass; new tests added for:
    • accessorKey-format inference path
    • humanizeLabel() edge cases
    • PercentCellRenderer with progress-type fields
  • ROADMAP.md updated

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions