Skip to content

Commit

Permalink
[DataGrid] Fix issue with visible rows state (#1113)
Browse files Browse the repository at this point in the history
  • Loading branch information
dtassone authored Feb 26, 2021
1 parent 635dbb2 commit 9e1589e
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/pages/api-docs/data-grid.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import { DataGrid } from '@material-ui/data-grid';
| <span class="prop-name">onCellHover</span> | <span class="prop-type">(param: GridCellParams) => void</span> | | Callback fired when a hover event comes from a cell element. |
| <span class="prop-name">onColumnHeaderClick</span> | <span class="prop-type">(param: GridColParams) => void</span> | | Callback fired when a click event comes from a column header element. |
| <span class="prop-name">onError</span> | <span class="prop-type">(args: any) => void</span> | | Callback fired when an exception is thrown in the grid, or when the `showError` API method is called. |
| <span class="prop-name">onFilterModelChange</span> | <span class="prop-type">(params: GridFilterModelParams) => void</span> | | Callback fired when the Filter model changes before the filters are applied. |
| <span class="prop-name">onPageChange</span> | <span class="prop-type">(param: GridPageChangeParams) => void</span> | | Callback fired when the current page has changed. |
| <span class="prop-name">onPageSizeChange</span> | <span class="prop-type">(param: GridPageChangeParams) => void</span> | | Callback fired when the page size has changed. |
| <span class="prop-name">onRowClick</span> | <span class="prop-type">(param: GridRowParams) => void</span> | | Callback fired when a click event comes from a row container element. |
Expand Down
1 change: 1 addition & 0 deletions docs/pages/api-docs/x-grid.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { XGrid } from '@material-ui/x-grid';
| <span class="prop-name">onCellHover</span> | <span class="prop-type">(param: GridCellParams) => void</span> | | Callback fired when a hover event comes from a cell element. |
| <span class="prop-name">onColumnHeaderClick</span> | <span class="prop-type">(param: GridColParams) => void</span> | | Callback fired when a click event comes from a column header element. |
| <span class="prop-name">onError</span> | <span class="prop-type">(args: any) => void</span> | | Callback fired when an exception is thrown in the grid, or when the `showError` API method is called. |
| <span class="prop-name">onFilterModelChange</span> | <span class="prop-type">(params: GridFilterModelParams) => void</span> | | Callback fired when the Filter model changes before the filters are applied. |
| <span class="prop-name">onPageChange</span> | <span class="prop-type">(param: GridPageChangeParams) => void</span> | | Callback fired when the current page has changed. |
| <span class="prop-name">onPageSizeChange</span> | <span class="prop-type">(param: GridPageChangeParams) => void</span> | | Callback fired when the page size has changed. |
| <span class="prop-name">onRowClick</span> | <span class="prop-type">(param: GridRowParams) => void</span> | | Callback fired when a click event comes from a row container element. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import TextField, { TextFieldProps } from '@material-ui/core/TextField';
import { GridLoadIcon } from '../../icons/index';
import { FilterInputValueProps } from './FilterInputValueProps';

const SUBMIT_FILTER_STROKE_TIME = 500;
export const SUBMIT_FILTER_STROKE_TIME = 500;

export interface TypeFilterInputValueProps extends FilterInputValueProps {
type?: 'text' | 'number' | 'date' | 'datetime-local';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { GridPreferencePanelsValue } from '../preferencesPanel/gridPreferencePan
import { sortedGridRowsSelector } from '../sorting/gridSortingSelector';
import { FilterModel, FilterModelState, getInitialGridFilterState } from './FilterModelState';
import { getInitialVisibleGridRowsState } from './visibleGridRowsState';
import { visibleSortedGridRowsSelector } from './gridFilterSelector';

export const useGridFilter = (apiRef: GridApiRef, rowsProp: GridRowsProp): void => {
const logger = useLogger('useGridFilter');
Expand All @@ -37,6 +38,7 @@ export const useGridFilter = (apiRef: GridApiRef, rowsProp: GridRowsProp): void
api: apiRef.current,
columns: apiRef.current.getAllColumns(),
rows: apiRef.current.getRowModels(),
visibleRows: apiRef.current.getVisibleRowModels(),
}),
[apiRef],
);
Expand Down Expand Up @@ -111,8 +113,8 @@ export const useGridFilter = (apiRef: GridApiRef, rowsProp: GridRowsProp): void
visibleRows: {
visibleRowsLookup,
visibleRows: Object.entries(visibleRowsLookup)
.filter((entry) => entry[1])
.map((entry) => entry[0]),
.filter(([, isVisible]) => isVisible)
.map(([id]) => id),
},
};
});
Expand Down Expand Up @@ -175,9 +177,8 @@ export const useGridFilter = (apiRef: GridApiRef, rowsProp: GridRowsProp): void
};
return newState;
});
apiRef.current.publishEvent(GRID_FILTER_MODEL_CHANGE, getFilterModelParams());

