diff --git a/packages/ra-core/src/dataTable/DataTableBase.spec.tsx b/packages/ra-core/src/dataTable/DataTableBase.spec.tsx new file mode 100644 index 00000000000..7ec6f2d25af --- /dev/null +++ b/packages/ra-core/src/dataTable/DataTableBase.spec.tsx @@ -0,0 +1,200 @@ +import * as React from 'react'; +import expect from 'expect'; +import { render, screen } from '@testing-library/react'; +import { DataTableBase } from './DataTableBase'; +import { ResourceContextProvider, useResourceContext } from '../core'; +import { ListContextProvider } from '../controller'; + +describe('', () => { + const defaultListContext = { + resource: 'posts', + data: [], + total: 0, + isPending: false, + isFetching: false, + sort: { field: 'id', order: 'ASC' }, + }; + + it('should render children when data is present', () => { + render( + + + Empty} + loading={
Loading
} + hasBulkActions={false} + > +
Child Content
+
+
+
+ ); + + expect(screen.queryByText('Child Content')).not.toBeNull(); + expect(screen.queryByText('Loading')).toBeNull(); + expect(screen.queryByText('Empty')).toBeNull(); + }); + + it('should render empty component when no data', () => { + render( + + + Empty Component} + loading={
Loading
} + hasBulkActions={false} + > +
Child
+
+
+
+ ); + + expect(screen.queryByText('Empty Component')).not.toBeNull(); + expect(screen.queryByText('Child')).toBeNull(); + }); + + it('should render loading component when pending', () => { + render( + + + Empty} + loading={
Loading Component
} + hasBulkActions={false} + > +
Child
+
+
+
+ ); + + expect(screen.queryByText('Loading Component')).not.toBeNull(); + expect(screen.queryByText('Child')).toBeNull(); + }); + + it('should display the empty component instead of the table header when loaded with no data', () => { + render( + + + Empty Component} + loading={
Loading
} + hasBulkActions={false} + > +
Table Header and Body
+
+
+
+ ); + + expect(screen.queryByText('Empty Component')).not.toBeNull(); + expect(screen.queryByText('Table Header and Body')).toBeNull(); + }); + + it('should display the current data when data is refreshing', () => { + render( + + + Empty} + loading={
Loading Component
} + hasBulkActions={false} + > +
Child Content
+
+
+
+ ); + + expect(screen.queryByText('Child Content')).not.toBeNull(); + expect(screen.queryByText('Loading Component')).toBeNull(); + }); + + it('should provide ResourceContext to the loading component', () => { + const Loading = () => { + const resource = useResourceContext(); + return
Loading resource: {resource}
; + }; + + render( + + + Empty} + loading={} + hasBulkActions={false} + > +
Child
+
+
+
+ ); + + expect(screen.queryByText('Loading resource: posts')).not.toBeNull(); + }); + + it('should provide ResourceContext to the empty component', () => { + const Empty = () => { + const resource = useResourceContext(); + return
Empty resource: {resource}
; + }; + + render( + + + } + loading={
Loading
} + hasBulkActions={false} + > +
Child
+
+
+
+ ); + + expect(screen.queryByText('Empty resource: posts')).not.toBeNull(); + }); +}); diff --git a/packages/ra-core/src/dataTable/DataTableBase.tsx b/packages/ra-core/src/dataTable/DataTableBase.tsx index 6db42fb568b..34024a5f655 100644 --- a/packages/ra-core/src/dataTable/DataTableBase.tsx +++ b/packages/ra-core/src/dataTable/DataTableBase.tsx @@ -145,43 +145,43 @@ export const DataTableBase = function DataTable< ] ); - if (isPending === true) { - return loading; - } - - /** - * Once loaded, the data for the list may be empty. Instead of - * displaying the table header with zero data rows, - * the DataTable displays the empty component. - */ - if (data == null || data.length === 0 || total === 0) { - return empty ?? null; - } - - /** - * After the initial load, if the data for the list isn't empty, - * and even if the data is refreshing (e.g. after a filter change), - * the DataTable displays the current data. - */ return ( - - - - - - - {children} - - - - - - + + + {isPending ? ( + loading + ) : data == null || data.length === 0 || total === 0 ? ( + /** + * Once loaded, the data for the list may be empty. + * Instead of displaying the table header + * with zero data rows, the DataTable + * displays the empty component. + */ + empty + ) : ( + /** + * After the initial load, if the data for the list + * isn't empty, and even if the data is refreshing + * (e.g. after a filter change), the DataTable + * displays the current data. + */ + + + + + {children} + + + + + )} + + ); };