Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add <Datagrid empty> prop to display column headers even on empty lists #6164

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/List.md
Original file line number Diff line number Diff line change
Expand Up @@ -1981,6 +1981,7 @@ Here are all the props accepted by the component:
* [`isRowExpandable`](#isrowexpandable)
* [`isRowSelectable`](#isrowselectable)
* [`optimized`](#performance)
* [`empty`](#empty)

Additional props are passed down to [the material-ui `<Table>` element](https://material-ui.com/api/table/).

Expand Down Expand Up @@ -2261,6 +2262,10 @@ const PostList = props => (
export default withStyles(styles)(PostList);
```

### Empty

It's possible that a Datagrid will have no records to display. If the Datagrid's parent component handles the loading state, the Datagrid will return `null` and render nothing.
Passing through a component to the `empty` prop will cause the Datagrid to render the `empty` component instead of `null`.
### CSS API

The `Datagrid` component accepts the usual `className` prop but you can override many class names injected to the inner components by React-admin thanks to the `classes` property (as most Material UI components, see their [documentation about it](https://material-ui.com/customization/components/#overriding-styles-with-classes)). This property accepts the following keys:
Expand Down
20 changes: 20 additions & 0 deletions packages/ra-ui-materialui/src/list/datagrid/Datagrid.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ describe('<Datagrid />', () => {
expect(contextValue.onSelect).toHaveBeenCalledTimes(0);
});

it('should display the correct empty component', () => {
const Empty = () => <div>No records to show</div>;

const emptyData = {
...contextValue,
data: [],
ids: [],
};

const { queryByText } = renderWithRedux(
<ListContextProvider value={emptyData}>
<Datagrid empty={<Empty />} hasBulkActions>
<TitleField />
</Datagrid>
</ListContextProvider>
);

expect(queryByText('No records to show')).toBeTruthy();
});

describe('selecting items with the shift key', () => {
it('should call onSelect with the correct ids when the last selection is after the first', () => {
const Test = ({ selectedIds = [] }) => (
Expand Down
9 changes: 8 additions & 1 deletion packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
children,
classes: classesOverride,
className,
empty,
expand,
hasBulkActions = false,
hover,
Expand Down Expand Up @@ -242,9 +243,13 @@ const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
/**
* Once loaded, the data for the list may be empty. Instead of
* displaying the table header with zero data rows,
* the datagrid displays nothing in this case.
* the datagrid displays nothing or a custom empty component.
*/
if (loaded && (ids.length === 0 || total === 0)) {
if (empty) {
return empty;
}

return null;
}

Expand Down Expand Up @@ -353,6 +358,7 @@ Datagrid.propTypes = {
order: PropTypes.string.isRequired,
}),
data: PropTypes.any,
empty: PropTypes.element,
// @ts-ignore
expand: PropTypes.oneOfType([PropTypes.element, PropTypes.elementType]),
hasBulkActions: PropTypes.bool,
Expand Down Expand Up @@ -387,6 +393,7 @@ export interface DatagridProps<RecordType extends Record = Record>
}>;
hasBulkActions?: boolean;
hover?: boolean;
empty?: ReactElement;
isRowSelectable?: (record: Record) => boolean;
isRowExpandable?: (record: Record) => boolean;
optimized?: boolean;
Expand Down