@mui/x-data-grid-pro 7.7.1 → 7.9.0
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 +166 -1
- package/DataGridPro/DataGridPro.js +13 -1
- package/DataGridPro/useDataGridProComponent.js +6 -1
- package/DataGridPro/useDataGridProProps.js +10 -3
- package/components/GridDataSourceTreeDataGroupingCell.d.ts +12 -0
- package/components/GridDataSourceTreeDataGroupingCell.js +120 -0
- package/components/GridDetailPanel.js +2 -2
- package/components/GridTreeDataGroupingCell.js +1 -4
- package/esm/DataGridPro/DataGridPro.js +13 -1
- package/esm/DataGridPro/useDataGridProComponent.js +6 -1
- package/esm/DataGridPro/useDataGridProProps.js +9 -3
- package/esm/components/GridDataSourceTreeDataGroupingCell.js +111 -0
- package/esm/components/GridDetailPanel.js +1 -1
- package/esm/components/GridTreeDataGroupingCell.js +1 -4
- package/esm/hooks/features/dataSource/cache.js +36 -0
- package/esm/hooks/features/dataSource/gridDataSourceSelector.js +24 -0
- package/esm/hooks/features/dataSource/useGridDataSource.js +218 -0
- package/esm/hooks/features/dataSource/utils.js +87 -0
- package/esm/hooks/features/index.js +3 -1
- package/esm/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.js +148 -0
- package/esm/hooks/features/serverSideTreeData/utils.js +18 -0
- package/esm/hooks/features/treeData/useGridTreeData.js +6 -2
- package/esm/hooks/features/treeData/useGridTreeDataPreProcessors.js +6 -3
- package/esm/internals/index.js +2 -0
- package/esm/internals/propValidation.js +1 -1
- package/esm/models/index.js +2 -1
- package/esm/utils/releaseInfo.js +1 -1
- package/esm/utils/tree/createRowTree.js +6 -2
- package/esm/utils/tree/insertDataRowInTree.js +34 -10
- package/esm/utils/tree/updateRowTree.js +13 -5
- package/esm/utils/tree/utils.js +5 -1
- package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +1 -1
- package/hooks/features/columnPinning/useGridColumnPinning.d.ts +1 -1
- package/hooks/features/columnReorder/useGridColumnReorder.d.ts +1 -1
- package/hooks/features/dataSource/cache.d.ts +18 -0
- package/hooks/features/dataSource/cache.js +43 -0
- package/hooks/features/dataSource/gridDataSourceSelector.d.ts +14 -0
- package/hooks/features/dataSource/gridDataSourceSelector.js +32 -0
- package/hooks/features/dataSource/interfaces.d.ts +50 -0
- package/hooks/features/dataSource/useGridDataSource.d.ts +6 -0
- package/hooks/features/dataSource/useGridDataSource.js +229 -0
- package/hooks/features/dataSource/utils.d.ts +29 -0
- package/hooks/features/dataSource/utils.js +95 -0
- package/hooks/features/detailPanel/gridDetailPanelSelector.d.ts +0 -1
- package/hooks/features/detailPanel/useGridDetailPanel.d.ts +1 -1
- package/hooks/features/index.d.ts +2 -0
- package/hooks/features/index.js +22 -0
- package/hooks/features/infiniteLoader/useGridInfiniteLoader.d.ts +1 -1
- package/hooks/features/lazyLoader/useGridLazyLoader.d.ts +1 -1
- package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.d.ts +1 -1
- package/hooks/features/rowPinning/useGridRowPinning.d.ts +1 -1
- package/hooks/features/rowPinning/useGridRowPinningPreProcessors.d.ts +2 -2
- package/hooks/features/rowReorder/useGridRowReorder.d.ts +1 -1
- package/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.d.ts +4 -0
- package/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.js +158 -0
- package/hooks/features/serverSideTreeData/utils.d.ts +6 -0
- package/hooks/features/serverSideTreeData/utils.js +25 -0
- package/hooks/features/treeData/gridTreeDataUtils.d.ts +1 -2
- package/hooks/features/treeData/useGridTreeData.d.ts +2 -1
- package/hooks/features/treeData/useGridTreeData.js +6 -2
- package/hooks/features/treeData/useGridTreeDataPreProcessors.d.ts +1 -1
- package/hooks/features/treeData/useGridTreeDataPreProcessors.js +6 -3
- package/hooks/utils/useGridApiContext.d.ts +0 -1
- package/hooks/utils/useGridApiRef.d.ts +0 -1
- package/hooks/utils/useGridPrivateApiContext.d.ts +0 -1
- package/index.js +1 -1
- package/internals/index.d.ts +2 -0
- package/internals/index.js +23 -0
- package/internals/propValidation.js +1 -1
- package/material/index.d.ts +0 -1
- package/models/dataGridProProps.d.ts +17 -11
- package/models/gridApiPro.d.ts +3 -3
- package/models/gridProSlotsComponent.d.ts +0 -1
- package/models/gridStatePro.d.ts +2 -0
- package/models/index.d.ts +1 -0
- package/modern/DataGridPro/DataGridPro.js +13 -1
- package/modern/DataGridPro/useDataGridProComponent.js +6 -1
- package/modern/DataGridPro/useDataGridProProps.js +9 -3
- package/modern/components/GridDataSourceTreeDataGroupingCell.js +111 -0
- package/modern/components/GridDetailPanel.js +1 -1
- package/modern/components/GridTreeDataGroupingCell.js +1 -4
- package/modern/hooks/features/dataSource/cache.js +36 -0
- package/modern/hooks/features/dataSource/gridDataSourceSelector.js +24 -0
- package/modern/hooks/features/dataSource/useGridDataSource.js +218 -0
- package/modern/hooks/features/dataSource/utils.js +87 -0
- package/modern/hooks/features/index.js +3 -1
- package/modern/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.js +148 -0
- package/modern/hooks/features/serverSideTreeData/utils.js +18 -0
- package/modern/hooks/features/treeData/useGridTreeData.js +6 -2
- package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +6 -3
- package/modern/index.js +1 -1
- package/modern/internals/index.js +2 -0
- package/modern/internals/propValidation.js +1 -1
- package/modern/models/index.js +2 -1
- package/modern/utils/releaseInfo.js +1 -1
- package/modern/utils/tree/createRowTree.js +6 -2
- package/modern/utils/tree/insertDataRowInTree.js +34 -10
- package/modern/utils/tree/updateRowTree.js +13 -5
- package/modern/utils/tree/utils.js +5 -1
- package/package.json +6 -5
- package/typeOverloads/modules.d.ts +0 -1
- package/utils/releaseInfo.js +1 -1
- package/utils/tree/createRowTree.js +6 -2
- package/utils/tree/insertDataRowInTree.d.ts +3 -1
- package/utils/tree/insertDataRowInTree.js +33 -9
- package/utils/tree/models.d.ts +1 -0
- package/utils/tree/updateRowTree.d.ts +1 -0
- package/utils/tree/updateRowTree.js +13 -5
- package/utils/tree/utils.d.ts +5 -4
- package/utils/tree/utils.js +7 -2
- package/models/dataSource.d.ts +0 -64
- /package/esm/{models/dataSource.js → hooks/features/dataSource/interfaces.js} +0 -0
- /package/{models/dataSource.js → hooks/features/dataSource/interfaces.js} +0 -0
- /package/modern/{models/dataSource.js → hooks/features/dataSource/interfaces.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { GridEventListener, GridCallbackDetails, GridRowParams, GridRowId, GridValidRowModel, GridGroupNode, GridFeatureMode } from '@mui/x-data-grid';
|
|
3
|
-
import { GridExperimentalFeatures, DataGridPropsWithoutDefaultValue, DataGridPropsWithDefaultValues, DataGridPropsWithComplexDefaultValueAfterProcessing, DataGridPropsWithComplexDefaultValueBeforeProcessing, GridPinnedColumnFields, DataGridProSharedPropsWithDefaultValue, DataGridProSharedPropsWithoutDefaultValue } from '@mui/x-data-grid/internals';
|
|
3
|
+
import type { GridExperimentalFeatures, DataGridPropsWithoutDefaultValue, DataGridPropsWithDefaultValues, DataGridPropsWithComplexDefaultValueAfterProcessing, DataGridPropsWithComplexDefaultValueBeforeProcessing, GridPinnedColumnFields, DataGridProSharedPropsWithDefaultValue, DataGridProSharedPropsWithoutDefaultValue, GridDataSourceCache, GridGetRowsParams } from '@mui/x-data-grid/internals';
|
|
4
4
|
import type { GridPinnedRowsProp } from '../hooks/features/rowPinning';
|
|
5
5
|
import { GridApiPro } from './gridApiPro';
|
|
6
6
|
import { GridGroupingColDefOverride, GridGroupingColDefOverrideParams } from './gridGroupingColDefOverride';
|
|
@@ -99,7 +99,22 @@ export interface DataGridProPropsWithDefaultValue<R extends GridValidRowModel =
|
|
|
99
99
|
*/
|
|
100
100
|
keepColumnPositionIfDraggedOutside: boolean;
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
interface DataGridProDataSourceProps {
|
|
103
|
+
unstable_dataSourceCache?: GridDataSourceCache | null;
|
|
104
|
+
unstable_onDataSourceError?: (error: Error, params: GridGetRowsParams) => void;
|
|
105
|
+
}
|
|
106
|
+
interface DataGridProRegularProps<R extends GridValidRowModel> {
|
|
107
|
+
/**
|
|
108
|
+
* Determines the path of a row in the tree data.
|
|
109
|
+
* For instance, a row with the path ["A", "B"] is the child of the row with the path ["A"].
|
|
110
|
+
* Note that all paths must contain at least one element.
|
|
111
|
+
* @template R
|
|
112
|
+
* @param {R} row The row from which we want the path.
|
|
113
|
+
* @returns {string[]} The path to the row.
|
|
114
|
+
*/
|
|
115
|
+
getTreeDataPath?: (row: R) => string[];
|
|
116
|
+
}
|
|
117
|
+
export interface DataGridProPropsWithoutDefaultValue<R extends GridValidRowModel = any> extends Omit<DataGridPropsWithoutDefaultValue<R>, 'initialState' | 'componentsProps' | 'slotProps'>, DataGridProRegularProps<R>, DataGridProDataSourceProps, DataGridProSharedPropsWithoutDefaultValue {
|
|
103
118
|
/**
|
|
104
119
|
* The ref object that allows grid manipulation. Can be instantiated with `useGridApiRef()`.
|
|
105
120
|
*/
|
|
@@ -115,15 +130,6 @@ export interface DataGridProPropsWithoutDefaultValue<R extends GridValidRowModel
|
|
|
115
130
|
* For each feature, if the flag is not explicitly set to `true`, the feature will be fully disabled and any property / method call will not have any effect.
|
|
116
131
|
*/
|
|
117
132
|
experimentalFeatures?: Partial<GridExperimentalProFeatures>;
|
|
118
|
-
/**
|
|
119
|
-
* Determines the path of a row in the tree data.
|
|
120
|
-
* For instance, a row with the path ["A", "B"] is the child of the row with the path ["A"].
|
|
121
|
-
* Note that all paths must contain at least one element.
|
|
122
|
-
* @template R
|
|
123
|
-
* @param {R} row The row from which we want the path.
|
|
124
|
-
* @returns {string[]} The path to the row.
|
|
125
|
-
*/
|
|
126
|
-
getTreeDataPath?: (row: R) => string[];
|
|
127
133
|
/**
|
|
128
134
|
* Callback fired when scrolling to the bottom of the grid viewport.
|
|
129
135
|
* @param {GridRowScrollEndParams} params With all properties from [[GridRowScrollEndParams]].
|
package/models/gridApiPro.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { GridApiCommon, GridColumnReorderApi, GridRowMultiSelectionApi, GridRowProApi } from '@mui/x-data-grid';
|
|
2
2
|
import { GridPrivateOnlyApiCommon, GridInfiniteLoaderPrivateApi } from '@mui/x-data-grid/internals';
|
|
3
3
|
import { GridInitialStatePro, GridStatePro } from './gridStatePro';
|
|
4
|
-
import type { GridColumnPinningApi, GridDetailPanelApi, GridRowPinningApi, GridDetailPanelPrivateApi } from '../hooks';
|
|
4
|
+
import type { GridColumnPinningApi, GridDetailPanelApi, GridRowPinningApi, GridDetailPanelPrivateApi, GridDataSourceApi, GridDataSourcePrivateApi } from '../hooks';
|
|
5
5
|
import type { DataGridProProcessedProps } from './dataGridProProps';
|
|
6
6
|
/**
|
|
7
7
|
* The api of `DataGridPro`.
|
|
8
8
|
*/
|
|
9
|
-
export interface GridApiPro extends GridApiCommon<GridStatePro, GridInitialStatePro>, GridRowProApi, GridColumnPinningApi, GridDetailPanelApi, GridRowPinningApi, GridRowMultiSelectionApi, GridColumnReorderApi {
|
|
9
|
+
export interface GridApiPro extends GridApiCommon<GridStatePro, GridInitialStatePro>, GridRowProApi, GridColumnPinningApi, GridDetailPanelApi, GridRowPinningApi, GridDataSourceApi, GridRowMultiSelectionApi, GridColumnReorderApi {
|
|
10
10
|
}
|
|
11
|
-
export interface GridPrivateApiPro extends GridApiPro, GridPrivateOnlyApiCommon<GridApiPro, GridPrivateApiPro, DataGridProProcessedProps>, GridDetailPanelPrivateApi, GridInfiniteLoaderPrivateApi {
|
|
11
|
+
export interface GridPrivateApiPro extends GridApiPro, GridPrivateOnlyApiCommon<GridApiPro, GridPrivateApiPro, DataGridProProcessedProps>, GridDetailPanelPrivateApi, GridInfiniteLoaderPrivateApi, GridDataSourcePrivateApi {
|
|
12
12
|
}
|
package/models/gridStatePro.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { GridInitialState as GridInitialStateCommunity, GridState as GridStateCommunity, GridColumnPinningState, GridPinnedColumnFields } from '@mui/x-data-grid';
|
|
2
2
|
import type { GridDetailPanelState, GridDetailPanelInitialState, GridColumnReorderState } from '../hooks';
|
|
3
|
+
import type { GridDataSourceState } from '../hooks/features/dataSource/interfaces';
|
|
3
4
|
/**
|
|
4
5
|
* The state of `DataGridPro`.
|
|
5
6
|
*/
|
|
@@ -7,6 +8,7 @@ export interface GridStatePro extends GridStateCommunity {
|
|
|
7
8
|
columnReorder: GridColumnReorderState;
|
|
8
9
|
pinnedColumns: GridColumnPinningState;
|
|
9
10
|
detailPanel: GridDetailPanelState;
|
|
11
|
+
dataSource: GridDataSourceState;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
14
|
* The initial state of `DataGridPro`.
|
package/models/index.d.ts
CHANGED
|
@@ -898,5 +898,17 @@ DataGridProRaw.propTypes = {
|
|
|
898
898
|
* If `true`, the rows will be gathered in a tree structure according to the `getTreeDataPath` prop.
|
|
899
899
|
* @default false
|
|
900
900
|
*/
|
|
901
|
-
treeData: PropTypes.bool
|
|
901
|
+
treeData: PropTypes.bool,
|
|
902
|
+
unstable_dataSource: PropTypes.shape({
|
|
903
|
+
getChildrenCount: PropTypes.func,
|
|
904
|
+
getGroupKey: PropTypes.func,
|
|
905
|
+
getRows: PropTypes.func.isRequired,
|
|
906
|
+
updateRow: PropTypes.func
|
|
907
|
+
}),
|
|
908
|
+
unstable_dataSourceCache: PropTypes.shape({
|
|
909
|
+
clear: PropTypes.func.isRequired,
|
|
910
|
+
get: PropTypes.func.isRequired,
|
|
911
|
+
set: PropTypes.func.isRequired
|
|
912
|
+
}),
|
|
913
|
+
unstable_onDataSourceError: PropTypes.func
|
|
902
914
|
};
|
|
@@ -4,6 +4,7 @@ import { useGridInfiniteLoader } from '../hooks/features/infiniteLoader/useGridI
|
|
|
4
4
|
import { useGridColumnReorder, columnReorderStateInitializer } from '../hooks/features/columnReorder/useGridColumnReorder';
|
|
5
5
|
import { useGridTreeData } from '../hooks/features/treeData/useGridTreeData';
|
|
6
6
|
import { useGridTreeDataPreProcessors } from '../hooks/features/treeData/useGridTreeDataPreProcessors';
|
|
7
|
+
import { useGridDataSourceTreeDataPreProcessors } from '../hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors';
|
|
7
8
|
import { useGridColumnPinning, columnPinningStateInitializer } from '../hooks/features/columnPinning/useGridColumnPinning';
|
|
8
9
|
import { useGridColumnPinningPreProcessors } from '../hooks/features/columnPinning/useGridColumnPinningPreProcessors';
|
|
9
10
|
import { useGridDetailPanel, detailPanelStateInitializer } from '../hooks/features/detailPanel/useGridDetailPanel';
|
|
@@ -14,6 +15,7 @@ import { useGridLazyLoader } from '../hooks/features/lazyLoader/useGridLazyLoade
|
|
|
14
15
|
import { useGridLazyLoaderPreProcessors } from '../hooks/features/lazyLoader/useGridLazyLoaderPreProcessors';
|
|
15
16
|
import { useGridRowPinning, rowPinningStateInitializer } from '../hooks/features/rowPinning/useGridRowPinning';
|
|
16
17
|
import { useGridRowPinningPreProcessors } from '../hooks/features/rowPinning/useGridRowPinningPreProcessors';
|
|
18
|
+
import { useGridDataSource, dataSourceStateInitializer } from '../hooks/features/dataSource/useGridDataSource';
|
|
17
19
|
export const useDataGridProComponent = (inputApiRef, props) => {
|
|
18
20
|
const apiRef = useGridInitialization(inputApiRef, props);
|
|
19
21
|
|
|
@@ -23,6 +25,7 @@ export const useDataGridProComponent = (inputApiRef, props) => {
|
|
|
23
25
|
useGridRowSelectionPreProcessors(apiRef, props);
|
|
24
26
|
useGridRowReorderPreProcessors(apiRef, props);
|
|
25
27
|
useGridTreeDataPreProcessors(apiRef, props);
|
|
28
|
+
useGridDataSourceTreeDataPreProcessors(apiRef, props);
|
|
26
29
|
useGridLazyLoaderPreProcessors(apiRef, props);
|
|
27
30
|
useGridRowPinningPreProcessors(apiRef);
|
|
28
31
|
useGridDetailPanelPreProcessors(apiRef, props);
|
|
@@ -55,8 +58,9 @@ export const useDataGridProComponent = (inputApiRef, props) => {
|
|
|
55
58
|
useGridInitializeState(columnMenuStateInitializer, apiRef, props);
|
|
56
59
|
useGridInitializeState(columnGroupsStateInitializer, apiRef, props);
|
|
57
60
|
useGridInitializeState(virtualizationStateInitializer, apiRef, props);
|
|
61
|
+
useGridInitializeState(dataSourceStateInitializer, apiRef, props);
|
|
58
62
|
useGridHeaderFiltering(apiRef, props);
|
|
59
|
-
useGridTreeData(apiRef);
|
|
63
|
+
useGridTreeData(apiRef, props);
|
|
60
64
|
useGridKeyboardNavigation(apiRef, props);
|
|
61
65
|
useGridRowSelection(apiRef, props);
|
|
62
66
|
useGridColumnPinning(apiRef, props);
|
|
@@ -89,5 +93,6 @@ export const useDataGridProComponent = (inputApiRef, props) => {
|
|
|
89
93
|
useGridEvents(apiRef, props);
|
|
90
94
|
useGridStatePersistence(apiRef);
|
|
91
95
|
useGridVirtualization(apiRef, props);
|
|
96
|
+
useGridDataSource(apiRef, props);
|
|
92
97
|
return apiRef;
|
|
93
98
|
};
|
|
@@ -4,6 +4,13 @@ import { useThemeProps } from '@mui/material/styles';
|
|
|
4
4
|
import { GRID_DEFAULT_LOCALE_TEXT, DATA_GRID_PROPS_DEFAULT_VALUES } from '@mui/x-data-grid';
|
|
5
5
|
import { computeSlots, useProps } from '@mui/x-data-grid/internals';
|
|
6
6
|
import { DATA_GRID_PRO_DEFAULT_SLOTS_COMPONENTS } from '../constants/dataGridProDefaultSlotsComponents';
|
|
7
|
+
const getDataGridProForcedProps = themedProps => _extends({
|
|
8
|
+
signature: 'DataGridPro'
|
|
9
|
+
}, themedProps.unstable_dataSource ? {
|
|
10
|
+
filterMode: 'server',
|
|
11
|
+
sortingMode: 'server',
|
|
12
|
+
paginationMode: 'server'
|
|
13
|
+
} : {});
|
|
7
14
|
|
|
8
15
|
/**
|
|
9
16
|
* The default values of `DataGridProPropsWithDefaultValue` to inject in the props of DataGridPro.
|
|
@@ -38,7 +45,6 @@ export const useDataGridProProps = inProps => {
|
|
|
38
45
|
}), [themedProps.slots]);
|
|
39
46
|
return React.useMemo(() => _extends({}, DATA_GRID_PRO_PROPS_DEFAULT_VALUES, themedProps, {
|
|
40
47
|
localeText,
|
|
41
|
-
slots
|
|
42
|
-
|
|
43
|
-
}), [themedProps, localeText, slots]);
|
|
48
|
+
slots
|
|
49
|
+
}, getDataGridProForcedProps(themedProps)), [themedProps, localeText, slots]);
|
|
44
50
|
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { unstable_composeClasses as composeClasses } from '@mui/utils';
|
|
4
|
+
import Box from '@mui/material/Box';
|
|
5
|
+
import Badge from '@mui/material/Badge';
|
|
6
|
+
import { getDataGridUtilityClass, useGridSelector } from '@mui/x-data-grid';
|
|
7
|
+
import CircularProgress from '@mui/material/CircularProgress';
|
|
8
|
+
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
|
|
9
|
+
import { useGridPrivateApiContext } from '../hooks/utils/useGridPrivateApiContext';
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
const useUtilityClasses = ownerState => {
|
|
12
|
+
const {
|
|
13
|
+
classes
|
|
14
|
+
} = ownerState;
|
|
15
|
+
const slots = {
|
|
16
|
+
root: ['treeDataGroupingCell'],
|
|
17
|
+
toggle: ['treeDataGroupingCellToggle'],
|
|
18
|
+
loadingContainer: ['treeDataGroupingCellLoadingContainer']
|
|
19
|
+
};
|
|
20
|
+
return composeClasses(slots, getDataGridUtilityClass, classes);
|
|
21
|
+
};
|
|
22
|
+
function GridTreeDataGroupingCellIcon(props) {
|
|
23
|
+
const apiRef = useGridPrivateApiContext();
|
|
24
|
+
const rootProps = useGridRootProps();
|
|
25
|
+
const classes = useUtilityClasses(rootProps);
|
|
26
|
+
const {
|
|
27
|
+
rowNode,
|
|
28
|
+
id,
|
|
29
|
+
field,
|
|
30
|
+
descendantCount
|
|
31
|
+
} = props;
|
|
32
|
+
const loadingSelector = state => state.dataSource.loading[id] ?? false;
|
|
33
|
+
const errorSelector = state => state.dataSource.errors[id];
|
|
34
|
+
const isDataLoading = useGridSelector(apiRef, loadingSelector);
|
|
35
|
+
const error = useGridSelector(apiRef, errorSelector);
|
|
36
|
+
const handleClick = event => {
|
|
37
|
+
if (!rowNode.childrenExpanded) {
|
|
38
|
+
// always fetch/get from cache the children when the node is expanded
|
|
39
|
+
apiRef.current.unstable_dataSource.fetchRows(id);
|
|
40
|
+
} else {
|
|
41
|
+
apiRef.current.setRowChildrenExpansion(id, !rowNode.childrenExpanded);
|
|
42
|
+
}
|
|
43
|
+
apiRef.current.setCellFocus(id, field);
|
|
44
|
+
event.stopPropagation(); // TODO remove event.stopPropagation
|
|
45
|
+
};
|
|
46
|
+
const Icon = rowNode.childrenExpanded ? rootProps.slots.treeDataCollapseIcon : rootProps.slots.treeDataExpandIcon;
|
|
47
|
+
if (isDataLoading) {
|
|
48
|
+
return /*#__PURE__*/_jsx("div", {
|
|
49
|
+
className: classes.loadingContainer,
|
|
50
|
+
children: /*#__PURE__*/_jsx(CircularProgress, {
|
|
51
|
+
size: "1rem",
|
|
52
|
+
color: "inherit"
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return descendantCount > 0 ? /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, _extends({
|
|
57
|
+
size: "small",
|
|
58
|
+
onClick: handleClick,
|
|
59
|
+
tabIndex: -1,
|
|
60
|
+
"aria-label": rowNode.childrenExpanded ? apiRef.current.getLocaleText('treeDataCollapse') : apiRef.current.getLocaleText('treeDataExpand')
|
|
61
|
+
}, rootProps?.slotProps?.baseIconButton, {
|
|
62
|
+
children: /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
|
|
63
|
+
title: error?.message ?? null,
|
|
64
|
+
children: /*#__PURE__*/_jsx(Badge, {
|
|
65
|
+
variant: "dot",
|
|
66
|
+
color: "error",
|
|
67
|
+
invisible: !error,
|
|
68
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
69
|
+
fontSize: "inherit"
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
})) : null;
|
|
74
|
+
}
|
|
75
|
+
export function GridDataSourceTreeDataGroupingCell(props) {
|
|
76
|
+
const {
|
|
77
|
+
id,
|
|
78
|
+
field,
|
|
79
|
+
formattedValue,
|
|
80
|
+
rowNode,
|
|
81
|
+
hideDescendantCount,
|
|
82
|
+
offsetMultiplier = 2
|
|
83
|
+
} = props;
|
|
84
|
+
const rootProps = useGridRootProps();
|
|
85
|
+
const apiRef = useGridPrivateApiContext();
|
|
86
|
+
const rowSelector = state => state.rows.dataRowIdToModelLookup[id];
|
|
87
|
+
const row = useGridSelector(apiRef, rowSelector);
|
|
88
|
+
const classes = useUtilityClasses(rootProps);
|
|
89
|
+
let descendantCount = 0;
|
|
90
|
+
if (row) {
|
|
91
|
+
descendantCount = Math.max(rootProps.unstable_dataSource?.getChildrenCount?.(row) ?? 0, 0);
|
|
92
|
+
}
|
|
93
|
+
return /*#__PURE__*/_jsxs(Box, {
|
|
94
|
+
className: classes.root,
|
|
95
|
+
sx: {
|
|
96
|
+
ml: rowNode.depth * offsetMultiplier
|
|
97
|
+
},
|
|
98
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
99
|
+
className: classes.toggle,
|
|
100
|
+
children: /*#__PURE__*/_jsx(GridTreeDataGroupingCellIcon, {
|
|
101
|
+
id: id,
|
|
102
|
+
field: field,
|
|
103
|
+
rowNode: rowNode,
|
|
104
|
+
row: row,
|
|
105
|
+
descendantCount: descendantCount
|
|
106
|
+
})
|
|
107
|
+
}), /*#__PURE__*/_jsxs("span", {
|
|
108
|
+
children: [formattedValue === undefined ? rowNode.groupingKey : formattedValue, !hideDescendantCount && descendantCount > 0 ? ` (${descendantCount})` : '']
|
|
109
|
+
})]
|
|
110
|
+
});
|
|
111
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { styled } from '@mui/material/styles';
|
|
3
|
-
import { useResizeObserver } from '@mui/x-
|
|
3
|
+
import { useResizeObserver } from '@mui/x-internals/useResizeObserver';
|
|
4
4
|
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
|
|
5
5
|
import { useGridPrivateApiContext } from '../hooks/utils/useGridPrivateApiContext';
|
|
6
6
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -28,10 +28,7 @@ function GridTreeDataGroupingCell(props) {
|
|
|
28
28
|
} = props;
|
|
29
29
|
const rootProps = useGridRootProps();
|
|
30
30
|
const apiRef = useGridApiContext();
|
|
31
|
-
const
|
|
32
|
-
classes: rootProps.classes
|
|
33
|
-
};
|
|
34
|
-
const classes = useUtilityClasses(ownerState);
|
|
31
|
+
const classes = useUtilityClasses(rootProps);
|
|
35
32
|
const filteredDescendantCountLookup = useGridSelector(apiRef, gridFilteredDescendantCountLookupSelector);
|
|
36
33
|
const filteredDescendantCount = filteredDescendantCountLookup[rowNode.id] ?? 0;
|
|
37
34
|
const Icon = rowNode.childrenExpanded ? rootProps.slots.treeDataCollapseIcon : rootProps.slots.treeDataExpandIcon;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function getKey(params) {
|
|
2
|
+
return JSON.stringify([params.paginationModel, params.filterModel, params.sortModel, params.groupKeys]);
|
|
3
|
+
}
|
|
4
|
+
export class GridDataSourceCacheDefault {
|
|
5
|
+
constructor({
|
|
6
|
+
ttl = 300000
|
|
7
|
+
}) {
|
|
8
|
+
this.cache = void 0;
|
|
9
|
+
this.ttl = void 0;
|
|
10
|
+
this.cache = {};
|
|
11
|
+
this.ttl = ttl;
|
|
12
|
+
}
|
|
13
|
+
set(key, value) {
|
|
14
|
+
const keyString = getKey(key);
|
|
15
|
+
const expiry = Date.now() + this.ttl;
|
|
16
|
+
this.cache[keyString] = {
|
|
17
|
+
value,
|
|
18
|
+
expiry
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
get(key) {
|
|
22
|
+
const keyString = getKey(key);
|
|
23
|
+
const entry = this.cache[keyString];
|
|
24
|
+
if (!entry) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
if (Date.now() > entry.expiry) {
|
|
28
|
+
delete this.cache[keyString];
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return entry.value;
|
|
32
|
+
}
|
|
33
|
+
clear() {
|
|
34
|
+
this.cache = {};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import { gridFilterModelSelector, gridSortModelSelector, gridPaginationModelSelector } from '@mui/x-data-grid';
|
|
3
|
+
import { createSelector } from '@mui/x-data-grid/internals';
|
|
4
|
+
const computeStartEnd = paginationModel => {
|
|
5
|
+
const start = paginationModel.page * paginationModel.pageSize;
|
|
6
|
+
const end = start + paginationModel.pageSize - 1;
|
|
7
|
+
return {
|
|
8
|
+
start,
|
|
9
|
+
end
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export const gridGetRowsParamsSelector = createSelector(gridFilterModelSelector, gridSortModelSelector, gridPaginationModelSelector, (filterModel, sortModel, paginationModel) => {
|
|
13
|
+
return _extends({
|
|
14
|
+
groupKeys: [],
|
|
15
|
+
// TODO: Implement with `rowGrouping`
|
|
16
|
+
groupFields: [],
|
|
17
|
+
paginationModel,
|
|
18
|
+
sortModel,
|
|
19
|
+
filterModel
|
|
20
|
+
}, computeStartEnd(paginationModel));
|
|
21
|
+
});
|
|
22
|
+
export const gridDataSourceStateSelector = state => state.dataSource;
|
|
23
|
+
export const gridDataSourceLoadingSelector = createSelector(gridDataSourceStateSelector, dataSource => dataSource.loading);
|
|
24
|
+
export const gridDataSourceErrorsSelector = createSelector(gridDataSourceStateSelector, dataSource => dataSource.errors);
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import useLazyRef from '@mui/utils/useLazyRef';
|
|
4
|
+
import { useGridApiEventHandler, gridRowsLoadingSelector, useGridApiMethod, useGridSelector } from '@mui/x-data-grid';
|
|
5
|
+
import { gridRowGroupsToFetchSelector } from '@mui/x-data-grid/internals';
|
|
6
|
+
import { gridGetRowsParamsSelector, gridDataSourceErrorsSelector } from './gridDataSourceSelector';
|
|
7
|
+
import { runIfServerMode, NestedDataManager, RequestStatus } from './utils';
|
|
8
|
+
import { GridDataSourceCacheDefault } from './cache';
|
|
9
|
+
const INITIAL_STATE = {
|
|
10
|
+
loading: {},
|
|
11
|
+
errors: {}
|
|
12
|
+
};
|
|
13
|
+
const noopCache = {
|
|
14
|
+
clear: () => {},
|
|
15
|
+
get: () => undefined,
|
|
16
|
+
set: () => {}
|
|
17
|
+
};
|
|
18
|
+
function getCache(cacheProp) {
|
|
19
|
+
if (cacheProp === null) {
|
|
20
|
+
return noopCache;
|
|
21
|
+
}
|
|
22
|
+
return cacheProp ?? new GridDataSourceCacheDefault({});
|
|
23
|
+
}
|
|
24
|
+
export const dataSourceStateInitializer = state => {
|
|
25
|
+
return _extends({}, state, {
|
|
26
|
+
dataSource: INITIAL_STATE
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
export const useGridDataSource = (apiRef, props) => {
|
|
30
|
+
const nestedDataManager = useLazyRef(() => new NestedDataManager(apiRef)).current;
|
|
31
|
+
const groupsToAutoFetch = useGridSelector(apiRef, gridRowGroupsToFetchSelector);
|
|
32
|
+
const scheduledGroups = React.useRef(0);
|
|
33
|
+
const onError = props.unstable_onDataSourceError;
|
|
34
|
+
const [cache, setCache] = React.useState(() => getCache(props.unstable_dataSourceCache));
|
|
35
|
+
const fetchRows = React.useCallback(async parentId => {
|
|
36
|
+
const getRows = props.unstable_dataSource?.getRows;
|
|
37
|
+
if (!getRows) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (parentId) {
|
|
41
|
+
nestedDataManager.queue([parentId]);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
nestedDataManager.clear();
|
|
45
|
+
scheduledGroups.current = 0;
|
|
46
|
+
const dataSourceState = apiRef.current.state.dataSource;
|
|
47
|
+
if (dataSourceState !== INITIAL_STATE) {
|
|
48
|
+
apiRef.current.resetDataSourceState();
|
|
49
|
+
}
|
|
50
|
+
const fetchParams = gridGetRowsParamsSelector(apiRef);
|
|
51
|
+
const cachedData = apiRef.current.unstable_dataSource.cache.get(fetchParams);
|
|
52
|
+
if (cachedData !== undefined) {
|
|
53
|
+
const rows = cachedData.rows;
|
|
54
|
+
apiRef.current.setRows(rows);
|
|
55
|
+
if (cachedData.rowCount) {
|
|
56
|
+
apiRef.current.setRowCount(cachedData.rowCount);
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const isLoading = gridRowsLoadingSelector(apiRef);
|
|
61
|
+
if (!isLoading) {
|
|
62
|
+
apiRef.current.setLoading(true);
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const getRowsResponse = await getRows(fetchParams);
|
|
66
|
+
apiRef.current.unstable_dataSource.cache.set(fetchParams, getRowsResponse);
|
|
67
|
+
if (getRowsResponse.rowCount) {
|
|
68
|
+
apiRef.current.setRowCount(getRowsResponse.rowCount);
|
|
69
|
+
}
|
|
70
|
+
apiRef.current.setRows(getRowsResponse.rows);
|
|
71
|
+
apiRef.current.setLoading(false);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
apiRef.current.setRows([]);
|
|
74
|
+
apiRef.current.setLoading(false);
|
|
75
|
+
onError?.(error, fetchParams);
|
|
76
|
+
}
|
|
77
|
+
}, [nestedDataManager, apiRef, props.unstable_dataSource?.getRows, onError]);
|
|
78
|
+
const fetchRowChildren = React.useCallback(async id => {
|
|
79
|
+
if (!props.treeData) {
|
|
80
|
+
nestedDataManager.clearPendingRequest(id);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const getRows = props.unstable_dataSource?.getRows;
|
|
84
|
+
if (!getRows) {
|
|
85
|
+
nestedDataManager.clearPendingRequest(id);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const rowNode = apiRef.current.getRowNode(id);
|
|
89
|
+
if (!rowNode) {
|
|
90
|
+
nestedDataManager.clearPendingRequest(id);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const fetchParams = _extends({}, gridGetRowsParamsSelector(apiRef), {
|
|
94
|
+
groupKeys: rowNode.path
|
|
95
|
+
});
|
|
96
|
+
const cachedData = apiRef.current.unstable_dataSource.cache.get(fetchParams);
|
|
97
|
+
if (cachedData !== undefined) {
|
|
98
|
+
const rows = cachedData.rows;
|
|
99
|
+
nestedDataManager.setRequestSettled(id);
|
|
100
|
+
apiRef.current.updateServerRows(rows, rowNode.path);
|
|
101
|
+
if (cachedData.rowCount) {
|
|
102
|
+
apiRef.current.setRowCount(cachedData.rowCount);
|
|
103
|
+
}
|
|
104
|
+
apiRef.current.setRowChildrenExpansion(id, true);
|
|
105
|
+
apiRef.current.unstable_dataSource.setChildrenLoading(id, false);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const existingError = gridDataSourceErrorsSelector(apiRef)[id] ?? null;
|
|
109
|
+
if (existingError) {
|
|
110
|
+
apiRef.current.unstable_dataSource.setChildrenFetchError(id, null);
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const getRowsResponse = await getRows(fetchParams);
|
|
114
|
+
if (!apiRef.current.getRowNode(id)) {
|
|
115
|
+
// The row has been removed from the grid
|
|
116
|
+
nestedDataManager.clearPendingRequest(id);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (nestedDataManager.getRequestStatus(id) === RequestStatus.UNKNOWN) {
|
|
120
|
+
apiRef.current.unstable_dataSource.setChildrenLoading(id, false);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
nestedDataManager.setRequestSettled(id);
|
|
124
|
+
apiRef.current.unstable_dataSource.cache.set(fetchParams, getRowsResponse);
|
|
125
|
+
if (getRowsResponse.rowCount) {
|
|
126
|
+
apiRef.current.setRowCount(getRowsResponse.rowCount);
|
|
127
|
+
}
|
|
128
|
+
apiRef.current.updateServerRows(getRowsResponse.rows, rowNode.path);
|
|
129
|
+
apiRef.current.setRowChildrenExpansion(id, true);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
const e = error;
|
|
132
|
+
apiRef.current.unstable_dataSource.setChildrenFetchError(id, e);
|
|
133
|
+
onError?.(e, fetchParams);
|
|
134
|
+
} finally {
|
|
135
|
+
apiRef.current.unstable_dataSource.setChildrenLoading(id, false);
|
|
136
|
+
nestedDataManager.setRequestSettled(id);
|
|
137
|
+
}
|
|
138
|
+
}, [nestedDataManager, onError, apiRef, props.treeData, props.unstable_dataSource?.getRows]);
|
|
139
|
+
const setChildrenLoading = React.useCallback((parentId, isLoading) => {
|
|
140
|
+
apiRef.current.setState(state => {
|
|
141
|
+
if (!state.dataSource.loading[parentId] && isLoading === false) {
|
|
142
|
+
return state;
|
|
143
|
+
}
|
|
144
|
+
const newLoadingState = _extends({}, state.dataSource.loading);
|
|
145
|
+
if (isLoading === false) {
|
|
146
|
+
delete newLoadingState[parentId];
|
|
147
|
+
} else {
|
|
148
|
+
newLoadingState[parentId] = isLoading;
|
|
149
|
+
}
|
|
150
|
+
return _extends({}, state, {
|
|
151
|
+
dataSource: _extends({}, state.dataSource, {
|
|
152
|
+
loading: newLoadingState
|
|
153
|
+
})
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}, [apiRef]);
|
|
157
|
+
const setChildrenFetchError = React.useCallback((parentId, error) => {
|
|
158
|
+
apiRef.current.setState(state => {
|
|
159
|
+
const newErrorsState = _extends({}, state.dataSource.errors);
|
|
160
|
+
if (error === null && newErrorsState[parentId] !== undefined) {
|
|
161
|
+
delete newErrorsState[parentId];
|
|
162
|
+
} else {
|
|
163
|
+
newErrorsState[parentId] = error;
|
|
164
|
+
}
|
|
165
|
+
return _extends({}, state, {
|
|
166
|
+
dataSource: _extends({}, state.dataSource, {
|
|
167
|
+
errors: newErrorsState
|
|
168
|
+
})
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}, [apiRef]);
|
|
172
|
+
const resetDataSourceState = React.useCallback(() => {
|
|
173
|
+
apiRef.current.setState(state => {
|
|
174
|
+
return _extends({}, state, {
|
|
175
|
+
dataSource: INITIAL_STATE
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
}, [apiRef]);
|
|
179
|
+
const dataSourceApi = {
|
|
180
|
+
unstable_dataSource: {
|
|
181
|
+
setChildrenLoading,
|
|
182
|
+
setChildrenFetchError,
|
|
183
|
+
fetchRows,
|
|
184
|
+
cache
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const dataSourcePrivateApi = {
|
|
188
|
+
fetchRowChildren,
|
|
189
|
+
resetDataSourceState
|
|
190
|
+
};
|
|
191
|
+
useGridApiMethod(apiRef, dataSourceApi, 'public');
|
|
192
|
+
useGridApiMethod(apiRef, dataSourcePrivateApi, 'private');
|
|
193
|
+
useGridApiEventHandler(apiRef, 'sortModelChange', runIfServerMode(props.sortingMode, fetchRows));
|
|
194
|
+
useGridApiEventHandler(apiRef, 'filterModelChange', runIfServerMode(props.filterMode, fetchRows));
|
|
195
|
+
useGridApiEventHandler(apiRef, 'paginationModelChange', runIfServerMode(props.paginationMode, fetchRows));
|
|
196
|
+
const isFirstRender = React.useRef(true);
|
|
197
|
+
React.useEffect(() => {
|
|
198
|
+
if (isFirstRender.current) {
|
|
199
|
+
isFirstRender.current = false;
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const newCache = getCache(props.unstable_dataSourceCache);
|
|
203
|
+
setCache(prevCache => prevCache !== newCache ? newCache : prevCache);
|
|
204
|
+
}, [props.unstable_dataSourceCache]);
|
|
205
|
+
React.useEffect(() => {
|
|
206
|
+
if (props.unstable_dataSource) {
|
|
207
|
+
apiRef.current.unstable_dataSource.cache.clear();
|
|
208
|
+
apiRef.current.unstable_dataSource.fetchRows();
|
|
209
|
+
}
|
|
210
|
+
}, [apiRef, props.unstable_dataSource]);
|
|
211
|
+
React.useEffect(() => {
|
|
212
|
+
if (groupsToAutoFetch && groupsToAutoFetch.length && scheduledGroups.current < groupsToAutoFetch.length) {
|
|
213
|
+
const groupsToSchedule = groupsToAutoFetch.slice(scheduledGroups.current);
|
|
214
|
+
nestedDataManager.queue(groupsToSchedule);
|
|
215
|
+
scheduledGroups.current = groupsToAutoFetch.length;
|
|
216
|
+
}
|
|
217
|
+
}, [apiRef, nestedDataManager, groupsToAutoFetch]);
|
|
218
|
+
};
|