@mui/x-data-grid 6.20.1 → 6.20.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/DataGrid/DataGrid.js +5 -0
- package/components/GridPagination.js +2 -7
- package/hooks/features/export/useGridPrintExport.js +8 -4
- package/hooks/features/pagination/gridPaginationInterfaces.d.ts +19 -2
- package/hooks/features/pagination/gridPaginationSelector.d.ts +5 -0
- package/hooks/features/pagination/gridPaginationSelector.js +8 -2
- package/hooks/features/pagination/useGridPagination.d.ts +1 -6
- package/hooks/features/pagination/useGridPagination.js +9 -159
- package/hooks/features/pagination/useGridPaginationModel.d.ts +11 -0
- package/hooks/features/pagination/useGridPaginationModel.js +176 -0
- package/hooks/features/pagination/useGridRowCount.d.ts +8 -0
- package/hooks/features/pagination/useGridRowCount.js +97 -0
- package/index.js +1 -1
- package/legacy/DataGrid/DataGrid.js +5 -0
- package/legacy/components/GridPagination.js +2 -7
- package/legacy/hooks/features/export/useGridPrintExport.js +10 -4
- package/legacy/hooks/features/pagination/gridPaginationSelector.js +11 -3
- package/legacy/hooks/features/pagination/useGridPagination.js +9 -161
- package/legacy/hooks/features/pagination/useGridPaginationModel.js +182 -0
- package/legacy/hooks/features/pagination/useGridRowCount.js +101 -0
- package/legacy/index.js +1 -1
- package/models/events/gridEventLookup.d.ts +6 -0
- package/models/props/DataGridProps.d.ts +5 -0
- package/modern/DataGrid/DataGrid.js +5 -0
- package/modern/components/GridPagination.js +2 -4
- package/modern/hooks/features/export/useGridPrintExport.js +8 -4
- package/modern/hooks/features/pagination/gridPaginationSelector.js +8 -2
- package/modern/hooks/features/pagination/useGridPagination.js +8 -151
- package/modern/hooks/features/pagination/useGridPaginationModel.js +171 -0
- package/modern/hooks/features/pagination/useGridRowCount.js +94 -0
- package/modern/index.js +1 -1
- package/node/DataGrid/DataGrid.js +5 -0
- package/node/components/GridPagination.js +1 -3
- package/node/hooks/features/export/useGridPrintExport.js +8 -4
- package/node/hooks/features/pagination/gridPaginationSelector.js +8 -2
- package/node/hooks/features/pagination/useGridPagination.js +9 -155
- package/node/hooks/features/pagination/useGridPaginationModel.js +182 -0
- package/node/hooks/features/pagination/useGridRowCount.js +103 -0
- package/node/index.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { gridFilteredTopLevelRowCountSelector } from '../filter';
|
|
4
|
+
import { useGridLogger, useGridSelector, useGridApiMethod } from '../../utils';
|
|
5
|
+
import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
|
|
6
|
+
import { gridPaginationRowCountSelector } from './gridPaginationSelector';
|
|
7
|
+
import { noRowCountInServerMode } from './gridPaginationUtils';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @requires useGridFilter (state)
|
|
11
|
+
* @requires useGridDimensions (event) - can be after
|
|
12
|
+
*/
|
|
13
|
+
export var useGridRowCount = function useGridRowCount(apiRef, props) {
|
|
14
|
+
var _props$initialState2;
|
|
15
|
+
var logger = useGridLogger(apiRef, 'useGridRowCount');
|
|
16
|
+
var visibleTopLevelRowCount = useGridSelector(apiRef, gridFilteredTopLevelRowCountSelector);
|
|
17
|
+
var rowCount = useGridSelector(apiRef, gridPaginationRowCountSelector);
|
|
18
|
+
apiRef.current.registerControlState({
|
|
19
|
+
stateId: 'paginationRowCount',
|
|
20
|
+
propModel: props.rowCount,
|
|
21
|
+
propOnChange: props.onRowCountChange,
|
|
22
|
+
stateSelector: gridPaginationRowCountSelector,
|
|
23
|
+
changeEvent: 'rowCountChange'
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* API METHODS
|
|
28
|
+
*/
|
|
29
|
+
var setRowCount = React.useCallback(function (newRowCount) {
|
|
30
|
+
if (rowCount === newRowCount) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
logger.debug("Setting 'rowCount' to", newRowCount);
|
|
34
|
+
apiRef.current.setState(function (state) {
|
|
35
|
+
return _extends({}, state, {
|
|
36
|
+
pagination: _extends({}, state.pagination, {
|
|
37
|
+
rowCount: newRowCount
|
|
38
|
+
})
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}, [apiRef, logger, rowCount]);
|
|
42
|
+
var paginationRowCountApi = {
|
|
43
|
+
setRowCount: setRowCount
|
|
44
|
+
};
|
|
45
|
+
useGridApiMethod(apiRef, paginationRowCountApi, 'public');
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* PRE-PROCESSING
|
|
49
|
+
*/
|
|
50
|
+
var stateExportPreProcessing = React.useCallback(function (prevState, context) {
|
|
51
|
+
var _props$initialState;
|
|
52
|
+
var exportedRowCount = gridPaginationRowCountSelector(apiRef);
|
|
53
|
+
var shouldExportRowCount =
|
|
54
|
+
// Always export if the `exportOnlyDirtyModels` property is not activated
|
|
55
|
+
!context.exportOnlyDirtyModels ||
|
|
56
|
+
// Always export if the `rowCount` is controlled
|
|
57
|
+
props.rowCount != null ||
|
|
58
|
+
// Always export if the `rowCount` has been initialized
|
|
59
|
+
((_props$initialState = props.initialState) == null || (_props$initialState = _props$initialState.pagination) == null ? void 0 : _props$initialState.rowCount) != null;
|
|
60
|
+
if (!shouldExportRowCount) {
|
|
61
|
+
return prevState;
|
|
62
|
+
}
|
|
63
|
+
return _extends({}, prevState, {
|
|
64
|
+
pagination: _extends({}, prevState.pagination, {
|
|
65
|
+
rowCount: exportedRowCount
|
|
66
|
+
})
|
|
67
|
+
});
|
|
68
|
+
}, [apiRef, props.rowCount, (_props$initialState2 = props.initialState) == null || (_props$initialState2 = _props$initialState2.pagination) == null ? void 0 : _props$initialState2.rowCount]);
|
|
69
|
+
var stateRestorePreProcessing = React.useCallback(function (params, context) {
|
|
70
|
+
var _context$stateToResto;
|
|
71
|
+
var restoredRowCount = (_context$stateToResto = context.stateToRestore.pagination) != null && _context$stateToResto.rowCount ? context.stateToRestore.pagination.rowCount : gridPaginationRowCountSelector(apiRef);
|
|
72
|
+
apiRef.current.setState(function (state) {
|
|
73
|
+
return _extends({}, state, {
|
|
74
|
+
pagination: _extends({}, state.pagination, {
|
|
75
|
+
rowCount: restoredRowCount
|
|
76
|
+
})
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
return params;
|
|
80
|
+
}, [apiRef]);
|
|
81
|
+
useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
|
|
82
|
+
useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* EFFECTS
|
|
86
|
+
*/
|
|
87
|
+
React.useEffect(function () {
|
|
88
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
89
|
+
if (props.paginationMode === 'server' && props.rowCount == null) {
|
|
90
|
+
noRowCountInServerMode();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}, [props.rowCount, props.paginationMode]);
|
|
94
|
+
React.useEffect(function () {
|
|
95
|
+
if (props.paginationMode === 'client') {
|
|
96
|
+
apiRef.current.setRowCount(visibleTopLevelRowCount);
|
|
97
|
+
} else if (props.rowCount != null) {
|
|
98
|
+
apiRef.current.setRowCount(props.rowCount);
|
|
99
|
+
}
|
|
100
|
+
}, [apiRef, visibleTopLevelRowCount, props.paginationMode, props.rowCount]);
|
|
101
|
+
};
|
package/legacy/index.js
CHANGED
|
@@ -369,6 +369,12 @@ export interface GridControlledStateEventLookup {
|
|
|
369
369
|
columnVisibilityModelChange: {
|
|
370
370
|
params: GridColumnVisibilityModel;
|
|
371
371
|
};
|
|
372
|
+
/**
|
|
373
|
+
* Fired when the row count change.
|
|
374
|
+
*/
|
|
375
|
+
rowCountChange: {
|
|
376
|
+
params: number;
|
|
377
|
+
};
|
|
372
378
|
}
|
|
373
379
|
export interface GridControlledStateReasonLookup {
|
|
374
380
|
filter: 'upsertFilterItem' | 'upsertFilterItems' | 'deleteFilterItem' | 'changeLogicOperator' | 'restoreState';
|
|
@@ -569,6 +569,11 @@ export interface DataGridPropsWithoutDefaultValue<R extends GridValidRowModel =
|
|
|
569
569
|
* @param {GridCallbackDetails} details Additional details for this callback.
|
|
570
570
|
*/
|
|
571
571
|
onPaginationModelChange?: (model: GridPaginationModel, details: GridCallbackDetails) => void;
|
|
572
|
+
/**
|
|
573
|
+
* Callback fired when the row count has changed.
|
|
574
|
+
* @param {number} count Updated row count.
|
|
575
|
+
*/
|
|
576
|
+
onRowCountChange?: (count: number) => void;
|
|
572
577
|
/**
|
|
573
578
|
* Callback fired when the preferences panel is closed.
|
|
574
579
|
* @param {GridPreferencePanelParams} params With all properties from [[GridPreferencePanelParams]].
|
|
@@ -495,6 +495,11 @@ DataGridRaw.propTypes = {
|
|
|
495
495
|
* @param {GridCallbackDetails} details Additional details for this callback.
|
|
496
496
|
*/
|
|
497
497
|
onRowClick: PropTypes.func,
|
|
498
|
+
/**
|
|
499
|
+
* Callback fired when the row count has changed.
|
|
500
|
+
* @param {number} count Updated row count.
|
|
501
|
+
*/
|
|
502
|
+
onRowCountChange: PropTypes.func,
|
|
498
503
|
/**
|
|
499
504
|
* Callback fired when a double click event comes from a row container element.
|
|
500
505
|
* @param {GridRowParams} params With all properties from [[RowParams]].
|
|
@@ -6,8 +6,7 @@ import { styled } from '@mui/material/styles';
|
|
|
6
6
|
import { useGridSelector } from '../hooks/utils/useGridSelector';
|
|
7
7
|
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
|
|
8
8
|
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
|
|
9
|
-
import {
|
|
10
|
-
import { gridPaginationModelSelector } from '../hooks/features/pagination/gridPaginationSelector';
|
|
9
|
+
import { gridPaginationModelSelector, gridPaginationRowCountSelector } from '../hooks/features/pagination/gridPaginationSelector';
|
|
11
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
11
|
const GridPaginationRoot = styled(TablePagination)(({
|
|
13
12
|
theme
|
|
@@ -32,8 +31,7 @@ const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(pro
|
|
|
32
31
|
const apiRef = useGridApiContext();
|
|
33
32
|
const rootProps = useGridRootProps();
|
|
34
33
|
const paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
|
|
35
|
-
const
|
|
36
|
-
const rowCount = React.useMemo(() => rootProps.rowCount ?? visibleTopLevelRowCount ?? 0, [rootProps.rowCount, visibleTopLevelRowCount]);
|
|
34
|
+
const rowCount = useGridSelector(apiRef, gridPaginationRowCountSelector);
|
|
37
35
|
const lastPage = React.useMemo(() => Math.floor(rowCount / (paginationModel.pageSize || 1)), [rowCount, paginationModel.pageSize]);
|
|
38
36
|
const handlePageSizeChange = React.useCallback(event => {
|
|
39
37
|
const pageSize = Number(event.target.value);
|
|
@@ -8,7 +8,7 @@ import { gridClasses } from '../../../constants/gridClasses';
|
|
|
8
8
|
import { useGridApiMethod } from '../../utils/useGridApiMethod';
|
|
9
9
|
import { gridRowsMetaSelector } from '../rows/gridRowsMetaSelector';
|
|
10
10
|
import { getColumnsToExport } from './utils';
|
|
11
|
-
import {
|
|
11
|
+
import { getDerivedPaginationModel } from '../pagination/useGridPaginationModel';
|
|
12
12
|
import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
|
|
13
13
|
import { GridPrintExportMenuItem } from '../../../components/toolbar/GridToolbarExport';
|
|
14
14
|
import { getTotalHeaderHeight } from '../columns/gridColumnsUtils';
|
|
@@ -222,9 +222,13 @@ export const useGridPrintExport = (apiRef, props) => {
|
|
|
222
222
|
page: 0,
|
|
223
223
|
pageSize: visibleRowCount
|
|
224
224
|
};
|
|
225
|
-
apiRef.current.
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
apiRef.current.setState(state => _extends({}, state, {
|
|
226
|
+
pagination: _extends({}, state.pagination, {
|
|
227
|
+
paginationModel: getDerivedPaginationModel(state.pagination,
|
|
228
|
+
// Using signature `DataGridPro` to allow more than 100 rows in the print export
|
|
229
|
+
'DataGridPro', paginationModel)
|
|
230
|
+
})
|
|
231
|
+
}));
|
|
228
232
|
apiRef.current.forceUpdate();
|
|
229
233
|
}
|
|
230
234
|
await updateGridColumnsForPrint(options?.fields, options?.allColumns, options?.includeCheckboxes);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createSelector, createSelectorMemoized } from '../../../utils/createSelector';
|
|
2
|
-
import {
|
|
2
|
+
import { gridExpandedSortedRowEntriesSelector, gridExpandedSortedRowIdsSelector, gridFilteredSortedTopLevelRowEntriesSelector } from '../filter/gridFilterSelector';
|
|
3
3
|
import { gridRowMaximumTreeDepthSelector, gridRowTreeSelector } from '../rows/gridRowsSelector';
|
|
4
4
|
import { getPageCount } from './gridPaginationUtils';
|
|
5
5
|
|
|
@@ -15,6 +15,12 @@ export const gridPaginationSelector = state => state.pagination;
|
|
|
15
15
|
*/
|
|
16
16
|
export const gridPaginationModelSelector = createSelector(gridPaginationSelector, pagination => pagination.paginationModel);
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Get the row count
|
|
20
|
+
* @category Pagination
|
|
21
|
+
*/
|
|
22
|
+
export const gridPaginationRowCountSelector = createSelector(gridPaginationSelector, pagination => pagination.rowCount);
|
|
23
|
+
|
|
18
24
|
/**
|
|
19
25
|
* Get the index of the page to render if the pagination is enabled
|
|
20
26
|
* @category Pagination
|
|
@@ -31,7 +37,7 @@ export const gridPageSizeSelector = createSelector(gridPaginationModelSelector,
|
|
|
31
37
|
* Get the amount of pages needed to display all the rows if the pagination is enabled
|
|
32
38
|
* @category Pagination
|
|
33
39
|
*/
|
|
34
|
-
export const gridPageCountSelector = createSelector(
|
|
40
|
+
export const gridPageCountSelector = createSelector(gridPageSizeSelector, gridPaginationRowCountSelector, (pageSize, rowCount) => getPageCount(rowCount, pageSize));
|
|
35
41
|
|
|
36
42
|
/**
|
|
37
43
|
* Get the index of the first and the last row to include in the current page if the pagination is enabled.
|
|
@@ -1,167 +1,24 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { useGridLogger, useGridSelector, useGridApiMethod, useGridApiEventHandler } from '../../utils';
|
|
6
|
-
import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
|
|
7
|
-
import { gridPaginationModelSelector } from './gridPaginationSelector';
|
|
8
|
-
import { calculatePinnedRowsHeight } from '../rows/gridRowsUtils';
|
|
9
|
-
import { getPageCount, noRowCountInServerMode, defaultPageSize, throwIfPageSizeExceedsTheLimit, getDefaultGridPaginationModel, getValidPage } from './gridPaginationUtils';
|
|
2
|
+
import { throwIfPageSizeExceedsTheLimit, getDefaultGridPaginationModel } from './gridPaginationUtils';
|
|
3
|
+
import { useGridPaginationModel } from './useGridPaginationModel';
|
|
4
|
+
import { useGridRowCount } from './useGridRowCount';
|
|
10
5
|
export const paginationStateInitializer = (state, props) => {
|
|
11
6
|
const paginationModel = _extends({}, getDefaultGridPaginationModel(props.autoPageSize), props.paginationModel ?? props.initialState?.pagination?.paginationModel);
|
|
12
7
|
throwIfPageSizeExceedsTheLimit(paginationModel.pageSize, props.signature);
|
|
8
|
+
const rowCount = props.rowCount ?? props.initialState?.pagination?.rowCount ?? 0;
|
|
13
9
|
return _extends({}, state, {
|
|
14
10
|
pagination: {
|
|
15
|
-
paginationModel
|
|
11
|
+
paginationModel,
|
|
12
|
+
rowCount
|
|
16
13
|
}
|
|
17
14
|
});
|
|
18
15
|
};
|
|
19
|
-
export const mergeStateWithPaginationModel = (rowCount, signature, paginationModelProp) => paginationState => {
|
|
20
|
-
let paginationModel = paginationState.paginationModel;
|
|
21
|
-
const pageSize = paginationModelProp?.pageSize ?? paginationModel.pageSize;
|
|
22
|
-
const pageCount = getPageCount(rowCount, pageSize);
|
|
23
|
-
if (paginationModelProp && (paginationModelProp?.page !== paginationModel.page || paginationModelProp?.pageSize !== paginationModel.pageSize)) {
|
|
24
|
-
paginationModel = paginationModelProp;
|
|
25
|
-
}
|
|
26
|
-
const validPage = getValidPage(paginationModel.page, pageCount);
|
|
27
|
-
if (validPage !== paginationModel.page) {
|
|
28
|
-
paginationModel = _extends({}, paginationModel, {
|
|
29
|
-
page: validPage
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
throwIfPageSizeExceedsTheLimit(paginationModel.pageSize, signature);
|
|
33
|
-
return {
|
|
34
|
-
paginationModel
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
16
|
|
|
38
17
|
/**
|
|
39
18
|
* @requires useGridFilter (state)
|
|
40
19
|
* @requires useGridDimensions (event) - can be after
|
|
41
20
|
*/
|
|
42
21
|
export const useGridPagination = (apiRef, props) => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
|
|
46
|
-
const rowHeight = Math.floor(props.rowHeight * densityFactor);
|
|
47
|
-
apiRef.current.registerControlState({
|
|
48
|
-
stateId: 'pagination',
|
|
49
|
-
propModel: props.paginationModel,
|
|
50
|
-
propOnChange: props.onPaginationModelChange,
|
|
51
|
-
stateSelector: gridPaginationModelSelector,
|
|
52
|
-
changeEvent: 'paginationModelChange'
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* API METHODS
|
|
57
|
-
*/
|
|
58
|
-
const setPage = React.useCallback(page => {
|
|
59
|
-
const currentModel = gridPaginationModelSelector(apiRef);
|
|
60
|
-
if (page === currentModel.page) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
logger.debug(`Setting page to ${page}`);
|
|
64
|
-
apiRef.current.setPaginationModel({
|
|
65
|
-
page,
|
|
66
|
-
pageSize: currentModel.pageSize
|
|
67
|
-
});
|
|
68
|
-
}, [apiRef, logger]);
|
|
69
|
-
const setPageSize = React.useCallback(pageSize => {
|
|
70
|
-
const currentModel = gridPaginationModelSelector(apiRef);
|
|
71
|
-
if (pageSize === currentModel.pageSize) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
logger.debug(`Setting page size to ${pageSize}`);
|
|
75
|
-
apiRef.current.setPaginationModel({
|
|
76
|
-
pageSize,
|
|
77
|
-
page: currentModel.page
|
|
78
|
-
});
|
|
79
|
-
}, [apiRef, logger]);
|
|
80
|
-
const setPaginationModel = React.useCallback(paginationModel => {
|
|
81
|
-
const currentModel = gridPaginationModelSelector(apiRef);
|
|
82
|
-
if (paginationModel === currentModel) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
logger.debug("Setting 'paginationModel' to", paginationModel);
|
|
86
|
-
apiRef.current.updateControlState('pagination', mergeStateWithPaginationModel(props.rowCount ?? visibleTopLevelRowCount, props.signature, paginationModel), 'setPaginationModel');
|
|
87
|
-
apiRef.current.forceUpdate();
|
|
88
|
-
}, [apiRef, logger, props.rowCount, props.signature, visibleTopLevelRowCount]);
|
|
89
|
-
const pageApi = {
|
|
90
|
-
setPage,
|
|
91
|
-
setPageSize,
|
|
92
|
-
setPaginationModel
|
|
93
|
-
};
|
|
94
|
-
useGridApiMethod(apiRef, pageApi, 'public');
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* PRE-PROCESSING
|
|
98
|
-
*/
|
|
99
|
-
const stateExportPreProcessing = React.useCallback((prevState, context) => {
|
|
100
|
-
const paginationModel = gridPaginationModelSelector(apiRef);
|
|
101
|
-
const shouldExportPaginationModel =
|
|
102
|
-
// Always export if the `exportOnlyDirtyModels` property is not activated
|
|
103
|
-
!context.exportOnlyDirtyModels ||
|
|
104
|
-
// Always export if the `paginationModel` is controlled
|
|
105
|
-
props.paginationModel != null ||
|
|
106
|
-
// Always export if the `paginationModel` has been initialized
|
|
107
|
-
props.initialState?.pagination?.paginationModel != null ||
|
|
108
|
-
// Export if `page` or `pageSize` is not equal to the default value
|
|
109
|
-
paginationModel.page !== 0 && paginationModel.pageSize !== defaultPageSize(props.autoPageSize);
|
|
110
|
-
if (!shouldExportPaginationModel) {
|
|
111
|
-
return prevState;
|
|
112
|
-
}
|
|
113
|
-
return _extends({}, prevState, {
|
|
114
|
-
pagination: _extends({}, prevState.pagination, {
|
|
115
|
-
paginationModel
|
|
116
|
-
})
|
|
117
|
-
});
|
|
118
|
-
}, [apiRef, props.paginationModel, props.initialState?.pagination?.paginationModel, props.autoPageSize]);
|
|
119
|
-
const stateRestorePreProcessing = React.useCallback((params, context) => {
|
|
120
|
-
const paginationModel = context.stateToRestore.pagination?.paginationModel ? _extends({}, getDefaultGridPaginationModel(props.autoPageSize), context.stateToRestore.pagination?.paginationModel) : gridPaginationModelSelector(apiRef);
|
|
121
|
-
apiRef.current.updateControlState('pagination', mergeStateWithPaginationModel(props.rowCount ?? visibleTopLevelRowCount, props.signature, paginationModel), 'stateRestorePreProcessing');
|
|
122
|
-
return params;
|
|
123
|
-
}, [apiRef, props.autoPageSize, props.rowCount, props.signature, visibleTopLevelRowCount]);
|
|
124
|
-
useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
|
|
125
|
-
useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* EVENTS
|
|
129
|
-
*/
|
|
130
|
-
const handlePaginationModelChange = () => {
|
|
131
|
-
const paginationModel = gridPaginationModelSelector(apiRef);
|
|
132
|
-
if (apiRef.current.virtualScrollerRef?.current) {
|
|
133
|
-
apiRef.current.scrollToIndexes({
|
|
134
|
-
rowIndex: paginationModel.page * paginationModel.pageSize
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
apiRef.current.forceUpdate();
|
|
138
|
-
};
|
|
139
|
-
const handleUpdateAutoPageSize = React.useCallback(() => {
|
|
140
|
-
const dimensions = apiRef.current.getRootDimensions();
|
|
141
|
-
if (!props.autoPageSize || !dimensions) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
const pinnedRowsHeight = calculatePinnedRowsHeight(apiRef);
|
|
145
|
-
const maximumPageSizeWithoutScrollBar = Math.floor((dimensions.viewportInnerSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom) / rowHeight);
|
|
146
|
-
apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
|
|
147
|
-
}, [apiRef, props.autoPageSize, rowHeight]);
|
|
148
|
-
useGridApiEventHandler(apiRef, 'viewportInnerSizeChange', handleUpdateAutoPageSize);
|
|
149
|
-
useGridApiEventHandler(apiRef, 'paginationModelChange', handlePaginationModelChange);
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* EFFECTS
|
|
153
|
-
*/
|
|
154
|
-
React.useEffect(() => {
|
|
155
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
156
|
-
if (props.paginationMode === 'server' && props.rowCount == null) {
|
|
157
|
-
noRowCountInServerMode();
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}, [props.rowCount, props.paginationMode]);
|
|
161
|
-
React.useEffect(() => {
|
|
162
|
-
apiRef.current.updateControlState('pagination', mergeStateWithPaginationModel(props.rowCount ?? visibleTopLevelRowCount, props.signature, props.paginationModel));
|
|
163
|
-
}, [apiRef, props.paginationModel, props.rowCount, props.paginationMode, visibleTopLevelRowCount, props.signature]);
|
|
164
|
-
React.useEffect(() => {
|
|
165
|
-
handleUpdateAutoPageSize();
|
|
166
|
-
}, [handleUpdateAutoPageSize]);
|
|
22
|
+
useGridPaginationModel(apiRef, props);
|
|
23
|
+
useGridRowCount(apiRef, props);
|
|
167
24
|
};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { gridDensityFactorSelector } from '../density';
|
|
4
|
+
import { calculatePinnedRowsHeight } from '../rows/gridRowsUtils';
|
|
5
|
+
import { useGridLogger, useGridSelector, useGridApiMethod, useGridApiEventHandler } from '../../utils';
|
|
6
|
+
import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
|
|
7
|
+
import { gridPageCountSelector, gridPaginationModelSelector } from './gridPaginationSelector';
|
|
8
|
+
import { getPageCount, defaultPageSize, throwIfPageSizeExceedsTheLimit, getDefaultGridPaginationModel, getValidPage } from './gridPaginationUtils';
|
|
9
|
+
export const getDerivedPaginationModel = (paginationState, signature, paginationModelProp) => {
|
|
10
|
+
let paginationModel = paginationState.paginationModel;
|
|
11
|
+
const rowCount = paginationState.rowCount;
|
|
12
|
+
const pageSize = paginationModelProp?.pageSize ?? paginationModel.pageSize;
|
|
13
|
+
const pageCount = getPageCount(rowCount, pageSize);
|
|
14
|
+
if (paginationModelProp && (paginationModelProp?.page !== paginationModel.page || paginationModelProp?.pageSize !== paginationModel.pageSize)) {
|
|
15
|
+
paginationModel = paginationModelProp;
|
|
16
|
+
}
|
|
17
|
+
const validPage = getValidPage(paginationModel.page, pageCount);
|
|
18
|
+
if (validPage !== paginationModel.page) {
|
|
19
|
+
paginationModel = _extends({}, paginationModel, {
|
|
20
|
+
page: validPage
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
throwIfPageSizeExceedsTheLimit(paginationModel.pageSize, signature);
|
|
24
|
+
return paginationModel;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @requires useGridFilter (state)
|
|
29
|
+
* @requires useGridDimensions (event) - can be after
|
|
30
|
+
*/
|
|
31
|
+
export const useGridPaginationModel = (apiRef, props) => {
|
|
32
|
+
const logger = useGridLogger(apiRef, 'useGridPaginationModel');
|
|
33
|
+
const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
|
|
34
|
+
const rowHeight = Math.floor(props.rowHeight * densityFactor);
|
|
35
|
+
apiRef.current.registerControlState({
|
|
36
|
+
stateId: 'paginationModel',
|
|
37
|
+
propModel: props.paginationModel,
|
|
38
|
+
propOnChange: props.onPaginationModelChange,
|
|
39
|
+
stateSelector: gridPaginationModelSelector,
|
|
40
|
+
changeEvent: 'paginationModelChange'
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* API METHODS
|
|
45
|
+
*/
|
|
46
|
+
const setPage = React.useCallback(page => {
|
|
47
|
+
const currentModel = gridPaginationModelSelector(apiRef);
|
|
48
|
+
if (page === currentModel.page) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
logger.debug(`Setting page to ${page}`);
|
|
52
|
+
apiRef.current.setPaginationModel({
|
|
53
|
+
page,
|
|
54
|
+
pageSize: currentModel.pageSize
|
|
55
|
+
});
|
|
56
|
+
}, [apiRef, logger]);
|
|
57
|
+
const setPageSize = React.useCallback(pageSize => {
|
|
58
|
+
const currentModel = gridPaginationModelSelector(apiRef);
|
|
59
|
+
if (pageSize === currentModel.pageSize) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
logger.debug(`Setting page size to ${pageSize}`);
|
|
63
|
+
apiRef.current.setPaginationModel({
|
|
64
|
+
pageSize,
|
|
65
|
+
page: currentModel.page
|
|
66
|
+
});
|
|
67
|
+
}, [apiRef, logger]);
|
|
68
|
+
const setPaginationModel = React.useCallback(paginationModel => {
|
|
69
|
+
const currentModel = gridPaginationModelSelector(apiRef);
|
|
70
|
+
if (paginationModel === currentModel) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
logger.debug("Setting 'paginationModel' to", paginationModel);
|
|
74
|
+
apiRef.current.setState(state => _extends({}, state, {
|
|
75
|
+
pagination: _extends({}, state.pagination, {
|
|
76
|
+
paginationModel: getDerivedPaginationModel(state.pagination, props.signature, paginationModel)
|
|
77
|
+
})
|
|
78
|
+
}));
|
|
79
|
+
}, [apiRef, logger, props.signature]);
|
|
80
|
+
const paginationModelApi = {
|
|
81
|
+
setPage,
|
|
82
|
+
setPageSize,
|
|
83
|
+
setPaginationModel
|
|
84
|
+
};
|
|
85
|
+
useGridApiMethod(apiRef, paginationModelApi, 'public');
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* PRE-PROCESSING
|
|
89
|
+
*/
|
|
90
|
+
const stateExportPreProcessing = React.useCallback((prevState, context) => {
|
|
91
|
+
const paginationModel = gridPaginationModelSelector(apiRef);
|
|
92
|
+
const shouldExportPaginationModel =
|
|
93
|
+
// Always export if the `exportOnlyDirtyModels` property is not activated
|
|
94
|
+
!context.exportOnlyDirtyModels ||
|
|
95
|
+
// Always export if the `paginationModel` is controlled
|
|
96
|
+
props.paginationModel != null ||
|
|
97
|
+
// Always export if the `paginationModel` has been initialized
|
|
98
|
+
props.initialState?.pagination?.paginationModel != null ||
|
|
99
|
+
// Export if `page` or `pageSize` is not equal to the default value
|
|
100
|
+
paginationModel.page !== 0 && paginationModel.pageSize !== defaultPageSize(props.autoPageSize);
|
|
101
|
+
if (!shouldExportPaginationModel) {
|
|
102
|
+
return prevState;
|
|
103
|
+
}
|
|
104
|
+
return _extends({}, prevState, {
|
|
105
|
+
pagination: _extends({}, prevState.pagination, {
|
|
106
|
+
paginationModel
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
}, [apiRef, props.paginationModel, props.initialState?.pagination?.paginationModel, props.autoPageSize]);
|
|
110
|
+
const stateRestorePreProcessing = React.useCallback((params, context) => {
|
|
111
|
+
const paginationModel = context.stateToRestore.pagination?.paginationModel ? _extends({}, getDefaultGridPaginationModel(props.autoPageSize), context.stateToRestore.pagination?.paginationModel) : gridPaginationModelSelector(apiRef);
|
|
112
|
+
apiRef.current.setState(state => _extends({}, state, {
|
|
113
|
+
pagination: _extends({}, state.pagination, {
|
|
114
|
+
paginationModel: getDerivedPaginationModel(state.pagination, props.signature, paginationModel)
|
|
115
|
+
})
|
|
116
|
+
}));
|
|
117
|
+
return params;
|
|
118
|
+
}, [apiRef, props.autoPageSize, props.signature]);
|
|
119
|
+
useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
|
|
120
|
+
useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* EVENTS
|
|
124
|
+
*/
|
|
125
|
+
const handlePaginationModelChange = () => {
|
|
126
|
+
const paginationModel = gridPaginationModelSelector(apiRef);
|
|
127
|
+
if (apiRef.current.virtualScrollerRef?.current) {
|
|
128
|
+
apiRef.current.scrollToIndexes({
|
|
129
|
+
rowIndex: paginationModel.page * paginationModel.pageSize
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const handleUpdateAutoPageSize = React.useCallback(() => {
|
|
134
|
+
if (!props.autoPageSize) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const dimensions = apiRef.current.getRootDimensions() || {
|
|
138
|
+
viewportInnerSize: {
|
|
139
|
+
height: 0
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const pinnedRowsHeight = calculatePinnedRowsHeight(apiRef);
|
|
143
|
+
const maximumPageSizeWithoutScrollBar = Math.floor((dimensions.viewportInnerSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom) / rowHeight);
|
|
144
|
+
apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
|
|
145
|
+
}, [apiRef, props.autoPageSize, rowHeight]);
|
|
146
|
+
const handleRowCountChange = React.useCallback(newRowCount => {
|
|
147
|
+
if (newRowCount == null) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const paginationModel = gridPaginationModelSelector(apiRef);
|
|
151
|
+
const pageCount = gridPageCountSelector(apiRef);
|
|
152
|
+
if (paginationModel.page > pageCount - 1) {
|
|
153
|
+
apiRef.current.setPage(Math.max(0, pageCount - 1));
|
|
154
|
+
}
|
|
155
|
+
}, [apiRef]);
|
|
156
|
+
useGridApiEventHandler(apiRef, 'viewportInnerSizeChange', handleUpdateAutoPageSize);
|
|
157
|
+
useGridApiEventHandler(apiRef, 'paginationModelChange', handlePaginationModelChange);
|
|
158
|
+
useGridApiEventHandler(apiRef, 'rowCountChange', handleRowCountChange);
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* EFFECTS
|
|
162
|
+
*/
|
|
163
|
+
React.useEffect(() => {
|
|
164
|
+
apiRef.current.setState(state => _extends({}, state, {
|
|
165
|
+
pagination: _extends({}, state.pagination, {
|
|
166
|
+
paginationModel: getDerivedPaginationModel(state.pagination, props.signature, props.paginationModel)
|
|
167
|
+
})
|
|
168
|
+
}));
|
|
169
|
+
}, [apiRef, props.paginationModel, props.paginationMode, props.signature]);
|
|
170
|
+
React.useEffect(handleUpdateAutoPageSize, [handleUpdateAutoPageSize]);
|
|
171
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { gridFilteredTopLevelRowCountSelector } from '../filter';
|
|
4
|
+
import { useGridLogger, useGridSelector, useGridApiMethod } from '../../utils';
|
|
5
|
+
import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
|
|
6
|
+
import { gridPaginationRowCountSelector } from './gridPaginationSelector';
|
|
7
|
+
import { noRowCountInServerMode } from './gridPaginationUtils';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @requires useGridFilter (state)
|
|
11
|
+
* @requires useGridDimensions (event) - can be after
|
|
12
|
+
*/
|
|
13
|
+
export const useGridRowCount = (apiRef, props) => {
|
|
14
|
+
const logger = useGridLogger(apiRef, 'useGridRowCount');
|
|
15
|
+
const visibleTopLevelRowCount = useGridSelector(apiRef, gridFilteredTopLevelRowCountSelector);
|
|
16
|
+
const rowCount = useGridSelector(apiRef, gridPaginationRowCountSelector);
|
|
17
|
+
apiRef.current.registerControlState({
|
|
18
|
+
stateId: 'paginationRowCount',
|
|
19
|
+
propModel: props.rowCount,
|
|
20
|
+
propOnChange: props.onRowCountChange,
|
|
21
|
+
stateSelector: gridPaginationRowCountSelector,
|
|
22
|
+
changeEvent: 'rowCountChange'
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* API METHODS
|
|
27
|
+
*/
|
|
28
|
+
const setRowCount = React.useCallback(newRowCount => {
|
|
29
|
+
if (rowCount === newRowCount) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
logger.debug("Setting 'rowCount' to", newRowCount);
|
|
33
|
+
apiRef.current.setState(state => _extends({}, state, {
|
|
34
|
+
pagination: _extends({}, state.pagination, {
|
|
35
|
+
rowCount: newRowCount
|
|
36
|
+
})
|
|
37
|
+
}));
|
|
38
|
+
}, [apiRef, logger, rowCount]);
|
|
39
|
+
const paginationRowCountApi = {
|
|
40
|
+
setRowCount
|
|
41
|
+
};
|
|
42
|
+
useGridApiMethod(apiRef, paginationRowCountApi, 'public');
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* PRE-PROCESSING
|
|
46
|
+
*/
|
|
47
|
+
const stateExportPreProcessing = React.useCallback((prevState, context) => {
|
|
48
|
+
const exportedRowCount = gridPaginationRowCountSelector(apiRef);
|
|
49
|
+
const shouldExportRowCount =
|
|
50
|
+
// Always export if the `exportOnlyDirtyModels` property is not activated
|
|
51
|
+
!context.exportOnlyDirtyModels ||
|
|
52
|
+
// Always export if the `rowCount` is controlled
|
|
53
|
+
props.rowCount != null ||
|
|
54
|
+
// Always export if the `rowCount` has been initialized
|
|
55
|
+
props.initialState?.pagination?.rowCount != null;
|
|
56
|
+
if (!shouldExportRowCount) {
|
|
57
|
+
return prevState;
|
|
58
|
+
}
|
|
59
|
+
return _extends({}, prevState, {
|
|
60
|
+
pagination: _extends({}, prevState.pagination, {
|
|
61
|
+
rowCount: exportedRowCount
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
}, [apiRef, props.rowCount, props.initialState?.pagination?.rowCount]);
|
|
65
|
+
const stateRestorePreProcessing = React.useCallback((params, context) => {
|
|
66
|
+
const restoredRowCount = context.stateToRestore.pagination?.rowCount ? context.stateToRestore.pagination.rowCount : gridPaginationRowCountSelector(apiRef);
|
|
67
|
+
apiRef.current.setState(state => _extends({}, state, {
|
|
68
|
+
pagination: _extends({}, state.pagination, {
|
|
69
|
+
rowCount: restoredRowCount
|
|
70
|
+
})
|
|
71
|
+
}));
|
|
72
|
+
return params;
|
|
73
|
+
}, [apiRef]);
|
|
74
|
+
useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
|
|
75
|
+
useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* EFFECTS
|
|
79
|
+
*/
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
82
|
+
if (props.paginationMode === 'server' && props.rowCount == null) {
|
|
83
|
+
noRowCountInServerMode();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}, [props.rowCount, props.paginationMode]);
|
|
87
|
+
React.useEffect(() => {
|
|
88
|
+
if (props.paginationMode === 'client') {
|
|
89
|
+
apiRef.current.setRowCount(visibleTopLevelRowCount);
|
|
90
|
+
} else if (props.rowCount != null) {
|
|
91
|
+
apiRef.current.setRowCount(props.rowCount);
|
|
92
|
+
}
|
|
93
|
+
}, [apiRef, visibleTopLevelRowCount, props.paginationMode, props.rowCount]);
|
|
94
|
+
};
|