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

[DataGrid] Fix double-click issue #1919

Merged
merged 3 commits into from Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -23,24 +23,13 @@ export const GridHeaderCheckbox = React.forwardRef<HTMLInputElement, GridColumnH
const totalSelectedRows = useGridSelector(apiRef, selectedGridRowsCountSelector);
const totalRows = useGridSelector(apiRef, gridRowCountSelector);

const [isIndeterminate, setIsIndeterminate] = React.useState(
totalSelectedRows > 0 && totalSelectedRows !== totalRows,
);
const [isChecked, setChecked] = React.useState(
totalSelectedRows === totalRows || isIndeterminate,
);

React.useEffect(() => {
const isNewIndeterminate = totalSelectedRows > 0 && totalSelectedRows !== totalRows;
const isNewChecked = (totalRows > 0 && totalSelectedRows === totalRows) || isIndeterminate;
setChecked(isNewChecked);
setIsIndeterminate(isNewIndeterminate);
}, [isIndeterminate, totalRows, totalSelectedRows]);
const isIndeterminate = totalSelectedRows > 0 && totalSelectedRows !== totalRows;
// TODO core v5 remove || isIndeterminate, no longer has any effect
const isChecked = (totalSelectedRows > 0 && totalSelectedRows === totalRows) || isIndeterminate;

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const checked = event.target.checked;
setChecked(checked);
apiRef!.current.selectRows(visibleRowIds, checked);
apiRef!.current.selectRows(visibleRowIds, checked, !event.target.indeterminate);
};

const tabIndex = tabIndexState !== null && tabIndexState.field === props.field ? 0 : -1;
Expand Down
35 changes: 34 additions & 1 deletion packages/grid/x-grid/src/tests/selection.XGrid.test.tsx
@@ -1,7 +1,14 @@
import * as React from 'react';
import { createClientRenderStrictMode } from 'test/utils';
import { expect } from 'chai';
import { spy } from 'sinon';
import { getColumnValues } from 'test/utils/helperFn';
import {
// @ts-expect-error need to migrate helpers to TypeScript
screen,
createClientRenderStrictMode,
// @ts-expect-error need to migrate helpers to TypeScript
fireEvent,
} from 'test/utils';
import { GridApiRef, GridComponentProps, useGridApiRef, XGrid } from '@material-ui/x-grid';

const isJSDOM = /jsdom/.test(window.navigator.userAgent);
Expand Down Expand Up @@ -126,4 +133,30 @@ describe('<XGrid /> - Selection', () => {
});
expect(apiRef.current.getSelectedRows()).to.have.keys([0]);
});

it('should select only filtered rows after filter is applied', () => {
render(<Test checkboxSelection />);
const selectAll = screen.getByRole('checkbox', {
name: /select all rows checkbox/i,
});
apiRef.current.setFilterModel({
items: [
{
columnField: 'brand',
operatorValue: 'contains',
value: 'Puma',
},
],
});
expect(getColumnValues(1)).to.deep.equal(['Puma']);
fireEvent.click(selectAll);
// TODO fix, should be only 2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, this will get fixed by removing React.memo after which we get the updated visible rows in GridHeaderCheckbox.

expect(Array.from(apiRef.current.getSelectedRows().keys())).to.deep.equal([0, 1, 2]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fine to use apiRef to assert the state but your test coverage would be higher if you check the Mui-selected css class on the row

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, we can replace it. I had a similar thought last week on another PR. Then realized it was needed because of pagination/virtualization, but here, we don't.

On another note, I didn't use .to.have.keys() as in the other tests because when the test fails, the error message is crap (try removing the change in the source and see how the test behaves on HEAD)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but your test coverage would be higher if you check the Mui-selected css class on the row

@dtassone My bad, no we can't, I got trapped 😁. The selected rows 0 and 1 are not visible, they are filtered. I would have needed to assert the "X rows selected" message at the footer.

I'm a believer that the quality of the tests ultimately drives the quality of the code

I was mostly interested in making sure that each bug has its corresponding failing test case. For instance, if we fix 3 bugs, and only cover one with the tests. Something diverges from the standard.

fireEvent.click(selectAll);
expect(Array.from(apiRef.current.getSelectedRows().keys())).to.deep.equal([]);
fireEvent.click(selectAll);
expect(Array.from(apiRef.current.getSelectedRows().keys())).to.deep.equal([2]);
fireEvent.click(selectAll);
expect(Array.from(apiRef.current.getSelectedRows().keys())).to.deep.equal([]);
});
});