import { FileField } from '@/components/ra-fields';
import { LabeledInput } from '@/components/ra-inputs/LabeledInput';
import { styled } from '@mui/material/styles';
import { get } from 'lodash';
import React, { useMemo } from 'react';
import { FileInput as RaFileInput, FileInputProps as RaFileInputProps, useRecordContext } from 'react-admin';
import { useWatch } from 'react-hook-form';
const StyledFileInput = styled(RaFileInput, { slot: 'root' })(({ theme }) => ({
'& .previews': {},
'& .previews>div': {
marginTop: theme.spacing(1),
padding: theme.spacing(1.5),
border: `1px solid ${theme.palette.divider}`,
borderRadius: theme.shape.borderRadius,
'& button': {
float: 'right',
placeItems: 'flex-end',
verticalAlign: 'middle'
},
'&:hover': {
backgroundColor: theme.palette.action.hover
},
'& .MuiLink-root': {
fontSize: theme.typography.body1.fontSize
}
}
}));
/**
* FileInput is designed to be used as single input. It does not support multiple files and
* can be used only for base64 encoded files using applica framework.
*
* @example
* // If you hav an object class with @File annotation, you can map it to a FileInput:
* ...
*
*
* The component will handle create and delete operations related to the source field associated
* in conjuction with Applica Framework backend API services.
*
*/
function FileInput({ children = , title, ...props }: FileInputProps): JSX.Element {
const file = useWatch({ name: props.source });
const record = useRecordContext(props);
const { source } = props;
// Base64 files are persisted with a simple string that contains the temporary filename.
// Applica Framework add a suffix to the temporary filename that is the original filename.
// With a little trick we try (because we are not sure that this is true) to get the original filename.
const filename = useMemo(() => {
if (file && file?.title) {
return file?.title;
}
const filename = get(record, source);
if (filename) {
const parts = filename.split('__');
return parts.length > 0 ? parts[parts.length - 1] : filename;
}
return filename;
}, [record, source, file]);
return (
// @ts-ignore
{/* @ts-ignore */}
{
/** @ts-ignore */
React.cloneElement(children, {
// @ts-ignore
...children.props,
title: title || source,
source,
record: {
...record,
[source]: file?.title || get(record, source),
[`_${source}`]: file?.src || get(record, `_${source}`),
[title || source]: filename
}
})
}
);
}
type FileInputProps = {
source: string;
title?: string;
children?: React.ReactNode;
} & RaFileInputProps;
export { FileInput };
export type { FileInputProps };