Wire up detail page autoTabs, autoDiscoverRelated, highlightFields, sectionGroups + reverse-reference child discovery in Console RecordDetailView - #985
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…Groups in Console RecordDetailView Passes autoTabs, autoDiscoverRelated, highlightFields, and sectionGroups from object definitions to the DetailView component schema, enabling: - Tab layout (Details/Related/Activity) - Auto-discovery of related tables from reference fields - Header highlight area with key fields (status, stage, priority, etc.) - Collapsible section groups from object definition config Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…vel, improve test assertions Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot 评估是否完成了任务中要求的所有开发,比如我进入订单的详情页还是看不到订单明细的列表 |
- RecordDetailView now scans all objects for lookup/master_detail fields pointing back to the current object (e.g., order_item.order → order), fetches filtered child records, and passes them as explicit related entries - DetailView's effectiveRelated now passes api: objectName for auto-discovered forward references so RelatedList can fetch data via dataSource - RelatedList syncs internal state when data prop changes (fixes stale initial state from useState(data)) Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…ncellation, log errors Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Found the root cause and fixed in
Now when viewing an order detail page, |
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot 还是不行,在订单详情页还是看不到订单明细 |
…ta string
The $filter was being passed as an OData string ("order eq 'o1'") but the
ObjectStackAdapter.convertQueryParams expects a Record<string, any> object
which gets converted to FilterNode AST. A string filter was silently mangled
by Object.entries() treating each character as a key, resulting in no matching
records returned.
Changed to: { [referenceField]: pureRecordId } which produces the correct
filter AST ['order', '=', 'o1'] for the backend query.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Found the root cause in Fixed by changing to object format: All 762 console tests and 295 plugin-detail tests pass. |
|
@copilot 订单的详情页还是看不到订单明细的列表 |
…' for lookup field discovery
The ObjectStack metadata API returns field definitions with `reference`
(e.g., `{ type: 'lookup', reference: 'order' }`) while ObjectUI code
checked only `reference_to`. This caused childRelations discovery and
auto-discovered related lists to always be empty since the property
was never matched. Now both property names are supported.
Fixed in: RecordDetailView.tsx (childRelations + section builder),
DetailView.tsx (discoveredRelated), DetailSection.tsx (field enrichment).
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…esolution Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Root cause found and fixed in Fixed in 4 files to check both
Verified with 762 console tests + 295 plugin-detail tests, all passing. |
There was a problem hiding this comment.
Pull request overview
This PR wires the Console record detail page to leverage newer @object-ui/plugin-detail capabilities (auto tabs, auto related discovery, highlight banner, section grouping), adds reverse-reference child discovery/fetching in RecordDetailView, and updates tests + roadmap to reflect end-to-end availability.
Changes:
- Sync
RelatedListinternal state whendataprop changes to fix stale rendering for async parent fetches. - Enhance detail/section logic to support both
reference_toand ObjectStack’sreferencefield metadata, and passapifor auto-discovered forward refs. - Add Console reverse-reference child discovery +
$filterobject-format fetch, and passautoTabs/autoDiscoverRelated/highlightFields/sectionGroupsintoDetailView, with new Console tests.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/plugin-detail/src/RelatedList.tsx | Syncs internal related list state from data prop updates. |
| packages/plugin-detail/src/DetailView.tsx | Supports reference metadata + passes api for discovered relations. |
| packages/plugin-detail/src/DetailSection.tsx | Enriches lookup/master_detail fields using `reference_to |
| apps/console/src/components/RecordDetailView.tsx | Adds reverse-reference child discovery/fetching and wires new DetailView schema features. |
| apps/console/src/tests/RecordDetailEdit.test.tsx | Adds coverage for tabs, discovered related, highlight fields, and reverse refs in Console. |
| ROADMAP.md | Marks Console integration + reverse-reference discovery as completed. |
| return discoveredRelated.map((r) => ({ | ||
| title: r.title, | ||
| type: r.type, | ||
| api: r.objectName, |
There was a problem hiding this comment.
effectiveRelated now sets api: r.objectName, which causes RelatedList to call dataSource.find(api) with no query/filter. For lookup/master_detail fields this will fetch all records of the referenced object, which is likely incorrect and can be very expensive in Console where autoDiscoverRelated: true is always enabled. Consider either (a) not auto-fetching for discovered relations, or (b) extending the related schema/RelatedList to pass query params and use the current record’s lookup value to filter to the referenced record(s).
| return discoveredRelated.map((r) => ({ | |
| title: r.title, | |
| type: r.type, | |
| api: r.objectName, | |
| // For auto-discovered relations, do not set `api` to avoid unfiltered fetches. | |
| // These entries can still be used by consumers that understand the discovery metadata. | |
| return discoveredRelated.map((r) => ({ | |
| title: r.title, | |
| type: r.type, |
| if (cancelled) return; | ||
| const data: Record<string, any[]> = {}; | ||
| for (const { childObject, items } of results) { | ||
| data[childObject] = items; |
There was a problem hiding this comment.
Reverse-reference fetching stores results in an object keyed only by childObject. If the same child object has multiple lookup/master_detail fields pointing to the current object (common for e.g. billingAccount vs shippingAccount), later results will overwrite earlier ones and the rendered related sections can show incorrect data. Use a key that includes referenceField (and reflect that key in the related entries), or de-duplicate/merge relations per (childObject, referenceField).
| data[childObject] = items; | |
| if (!data[childObject]) { | |
| data[childObject] = []; | |
| } | |
| data[childObject] = data[childObject].concat(items); |
| const related = childRelations.map(({ childObject, childLabel }) => ({ | ||
| title: childLabel, | ||
| type: 'table' as const, | ||
| data: childRelatedData[childObject] || [], | ||
| })); |
There was a problem hiding this comment.
related entries are built without carrying through the referenceField discovered in childRelations. This makes it impossible to distinguish multiple relations to the same child object and prevents downstream components from knowing which field was used for the reverse-reference filter. Consider including referenceField (or a stable relation key) in each related entry so future enhancements (View All / inline create / refetch) can target the correct relationship.
| const related = childRelations.map(({ childObject, childLabel }) => ({ | |
| title: childLabel, | |
| type: 'table' as const, | |
| data: childRelatedData[childObject] || [], | |
| })); | |
| const related = childRelations.map( | |
| ({ childObject, childLabel, referenceField }) => ({ | |
| title: childLabel, | |
| type: 'table' as const, | |
| data: childRelatedData[childObject] || [], | |
| referenceField, | |
| }), | |
| ); |
Console
RecordDetailViewconstructs adetailSchemabut omits the new plugin-detail features (autoTabs,autoDiscoverRelated,highlightFields,sectionGroups), so none of them render despite being fully implemented in@object-ui/plugin-detail. Additionally, child objects referencing the current record (e.g.,order_item→order) were not discovered or displayed.Changes
RecordDetailView.tsx: PassautoTabs: trueandautoDiscoverRelated: trueto enable tab layout and automatic related table discovery from reference fields. Auto-detecthighlightFieldsfrom well-known field names (status, stage, priority, amount, etc.) with override viaobjectDef.views.detail.highlightFields. ForwardsectionGroupsfrom object definition config. Added reverse-reference discovery: scans all objects forlookup/master_detailfields pointing back to the current object (e.g.,order_item.order→order), fetches filtered child records viadataSource.find(childObject, { $filter }), and passes them as explicitrelatedentries in the schema. UsesPromise.allwith cancellation and sanitized record IDs.DetailView.tsx: FixedeffectiveRelatedto passapi: r.objectNamefor auto-discovered forward references soRelatedListcan fetch data viadataSource. FixeddiscoveredRelatedto check bothreference_toandreferencefield properties for ObjectStack metadata compatibility.DetailSection.tsx: Fixed field enrichment to resolve reference target from bothreference_toandreferenceproperties on objectSchema fields.RelatedList.tsx: AddeduseEffectto sync internalrelatedDatastate when thedataprop changes, fixing stale initial state fromuseState(data).RecordDetailEdit.test.tsx: Four new integration tests covering auto tabs rendering, forward related list discovery from lookup fields, highlight field display, and reverse-reference child object discovery with filtered data fetching. Tests use ObjectStack-conventionreferenceproperty to match real runtime metadata.ROADMAP.md: Mark Console end-to-end integration and reverse-reference discovery as complete under P1.15.Key bug fixes
$filterformat — Changed from OData string ("order eq 'o1'") to object format ({ order: 'o1' }) matchingQueryParams.$filter: Record<string, any>. The string format was silently mangled byconvertFiltersToAST()treating character indices as keys, resulting in zero matching records.Field property name mismatch — ObjectStack metadata API returns lookup field references as
reference(e.g.,{ type: 'lookup', reference: 'order' }), but ObjectUI code only checkedreference_to. This causedchildRelationsdiscovery and auto-discovered related lists to always be empty. Fixed by checking bothreference_toandreferenceviarefTarget = fieldDef.reference_to || fieldDef.referencein RecordDetailView, DetailView, and DetailSection.Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.