Skip to content

Commit 190e963

Browse files
committed
Fix duplicate selections when using checkbox and add related tests
1 parent b30af64 commit 190e963

File tree

3 files changed

+66
-8
lines changed

3 files changed

+66
-8
lines changed

cypress/e2e/list.cy.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,37 @@ describe('List Page', () => {
170170
);
171171
});
172172

173+
it('should not create duplicate selections when checking page after individual selections', () => {
174+
cy.contains('1-10 of 13'); // wait for data
175+
cy.get('input[type="checkbox"]').eq(1).click();
176+
cy.get('input[type="checkbox"]').eq(2).click();
177+
cy.contains('2 items selected');
178+
ListPagePosts.toggleSelectAll();
179+
cy.contains('10 items selected');
180+
cy.get(ListPagePosts.elements.selectedItem).should(els =>
181+
expect(els).to.have.length(10)
182+
);
183+
});
184+
185+
it('should handle uncheck and recheck without duplicates', () => {
186+
cy.contains('1-10 of 13'); // wait for data
187+
cy.get('input[type="checkbox"]').eq(1).click();
188+
cy.get('input[type="checkbox"]').eq(2).click();
189+
cy.get('input[type="checkbox"]').eq(3).click();
190+
cy.contains('3 items selected');
191+
ListPagePosts.toggleSelectAll();
192+
cy.contains('10 items selected');
193+
ListPagePosts.toggleSelectAll();
194+
cy.get(ListPagePosts.elements.bulkActionsToolbar).should(
195+
'not.be.visible'
196+
);
197+
ListPagePosts.toggleSelectAll();
198+
cy.contains('10 items selected');
199+
cy.get(ListPagePosts.elements.selectedItem).should(els =>
200+
expect(els).to.have.length(10)
201+
);
202+
});
203+
173204
it('should allow to trigger a custom bulk action on selected items', () => {
174205
cy.contains('1-10 of 13'); // wait for data
175206
ListPagePosts.toggleSelectAll();

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,33 @@ describe('DataTable', () => {
270270
fireEvent.click(checkboxes[4], { shiftKey: true });
271271
await screen.findByText('4 items selected');
272272
});
273+
it('should not create duplicate selections when checking page after individual selections', async () => {
274+
render(<Basic />);
275+
const checkboxes = await screen.findAllByRole('checkbox');
276+
fireEvent.click(checkboxes[1]);
277+
fireEvent.click(checkboxes[2]);
278+
await screen.findByText('2 items selected');
279+
fireEvent.click(checkboxes[0]);
280+
await screen.findByText('5 items selected');
281+
const selectAllButton = await screen.findByText('Select all');
282+
selectAllButton.click();
283+
await screen.findByText('7 items selected');
284+
});
285+
it('should handle uncheck and recheck without duplicates', async () => {
286+
render(<Basic />);
287+
const checkboxes = await screen.findAllByRole('checkbox');
288+
fireEvent.click(checkboxes[1]);
289+
fireEvent.click(checkboxes[2]);
290+
await screen.findByText('2 items selected');
291+
fireEvent.click(checkboxes[0]);
292+
await screen.findByText('5 items selected');
293+
fireEvent.click(checkboxes[0]);
294+
await waitFor(() => {
295+
expect(screen.queryByText('items selected')).toBeNull();
296+
});
297+
fireEvent.click(checkboxes[0]);
298+
await screen.findByText('5 items selected');
299+
});
273300
});
274301
describe('isRowSelectable', () => {
275302
it('should allow to disable row selection', async () => {

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import * as React from 'react';
2-
import { useCallback } from 'react';
1+
import { Checkbox } from '@mui/material';
32
import {
43
useDataTableCallbacksContext,
54
useDataTableDataContext,
65
useDataTableSelectedIdsContext,
76
useTranslate,
87
} from 'ra-core';
9-
import { Checkbox } from '@mui/material';
8+
import * as React from 'react';
9+
import { useCallback } from 'react';
1010

1111
export const SelectPageCheckbox = () => {
1212
const data = useDataTableDataContext();
@@ -22,11 +22,11 @@ export const SelectPageCheckbox = () => {
2222
event.target.checked
2323
? selectedIds.concat(
2424
data
25-
.filter(record =>
26-
!selectedIds.includes(record.id) &&
27-
isRowSelectable
28-
? isRowSelectable(record)
29-
: true
25+
.filter(
26+
record =>
27+
!selectedIds.includes(record.id) &&
28+
(!isRowSelectable ||
29+
isRowSelectable(record))
3030
)
3131
.map(record => record.id)
3232
)

0 commit comments

Comments
 (0)