import React from 'react';
import {
ArrayField,
BooleanField,
ChipField,
DateField,
EmailField,
NumberField,
ReferenceArrayField,
ReferenceField,
SimpleList,
SingleFieldList,
TextField,
UrlField,
useResourceContext,
} from 'react-admin';
import type {
ArrayFieldProps,
BooleanFieldProps,
DateFieldProps,
EmailFieldProps,
NumberFieldProps,
ReferenceArrayFieldProps,
ReferenceFieldProps,
SingleFieldListProps,
TextFieldProps,
UrlFieldProps,
} from 'react-admin';
import type { Field, Resource } from '@api-platform/api-doc-parser';
import Introspecter from '../introspection/Introspecter.js';
import EnumField from './EnumField.js';
import type {
EnumFieldProps,
FieldGuesserProps,
FieldProps,
IntrospectedFieldGuesserProps,
SchemaAnalyzer,
} from '../types.js';
const isFieldSortable = (field: Field, schema: Resource) =>
!!schema.parameters &&
schema.parameters.filter((parameter) => parameter.variable === field.name)
.length > 0 &&
schema.parameters.filter(
(parameter) => parameter.variable === `order[${field.name}]`,
).length > 0;
const renderField = (
field: Field,
schemaAnalyzer: SchemaAnalyzer,
props: FieldProps,
) => {
if (field.reference !== null && typeof field.reference === 'object') {
if (field.maxCardinality === 1) {
return (
);
}
const fieldName = schemaAnalyzer.getFieldNameFromSchema(field.reference);
const { linkType, ...rest } = props as ReferenceArrayFieldProps &
Pick;
return (
);
}
if (field.embedded !== null && field.maxCardinality !== 1) {
return (
JSON.stringify(record)}
linkType={false}
// Workaround for forcing the list to display underlying data.
total={2}
/>
);
}
if (field.enum) {
return (
Object.entries(field.enum ?? {}).find(([, v]) => v === value)?.[0] ??
value
}
{...(props as EnumFieldProps)}
/>
);
}
const fieldType = schemaAnalyzer.getFieldType(field);
switch (fieldType) {
case 'email':
return ;
case 'url':
return ;
case 'integer':
case 'integer_id':
case 'float':
return ;
case 'boolean':
return ;
case 'date':
case 'dateTime':
return ;
default:
return ;
}
};
export const IntrospectedFieldGuesser = ({
fields,
readableFields,
writableFields,
schema,
schemaAnalyzer,
...props
}: IntrospectedFieldGuesserProps) => {
if (!props.source) {
// eslint-disable-next-line no-console
console.error('FieldGuesser: missing source property.');
return null;
}
const field = fields.find((f) => f.name === props.source);
if (!field) {
// eslint-disable-next-line no-console
console.error(
`Field "${props.source}" not present inside API description for the resource "${props.resource}"`,
);
return null;
}
return renderField(field, schemaAnalyzer, {
sortable: isFieldSortable(field, schema),
...props,
source: props.source,
});
};
const FieldGuesser = (props: FieldGuesserProps) => {
const resource = useResourceContext(props);
if (!resource) {
throw new Error('FieldGuesser must be used with a resource');
}
return (
);
};
export default FieldGuesser;