Files
khata-ui/react-openapi/components/fields/RelationField.tsx
2026-06-13 21:36:14 +05:30

68 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { FormControl, InputLabel, Select, MenuItem } from '@mui/material';
import { getFieldOptions } from '../../utils/options';
import { FieldComponentProps } from '../../types/overrides';
export default function RelationField({ field, value, onChange, disabled, relationDataMap = {} }: FieldComponentProps) {
console.log('RelationField render', field.label, 'enumOption:', field.enumOption, 'value prop:', value);
const relationName = field.relation ?? (field as any).refers;
if (!relationName || !relationDataMap[relationName]) {
throw new Error(`Relation data for "${relationName}" is missing cannot render options for field "${field.label}"`);
}
const relationData = relationDataMap[relationName];
const isArrayRelation = field.type === 'array';
const options = getFieldOptions(field, relationData);
console.log('Options for', field.label, 'keys:', options.map(o=>o.key));
if (options.length === 0) {
throw new Error(`No selectable options available for field "${field.label}" (relation "${relationName}")`);
}
const keyField = field.enumOption?.key ?? 'id';
const normalizedValue = (() => {
if (isArrayRelation && Array.isArray(value)) {
return value.map((v: any) => {
if (v != null && typeof v === 'object') {
return String(v[keyField] ?? '');
}
return String(v);
});
}
if (value != null && typeof value === 'object') {
return String(value[keyField] ?? '');
}
// Primitive (number/string) coerce to string for Select compatibility
return value != null ? String(value) : (isArrayRelation ? [] : "");
})();
return (
<FormControl fullWidth>
<InputLabel shrink>{field.label}</InputLabel>
<Select
multiple={isArrayRelation}
value={normalizedValue}
label={field.label}
displayEmpty
onChange={(e) => onChange(e.target.value)}
disabled={disabled}
renderValue={(selected: any) => {
console.log('Select renderValue for', field.label, 'selected:', selected);
if (isArrayRelation) {
return (selected as string[]).map(k => options.find(o => o.key === k)?.value ?? k).join(', ');
}
const display = options.find(o => o.key === selected)?.value ?? selected;
console.log('Display value for', field.label, ':', display);
return display;
}}
>
{options.map((opt) => (
<MenuItem key={opt.key} value={opt.key}>
{opt.value}
</MenuItem>
))}
</Select>
</FormControl>
);
}