From 65fafa2984207080395db5ed45ba7f1d80ffbb2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Zaninotto?= Date: Sun, 29 Jun 2025 18:12:30 +0200 Subject: [PATCH 1/2] Fix Datagrid empty throws error when used in standalone mode Closes #10811 --- .../ra-core/src/dataTable/DataTableBase.tsx | 6 +-- .../src/list/ListNoResults.tsx | 12 +++-- .../src/list/datagrid/Datagrid.stories.tsx | 53 ++++++++++++++----- .../src/list/datagrid/Datagrid.tsx | 13 ++--- .../src/list/datatable/DataTable.stories.tsx | 49 +++++++++++++---- .../src/list/datatable/DataTable.tsx | 5 +- 6 files changed, 95 insertions(+), 43 deletions(-) diff --git a/packages/ra-core/src/dataTable/DataTableBase.tsx b/packages/ra-core/src/dataTable/DataTableBase.tsx index b16e732da00..1453a08da99 100644 --- a/packages/ra-core/src/dataTable/DataTableBase.tsx +++ b/packages/ra-core/src/dataTable/DataTableBase.tsx @@ -155,11 +155,7 @@ export const DataTableBase = function DataTable< * the DataTable displays the empty component. */ if (data == null || data.length === 0 || total === 0) { - if (empty) { - return empty; - } - - return null; + return empty ?? null; } /** diff --git a/packages/ra-ui-materialui/src/list/ListNoResults.tsx b/packages/ra-ui-materialui/src/list/ListNoResults.tsx index dff2f3f1fb4..d8cab360ec3 100644 --- a/packages/ra-ui-materialui/src/list/ListNoResults.tsx +++ b/packages/ra-ui-materialui/src/list/ListNoResults.tsx @@ -9,10 +9,10 @@ import { import { Button } from '../button'; -export const ListNoResults = () => { +export const ListNoResults = (props: ListNoResultsProps) => { const translate = useTranslate(); - const resource = useResourceContext(); - const { filterValues, setFilters } = useListContextWithProps(); + const resource = useResourceContext(props); + const { filterValues, setFilters } = useListContextWithProps(props); const getResourceLabel = useGetResourceLabel(); if (!resource) { throw new Error( @@ -49,3 +49,9 @@ export const ListNoResults = () => { ); }; + +export interface ListNoResultsProps { + resource?: string; + filterValues?: any; + setFilters?: (filters: any, filterTypes?: string[]) => void; +} diff --git a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.stories.tsx b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.stories.tsx index 08245ea1e42..07e791d16e1 100644 --- a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.stories.tsx +++ b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.stories.tsx @@ -409,6 +409,7 @@ const MyCustomList = () => { isPending={isPending} sort={sort} bulkActionButtons={false} + resource="books" > @@ -424,24 +425,52 @@ const MyCustomListInteractive = () => { const listContext = useList({ data, isPending }); return ( - - - - - - + + + + + + + + ); }; export const Standalone = () => ( - -

Static

- -

Dynamic (with useList)

- -
+

Static

+ +

Dynamic (with useList)

