diff --git a/react-openapi/components/EnhancedTable.tsx b/react-openapi/components/EnhancedTable.tsx index 22be2f0..cad20b2 100644 --- a/react-openapi/components/EnhancedTable.tsx +++ b/react-openapi/components/EnhancedTable.tsx @@ -31,7 +31,7 @@ import VisibilityIcon from '@mui/icons-material/Visibility'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import { useNavigate } from 'react-router-dom'; import { ResourceConfig } from '../types/config'; -import { getFieldOptions, toGridValueOptions } from '../utils/options'; +import { getFieldOptions, toGridValueOptions, resolveTemplate } from '../utils/options'; interface EnhancedTableProps { config: ResourceConfig; @@ -274,8 +274,9 @@ function MobileCardRow({ row, config, onDelete, onNavigate, navigate }: any) { ); } -function getFormattedDisplayValue(item: any, displayField?: string | string[]) { +function getFormattedDisplayValue(item: any, displayField?: string | string[], enumValue?: string) { if (!item) return ""; + if (enumValue) return resolveTemplate(enumValue, item); if (!displayField) return item.name || item.title || item.label || item.id || JSON.stringify(item); if (Array.isArray(displayField)) { @@ -297,7 +298,7 @@ function FieldRenderer({ params, field, fieldKey, config, onNavigate, navigate, // 1. Single Relation if (field.relation && value && !Array.isArray(value)) { const relationId = typeof value === 'object' ? (value.id || value._id || value.pk) : value; - const displayValue = getFormattedDisplayValue(value, field.displayField); + const displayValue = getFormattedDisplayValue(value, field.displayField, field.enumOption?.value); return ( getFormattedDisplayValue(item, field.displayField)).join(', '); + const enumValue = field.enumOption?.value; + const tooltipTitle = value.map((item) => getFormattedDisplayValue(item, field.displayField, enumValue)).join(', '); return ( @@ -324,7 +326,7 @@ function FieldRenderer({ params, field, fieldKey, config, onNavigate, navigate, {value.map((item, idx) => ( item[k]).filter((v) => v != null); if (parts.length > 0) return parts.join(" "); - } else { - const v = item[df]; - if (v != null) return String(v); } + const v = item[df]; + if (v != null) return String(v); - debugger; return null; }; diff --git a/react-openapi/components/ResourceView.tsx b/react-openapi/components/ResourceView.tsx index d75b439..e6ab18d 100644 --- a/react-openapi/components/ResourceView.tsx +++ b/react-openapi/components/ResourceView.tsx @@ -3,6 +3,7 @@ import { Box, Paper, CircularProgress } from '@mui/material'; import { ResourceConfig } from '../types/config'; import type { ResourceField } from '../types/config'; import { useResource } from '../hooks/useResource'; +import { resolveTemplate } from '../utils/options'; import GenericForm from './GenericForm'; import EnhancedTable from './EnhancedTable'; import FilterBar from './FilterBar'; @@ -61,6 +62,7 @@ function applyClientFilters( if (field.type === "array" && Array.isArray(itemValue)) { return itemValue.some((el: any) => { if (el != null && typeof el === "object") { + if (field.enumOption?.value) return filterValue.includes(resolveTemplate(field.enumOption.value, el)); const dispFields = getFilterDisplayFields(field); return dispFields.some((df) => filterValue.includes(String(el[df]))); } @@ -68,6 +70,7 @@ function applyClientFilters( }); } if (itemValue && typeof itemValue === "object") { + if (field.enumOption?.value) return filterValue.includes(resolveTemplate(field.enumOption.value, itemValue)); const dispFields = getFilterDisplayFields(field); const itemDisplay = dispFields.map((df) => itemValue[df]).filter((v) => v != null).join(" "); return filterValue.includes(itemDisplay); @@ -84,6 +87,7 @@ function applyClientFilters( if (field.type === "array" && Array.isArray(itemValue)) { return itemValue.some((el: any) => { if (el != null && typeof el === "object") { + if (field.enumOption?.value) return resolveTemplate(field.enumOption.value, el) === String(filterValue); const dispFields = getFilterDisplayFields(field); return dispFields.some((df) => String(el[df]) === String(filterValue)); } @@ -92,6 +96,7 @@ function applyClientFilters( } if (itemValue && typeof itemValue === "object") { + if (field.enumOption?.value) return resolveTemplate(field.enumOption.value, itemValue) === String(filterValue); const dispFields = getFilterDisplayFields(field); return dispFields.some((df) => String(itemValue[df]) === String(filterValue)); } diff --git a/react-openapi/types/config.ts b/react-openapi/types/config.ts index d0b46b3..b7be75d 100644 --- a/react-openapi/types/config.ts +++ b/react-openapi/types/config.ts @@ -17,7 +17,7 @@ export interface SelectOption { export interface EnumOption { key: string; - value: string | string[]; + value: string; } export interface ResourceField { diff --git a/react-openapi/types/overrides.ts b/react-openapi/types/overrides.ts index e3dbfe8..89267be 100644 --- a/react-openapi/types/overrides.ts +++ b/react-openapi/types/overrides.ts @@ -1,6 +1,6 @@ export interface EnumOption { key: string; - value: string | string[]; + value: string; } export interface FieldOverride { diff --git a/react-openapi/utils/options.ts b/react-openapi/utils/options.ts index 4914b3b..c8c3995 100644 --- a/react-openapi/utils/options.ts +++ b/react-openapi/utils/options.ts @@ -1,5 +1,12 @@ import { ResourceField, SelectOption } from "../types/config"; +export function resolveTemplate(template: string, item: any): string { + if (/\{(\w+)\}/.test(template)) { + return template.replace(/\{(\w+)\}/g, (_, field: string) => String(item[field] ?? '')); + } + return String(item[template] ?? ''); +} + export function getFieldOptions(field: ResourceField, relationData?: any[]): SelectOption[] { if (field.type === 'enum' && field.options) { return field.options.map(opt => ({ @@ -14,9 +21,7 @@ export function getFieldOptions(field: ResourceField, relationData?: any[]): Sel return data.map(item => ({ key: String(item[enumOption.key] ?? ''), - value: Array.isArray(enumOption.value) - ? enumOption.value.map(k => item[k]).filter(v => v != null).join(' ') - : String(item[enumOption.value] ?? ''), + value: resolveTemplate(enumOption.value, item), })); } diff --git a/src/openapi-config.ts b/src/openapi-config.ts index 57eb1a2..ef1a95f 100644 --- a/src/openapi-config.ts +++ b/src/openapi-config.ts @@ -53,13 +53,13 @@ export const configuration: Record = { accounts: { enumOption: { key: 'id', - value: ['name', 'number'] + value: '{name} - XXXX{number}' } }, tags: { enumOption: { key: 'id', - value: ['icon', 'name'] + value: '{icon} {name}' } }, };