-
Notifications
You must be signed in to change notification settings - Fork 2
fix: auto-generate RelatedList columns from object schema metadata #997
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,13 +76,23 @@ export const RelatedList: React.FC<RelatedListProps> = ({ | |
| const [sortField, setSortField] = React.useState<string | null>(null); | ||
| const [sortDirection, setSortDirection] = React.useState<'asc' | 'desc'>('asc'); | ||
| const [filterText, setFilterText] = React.useState(''); | ||
| const [objectSchema, setObjectSchema] = React.useState<any>(null); | ||
| const { t } = useDetailTranslation(); | ||
|
|
||
| // Sync internal state when data prop changes (e.g., parent fetches async data) | ||
| React.useEffect(() => { | ||
| setRelatedData(data); | ||
| }, [data]); | ||
|
|
||
| // Auto-fetch object schema when api/dataSource available but columns missing | ||
| 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]); | ||
|
|
||
| React.useEffect(() => { | ||
| if (api && !data.length) { | ||
| setLoading(true); | ||
|
|
@@ -166,6 +176,18 @@ export const RelatedList: React.FC<RelatedListProps> = ({ | |
| } | ||
| }, [onRowDelete, t]); | ||
|
|
||
| // Generate effective columns from explicit prop or object schema fields | ||
| const effectiveColumns = React.useMemo(() => { | ||
| if (columns && columns.length > 0) return columns; | ||
| if (!objectSchema?.fields) return []; | ||
| return Object.entries(objectSchema.fields) | ||
| .filter(([key]) => !key.startsWith('_')) | ||
| .map(([key, def]: [string, any]) => ({ | ||
| accessorKey: key, | ||
| header: def.label || key, | ||
| })); | ||
| }, [columns, objectSchema]); | ||
|
|
||
| const viewSchema = React.useMemo(() => { | ||
| if (schema) return schema; | ||
|
|
||
|
|
@@ -176,7 +198,7 @@ export const RelatedList: React.FC<RelatedListProps> = ({ | |
| return { | ||
| type: 'data-table', | ||
| data: paginatedData, | ||
| columns: columns || [], | ||
| columns: effectiveColumns, | ||
|
Comment on lines
180
to
+201
|
||
| pagination: false, // We handle pagination ourselves | ||
| pageSize: effectivePageSize || 10, | ||
| }; | ||
|
|
@@ -188,7 +210,7 @@ export const RelatedList: React.FC<RelatedListProps> = ({ | |
| default: | ||
| return { type: 'div', children: 'No view configured' }; | ||
| } | ||
| }, [type, paginatedData, columns, schema, effectivePageSize]); | ||
| }, [type, paginatedData, effectiveColumns, schema, effectivePageSize]); | ||
|
|
||
| const recordCountText = relatedData.length === 1 | ||
| ? t('detail.relatedRecordOne', { count: relatedData.length }) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the
apiprop changes (e.g., when the component is reused for a different child object), theobjectSchemastate is not reset tonullbefore the newgetObjectSchema()call resolves. This means there's a brief window where the stale schema from the previousapiis used to generateeffectiveColumns. Adding asetObjectSchema(null)call at the start of the effect (before the async fetch) would prevent briefly showing wrong columns from the old schema.