+ +
+
+); + +const MyCustomListNoResults = () => { + const { data, total, isPending } = useGetList('books', { + filter: { title: 'Non-existing book' }, + }); + + return ( + + + + + ); +}; + +export const StandaloneNoResults = () => ( + + + ); diff --git a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx index 4d6f2fe95b2..47c57ecbcf9 100644 --- a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx +++ b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx @@ -9,6 +9,7 @@ import { FC, ComponentType, ReactElement, + ReactNode, useMemo, } from 'react'; import { @@ -139,7 +140,7 @@ export const Datagrid: React.ForwardRefExoticComponent< header = DatagridHeader, children, className, - empty = DefaultEmpty, + empty, expand, bulkActionsToolbar, bulkActionButtons = canDelete ? defaultBulkActionButtons : false, @@ -235,11 +236,7 @@ export const Datagrid: React.ForwardRefExoticComponent< * the Datagrid displays the empty component. */ if (data == null || data.length === 0 || total === 0) { - if (empty) { - return empty; - } - - return null; + return empty ?? ; } /** @@ -464,7 +461,7 @@ export interface DatagridProps * * ); */ - empty?: ReactElement; + empty?: ReactNode; /** * A function that returns whether the row for a record is expandable. @@ -608,5 +605,3 @@ const sanitizeRestProps = props => .reduce((acc, key) => ({ ...acc, [key]: props[key] }), {}); Datagrid.displayName = 'Datagrid'; - -const DefaultEmpty = ; diff --git a/packages/ra-ui-materialui/src/list/datatable/DataTable.stories.tsx b/packages/ra-ui-materialui/src/list/datatable/DataTable.stories.tsx index b2912d9e0f5..b3c5252ba87 100644 --- a/packages/ra-ui-materialui/src/list/datatable/DataTable.stories.tsx +++ b/packages/ra-ui-materialui/src/list/datatable/DataTable.stories.tsx @@ -342,7 +342,12 @@ const MyCustomList = () => { }); return ( - + @@ -351,9 +356,31 @@ const MyCustomList = () => { export const StandaloneStatic = () => ( - - - + + +); + +const MyCustomListNoResults = () => { + const { data, total, isPending } = useGetList('books', { + filter: { title: 'Non-existing book' }, + }); + + return ( + + + + + ); +}; + +export const StandaloneNoResults = () => ( + + ); @@ -366,19 +393,19 @@ const MyCustomListInteractive = () => { return ( - - - - + + + + + + ); }; export const StandaloneDynamic = () => ( - - - + ); diff --git a/packages/ra-ui-materialui/src/list/datatable/DataTable.tsx b/packages/ra-ui-materialui/src/list/datatable/DataTable.tsx index 91c7c7059f5..9fffb7e9413 100644 --- a/packages/ra-ui-materialui/src/list/datatable/DataTable.tsx +++ b/packages/ra-ui-materialui/src/list/datatable/DataTable.tsx @@ -39,7 +39,6 @@ import { DataTableNumberColumn } from './DataTableNumberColumn'; import { ColumnsSelector } from './ColumnsSelector'; import { DataTableRowSxContext } from './DataTableRowSxContext'; -const DefaultEmpty = ; const DefaultFoot = (_props: { children: ReactNode }) => null; const PREFIX = 'RaDataTable'; @@ -148,7 +147,7 @@ export const DataTable = React.forwardRef(function DataTable< foot: TableFoot = DefaultFoot, children, className, - empty = DefaultEmpty, + empty, expand, bulkActionsToolbar, bulkActionButtons = canDelete ? defaultBulkActionButtons : false, @@ -183,7 +182,7 @@ export const DataTable = React.forwardRef(function DataTable< {...props} hasBulkActions={hasBulkActions} loading={loading} - empty={empty} + empty={empty ?? } > Date: Wed, 2 Jul 2025 10:02:55 +0200 Subject: [PATCH 2/2] review --- packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx | 6 +++++- .../ra-ui-materialui/src/list/datatable/DataTable.tsx | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx index 47c57ecbcf9..95b0be7aa57 100644 --- a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx +++ b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx @@ -236,7 +236,11 @@ export const Datagrid: React.ForwardRefExoticComponent< * the Datagrid displays the empty component. */ if (data == null || data.length === 0 || total === 0) { - return empty ?? ; + return empty === undefined ? ( + + ) : ( + empty + ); } /** diff --git a/packages/ra-ui-materialui/src/list/datatable/DataTable.tsx b/packages/ra-ui-materialui/src/list/datatable/DataTable.tsx index 9fffb7e9413..8ccbfdf3927 100644 --- a/packages/ra-ui-materialui/src/list/datatable/DataTable.tsx +++ b/packages/ra-ui-materialui/src/list/datatable/DataTable.tsx @@ -182,7 +182,13 @@ export const DataTable = React.forwardRef(function DataTable< {...props} hasBulkActions={hasBulkActions} loading={loading} - empty={empty ?? } + empty={ + empty === undefined ? ( + + ) : ( + empty + ) + } >