applyFilters();
apiRef.current.publishEvent(GRID_FILTER_MODEL_CHANGE, getFilterModelParams());
},
[
logger,
Expand Down Expand Up @@ -206,9 +207,8 @@ export const useGridFilter = (apiRef: GridApiRef, rowsProp: GridRowsProp): void
if (hasNoItem) {
upsertFilter({});
}
apiRef.current.publishEvent(GRID_FILTER_MODEL_CHANGE, getFilterModelParams());

applyFilters();
apiRef.current.publishEvent(GRID_FILTER_MODEL_CHANGE, getFilterModelParams());
},
[apiRef, applyFilters, getFilterModelParams, logger, setGridState, upsertFilter],
);
Expand Down Expand Up @@ -271,6 +271,11 @@ export const useGridFilter = (apiRef: GridApiRef, rowsProp: GridRowsProp): void
[apiRef],
);

const getVisibleRowModels = React.useCallback(
() => visibleSortedGridRowsSelector(apiRef.current.state),
[apiRef],
);

useGridApiMethod<FilterApi>(
apiRef,
{
Expand All @@ -283,6 +288,7 @@ export const useGridFilter = (apiRef: GridApiRef, rowsProp: GridRowsProp): void
setFilterModel,
showFilterPanel,
hideFilterPanel,
getVisibleRowModels,
},
'FilterApi',
);
Expand Down
2 changes: 2 additions & 0 deletions packages/grid/_modules_/grid/models/api/filterApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FilterModel } from '../../hooks/features/filter/FilterModelState';
import { GridFilterItem, GridLinkOperator } from '../gridFilterItem';
import { GridRowModel } from '../gridRows';
import { GridFilterModelParams } from '../params/gridFilterModelParams';

export interface FilterApi {
Expand All @@ -12,4 +13,5 @@ export interface FilterApi {
applyFilterLinkOperator: (operator: GridLinkOperator) => void;
onFilterModelChange: (handler: (params: GridFilterModelParams) => void) => void;
setFilterModel: (model: FilterModel) => void;
getVisibleRowModels: () => GridRowModel[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export interface GridFilterModelParams {
* The full set of rows.
*/
rows: GridRowModel[];
/**
* The set of currently visible rows.
*/
visibleRows: GridRowModel[];
/**
* Api that let you manipulate the grid.
*/
Expand Down
28 changes: 28 additions & 0 deletions packages/grid/x-grid/src/tests/filtering.XGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
GridRowModel,
useGridApiRef,
XGrid,
SUBMIT_FILTER_STROKE_TIME,
} from '@material-ui/x-grid';
import {
// @ts-expect-error need to migrate helpers to TypeScript
Expand Down Expand Up @@ -229,6 +230,33 @@ describe('<XGrid /> - Filter', () => {
expect(getColumnValues()).to.deep.equal(['Nike', 'Adidas', 'Puma']);
});

it('should show the latest visibleRows onFilterChange', () => {
let visibleRows: any[] = [];
const onFilterChange = (params) => {
visibleRows = params.visibleRows;
};

render(
<TestCase
filterModel={model}
onFilterModelChange={onFilterChange}
state={{
preferencePanel: {
open: true,
openedPanelValue: GridPreferencePanelsValue.filters,
},
}}
/>,
);

expect(getColumnValues()).to.deep.equal(['Adidas', 'Puma']);
const input = screen.getByPlaceholderText('Filter value');
fireEvent.change(input, { target: { value: 'ad' } });
clock.tick(SUBMIT_FILTER_STROKE_TIME);
expect(visibleRows).to.deep.equal([{ id: 1, brand: 'Adidas' }]);
expect(apiRef.current.getVisibleRowModels()).to.deep.equal([{ id: 1, brand: 'Adidas' }]);
});

describe('Server', () => {
it('should refresh the filter panel when adding filters', () => {
function loadServerRows(commodityFilterValue) {
Expand Down

0 comments on commit 9e1589e

Please sign in to comment.