Skip to content

Commit

Permalink
[DataGridPro] Only apply checkboxSelectionVisibleOnly when pagination…
Browse files Browse the repository at this point in the history
… is enabled (#2443)

* [DataGridPro] Only apply checkboxSelectionVisibleOnly when pagination is enabled
  • Loading branch information
flaviendelangle authored Sep 4, 2021
1 parent e214b3a commit 02f9391
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 22 deletions.
2 changes: 1 addition & 1 deletion docs/pages/api-docs/data-grid/data-grid-pro.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The name <code>MuiDataGridPro</code> can be used when providing [default props](
| <span class="prop-name">autoHeight</span> | <span class="prop-type">boolean</span> | false | If `true`, the grid height is dynamic and follow the number of rows in the grid. |
| <span class="prop-name">autoPageSize</span> | <span class="prop-type">boolean</span> | false | If `true`, the pageSize is calculated according to the container size and the max number of rows to avoid rendering a vertical scroll bar. |
| <span class="prop-name">checkboxSelection</span> | <span class="prop-type">boolean</span> | false | If `true`, the grid get a first column with a checkbox that allows to select rows. |
| <span class="prop-name">checkboxSelectionVisibleOnly</span> | <span class="prop-type">boolean</span> | false | If `true`, the "Select All" header checkbox selects only the rows on the current page. To be used in combination with `checkboxSelection`. |
| <span class="prop-name">checkboxSelectionVisibleOnly</span> | <span class="prop-type">boolean</span> | false | If `true`, the "Select All" header checkbox selects only the rows on the current page. To be used in combination with `checkboxSelection`. It only works if the pagination is enabled. |
| <span class="prop-name">classes</span> | <span class="prop-type">GridClasses</span> | | Override or extend the styles applied to the component. See [CSS API](/api/data-grid/x-grid/#css) below for more details. |
| <span class="prop-name">className</span> | <span class="prop-type">string</span> | | CSS classname to add on the outer container. |
| <span class="prop-name">columnBuffer</span> | <span class="prop-type">number</span> | 2 | Number of columns rendered outside the grid viewport. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ export const GridHeaderCheckbox = React.forwardRef<HTMLInputElement, GridColumnH

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const checked = event.target.checked;
const rowsToBeSelected = rootProps.checkboxSelectionVisibleOnly

const shouldLimitSelectionToCurrentPage =
rootProps.checkboxSelectionVisibleOnly && rootProps.pagination;

const rowsToBeSelected = shouldLimitSelectionToCurrentPage
? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef.current.state)
: visibleSortedGridRowIdsSelector(apiRef.current.state);
apiRef.current.selectRows(rowsToBeSelected, checked, !event.target.indeterminate);
Expand Down
1 change: 1 addition & 0 deletions packages/grid/_modules_/grid/models/gridOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface GridSimpleOptions {
checkboxSelection: boolean;
/**
* If `true`, the "Select All" header checkbox selects only the rows on the current page. To be used in combination with `checkboxSelection`.
* It only works if the pagination is enabled.
* @default false
*/
checkboxSelectionVisibleOnly: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/grid/data-grid/src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ DataGrid.propTypes = {
return null;
}),
checkboxSelectionVisibleOnly: chainPropTypes(PropTypes.bool, (props: any) => {
if (props.checkboxSelectionVisibleOnly === true) {
if (props.checkboxSelectionVisibleOnly) {
return new Error(
[
`Material-UI: \`<DataGrid checkboxSelectionVisibleOnly={true} />\` is not a valid prop.`,
Expand Down
10 changes: 9 additions & 1 deletion packages/grid/x-grid/src/DataGridPro.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { LicenseInfo } from '@mui/x-license-pro';
import { ponyfillGlobal } from '@material-ui/utils';
import { chainPropTypes, ponyfillGlobal } from '@material-ui/utils';
import {
GridBody,
GridErrorHandler,
Expand Down Expand Up @@ -57,4 +57,12 @@ export const DataGridPro = React.memo(DataGridProRaw);
DataGridProRaw.propTypes = {
columns: PropTypes.array.isRequired,
rows: PropTypes.array.isRequired,
checkboxSelectionVisibleOnly: chainPropTypes(PropTypes.bool, (props: any) => {
if (!props.pagination && props.checkboxSelectionVisibleOnly) {
return new Error(
'Material-UI: The `checkboxSelectionVisibleOnly` prop has no effect when the pagination is not enabled.',
);
}
return null;
}),
} as any;
63 changes: 45 additions & 18 deletions packages/grid/x-grid/src/tests/selection.DataGridPro.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { getColumnValues, getRow, getSelectedRowIndexes } from 'test/utils/helperFn';
import { getColumnValues, getSelectedRowIndexes } from 'test/utils/helperFn';
import {
// @ts-expect-error need to migrate helpers to TypeScript
screen,
Expand All @@ -26,23 +26,24 @@ describe('<DataGridPro /> - Selection', () => {

let apiRef: GridApiRef;

const defaultData = getData(4, 2);

const TestDataGridSelection = (
props: Omit<DataGridProProps, 'rows' | 'columns' | 'apiRef'> &
Partial<Pick<DataGridProProps, 'rows' | 'columns'>>,
) => {
const TestDataGridSelection = ({
rowLength = 4,
...other
}: Omit<DataGridProProps, 'rows' | 'columns' | 'apiRef'> &
Partial<Pick<DataGridProProps, 'rows' | 'columns'>> & { rowLength?: number }) => {
apiRef = useGridApiRef();

const data = React.useMemo(() => getData(rowLength, 2), [rowLength]);

return (
<div style={{ width: 300, height: 300 }}>
<DataGridPro {...defaultData} {...props} apiRef={apiRef} autoHeight={isJSDOM} />
<DataGridPro {...data} {...other} apiRef={apiRef} autoHeight={isJSDOM} />
</div>
);
};

describe('prop: checkboxSelectionVisibleOnly', () => {
it('should select all visible rows regardless of pagination if checkboxSelectionVisibleOnly = false', () => {
it('should select all visible rows of all pages if checkboxSelectionVisibleOnly = false', () => {
render(
<TestDataGridSelection
checkboxSelection
Expand All @@ -53,12 +54,10 @@ describe('<DataGridPro /> - Selection', () => {
);
const selectAllCheckbox = document.querySelector('input[type="checkbox"]');
fireEvent.click(selectAllCheckbox);
expect(getRow(0)).to.have.class('Mui-selected');
fireEvent.click(screen.getByRole('button', { name: /next page/i }));
expect(getRow(1)).to.have.class('Mui-selected');
expect(apiRef.current.getSelectedRows()).to.have.length(4);
});

it('should select all visible rows of the current page if checkboxSelectionVisibleOnly = true', () => {
it('should select all visible rows of the current page if checkboxSelectionVisibleOnly = true and pagination is enabled', () => {
render(
<TestDataGridSelection
checkboxSelection
Expand All @@ -70,9 +69,37 @@ describe('<DataGridPro /> - Selection', () => {
);
const selectAllCheckbox = document.querySelector('input[type="checkbox"]');
fireEvent.click(selectAllCheckbox);
expect(getRow(0)).to.have.class('Mui-selected');
fireEvent.click(screen.getByRole('button', { name: /next page/i }));
expect(getRow(1)).not.to.have.class('Mui-selected');
expect(apiRef.current.getSelectedRows()).to.have.keys([0]);
});

it('should select all rows when if checkboxSelectionVisibleOnly = false and pagination is not enabled', () => {
const rowLength = 10;

render(
<TestDataGridSelection
checkboxSelection
checkboxSelectionVisibleOnly={false}
rowLength={rowLength}
/>,
);

const selectAll = screen.getByRole('checkbox', {
name: /select all rows checkbox/i,
});
fireEvent.click(selectAll);
expect(apiRef.current.getSelectedRows()).to.have.length(rowLength);
});

it('should throw a console error if checkboxSelectionVisibleOnly is used without pagination', () => {
expect(() => {
render(
<TestDataGridSelection checkboxSelection checkboxSelectionVisibleOnly rowLength={100} />,
);
})
// @ts-expect-error need to migrate helpers to TypeScript
.toErrorDev(
'Material-UI: The `checkboxSelectionVisibleOnly` prop has no effect when the pagination is not enabled.',
);
});
});

Expand All @@ -81,12 +108,12 @@ describe('<DataGridPro /> - Selection', () => {
render(
<TestDataGridSelection
onSelectionModelChange={(model) => {
expect(apiRef.current.getSelectedRows().size).to.equal(1);
expect(apiRef.current.getSelectedRows()).to.have.length(1);
expect(model).to.deep.equal([1]);
}}
/>,
);
expect(apiRef.current.getSelectedRows().size).to.equal(0);
expect(apiRef.current.getSelectedRows()).to.have.length(0);
apiRef.current.selectRow(1);
expect(apiRef.current.getSelectedRows().get(1)).to.deep.equal({
id: 1,
Expand Down

0 comments on commit 02f9391

Please sign in to comment.