Skip to content

Commit f9a80e8

Browse files
Copilothotlong
andcommitted
fix: add type-aware cell renderers to RelatedList columns and i18n fallback section title
- RelatedList auto-generated columns now use getCellRenderer for type-aware rendering (dates, currencies, selects/badges, lookups, booleans, etc.) - RecordDetailView fallback section title uses t('detail.details') instead of hardcoded 'Details' - Updated ROADMAP.md with new items Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent cc38668 commit f9a80e8

3 files changed

Lines changed: 37 additions & 7 deletions

File tree

ROADMAP.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,8 @@ All 313 `@object-ui/fields` tests pass.
14991499
- [x] `objectName` threaded through `DetailView``SectionGroup``DetailSection` / `HeaderHighlight` / `RelatedList`
15001500
- [x] RelatedList sortable headers fixed to use `effectiveColumns` (auto-generated from schema) instead of raw `columns` prop
15011501
- [x] Added missing `detail.*` i18n keys (`activity`, `editRow`, `deleteRow`, `previousPage`, `nextPage`, etc.) to en.ts and zh.ts
1502+
- [x] RelatedList auto-generated columns use `getCellRenderer` for type-aware cell rendering (date, currency, select/badge, lookup, boolean, etc.)
1503+
- [x] Console `RecordDetailView` fallback section title uses `t('detail.details')` instead of hardcoded English
15021504

15031505
---
15041506

apps/console/src/components/RecordDetailView.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { DetailView, RecordChatterPanel } from '@object-ui/plugin-detail';
1212
import { Empty, EmptyTitle, EmptyDescription } from '@object-ui/components';
1313
import { PresenceAvatars, type PresenceUser } from '@object-ui/collaboration';
1414
import { useAuth } from '@object-ui/auth';
15-
import { ActionProvider } from '@object-ui/react';
15+
import { ActionProvider, useObjectTranslation } from '@object-ui/react';
1616
import { toast } from 'sonner';
1717
import { Database, Users } from 'lucide-react';
1818
import { MetadataPanel, useMetadataInspector } from './MetadataInspector';
@@ -38,6 +38,7 @@ export function RecordDetailView({ dataSource, objects, onEdit }: RecordDetailVi
3838
const { showDebug } = useMetadataInspector();
3939
const { user } = useAuth();
4040
const navigate = useNavigate();
41+
const { t } = useObjectTranslation();
4142
const [isLoading, setIsLoading] = useState(true);
4243
const [feedItems, setFeedItems] = useState<FeedItem[]>([]);
4344
const [recordViewers, setRecordViewers] = useState<PresenceUser[]>([]);
@@ -368,7 +369,7 @@ export function RecordDetailView({ dataSource, objects, onEdit }: RecordDetailVi
368369
}))
369370
: [
370371
{
371-
title: 'Details',
372+
title: t('detail.details', { defaultValue: 'Details' }),
372373
fields: Object.keys(objectDef.fields || {}).map(key => {
373374
const fieldDef = objectDef.fields[key];
374375
const refTarget = fieldDef.reference_to || fieldDef.reference;

packages/plugin-detail/src/RelatedList.tsx

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import {
2525
ChevronRight,
2626
ArrowUpDown,
2727
} from 'lucide-react';
28-
import type { DataSource } from '@object-ui/types';
28+
import type { DataSource, FieldMetadata } from '@object-ui/types';
29+
import { getCellRenderer } from '@object-ui/fields';
2930
import { useDetailTranslation } from './useDetailTranslation';
3031
import { useSafeFieldLabel } from '@object-ui/react';
3132

@@ -188,10 +189,36 @@ export const RelatedList: React.FC<RelatedListProps> = ({
188189
const resolvedObjectName = objectName || api || '';
189190
return Object.entries(objectSchema.fields)
190191
.filter(([key]) => !key.startsWith('_'))
191-
.map(([key, def]: [string, any]) => ({
192-
accessorKey: key,
193-
header: resolveFieldLabel(resolvedObjectName, key, def.label || key),
194-
}));
192+
.map(([key, def]: [string, any]) => {
193+
const col: any = {
194+
accessorKey: key,
195+
header: resolveFieldLabel(resolvedObjectName, key, def.label || key),
196+
};
197+
// Add type-aware cell renderer for typed fields
198+
if (def.type) {
199+
const CellRenderer = getCellRenderer(def.type);
200+
if (CellRenderer) {
201+
const fieldMeta: FieldMetadata = {
202+
name: key,
203+
label: def.label || key,
204+
type: def.type,
205+
...(def.options && { options: def.options }),
206+
...(def.currency && { currency: def.currency }),
207+
...(def.precision !== undefined && { precision: def.precision }),
208+
...(def.format && { format: def.format }),
209+
...((def.reference_to || def.reference) && { reference_to: def.reference_to || def.reference }),
210+
...(def.reference_field && { reference_field: def.reference_field }),
211+
};
212+
col.cell = (value: any) => {
213+
if (value === null || value === undefined) {
214+
return React.createElement('span', { className: 'text-muted-foreground/50 text-xs italic' }, '—');
215+
}
216+
return React.createElement(CellRenderer, { value, field: fieldMeta });
217+
};
218+
}
219+
}
220+
return col;
221+
});
195222
}, [columns, objectSchema, objectName, api, resolveFieldLabel]);
196223

197224
const viewSchema = React.useMemo(() => {

0 commit comments

Comments
 (0)