@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.
Files changed (114) hide show
  1. package/CHANGELOG.md +166 -1
  2. package/DataGridPro/DataGridPro.js +13 -1
  3. package/DataGridPro/useDataGridProComponent.js +6 -1
  4. package/DataGridPro/useDataGridProProps.js +10 -3
  5. package/components/GridDataSourceTreeDataGroupingCell.d.ts +12 -0
  6. package/components/GridDataSourceTreeDataGroupingCell.js +120 -0
  7. package/components/GridDetailPanel.js +2 -2
  8. package/components/GridTreeDataGroupingCell.js +1 -4
  9. package/esm/DataGridPro/DataGridPro.js +13 -1
  10. package/esm/DataGridPro/useDataGridProComponent.js +6 -1
  11. package/esm/DataGridPro/useDataGridProProps.js +9 -3
  12. package/esm/components/GridDataSourceTreeDataGroupingCell.js +111 -0
  13. package/esm/components/GridDetailPanel.js +1 -1
  14. package/esm/components/GridTreeDataGroupingCell.js +1 -4
  15. package/esm/hooks/features/dataSource/cache.js +36 -0
  16. package/esm/hooks/features/dataSource/gridDataSourceSelector.js +24 -0
  17. package/esm/hooks/features/dataSource/useGridDataSource.js +218 -0
  18. package/esm/hooks/features/dataSource/utils.js +87 -0
  19. package/esm/hooks/features/index.js +3 -1
  20. package/esm/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.js +148 -0
  21. package/esm/hooks/features/serverSideTreeData/utils.js +18 -0
  22. package/esm/hooks/features/treeData/useGridTreeData.js +6 -2
  23. package/esm/hooks/features/treeData/useGridTreeDataPreProcessors.js +6 -3
  24. package/esm/internals/index.js +2 -0
  25. package/esm/internals/propValidation.js +1 -1
  26. package/esm/models/index.js +2 -1
  27. package/esm/utils/releaseInfo.js +1 -1
  28. package/esm/utils/tree/createRowTree.js +6 -2
  29. package/esm/utils/tree/insertDataRowInTree.js +34 -10
  30. package/esm/utils/tree/updateRowTree.js +13 -5
  31. package/esm/utils/tree/utils.js +5 -1
  32. package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +1 -1
  33. package/hooks/features/columnPinning/useGridColumnPinning.d.ts +1 -1
  34. package/hooks/features/columnReorder/useGridColumnReorder.d.ts +1 -1
  35. package/hooks/features/dataSource/cache.d.ts +18 -0
  36. package/hooks/features/dataSource/cache.js +43 -0
  37. package/hooks/features/dataSource/gridDataSourceSelector.d.ts +14 -0
  38. package/hooks/features/dataSource/gridDataSourceSelector.js +32 -0
  39. package/hooks/features/dataSource/interfaces.d.ts +50 -0
  40. package/hooks/features/dataSource/useGridDataSource.d.ts +6 -0
  41. package/hooks/features/dataSource/useGridDataSource.js +229 -0
  42. package/hooks/features/dataSource/utils.d.ts +29 -0
  43. package/hooks/features/dataSource/utils.js +95 -0
  44. package/hooks/features/detailPanel/gridDetailPanelSelector.d.ts +0 -1
  45. package/hooks/features/detailPanel/useGridDetailPanel.d.ts +1 -1
  46. package/hooks/features/index.d.ts +2 -0
  47. package/hooks/features/index.js +22 -0
  48. package/hooks/features/infiniteLoader/useGridInfiniteLoader.d.ts +1 -1
  49. package/hooks/features/lazyLoader/useGridLazyLoader.d.ts +1 -1
  50. package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.d.ts +1 -1
  51. package/hooks/features/rowPinning/useGridRowPinning.d.ts +1 -1
  52. package/hooks/features/rowPinning/useGridRowPinningPreProcessors.d.ts +2 -2
  53. package/hooks/features/rowReorder/useGridRowReorder.d.ts +1 -1
  54. package/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.d.ts +4 -0
  55. package/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.js +158 -0
  56. package/hooks/features/serverSideTreeData/utils.d.ts +6 -0
  57. package/hooks/features/serverSideTreeData/utils.js +25 -0
  58. package/hooks/features/treeData/gridTreeDataUtils.d.ts +1 -2
  59. package/hooks/features/treeData/useGridTreeData.d.ts +2 -1
  60. package/hooks/features/treeData/useGridTreeData.js +6 -2
  61. package/hooks/features/treeData/useGridTreeDataPreProcessors.d.ts +1 -1
  62. package/hooks/features/treeData/useGridTreeDataPreProcessors.js +6 -3
  63. package/hooks/utils/useGridApiContext.d.ts +0 -1
  64. package/hooks/utils/useGridApiRef.d.ts +0 -1
  65. package/hooks/utils/useGridPrivateApiContext.d.ts +0 -1
  66. package/index.js +1 -1
  67. package/internals/index.d.ts +2 -0
  68. package/internals/index.js +23 -0
  69. package/internals/propValidation.js +1 -1
  70. package/material/index.d.ts +0 -1
  71. package/models/dataGridProProps.d.ts +17 -11
  72. package/models/gridApiPro.d.ts +3 -3
  73. package/models/gridProSlotsComponent.d.ts +0 -1
  74. package/models/gridStatePro.d.ts +2 -0
  75. package/models/index.d.ts +1 -0
  76. package/modern/DataGridPro/DataGridPro.js +13 -1
  77. package/modern/DataGridPro/useDataGridProComponent.js +6 -1
  78. package/modern/DataGridPro/useDataGridProProps.js +9 -3
  79. package/modern/components/GridDataSourceTreeDataGroupingCell.js +111 -0
  80. package/modern/components/GridDetailPanel.js +1 -1
  81. package/modern/components/GridTreeDataGroupingCell.js +1 -4
  82. package/modern/hooks/features/dataSource/cache.js +36 -0
  83. package/modern/hooks/features/dataSource/gridDataSourceSelector.js +24 -0
  84. package/modern/hooks/features/dataSource/useGridDataSource.js +218 -0
  85. package/modern/hooks/features/dataSource/utils.js +87 -0
  86. package/modern/hooks/features/index.js +3 -1
  87. package/modern/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.js +148 -0
  88. package/modern/hooks/features/serverSideTreeData/utils.js +18 -0
  89. package/modern/hooks/features/treeData/useGridTreeData.js +6 -2
  90. package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +6 -3
  91. package/modern/index.js +1 -1
  92. package/modern/internals/index.js +2 -0
  93. package/modern/internals/propValidation.js +1 -1
  94. package/modern/models/index.js +2 -1
  95. package/modern/utils/releaseInfo.js +1 -1
  96. package/modern/utils/tree/createRowTree.js +6 -2
  97. package/modern/utils/tree/insertDataRowInTree.js +34 -10
  98. package/modern/utils/tree/updateRowTree.js +13 -5
  99. package/modern/utils/tree/utils.js +5 -1
  100. package/package.json +6 -5
  101. package/typeOverloads/modules.d.ts +0 -1
  102. package/utils/releaseInfo.js +1 -1
  103. package/utils/tree/createRowTree.js +6 -2
  104. package/utils/tree/insertDataRowInTree.d.ts +3 -1
  105. package/utils/tree/insertDataRowInTree.js +33 -9
  106. package/utils/tree/models.d.ts +1 -0
  107. package/utils/tree/updateRowTree.d.ts +1 -0
  108. package/utils/tree/updateRowTree.js +13 -5
  109. package/utils/tree/utils.d.ts +5 -4
  110. package/utils/tree/utils.js +7 -2
  111. package/models/dataSource.d.ts +0 -64
  112. /package/esm/{models/dataSource.js → hooks/features/dataSource/interfaces.js} +0 -0
  113. /package/{models/dataSource.js → hooks/features/dataSource/interfaces.js} +0 -0
  114. /package/modern/{models/dataSource.js → hooks/features/dataSource/interfaces.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { GRID_ROOT_GROUP_ID } from '@mui/x-data-grid';
2
- import { updateGroupDefaultExpansion, getGroupRowIdFromPath, insertNodeInTree, updateGroupNodeIdAndAutoGenerated } from './utils';
2
+ import { updateGroupDefaultExpansion, checkGroupChildrenExpansion, getGroupRowIdFromPath, insertNodeInTree, updateGroupNodeIdAndAutoGenerated } from './utils';
3
3
  /**
4
4
  * Inserts a data row in a tree.
5
5
  * For each steps of its path:
@@ -15,7 +15,9 @@ export const insertDataRowInTree = ({
15
15
  treeDepths,
16
16
  onDuplicatePath,
17
17
  isGroupExpandedByDefault,
18
- defaultGroupingExpansionDepth
18
+ defaultGroupingExpansionDepth,
19
+ hasServerChildren,
20
+ groupsToFetch
19
21
  }) => {
20
22
  let parentNodeId = GRID_ROOT_GROUP_ID;
21
23
  for (let depth = 0; depth < path.length; depth += 1) {
@@ -33,15 +35,37 @@ export const insertDataRowInTree = ({
33
35
  // If no node matches the full path,
34
36
  // We create a leaf node for the data row.
35
37
  if (existingNodeIdWithPartialPath == null) {
36
- const leafNode = {
37
- type: 'leaf',
38
- id,
39
- depth,
40
- parent: parentNodeId,
41
- groupingKey: key
42
- };
38
+ let node;
39
+ if (hasServerChildren) {
40
+ node = {
41
+ type: 'group',
42
+ id,
43
+ parent: parentNodeId,
44
+ path: path.map(step => step.key),
45
+ depth,
46
+ isAutoGenerated: false,
47
+ groupingKey: key,
48
+ groupingField: field,
49
+ children: [],
50
+ childrenFromPath: {},
51
+ childrenExpanded: false,
52
+ hasServerChildren: true
53
+ };
54
+ const shouldFetchChildren = checkGroupChildrenExpansion(node, defaultGroupingExpansionDepth, isGroupExpandedByDefault);
55
+ if (shouldFetchChildren) {
56
+ groupsToFetch?.add(id);
57
+ }
58
+ } else {
59
+ node = {
60
+ type: 'leaf',
61
+ id,
62
+ depth,
63
+ parent: parentNodeId,
64
+ groupingKey: key
65
+ };
66
+ }
43
67
  updatedGroupsManager?.addAction(parentNodeId, 'insertChildren');
44
- insertNodeInTree(leafNode, tree, treeDepths, previousTree);
68
+ insertNodeInTree(node, tree, treeDepths, previousTree);
45
69
  } else {
46
70
  const existingNodeWithPartialPath = tree[existingNodeIdWithPartialPath];
47
71
 
@@ -8,10 +8,12 @@ export const updateRowTree = params => {
8
8
  const tree = _extends({}, params.previousTree);
9
9
  const treeDepths = _extends({}, params.previousTreeDepth);
10
10
  const updatedGroupsManager = createUpdatedGroupsManager();
11
+ const groupsToFetch = params.previousGroupsToFetch ? new Set([...params.previousGroupsToFetch]) : new Set([]);
11
12
  for (let i = 0; i < params.nodes.inserted.length; i += 1) {
12
13
  const {
13
14
  id,
14
- path
15
+ path,
16
+ hasServerChildren
15
17
  } = params.nodes.inserted[i];
16
18
  insertDataRowInTree({
17
19
  previousTree: params.previousTree,
@@ -20,9 +22,11 @@ export const updateRowTree = params => {
20
22
  updatedGroupsManager,
21
23
  id,
22
24
  path,
25
+ hasServerChildren,
23
26
  onDuplicatePath: params.onDuplicatePath,
24
27
  isGroupExpandedByDefault: params.isGroupExpandedByDefault,
25
- defaultGroupingExpansionDepth: params.defaultGroupingExpansionDepth
28
+ defaultGroupingExpansionDepth: params.defaultGroupingExpansionDepth,
29
+ groupsToFetch
26
30
  });
27
31
  }
28
32
  for (let i = 0; i < params.nodes.removed.length; i += 1) {
@@ -37,7 +41,8 @@ export const updateRowTree = params => {
37
41
  for (let i = 0; i < params.nodes.modified.length; i += 1) {
38
42
  const {
39
43
  id,
40
- path
44
+ path,
45
+ hasServerChildren
41
46
  } = params.nodes.modified[i];
42
47
  const pathInPreviousTree = getNodePathInTree({
43
48
  tree,
@@ -58,9 +63,11 @@ export const updateRowTree = params => {
58
63
  updatedGroupsManager,
59
64
  id,
60
65
  path,
66
+ hasServerChildren,
61
67
  onDuplicatePath: params.onDuplicatePath,
62
68
  isGroupExpandedByDefault: params.isGroupExpandedByDefault,
63
- defaultGroupingExpansionDepth: params.defaultGroupingExpansionDepth
69
+ defaultGroupingExpansionDepth: params.defaultGroupingExpansionDepth,
70
+ groupsToFetch
64
71
  });
65
72
  } else {
66
73
  updatedGroupsManager?.addAction(tree[id].parent, 'modifyChildren');
@@ -74,6 +81,7 @@ export const updateRowTree = params => {
74
81
  treeDepths,
75
82
  groupingName: params.groupingName,
76
83
  dataRowIds,
77
- updatedGroupsManager
84
+ updatedGroupsManager,
85
+ groupsToFetch: Array.from(groupsToFetch)
78
86
  };
79
87
  };
@@ -20,7 +20,7 @@ export const getNodePathInTree = ({
20
20
  path.reverse();
21
21
  return path;
22
22
  };
23
- export const updateGroupDefaultExpansion = (node, defaultGroupingExpansionDepth, isGroupExpandedByDefault) => {
23
+ export const checkGroupChildrenExpansion = (node, defaultGroupingExpansionDepth, isGroupExpandedByDefault) => {
24
24
  let childrenExpanded;
25
25
  if (node.id === GRID_ROOT_GROUP_ID) {
26
26
  childrenExpanded = true;
@@ -29,6 +29,10 @@ export const updateGroupDefaultExpansion = (node, defaultGroupingExpansionDepth,
29
29
  } else {
30
30
  childrenExpanded = defaultGroupingExpansionDepth === -1 || defaultGroupingExpansionDepth > node.depth;
31
31
  }
32
+ return childrenExpanded;
33
+ };
34
+ export const updateGroupDefaultExpansion = (node, defaultGroupingExpansionDepth, isGroupExpandedByDefault) => {
35
+ const childrenExpanded = checkGroupChildrenExpansion(node, defaultGroupingExpansionDepth, isGroupExpandedByDefault);
32
36
  node.childrenExpanded = childrenExpanded;
33
37
  return node;
34
38
  };
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { UseGridColumnHeadersProps, GetHeadersParams } from '@mui/x-data-grid/internals';
3
3
  export declare const useGridColumnHeaders: (props: UseGridColumnHeadersProps) => {
4
4
  getColumnFiltersRow: () => React.JSX.Element | null;
5
- getFillers: (params: GetHeadersParams | undefined, children: React.ReactNode, leftOverflow: number, borderTop?: boolean | undefined) => React.JSX.Element;
5
+ getFillers: (params: GetHeadersParams | undefined, children: React.ReactNode, leftOverflow: number, borderTop?: boolean) => React.JSX.Element;
6
6
  getColumnHeadersRow: () => React.JSX.Element;
7
7
  getColumnGroupHeadersRows: () => React.JSX.Element[] | null;
8
8
  isDragging: boolean;
@@ -3,4 +3,4 @@ import { GridStateInitializer } from '@mui/x-data-grid/internals';
3
3
  import { GridPrivateApiPro } from '../../../models/gridApiPro';
4
4
  import { DataGridProProcessedProps } from '../../../models/dataGridProProps';
5
5
  export declare const columnPinningStateInitializer: GridStateInitializer<Pick<DataGridProProcessedProps, 'pinnedColumns' | 'initialState'>>;
6
- export declare const useGridColumnPinning: (apiRef: React.MutableRefObject<GridPrivateApiPro>, props: Pick<DataGridProProcessedProps, 'disableColumnPinning' | 'initialState' | 'pinnedColumns' | 'onPinnedColumnsChange' | 'slotProps' | 'slots'>) => void;
6
+ export declare const useGridColumnPinning: (apiRef: React.MutableRefObject<GridPrivateApiPro>, props: Pick<DataGridProProcessedProps, "disableColumnPinning" | "initialState" | "pinnedColumns" | "onPinnedColumnsChange" | "slotProps" | "slots">) => void;
@@ -6,4 +6,4 @@ export declare const columnReorderStateInitializer: GridStateInitializer;
6
6
  /**
7
7
  * @requires useGridColumns (method)
8
8
  */
9
- export declare const useGridColumnReorder: (apiRef: React.MutableRefObject<GridPrivateApiPro>, props: Pick<DataGridProProcessedProps, 'disableColumnReorder' | 'keepColumnPositionIfDraggedOutside' | 'classes' | 'onColumnOrderChange'>) => void;
9
+ export declare const useGridColumnReorder: (apiRef: React.MutableRefObject<GridPrivateApiPro>, props: Pick<DataGridProProcessedProps, "disableColumnReorder" | "keepColumnPositionIfDraggedOutside" | "classes" | "onColumnOrderChange">) => void;
@@ -0,0 +1,18 @@
1
+ import { GridGetRowsParams, GridGetRowsResponse } from '../../../models';
2
+ type GridDataSourceCacheDefaultConfig = {
3
+ /**
4
+ * Time To Live for each cache entry in milliseconds.
5
+ * After this time the cache entry will become stale and the next query will result in cache miss.
6
+ * @default 300000 (5 minutes)
7
+ */
8
+ ttl?: number;
9
+ };
10
+ export declare class GridDataSourceCacheDefault {
11
+ private cache;
12
+ private ttl;
13
+ constructor({ ttl }: GridDataSourceCacheDefaultConfig);
14
+ set(key: GridGetRowsParams, value: GridGetRowsResponse): void;
15
+ get(key: GridGetRowsParams): GridGetRowsResponse | undefined;
16
+ clear(): void;
17
+ }
18
+ export {};
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.GridDataSourceCacheDefault = void 0;
7
+ function getKey(params) {
8
+ return JSON.stringify([params.paginationModel, params.filterModel, params.sortModel, params.groupKeys]);
9
+ }
10
+ class GridDataSourceCacheDefault {
11
+ constructor({
12
+ ttl = 300000
13
+ }) {
14
+ this.cache = void 0;
15
+ this.ttl = void 0;
16
+ this.cache = {};
17
+ this.ttl = ttl;
18
+ }
19
+ set(key, value) {
20
+ const keyString = getKey(key);
21
+ const expiry = Date.now() + this.ttl;
22
+ this.cache[keyString] = {
23
+ value,
24
+ expiry
25
+ };
26
+ }
27
+ get(key) {
28
+ const keyString = getKey(key);
29
+ const entry = this.cache[keyString];
30
+ if (!entry) {
31
+ return undefined;
32
+ }
33
+ if (Date.now() > entry.expiry) {
34
+ delete this.cache[keyString];
35
+ return undefined;
36
+ }
37
+ return entry.value;
38
+ }
39
+ clear() {
40
+ this.cache = {};
41
+ }
42
+ }
43
+ exports.GridDataSourceCacheDefault = GridDataSourceCacheDefault;
@@ -0,0 +1,14 @@
1
+ import { GridPaginationModel } from '@mui/x-data-grid';
2
+ import { GridStatePro } from '../../../models/gridStatePro';
3
+ export declare const gridGetRowsParamsSelector: import("@mui/x-data-grid").OutputSelector<import("@mui/x-data-grid/models/gridStateCommunity").GridStateCommunity, {
4
+ start: number;
5
+ end: number;
6
+ groupKeys: never[];
7
+ groupFields: never[];
8
+ paginationModel: GridPaginationModel;
9
+ sortModel: import("@mui/x-data-grid").GridSortModel;
10
+ filterModel: import("@mui/x-data-grid").GridFilterModel;
11
+ }>;
12
+ export declare const gridDataSourceStateSelector: (state: GridStatePro) => import("./interfaces").GridDataSourceState;
13
+ export declare const gridDataSourceLoadingSelector: import("@mui/x-data-grid").OutputSelector<GridStatePro, Record<import("@mui/x-data-grid").GridRowId, boolean>>;
14
+ export declare const gridDataSourceErrorsSelector: import("@mui/x-data-grid").OutputSelector<GridStatePro, Record<import("@mui/x-data-grid").GridRowId, any>>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.gridGetRowsParamsSelector = exports.gridDataSourceStateSelector = exports.gridDataSourceLoadingSelector = exports.gridDataSourceErrorsSelector = void 0;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _xDataGrid = require("@mui/x-data-grid");
10
+ var _internals = require("@mui/x-data-grid/internals");
11
+ const computeStartEnd = paginationModel => {
12
+ const start = paginationModel.page * paginationModel.pageSize;
13
+ const end = start + paginationModel.pageSize - 1;
14
+ return {
15
+ start,
16
+ end
17
+ };
18
+ };
19
+ const gridGetRowsParamsSelector = exports.gridGetRowsParamsSelector = (0, _internals.createSelector)(_xDataGrid.gridFilterModelSelector, _xDataGrid.gridSortModelSelector, _xDataGrid.gridPaginationModelSelector, (filterModel, sortModel, paginationModel) => {
20
+ return (0, _extends2.default)({
21
+ groupKeys: [],
22
+ // TODO: Implement with `rowGrouping`
23
+ groupFields: [],
24
+ paginationModel,
25
+ sortModel,
26
+ filterModel
27
+ }, computeStartEnd(paginationModel));
28
+ });
29
+ const gridDataSourceStateSelector = state => state.dataSource;
30
+ exports.gridDataSourceStateSelector = gridDataSourceStateSelector;
31
+ const gridDataSourceLoadingSelector = exports.gridDataSourceLoadingSelector = (0, _internals.createSelector)(gridDataSourceStateSelector, dataSource => dataSource.loading);
32
+ const gridDataSourceErrorsSelector = exports.gridDataSourceErrorsSelector = (0, _internals.createSelector)(gridDataSourceStateSelector, dataSource => dataSource.errors);
@@ -0,0 +1,50 @@
1
+ import { GridRowId } from '@mui/x-data-grid';
2
+ import { GridDataSourceCache } from '../../../models';
3
+ export interface GridDataSourceState {
4
+ loading: Record<GridRowId, boolean>;
5
+ errors: Record<GridRowId, any>;
6
+ }
7
+ /**
8
+ * The base data source API interface that is available in the grid [[apiRef]].
9
+ */
10
+ export interface GridDataSourceApiBase {
11
+ /**
12
+ * Set the loading state of a parent row.
13
+ * @param {string} parentId The id of the parent node.
14
+ * @param {boolean} loading The loading state to set.
15
+ */
16
+ setChildrenLoading: (parentId: GridRowId, loading: boolean) => void;
17
+ /**
18
+ * Set error occured while fetching the children of a row.
19
+ * @param {string} parentId The id of the parent node.
20
+ * @param {Error} error The error of type `Error` or `null`.
21
+ */
22
+ setChildrenFetchError: (parentId: GridRowId, error: Error | null) => void;
23
+ /**
24
+ * Fetches the rows from the server for a given `parentId`.
25
+ * If no `parentId` is provided, it fetches the root rows.
26
+ * @param {string} parentId The id of the group to be fetched.
27
+ */
28
+ fetchRows: (parentId?: GridRowId) => void;
29
+ /**
30
+ * The data source cache object.
31
+ */
32
+ cache: GridDataSourceCache;
33
+ }
34
+ export interface GridDataSourceApi {
35
+ /**
36
+ * The data source API.
37
+ */
38
+ unstable_dataSource: GridDataSourceApiBase;
39
+ }
40
+ export interface GridDataSourcePrivateApi {
41
+ /**
42
+ * Initiates the fetch of the children of a row.
43
+ * @param {string} id The id of the group to be fetched.
44
+ */
45
+ fetchRowChildren: (id: GridRowId) => void;
46
+ /**
47
+ * Resets the data source state.
48
+ */
49
+ resetDataSourceState: () => void;
50
+ }
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ import { GridStateInitializer } from '@mui/x-data-grid/internals';
3
+ import { GridPrivateApiPro } from '../../../models/gridApiPro';
4
+ import { DataGridProProcessedProps } from '../../../models/dataGridProProps';
5
+ export declare const dataSourceStateInitializer: GridStateInitializer;
6
+ export declare const useGridDataSource: (apiRef: React.MutableRefObject<GridPrivateApiPro>, props: Pick<DataGridProProcessedProps, "unstable_dataSource" | "unstable_dataSourceCache" | "unstable_onDataSourceError" | "sortingMode" | "filterMode" | "paginationMode" | "treeData">) => void;
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.useGridDataSource = exports.dataSourceStateInitializer = void 0;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var React = _interopRequireWildcard(require("react"));
10
+ var _useLazyRef = _interopRequireDefault(require("@mui/utils/useLazyRef"));
11
+ var _xDataGrid = require("@mui/x-data-grid");
12
+ var _internals = require("@mui/x-data-grid/internals");
13
+ var _gridDataSourceSelector = require("./gridDataSourceSelector");
14
+ var _utils = require("./utils");
15
+ var _cache = require("./cache");
16
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
17
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
18
+ const INITIAL_STATE = {
19
+ loading: {},
20
+ errors: {}
21
+ };
22
+ const noopCache = {
23
+ clear: () => {},
24
+ get: () => undefined,
25
+ set: () => {}
26
+ };
27
+ function getCache(cacheProp) {
28
+ if (cacheProp === null) {
29
+ return noopCache;
30
+ }
31
+ return cacheProp ?? new _cache.GridDataSourceCacheDefault({});
32
+ }
33
+ const dataSourceStateInitializer = state => {
34
+ return (0, _extends2.default)({}, state, {
35
+ dataSource: INITIAL_STATE
36
+ });
37
+ };
38
+ exports.dataSourceStateInitializer = dataSourceStateInitializer;
39
+ const useGridDataSource = (apiRef, props) => {
40
+ const nestedDataManager = (0, _useLazyRef.default)(() => new _utils.NestedDataManager(apiRef)).current;
41
+ const groupsToAutoFetch = (0, _xDataGrid.useGridSelector)(apiRef, _internals.gridRowGroupsToFetchSelector);
42
+ const scheduledGroups = React.useRef(0);
43
+ const onError = props.unstable_onDataSourceError;
44
+ const [cache, setCache] = React.useState(() => getCache(props.unstable_dataSourceCache));
45
+ const fetchRows = React.useCallback(async parentId => {
46
+ const getRows = props.unstable_dataSource?.getRows;
47
+ if (!getRows) {
48
+ return;
49
+ }
50
+ if (parentId) {
51
+ nestedDataManager.queue([parentId]);
52
+ return;
53
+ }
54
+ nestedDataManager.clear();
55
+ scheduledGroups.current = 0;
56
+ const dataSourceState = apiRef.current.state.dataSource;
57
+ if (dataSourceState !== INITIAL_STATE) {
58
+ apiRef.current.resetDataSourceState();
59
+ }
60
+ const fetchParams = (0, _gridDataSourceSelector.gridGetRowsParamsSelector)(apiRef);
61
+ const cachedData = apiRef.current.unstable_dataSource.cache.get(fetchParams);
62
+ if (cachedData !== undefined) {
63
+ const rows = cachedData.rows;
64
+ apiRef.current.setRows(rows);
65
+ if (cachedData.rowCount) {
66
+ apiRef.current.setRowCount(cachedData.rowCount);
67
+ }
68
+ return;
69
+ }
70
+ const isLoading = (0, _xDataGrid.gridRowsLoadingSelector)(apiRef);
71
+ if (!isLoading) {
72
+ apiRef.current.setLoading(true);
73
+ }
74
+ try {
75
+ const getRowsResponse = await getRows(fetchParams);
76
+ apiRef.current.unstable_dataSource.cache.set(fetchParams, getRowsResponse);
77
+ if (getRowsResponse.rowCount) {
78
+ apiRef.current.setRowCount(getRowsResponse.rowCount);
79
+ }
80
+ apiRef.current.setRows(getRowsResponse.rows);
81
+ apiRef.current.setLoading(false);
82
+ } catch (error) {
83
+ apiRef.current.setRows([]);
84
+ apiRef.current.setLoading(false);
85
+ onError?.(error, fetchParams);
86
+ }
87
+ }, [nestedDataManager, apiRef, props.unstable_dataSource?.getRows, onError]);
88
+ const fetchRowChildren = React.useCallback(async id => {
89
+ if (!props.treeData) {
90
+ nestedDataManager.clearPendingRequest(id);
91
+ return;
92
+ }
93
+ const getRows = props.unstable_dataSource?.getRows;
94
+ if (!getRows) {
95
+ nestedDataManager.clearPendingRequest(id);
96
+ return;
97
+ }
98
+ const rowNode = apiRef.current.getRowNode(id);
99
+ if (!rowNode) {
100
+ nestedDataManager.clearPendingRequest(id);
101
+ return;
102
+ }
103
+ const fetchParams = (0, _extends2.default)({}, (0, _gridDataSourceSelector.gridGetRowsParamsSelector)(apiRef), {
104
+ groupKeys: rowNode.path
105
+ });
106
+ const cachedData = apiRef.current.unstable_dataSource.cache.get(fetchParams);
107
+ if (cachedData !== undefined) {
108
+ const rows = cachedData.rows;
109
+ nestedDataManager.setRequestSettled(id);
110
+ apiRef.current.updateServerRows(rows, rowNode.path);
111
+ if (cachedData.rowCount) {
112
+ apiRef.current.setRowCount(cachedData.rowCount);
113
+ }
114
+ apiRef.current.setRowChildrenExpansion(id, true);
115
+ apiRef.current.unstable_dataSource.setChildrenLoading(id, false);
116
+ return;
117
+ }
118
+ const existingError = (0, _gridDataSourceSelector.gridDataSourceErrorsSelector)(apiRef)[id] ?? null;
119
+ if (existingError) {
120
+ apiRef.current.unstable_dataSource.setChildrenFetchError(id, null);
121
+ }
122
+ try {
123
+ const getRowsResponse = await getRows(fetchParams);
124
+ if (!apiRef.current.getRowNode(id)) {
125
+ // The row has been removed from the grid
126
+ nestedDataManager.clearPendingRequest(id);
127
+ return;
128
+ }
129
+ if (nestedDataManager.getRequestStatus(id) === _utils.RequestStatus.UNKNOWN) {
130
+ apiRef.current.unstable_dataSource.setChildrenLoading(id, false);
131
+ return;
132
+ }
133
+ nestedDataManager.setRequestSettled(id);
134
+ apiRef.current.unstable_dataSource.cache.set(fetchParams, getRowsResponse);
135
+ if (getRowsResponse.rowCount) {
136
+ apiRef.current.setRowCount(getRowsResponse.rowCount);
137
+ }
138
+ apiRef.current.updateServerRows(getRowsResponse.rows, rowNode.path);
139
+ apiRef.current.setRowChildrenExpansion(id, true);
140
+ } catch (error) {
141
+ const e = error;
142
+ apiRef.current.unstable_dataSource.setChildrenFetchError(id, e);
143
+ onError?.(e, fetchParams);
144
+ } finally {
145
+ apiRef.current.unstable_dataSource.setChildrenLoading(id, false);
146
+ nestedDataManager.setRequestSettled(id);
147
+ }
148
+ }, [nestedDataManager, onError, apiRef, props.treeData, props.unstable_dataSource?.getRows]);
149
+ const setChildrenLoading = React.useCallback((parentId, isLoading) => {
150
+ apiRef.current.setState(state => {
151
+ if (!state.dataSource.loading[parentId] && isLoading === false) {
152
+ return state;
153
+ }
154
+ const newLoadingState = (0, _extends2.default)({}, state.dataSource.loading);
155
+ if (isLoading === false) {
156
+ delete newLoadingState[parentId];
157
+ } else {
158
+ newLoadingState[parentId] = isLoading;
159
+ }
160
+ return (0, _extends2.default)({}, state, {
161
+ dataSource: (0, _extends2.default)({}, state.dataSource, {
162
+ loading: newLoadingState
163
+ })
164
+ });
165
+ });
166
+ }, [apiRef]);
167
+ const setChildrenFetchError = React.useCallback((parentId, error) => {
168
+ apiRef.current.setState(state => {
169
+ const newErrorsState = (0, _extends2.default)({}, state.dataSource.errors);
170
+ if (error === null && newErrorsState[parentId] !== undefined) {
171
+ delete newErrorsState[parentId];
172
+ } else {
173
+ newErrorsState[parentId] = error;
174
+ }
175
+ return (0, _extends2.default)({}, state, {
176
+ dataSource: (0, _extends2.default)({}, state.dataSource, {
177
+ errors: newErrorsState
178
+ })
179
+ });
180
+ });
181
+ }, [apiRef]);
182
+ const resetDataSourceState = React.useCallback(() => {
183
+ apiRef.current.setState(state => {
184
+ return (0, _extends2.default)({}, state, {
185
+ dataSource: INITIAL_STATE
186
+ });
187
+ });
188
+ }, [apiRef]);
189
+ const dataSourceApi = {
190
+ unstable_dataSource: {
191
+ setChildrenLoading,
192
+ setChildrenFetchError,
193
+ fetchRows,
194
+ cache
195
+ }
196
+ };
197
+ const dataSourcePrivateApi = {
198
+ fetchRowChildren,
199
+ resetDataSourceState
200
+ };
201
+ (0, _xDataGrid.useGridApiMethod)(apiRef, dataSourceApi, 'public');
202
+ (0, _xDataGrid.useGridApiMethod)(apiRef, dataSourcePrivateApi, 'private');
203
+ (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'sortModelChange', (0, _utils.runIfServerMode)(props.sortingMode, fetchRows));
204
+ (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'filterModelChange', (0, _utils.runIfServerMode)(props.filterMode, fetchRows));
205
+ (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'paginationModelChange', (0, _utils.runIfServerMode)(props.paginationMode, fetchRows));
206
+ const isFirstRender = React.useRef(true);
207
+ React.useEffect(() => {
208
+ if (isFirstRender.current) {
209
+ isFirstRender.current = false;
210
+ return;
211
+ }
212
+ const newCache = getCache(props.unstable_dataSourceCache);
213
+ setCache(prevCache => prevCache !== newCache ? newCache : prevCache);
214
+ }, [props.unstable_dataSourceCache]);
215
+ React.useEffect(() => {
216
+ if (props.unstable_dataSource) {
217
+ apiRef.current.unstable_dataSource.cache.clear();
218
+ apiRef.current.unstable_dataSource.fetchRows();
219
+ }
220
+ }, [apiRef, props.unstable_dataSource]);
221
+ React.useEffect(() => {
222
+ if (groupsToAutoFetch && groupsToAutoFetch.length && scheduledGroups.current < groupsToAutoFetch.length) {
223
+ const groupsToSchedule = groupsToAutoFetch.slice(scheduledGroups.current);
224
+ nestedDataManager.queue(groupsToSchedule);
225
+ scheduledGroups.current = groupsToAutoFetch.length;
226
+ }
227
+ }, [apiRef, nestedDataManager, groupsToAutoFetch]);
228
+ };
229
+ exports.useGridDataSource = useGridDataSource;
@@ -0,0 +1,29 @@
1
+ import { GridRowId } from '@mui/x-data-grid';
2
+ import { GridPrivateApiPro } from '../../../models/gridApiPro';
3
+ export declare const runIfServerMode: (modeProp: "server" | "client", fn: Function) => () => void;
4
+ export declare enum RequestStatus {
5
+ QUEUED = 0,
6
+ PENDING = 1,
7
+ SETTLED = 2,
8
+ UNKNOWN = 3
9
+ }
10
+ /**
11
+ * Fetches row children from the server with option to limit the number of concurrent requests
12
+ * Determines the status of a request based on the enum `RequestStatus`
13
+ * Uses `GridRowId` to uniquely identify a request
14
+ */
15
+ export declare class NestedDataManager {
16
+ private pendingRequests;
17
+ private queuedRequests;
18
+ private settledRequests;
19
+ private api;
20
+ private maxConcurrentRequests;
21
+ constructor(privateApiRef: React.MutableRefObject<GridPrivateApiPro>, maxConcurrentRequests?: number);
22
+ private processQueue;
23
+ queue: (ids: GridRowId[]) => Promise<void>;
24
+ setRequestSettled: (id: GridRowId) => void;
25
+ clear: () => void;
26
+ clearPendingRequest: (id: GridRowId) => void;
27
+ getRequestStatus: (id: GridRowId) => RequestStatus;
28
+ getActiveRequestsCount: () => number;
29
+ }