fix: auto-generate RelatedList columns from object schema metadata#997
fix: auto-generate RelatedList columns from object schema metadata#997
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…umns missing - RecordDetailView: pass api (childObject name) in related entries - RelatedList: fetch object schema via dataSource.getObjectSchema() when api/dataSource available but no explicit columns, then generate columns from field metadata (filtering out _-prefixed internal fields) - Add tests for auto-column generation behavior Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…, simplify condition Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a platform-level bug where the "Related" tab on detail pages rendered empty tables because no column definitions were ever passed to RelatedList. The fix adds schema-driven column auto-generation inside RelatedList using dataSource.getObjectSchema(), consistent with how ObjectGrid, ObjectAgGrid, and ObjectMap already work. It also threads api: childObject from RecordDetailView so RelatedList knows which object to query.
Changes:
RelatedList.tsx— Adds auseEffectto fetch the child object's schema and auseMemo(effectiveColumns) to derive column definitions fromobjectSchema.fieldswhen no explicitcolumnsprop is suppliedRecordDetailView.tsx— Passesapi: childObjectin each related entry soRelatedListcan identify the schema to fetchRelatedList.test.tsx— Adds tests verifying schema-driven column generation and that explicitcolumnsbypass schema fetching
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
packages/plugin-detail/src/RelatedList.tsx |
Core fix: schema fetch effect + effectiveColumns memoization, used in viewSchema |
apps/console/src/components/RecordDetailView.tsx |
Threads api: childObject into each related entry |
packages/plugin-detail/src/__tests__/RelatedList.test.tsx |
New tests for schema-derived columns and bypass behavior |
Two issues found:
1. sortable header rendering doesn't use effectiveColumns (bug)
The sortable column header buttons block (around line 261 in the unchanged portion of RelatedList.tsx) checks columns && columns.length > 0 and iterates columns — the raw prop — instead of effectiveColumns. When sortable={true} is used with no explicit columns (the exact scenario this PR is fixing), the sort buttons will never render even though effectiveColumns contains the schema-derived columns. Only viewSchema was updated to use effectiveColumns; the sort UI was not.
2. Stale objectSchema state when api changes
In the schema fetch useEffect (lines 88–94), there is no setObjectSchema(null) call before the async fetch. If the api prop changes to a new value, the stale schema from the previous object remains visible in effectiveColumns until the new request resolves, potentially briefly showing wrong columns.
| @@ -176,7 +198,7 @@ export const RelatedList: React.FC<RelatedListProps> = ({ | |||
| return { | |||
| type: 'data-table', | |||
| data: paginatedData, | |||
| columns: columns || [], | |||
| columns: effectiveColumns, | |||
There was a problem hiding this comment.
The new effectiveColumns variable (derived from schema when no explicit columns prop is set) is correctly used in viewSchema (line 201), but the sortable column headers rendering block elsewhere in the component still checks columns && columns.length > 0 and iterates over columns (the raw prop), not effectiveColumns. As a result, when sortable={true} is used without an explicit columns prop, the sort buttons will never render even when effectiveColumns has schema-derived values. That block should use effectiveColumns instead of columns.
| React.useEffect(() => { | ||
| if (api && dataSource?.getObjectSchema && !columns?.length) { | ||
| dataSource.getObjectSchema(api).then(setObjectSchema).catch((err: unknown) => { | ||
| console.warn(`[RelatedList] Failed to fetch schema for ${api}:`, err); | ||
| }); | ||
| } | ||
| }, [api, dataSource, columns]); |
There was a problem hiding this comment.
When the api prop changes (e.g., when the component is reused for a different child object), the objectSchema state is not reset to null before the new getObjectSchema() call resolves. This means there's a brief window where the stale schema from the previous api is used to generate effectiveColumns. Adding a setObjectSchema(null) call at the start of the effect (before the async fetch) would prevent briefly showing wrong columns from the old schema.
Detail page "Related" tab renders empty tables for all child objects — title and record count appear but zero columns/rows. The data flow never passes the child object name (
api) toRelatedList, andRelatedListnever consultsdataSource.getObjectSchema()to derive columns, socolumnsfalls back to[].Changes
RecordDetailView.tsx— Passapi: childObjectin related entries so downstream components know which object to queryRelatedList.tsx— WhenapianddataSourceare available butcolumnsis empty, fetch the child object schema and auto-generate column definitions fromobjectSchema.fields, filtering out_-prefixed internal fields:This aligns
RelatedListwith howObjectGrid,ObjectAgGrid, andObjectMapalready usegetObjectSchema()for metadata-driven column generation.Tests
Added tests verifying schema-derived columns render correctly (including
_-prefix exclusion) and that explicitcolumnsprop bypasses schema fetching.Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.