Skip to content

Commit 6dd1bcb

Browse files
committed
Fix <Datagrid> and <DataTable> bulk selection
1 parent df42551 commit 6dd1bcb

File tree

5 files changed

+54
-4
lines changed

5 files changed

+54
-4
lines changed

packages/ra-ui-materialui/src/list/datagrid/Datagrid.spec.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import { ThemeProvider, createTheme } from '@mui/material';
1111

1212
import { Datagrid } from './Datagrid';
13-
import { AccessControl, SelectAllButton } from './Datagrid.stories';
13+
import { AccessControl, FullApp, SelectAllButton } from './Datagrid.stories';
1414

1515
const TitleField = () => {
1616
const record = useRecordContext();
@@ -126,6 +126,36 @@ describe('<Datagrid />', () => {
126126
expect(screen.queryByText('Select All')).toBeNull();
127127
});
128128

129+
describe('row selection', () => {
130+
it('should reveal bulk delete button by default on row selection', async () => {
131+
render(<FullApp />);
132+
const checkboxes = await screen.findAllByRole('checkbox');
133+
fireEvent.click(checkboxes[1]);
134+
await screen.findByLabelText('Delete');
135+
await screen.findByText('1 item selected');
136+
fireEvent.click(checkboxes[2]);
137+
await screen.findByText('2 items selected');
138+
});
139+
it('should reveal select all button when selecting the entire page', async () => {
140+
render(<FullApp perPage={5} />);
141+
const checkboxes = await screen.findAllByRole('checkbox');
142+
fireEvent.click(checkboxes[0]);
143+
const selectAllButton = await screen.findByText('Select all');
144+
selectAllButton.click();
145+
await screen.findByText('7 items selected');
146+
});
147+
it('should only unselect the current page records', async () => {
148+
render(<FullApp perPage={5} />);
149+
const checkboxes = await screen.findAllByRole('checkbox');
150+
fireEvent.click(checkboxes[0]);
151+
const selectAllButton = await screen.findByText('Select all');
152+
selectAllButton.click();
153+
await screen.findByText('7 items selected');
154+
fireEvent.click(checkboxes[0]);
155+
await screen.findByText('2 items selected');
156+
});
157+
});
158+
129159
describe('selecting items with the shift key', () => {
130160
it('should call onSelect with the correct ids when the last selection is after the first', () => {
131161
const Test = ({ selectedIds = [] }) => (

packages/ra-ui-materialui/src/list/datagrid/Datagrid.stories.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
TestMemoryRouter,
1111
SortPayload,
1212
AuthProvider,
13+
memoryStore,
1314
} from 'ra-core';
1415
import fakeRestDataProvider from 'ra-data-fakerest';
1516
import defaultMessages from 'ra-language-english';
@@ -558,18 +559,21 @@ export const RowClickFalse = () => (
558559

559560
export const FullApp = ({
560561
rowClick,
562+
perPage = undefined,
561563
}: {
562564
rowClick?: DatagridRowProps['rowClick'];
565+
perPage?: number;
563566
}) => (
564567
<AdminContext
565568
dataProvider={dataProvider}
566569
i18nProvider={polyglotI18nProvider(() => defaultMessages, 'en')}
570+
store={memoryStore()}
567571
>
568572
<AdminUI>
569573
<Resource
570574
name="books"
571575
list={() => (
572-
<List>
576+
<List perPage={perPage}>
573577
<Datagrid
574578
expand={<ExpandDetails />}
575579
rowClick={rowClick}

packages/ra-ui-materialui/src/list/datagrid/DatagridHeader.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ export const DatagridHeader = (props: DatagridHeaderProps) => {
6868
)
6969
.map(record => record.id)
7070
)
71-
: []
71+
: // We should only unselect the ids present in the current page
72+
selectedIds.filter(
73+
id => !data.map(record => record.id).includes(id)
74+
)
7275
);
7376
},
7477
[data, onSelect, isRowSelectable, selectedIds]

packages/ra-ui-materialui/src/list/datatable/DataTable.spec.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,16 @@ describe('DataTable', () => {
235235
selectAllButton.click();
236236
await screen.findByText('7 items selected');
237237
});
238+
it('should only unselect the current page records', async () => {
239+
render(<Basic />);
240+
const checkboxes = await screen.findAllByRole('checkbox');
241+
fireEvent.click(checkboxes[0]);
242+
const selectAllButton = await screen.findByText('Select all');
243+
selectAllButton.click();
244+
await screen.findByText('7 items selected');
245+
fireEvent.click(checkboxes[0]);
246+
await screen.findByText('2 items selected');
247+
});
238248
});
239249
describe('isRowSelectable', () => {
240250
it('should allow to disable row selection', async () => {

packages/ra-ui-materialui/src/list/datatable/SelectPageCheckbox.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ export const SelectPageCheckbox = () => {
3232
)
3333
.map(record => record.id)
3434
)
35-
: []
35+
: // We should only unselect the ids present in the current page
36+
selectedIds.filter(
37+
id => !data.map(record => record.id).includes(id)
38+
)
3639
);
3740
},
3841
[data, onSelect, isRowSelectable, selectedIds]

0 commit comments

Comments
 (0)