enumOptions and enum reader used everywhere
This commit is contained in:
@@ -31,7 +31,7 @@ import VisibilityIcon from '@mui/icons-material/Visibility';
|
|||||||
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { ResourceConfig } from '../types/config';
|
import { ResourceConfig } from '../types/config';
|
||||||
import { getFieldOptions, toGridValueOptions } from '../utils/options';
|
import { getFieldOptions, toGridValueOptions, resolveTemplate } from '../utils/options';
|
||||||
|
|
||||||
interface EnhancedTableProps {
|
interface EnhancedTableProps {
|
||||||
config: ResourceConfig;
|
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 (!item) return "";
|
||||||
|
if (enumValue) return resolveTemplate(enumValue, item);
|
||||||
if (!displayField) return item.name || item.title || item.label || item.id || JSON.stringify(item);
|
if (!displayField) return item.name || item.title || item.label || item.id || JSON.stringify(item);
|
||||||
|
|
||||||
if (Array.isArray(displayField)) {
|
if (Array.isArray(displayField)) {
|
||||||
@@ -297,7 +298,7 @@ function FieldRenderer({ params, field, fieldKey, config, onNavigate, navigate,
|
|||||||
// 1. Single Relation
|
// 1. Single Relation
|
||||||
if (field.relation && value && !Array.isArray(value)) {
|
if (field.relation && value && !Array.isArray(value)) {
|
||||||
const relationId = typeof value === 'object' ? (value.id || value._id || value.pk) : 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 (
|
return (
|
||||||
<Chip
|
<Chip
|
||||||
@@ -316,7 +317,8 @@ function FieldRenderer({ params, field, fieldKey, config, onNavigate, navigate,
|
|||||||
|
|
||||||
// 2. Multi-Select (Array of relations or simple strings)
|
// 2. Multi-Select (Array of relations or simple strings)
|
||||||
if (field.type === 'array' && Array.isArray(value)) {
|
if (field.type === 'array' && Array.isArray(value)) {
|
||||||
const tooltipTitle = value.map((item) => getFormattedDisplayValue(item, field.displayField)).join(', ');
|
const enumValue = field.enumOption?.value;
|
||||||
|
const tooltipTitle = value.map((item) => getFormattedDisplayValue(item, field.displayField, enumValue)).join(', ');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip title={tooltipTitle} arrow placement="top">
|
<Tooltip title={tooltipTitle} arrow placement="top">
|
||||||
@@ -324,7 +326,7 @@ function FieldRenderer({ params, field, fieldKey, config, onNavigate, navigate,
|
|||||||
{value.map((item, idx) => (
|
{value.map((item, idx) => (
|
||||||
<Chip
|
<Chip
|
||||||
key={idx}
|
key={idx}
|
||||||
label={getFormattedDisplayValue(item, field.displayField)}
|
label={getFormattedDisplayValue(item, field.displayField, enumValue)}
|
||||||
size="small"
|
size="small"
|
||||||
variant="filled"
|
variant="filled"
|
||||||
sx={{ maxWidth: 120 }}
|
sx={{ maxWidth: 120 }}
|
||||||
@@ -344,7 +346,7 @@ function FieldRenderer({ params, field, fieldKey, config, onNavigate, navigate,
|
|||||||
|
|
||||||
// 3. Simple Objects
|
// 3. Simple Objects
|
||||||
if (field.type === 'object' && value) {
|
if (field.type === 'object' && value) {
|
||||||
return getFormattedDisplayValue(value, field.displayField) || (isMobile ? 'Object' : JSON.stringify(value));
|
return getFormattedDisplayValue(value, field.displayField, field.enumOption?.value) || (isMobile ? 'Object' : JSON.stringify(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.type === 'number' && typeof value === 'number') {
|
if (field.type === 'number' && typeof value === 'number') {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
import DoneIcon from "@mui/icons-material/Done";
|
import DoneIcon from "@mui/icons-material/Done";
|
||||||
import FilterListIcon from "@mui/icons-material/FilterList";
|
import FilterListIcon from "@mui/icons-material/FilterList";
|
||||||
import { ResourceField, ResourceMode } from "../types/config";
|
import { ResourceField, ResourceMode } from "../types/config";
|
||||||
import { getFieldOptions } from "../utils/options";
|
import { getFieldOptions, resolveTemplate } from "../utils/options";
|
||||||
|
|
||||||
function FilterAutocomplete({
|
function FilterAutocomplete({
|
||||||
options,
|
options,
|
||||||
@@ -121,18 +121,18 @@ function extractOptions(
|
|||||||
if (typeof item === "string") return item;
|
if (typeof item === "string") return item;
|
||||||
if (typeof item !== "object") return String(item);
|
if (typeof item !== "object") return String(item);
|
||||||
|
|
||||||
|
if (field.enumOption?.value) return resolveTemplate(field.enumOption.value, item);
|
||||||
|
|
||||||
const df = field.displayField;
|
const df = field.displayField;
|
||||||
if (!df) { debugger; return null; }
|
if (!df) return null;
|
||||||
|
|
||||||
if (Array.isArray(df)) {
|
if (Array.isArray(df)) {
|
||||||
const parts = df.map((k) => item[k]).filter((v) => v != null);
|
const parts = df.map((k) => item[k]).filter((v) => v != null);
|
||||||
if (parts.length > 0) return parts.join(" ");
|
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;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Box, Paper, CircularProgress } from '@mui/material';
|
|||||||
import { ResourceConfig } from '../types/config';
|
import { ResourceConfig } from '../types/config';
|
||||||
import type { ResourceField } from '../types/config';
|
import type { ResourceField } from '../types/config';
|
||||||
import { useResource } from '../hooks/useResource';
|
import { useResource } from '../hooks/useResource';
|
||||||
|
import { resolveTemplate } from '../utils/options';
|
||||||
import GenericForm from './GenericForm';
|
import GenericForm from './GenericForm';
|
||||||
import EnhancedTable from './EnhancedTable';
|
import EnhancedTable from './EnhancedTable';
|
||||||
import FilterBar from './FilterBar';
|
import FilterBar from './FilterBar';
|
||||||
@@ -61,6 +62,7 @@ function applyClientFilters(
|
|||||||
if (field.type === "array" && Array.isArray(itemValue)) {
|
if (field.type === "array" && Array.isArray(itemValue)) {
|
||||||
return itemValue.some((el: any) => {
|
return itemValue.some((el: any) => {
|
||||||
if (el != null && typeof el === "object") {
|
if (el != null && typeof el === "object") {
|
||||||
|
if (field.enumOption?.value) return filterValue.includes(resolveTemplate(field.enumOption.value, el));
|
||||||
const dispFields = getFilterDisplayFields(field);
|
const dispFields = getFilterDisplayFields(field);
|
||||||
return dispFields.some((df) => filterValue.includes(String(el[df])));
|
return dispFields.some((df) => filterValue.includes(String(el[df])));
|
||||||
}
|
}
|
||||||
@@ -68,6 +70,7 @@ function applyClientFilters(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (itemValue && typeof itemValue === "object") {
|
if (itemValue && typeof itemValue === "object") {
|
||||||
|
if (field.enumOption?.value) return filterValue.includes(resolveTemplate(field.enumOption.value, itemValue));
|
||||||
const dispFields = getFilterDisplayFields(field);
|
const dispFields = getFilterDisplayFields(field);
|
||||||
const itemDisplay = dispFields.map((df) => itemValue[df]).filter((v) => v != null).join(" ");
|
const itemDisplay = dispFields.map((df) => itemValue[df]).filter((v) => v != null).join(" ");
|
||||||
return filterValue.includes(itemDisplay);
|
return filterValue.includes(itemDisplay);
|
||||||
@@ -84,6 +87,7 @@ function applyClientFilters(
|
|||||||
if (field.type === "array" && Array.isArray(itemValue)) {
|
if (field.type === "array" && Array.isArray(itemValue)) {
|
||||||
return itemValue.some((el: any) => {
|
return itemValue.some((el: any) => {
|
||||||
if (el != null && typeof el === "object") {
|
if (el != null && typeof el === "object") {
|
||||||
|
if (field.enumOption?.value) return resolveTemplate(field.enumOption.value, el) === String(filterValue);
|
||||||
const dispFields = getFilterDisplayFields(field);
|
const dispFields = getFilterDisplayFields(field);
|
||||||
return dispFields.some((df) => String(el[df]) === String(filterValue));
|
return dispFields.some((df) => String(el[df]) === String(filterValue));
|
||||||
}
|
}
|
||||||
@@ -92,6 +96,7 @@ function applyClientFilters(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (itemValue && typeof itemValue === "object") {
|
if (itemValue && typeof itemValue === "object") {
|
||||||
|
if (field.enumOption?.value) return resolveTemplate(field.enumOption.value, itemValue) === String(filterValue);
|
||||||
const dispFields = getFilterDisplayFields(field);
|
const dispFields = getFilterDisplayFields(field);
|
||||||
return dispFields.some((df) => String(itemValue[df]) === String(filterValue));
|
return dispFields.some((df) => String(itemValue[df]) === String(filterValue));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export interface SelectOption {
|
|||||||
|
|
||||||
export interface EnumOption {
|
export interface EnumOption {
|
||||||
key: string;
|
key: string;
|
||||||
value: string | string[];
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResourceField {
|
export interface ResourceField {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export interface EnumOption {
|
export interface EnumOption {
|
||||||
key: string;
|
key: string;
|
||||||
value: string | string[];
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FieldOverride {
|
export interface FieldOverride {
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
import { ResourceField, SelectOption } from "../types/config";
|
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[] {
|
export function getFieldOptions(field: ResourceField, relationData?: any[]): SelectOption[] {
|
||||||
if (field.type === 'enum' && field.options) {
|
if (field.type === 'enum' && field.options) {
|
||||||
return field.options.map(opt => ({
|
return field.options.map(opt => ({
|
||||||
@@ -14,9 +21,7 @@ export function getFieldOptions(field: ResourceField, relationData?: any[]): Sel
|
|||||||
|
|
||||||
return data.map(item => ({
|
return data.map(item => ({
|
||||||
key: String(item[enumOption.key] ?? ''),
|
key: String(item[enumOption.key] ?? ''),
|
||||||
value: Array.isArray(enumOption.value)
|
value: resolveTemplate(enumOption.value, item),
|
||||||
? enumOption.value.map(k => item[k]).filter(v => v != null).join(' ')
|
|
||||||
: String(item[enumOption.value] ?? ''),
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ export const configuration: Record<string, ResourceOverride> = {
|
|||||||
accounts: {
|
accounts: {
|
||||||
enumOption: {
|
enumOption: {
|
||||||
key: 'id',
|
key: 'id',
|
||||||
value: ['name', 'number']
|
value: '{name} - XXXX{number}'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tags: {
|
tags: {
|
||||||
enumOption: {
|
enumOption: {
|
||||||
key: 'id',
|
key: 'id',
|
||||||
value: ['icon', 'name']
|
value: '{icon} {name}'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user