/* eslint-disable filenames/match-regex */
import { Box, SxProps, Typography, styled } from '@mui/material';
import { useGetResourceLabel, useResourceContext, useResourceDefinition, useTranslate } from 'ra-core';
import * as React from 'react';
import { CreateButton } from '@/components/ra-buttons';
import clsx from 'clsx';
import { EmptyIcon, NotFoundIcon } from './icons';
import { useThemeConfig } from '@/components/Layout/ThemeProvider';
type EmptyProps = {
/**
* The actions of the empty page.
*
* @example
* @example
* @example
* @example
**/
actions?: React.ReactNode;
/**
* The class name of the empty page.
*
* @example 'my-custom-empty'
* @example 'my-custom-empty my-custom-empty--full-width'
**/
className?: string;
hasCreate?: boolean;
/**
* The icon of the empty page.
*
* @example
* @example
**/
icon?: React.ReactNode;
/**
* The title of the empty page.
*
* @example 'No data available'
* @example translate('ra_text')
**/
title?: string | React.ReactNode;
/**
* The subtitle of the empty page.
*
* @example 'Please add some data'
* @example translate('ra_text')
**/
subtitle?: string | React.ReactNode;
sx?: SxProps;
/**
* If true the component height fits its content (auto),
* otherwise it takes the full available height.
*/
fitContent?: boolean;
};
const StyledToolbar = styled('div')(({ theme }) => ({
padding: theme.spacing(2),
display: 'flex',
justifyContent: 'center',
gap: theme.spacing(2)
}));
const PREFIX = 'ApplicaEmpty';
const EmptyClasses = {
message: `${PREFIX}-message`,
icon: `${PREFIX}-icon`,
toolbar: `${PREFIX}-toolbar`
};
interface RootProps {
horizontal?: boolean;
sx?: SxProps;
className?: string;
children?: React.ReactNode;
fitContent?: boolean;
}
const Root = styled('div', {
name: PREFIX,
slot: 'Root',
overridesResolver: (_, styles) => styles.root,
shouldForwardProp: (prop) => prop !== 'horizontal' && prop !== 'fitContent'
})(({ theme, horizontal, fitContent }) => ({
flex: 1,
height: fitContent ? 'auto' : horizontal ? 'calc(100vh - 240px)' : 'calc(100vh - 200px)',
[`& .${EmptyClasses.message}`]: {
textAlign: 'center',
opacity: theme.palette.mode === 'light' ? 1 : 0.8,
margin: '0 1em',
color: theme.palette.mode === 'light' ? 'inherit' : theme.palette.text.primary
},
[`& .${EmptyClasses.icon}`]: {
fontSize: '9em',
marginTop: '16px',
marginBottom: '16px'
},
[`& .${EmptyClasses.toolbar}`]: {
textAlign: 'center'
}
}));
function getEmptyIcon({ icon, className }: { icon?: React.ReactNode; className?: string }) {
if (icon !== undefined) return icon;
if (className?.includes('RaList-noResults')) {
return ;
}
return ;
}
/**
* Mostra una pagina vuota per le liste senza risultati o senza dati.
* Da usare solo all'interno di un componente List.
*
* @example
*
} />} />
*/
function Empty({
actions,
className,
hasCreate: hasCreateProp,
icon,
title,
subtitle,
sx,
fitContent = false,
...props
}: EmptyProps): JSX.Element {
const { hasCreate } = useResourceDefinition(props);
const canCreate = hasCreateProp !== undefined ? hasCreateProp : hasCreate;
const resource = useResourceContext();
const translate = useTranslate();
const getResourceLabel = useGetResourceLabel();
const resourceName = resource
? translate(`resources.${resource}.name`, {
smart_count: 0,
_: getResourceLabel(resource, 0)
})
: translate('ra.empty.no_resource');
const emptyMessage = translate('ra.page.empty', { name: resourceName });
const inviteMessage = translate('ra.page.invite');
const { themeOrientation } = useThemeConfig();
const isHorizontal = themeOrientation === 'horizontal';
return (
{getEmptyIcon({ icon, className })}
{title ||
translate(`resources.${resource}.empty`, {
_: emptyMessage
})}
{subtitle ||
(canCreate ? (
{translate(`resources.${resource}.invite`, {
_: inviteMessage
})}
) : null)}
{actions || (canCreate ? : null)}
);
}
export { Empty, EmptyClasses };
export type { EmptyProps };