@mui/x-data-grid-premium 8.0.0-alpha.6 → 8.0.0-alpha.7

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 (61) hide show
  1. package/CHANGELOG.md +127 -1
  2. package/DataGridPremium/DataGridPremium.js +2 -1
  3. package/DataGridPremium/useDataGridPremiumComponent.d.ts +1 -1
  4. package/DataGridPremium/useDataGridPremiumComponent.js +2 -1
  5. package/DataGridPremium/useDataGridPremiumProps.js +3 -1
  6. package/components/GridColumnMenuAggregationItem.js +53 -20
  7. package/esm/DataGridPremium/DataGridPremium.js +2 -1
  8. package/esm/DataGridPremium/useDataGridPremiumComponent.js +3 -2
  9. package/esm/DataGridPremium/useDataGridPremiumProps.js +3 -1
  10. package/esm/components/GridColumnMenuAggregationItem.js +51 -18
  11. package/esm/hooks/features/aggregation/createAggregationLookup.js +52 -55
  12. package/esm/hooks/features/aggregation/gridAggregationUtils.js +17 -13
  13. package/esm/hooks/features/aggregation/index.js +0 -1
  14. package/esm/hooks/features/aggregation/useGridAggregation.js +22 -10
  15. package/esm/hooks/features/aggregation/useGridAggregationPreProcessors.js +7 -14
  16. package/esm/hooks/features/cellSelection/useGridCellSelection.js +3 -3
  17. package/esm/hooks/features/dataSource/cache.js +3 -0
  18. package/esm/hooks/features/dataSource/models.js +1 -0
  19. package/esm/hooks/features/dataSource/useGridDataSourcePremium.js +53 -0
  20. package/esm/utils/releaseInfo.js +1 -1
  21. package/hooks/features/aggregation/createAggregationLookup.d.ts +6 -5
  22. package/hooks/features/aggregation/createAggregationLookup.js +52 -55
  23. package/hooks/features/aggregation/gridAggregationInterfaces.d.ts +18 -5
  24. package/hooks/features/aggregation/gridAggregationUtils.d.ts +9 -10
  25. package/hooks/features/aggregation/gridAggregationUtils.js +17 -13
  26. package/hooks/features/aggregation/index.d.ts +1 -1
  27. package/hooks/features/aggregation/index.js +0 -12
  28. package/hooks/features/aggregation/useGridAggregation.d.ts +1 -1
  29. package/hooks/features/aggregation/useGridAggregation.js +22 -10
  30. package/hooks/features/aggregation/useGridAggregationPreProcessors.d.ts +1 -1
  31. package/hooks/features/aggregation/useGridAggregationPreProcessors.js +7 -14
  32. package/hooks/features/cellSelection/useGridCellSelection.d.ts +1 -1
  33. package/hooks/features/cellSelection/useGridCellSelection.js +3 -3
  34. package/hooks/features/dataSource/cache.d.ts +2 -0
  35. package/hooks/features/dataSource/cache.js +9 -0
  36. package/hooks/features/dataSource/models.d.ts +47 -0
  37. package/hooks/features/dataSource/models.js +5 -0
  38. package/hooks/features/dataSource/useGridDataSourcePremium.d.ts +4 -0
  39. package/hooks/features/dataSource/useGridDataSourcePremium.js +62 -0
  40. package/hooks/utils/useGridApiRef.d.ts +1 -1
  41. package/index.d.ts +2 -0
  42. package/index.js +1 -1
  43. package/models/dataGridPremiumProps.d.ts +6 -4
  44. package/models/gridApiPremium.d.ts +5 -3
  45. package/modern/DataGridPremium/DataGridPremium.js +2 -1
  46. package/modern/DataGridPremium/useDataGridPremiumComponent.js +3 -2
  47. package/modern/DataGridPremium/useDataGridPremiumProps.js +3 -1
  48. package/modern/components/GridColumnMenuAggregationItem.js +51 -18
  49. package/modern/hooks/features/aggregation/createAggregationLookup.js +52 -55
  50. package/modern/hooks/features/aggregation/gridAggregationUtils.js +17 -13
  51. package/modern/hooks/features/aggregation/index.js +0 -1
  52. package/modern/hooks/features/aggregation/useGridAggregation.js +22 -10
  53. package/modern/hooks/features/aggregation/useGridAggregationPreProcessors.js +7 -14
  54. package/modern/hooks/features/cellSelection/useGridCellSelection.js +3 -3
  55. package/modern/hooks/features/dataSource/cache.js +3 -0
  56. package/modern/hooks/features/dataSource/models.js +1 -0
  57. package/modern/hooks/features/dataSource/useGridDataSourcePremium.js +53 -0
  58. package/modern/index.js +1 -1
  59. package/modern/utils/releaseInfo.js +1 -1
  60. package/package.json +5 -5
  61. package/utils/releaseInfo.js +1 -1
@@ -1,18 +1,13 @@
1
1
  import { gridColumnLookupSelector, gridFilteredRowsLookupSelector, gridRowTreeSelector, GRID_ROOT_GROUP_ID } from '@mui/x-data-grid-pro';
2
2
  import { getAggregationRules } from "./gridAggregationUtils.js";
3
3
  import { gridAggregationModelSelector } from "./gridAggregationSelectors.js";
4
- const getAggregationCellValue = ({
5
- apiRef,
6
- groupId,
7
- field,
8
- aggregationFunction,
9
- aggregationRowsScope
10
- }) => {
11
- const filteredRowsLookup = gridFilteredRowsLookupSelector(apiRef);
4
+ const getGroupAggregatedValue = (groupId, apiRef, aggregationRowsScope, aggregatedFields, aggregationRules, position) => {
5
+ const groupAggregationLookup = {};
6
+ const aggregatedValues = [];
12
7
  const rowIds = apiRef.current.getRowGroupChildren({
13
8
  groupId
14
9
  });
15
- const values = [];
10
+ const filteredRowsLookup = gridFilteredRowsLookupSelector(apiRef);
16
11
  rowIds.forEach(rowId => {
17
12
  if (aggregationRowsScope === 'filtered' && filteredRowsLookup[rowId] === false) {
18
13
  return;
@@ -29,42 +24,53 @@ const getAggregationCellValue = ({
29
24
  if (rowNode.type === 'group') {
30
25
  return;
31
26
  }
32
- if (typeof aggregationFunction.getCellValue === 'function') {
33
- const row = apiRef.current.getRow(rowId);
34
- values.push(aggregationFunction.getCellValue({
35
- row
36
- }));
37
- } else {
38
- values.push(apiRef.current.getCellValue(rowId, field));
27
+ const row = apiRef.current.getRow(rowId);
28
+ for (let j = 0; j < aggregatedFields.length; j += 1) {
29
+ const aggregatedField = aggregatedFields[j];
30
+ const columnAggregationRules = aggregationRules[aggregatedField];
31
+ const aggregationFunction = columnAggregationRules.aggregationFunction;
32
+ const field = aggregatedField;
33
+ if (aggregatedValues[j] === undefined) {
34
+ aggregatedValues[j] = {
35
+ aggregatedField,
36
+ values: []
37
+ };
38
+ }
39
+ if (typeof aggregationFunction.getCellValue === 'function') {
40
+ aggregatedValues[j].values.push(aggregationFunction.getCellValue({
41
+ row
42
+ }));
43
+ } else {
44
+ const colDef = apiRef.current.getColumn(field);
45
+ aggregatedValues[j].values.push(apiRef.current.getRowValue(row, colDef));
46
+ }
39
47
  }
40
48
  });
41
- return aggregationFunction.apply({
42
- values,
43
- groupId,
44
- field // Added per user request in https://github.com/mui/mui-x/issues/6995#issuecomment-1327423455
45
- });
49
+ for (let i = 0; i < aggregatedValues.length; i += 1) {
50
+ const {
51
+ aggregatedField,
52
+ values
53
+ } = aggregatedValues[i];
54
+ const aggregationFunction = aggregationRules[aggregatedField].aggregationFunction;
55
+ const value = aggregationFunction.apply({
56
+ values,
57
+ groupId,
58
+ field: aggregatedField // Added per user request in https://github.com/mui/mui-x/issues/6995#issuecomment-1327423455
59
+ });
60
+ groupAggregationLookup[aggregatedField] = {
61
+ position,
62
+ value
63
+ };
64
+ }
65
+ return groupAggregationLookup;
46
66
  };
47
- const getGroupAggregatedValue = ({
48
- groupId,
49
- apiRef,
50
- aggregationRowsScope,
51
- aggregatedFields,
52
- aggregationRules,
53
- position
54
- }) => {
67
+ const getGroupAggregatedValueDataSource = (groupId, apiRef, aggregatedFields, position) => {
55
68
  const groupAggregationLookup = {};
56
69
  for (let j = 0; j < aggregatedFields.length; j += 1) {
57
70
  const aggregatedField = aggregatedFields[j];
58
- const columnAggregationRules = aggregationRules[aggregatedField];
59
71
  groupAggregationLookup[aggregatedField] = {
60
72
  position,
61
- value: getAggregationCellValue({
62
- apiRef,
63
- groupId,
64
- field: aggregatedField,
65
- aggregationFunction: columnAggregationRules.aggregationFunction,
66
- aggregationRowsScope
67
- })
73
+ value: apiRef.current.resolveGroupAggregation(groupId, aggregatedField)
68
74
  };
69
75
  }
70
76
  return groupAggregationLookup;
@@ -73,13 +79,10 @@ export const createAggregationLookup = ({
73
79
  apiRef,
74
80
  aggregationFunctions,
75
81
  aggregationRowsScope,
76
- getAggregationPosition
82
+ getAggregationPosition,
83
+ isDataSource
77
84
  }) => {
78
- const aggregationRules = getAggregationRules({
79
- columnsLookup: gridColumnLookupSelector(apiRef),
80
- aggregationModel: gridAggregationModelSelector(apiRef),
81
- aggregationFunctions
82
- });
85
+ const aggregationRules = getAggregationRules(gridColumnLookupSelector(apiRef), gridAggregationModelSelector(apiRef), aggregationFunctions, isDataSource);
83
86
  const aggregatedFields = Object.keys(aggregationRules);
84
87
  if (aggregatedFields.length === 0) {
85
88
  return {};
@@ -94,18 +97,12 @@ export const createAggregationLookup = ({
94
97
  createGroupAggregationLookup(childNode);
95
98
  }
96
99
  }
97
- const hasAggregableChildren = groupNode.children.length;
98
- if (hasAggregableChildren) {
99
- const position = getAggregationPosition(groupNode);
100
- if (position != null) {
101
- aggregationLookup[groupNode.id] = getGroupAggregatedValue({
102
- groupId: groupNode.id,
103
- apiRef,
104
- aggregatedFields,
105
- aggregationRowsScope,
106
- aggregationRules,
107
- position
108
- });
100
+ const position = getAggregationPosition(groupNode);
101
+ if (position !== null) {
102
+ if (isDataSource) {
103
+ aggregationLookup[groupNode.id] = getGroupAggregatedValueDataSource(groupNode.id, apiRef, aggregatedFields, position);
104
+ } else if (groupNode.children.length) {
105
+ aggregationLookup[groupNode.id] = getGroupAggregatedValue(groupNode.id, apiRef, aggregationRowsScope, aggregatedFields, aggregationRules, position);
109
106
  }
110
107
  }
111
108
  };
@@ -10,56 +10,60 @@ export const getAggregationFooterRowIdFromGroupId = groupId => {
10
10
  }
11
11
  return `auto-generated-group-footer-${groupId}`;
12
12
  };
13
+ const isClientSideAggregateFunction = aggregationFunction => !!aggregationFunction && 'apply' in aggregationFunction;
13
14
  export const canColumnHaveAggregationFunction = ({
14
15
  colDef,
15
16
  aggregationFunctionName,
16
- aggregationFunction
17
+ aggregationFunction,
18
+ isDataSource
17
19
  }) => {
18
20
  if (!colDef) {
19
21
  return false;
20
22
  }
21
- if (!aggregationFunction) {
23
+ if (!isClientSideAggregateFunction(aggregationFunction) && !isDataSource) {
22
24
  return false;
23
25
  }
24
26
  if (colDef.availableAggregationFunctions != null) {
25
27
  return colDef.availableAggregationFunctions.includes(aggregationFunctionName);
26
28
  }
27
- if (!aggregationFunction.columnTypes) {
29
+ if (!aggregationFunction?.columnTypes) {
28
30
  return true;
29
31
  }
30
32
  return aggregationFunction.columnTypes.includes(colDef.type);
31
33
  };
32
34
  export const getAvailableAggregationFunctions = ({
33
35
  aggregationFunctions,
34
- colDef
36
+ colDef,
37
+ isDataSource
35
38
  }) => Object.keys(aggregationFunctions).filter(aggregationFunctionName => canColumnHaveAggregationFunction({
36
39
  colDef,
37
40
  aggregationFunctionName,
38
- aggregationFunction: aggregationFunctions[aggregationFunctionName]
41
+ aggregationFunction: aggregationFunctions[aggregationFunctionName],
42
+ isDataSource
39
43
  }));
40
44
  export const mergeStateWithAggregationModel = aggregationModel => state => _extends({}, state, {
41
45
  aggregation: _extends({}, state.aggregation, {
42
46
  model: aggregationModel
43
47
  })
44
48
  });
45
- export const getAggregationRules = ({
46
- columnsLookup,
47
- aggregationModel,
48
- aggregationFunctions
49
- }) => {
49
+ export const getAggregationRules = (columnsLookup, aggregationModel, aggregationFunctions, isDataSource) => {
50
50
  const aggregationRules = {};
51
- Object.entries(aggregationModel).forEach(([field, columnItem]) => {
51
+
52
+ // eslint-disable-next-line guard-for-in
53
+ for (const field in aggregationModel) {
54
+ const columnItem = aggregationModel[field];
52
55
  if (columnsLookup[field] && canColumnHaveAggregationFunction({
53
56
  colDef: columnsLookup[field],
54
57
  aggregationFunctionName: columnItem,
55
- aggregationFunction: aggregationFunctions[columnItem]
58
+ aggregationFunction: aggregationFunctions[columnItem],
59
+ isDataSource
56
60
  })) {
57
61
  aggregationRules[field] = {
58
62
  aggregationFunctionName: columnItem,
59
63
  aggregationFunction: aggregationFunctions[columnItem]
60
64
  };
61
65
  }
62
- });
66
+ }
63
67
  return aggregationRules;
64
68
  };
65
69
  /**
@@ -1,4 +1,3 @@
1
- export * from "./gridAggregationInterfaces.js";
2
1
  export * from "./gridAggregationSelectors.js";
3
2
  export * from "./gridAggregationFunctions.js";
4
3
  export { GRID_AGGREGATION_ROOT_FOOTER_ROW_ID, getAggregationFooterRowIdFromGroupId } from "./gridAggregationUtils.js";
@@ -1,6 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { gridColumnLookupSelector, useGridApiEventHandler, useGridApiMethod } from '@mui/x-data-grid-pro';
4
+ import { useGridRegisterPipeProcessor } from '@mui/x-data-grid-pro/internals';
4
5
  import { gridAggregationModelSelector } from "./gridAggregationSelectors.js";
5
6
  import { getAggregationRules, mergeStateWithAggregationModel, areAggregationRulesEqual } from "./gridAggregationUtils.js";
6
7
  import { createAggregationLookup } from "./createAggregationLookup.js";
@@ -39,18 +40,29 @@ export const useGridAggregation = (apiRef, props) => {
39
40
  apiRef,
40
41
  getAggregationPosition: props.getAggregationPosition,
41
42
  aggregationFunctions: props.aggregationFunctions,
42
- aggregationRowsScope: props.aggregationRowsScope
43
+ aggregationRowsScope: props.aggregationRowsScope,
44
+ isDataSource: !!props.unstable_dataSource
43
45
  });
44
46
  apiRef.current.setState(state => _extends({}, state, {
45
47
  aggregation: _extends({}, state.aggregation, {
46
48
  lookup: aggregationLookup
47
49
  })
48
50
  }));
49
- }, [apiRef, props.getAggregationPosition, props.aggregationFunctions, props.aggregationRowsScope]);
51
+ }, [apiRef, props.getAggregationPosition, props.aggregationFunctions, props.aggregationRowsScope, props.unstable_dataSource]);
50
52
  const aggregationApi = {
51
53
  setAggregationModel
52
54
  };
55
+ const aggregationPrivateApi = {
56
+ applyAggregation
57
+ };
53
58
  useGridApiMethod(apiRef, aggregationApi, 'public');
59
+ useGridApiMethod(apiRef, aggregationPrivateApi, 'private');
60
+ const addGetRowsParams = React.useCallback(params => {
61
+ return _extends({}, params, {
62
+ aggregationModel: gridAggregationModelSelector(apiRef)
63
+ });
64
+ }, [apiRef]);
65
+ useGridRegisterPipeProcessor(apiRef, 'getRowsParams', addGetRowsParams);
54
66
 
55
67
  /**
56
68
  * EVENTS
@@ -60,16 +72,16 @@ export const useGridAggregation = (apiRef, props) => {
60
72
  rulesOnLastRowHydration,
61
73
  rulesOnLastColumnHydration
62
74
  } = apiRef.current.caches.aggregation;
63
- const aggregationRules = props.disableAggregation ? {} : getAggregationRules({
64
- columnsLookup: gridColumnLookupSelector(apiRef),
65
- aggregationModel: gridAggregationModelSelector(apiRef),
66
- aggregationFunctions: props.aggregationFunctions
67
- });
75
+ const aggregationRules = props.disableAggregation ? {} : getAggregationRules(gridColumnLookupSelector(apiRef), gridAggregationModelSelector(apiRef), props.aggregationFunctions, !!props.unstable_dataSource);
68
76
 
69
77
  // Re-apply the row hydration to add / remove the aggregation footers
70
78
  if (!areAggregationRulesEqual(rulesOnLastRowHydration, aggregationRules)) {
71
- apiRef.current.requestPipeProcessorsApplication('hydrateRows');
72
- applyAggregation();
79
+ if (props.unstable_dataSource) {
80
+ apiRef.current.unstable_dataSource.fetchRows();
81
+ } else {
82
+ apiRef.current.requestPipeProcessorsApplication('hydrateRows');
83
+ applyAggregation();
84
+ }
73
85
  }
74
86
 
75
87
  // Re-apply the column hydration to wrap / unwrap the aggregated columns
@@ -77,7 +89,7 @@ export const useGridAggregation = (apiRef, props) => {
77
89
  apiRef.current.caches.aggregation.rulesOnLastColumnHydration = aggregationRules;
78
90
  apiRef.current.requestPipeProcessorsApplication('hydrateColumns');
79
91
  }
80
- }, [apiRef, applyAggregation, props.aggregationFunctions, props.disableAggregation]);
92
+ }, [apiRef, applyAggregation, props.aggregationFunctions, props.disableAggregation, props.unstable_dataSource]);
81
93
  useGridApiEventHandler(apiRef, 'aggregationModelChange', checkAggregationRulesDiff);
82
94
  useGridApiEventHandler(apiRef, 'columnsChange', checkAggregationRulesDiff);
83
95
  useGridApiEventHandler(apiRef, 'filteredRowsSet', applyAggregation);
@@ -10,11 +10,7 @@ export const useGridAggregationPreProcessors = (apiRef, props) => {
10
10
  // that the pre-processor is called it will already have been updated with the current rules.
11
11
  const rulesOnLastColumnHydration = React.useRef({});
12
12
  const updateAggregatedColumns = React.useCallback(columnsState => {
13
- const aggregationRules = props.disableAggregation ? {} : getAggregationRules({
14
- columnsLookup: columnsState.lookup,
15
- aggregationModel: gridAggregationModelSelector(apiRef),
16
- aggregationFunctions: props.aggregationFunctions
17
- });
13
+ const aggregationRules = props.disableAggregation ? {} : getAggregationRules(columnsState.lookup, gridAggregationModelSelector(apiRef), props.aggregationFunctions, !!props.unstable_dataSource);
18
14
  columnsState.orderedFields.forEach(field => {
19
15
  const shouldHaveAggregationValue = !!aggregationRules[field];
20
16
  const haveAggregationColumnValue = !!rulesOnLastColumnHydration.current[field];
@@ -35,13 +31,9 @@ export const useGridAggregationPreProcessors = (apiRef, props) => {
35
31
  });
36
32
  rulesOnLastColumnHydration.current = aggregationRules;
37
33
  return columnsState;
38
- }, [apiRef, props.aggregationFunctions, props.disableAggregation]);
34
+ }, [apiRef, props.aggregationFunctions, props.disableAggregation, props.unstable_dataSource]);
39
35
  const addGroupFooterRows = React.useCallback(value => {
40
- const aggregationRules = props.disableAggregation ? {} : getAggregationRules({
41
- columnsLookup: gridColumnLookupSelector(apiRef),
42
- aggregationModel: gridAggregationModelSelector(apiRef),
43
- aggregationFunctions: props.aggregationFunctions
44
- });
36
+ const aggregationRules = props.disableAggregation ? {} : getAggregationRules(gridColumnLookupSelector(apiRef), gridAggregationModelSelector(apiRef), props.aggregationFunctions, !!props.unstable_dataSource);
45
37
  const hasAggregationRule = Object.keys(aggregationRules).length > 0;
46
38
 
47
39
  // If we did not have any aggregation footer before, and we still don't have any,
@@ -56,20 +48,21 @@ export const useGridAggregationPreProcessors = (apiRef, props) => {
56
48
  getAggregationPosition: props.getAggregationPosition,
57
49
  hasAggregationRule
58
50
  });
59
- }, [apiRef, props.disableAggregation, props.getAggregationPosition, props.aggregationFunctions]);
51
+ }, [apiRef, props.disableAggregation, props.getAggregationPosition, props.aggregationFunctions, props.unstable_dataSource]);
60
52
  const addColumnMenuButtons = React.useCallback((columnMenuItems, colDef) => {
61
53
  if (props.disableAggregation || !colDef.aggregable) {
62
54
  return columnMenuItems;
63
55
  }
64
56
  const availableAggregationFunctions = getAvailableAggregationFunctions({
65
57
  aggregationFunctions: props.aggregationFunctions,
66
- colDef
58
+ colDef,
59
+ isDataSource: !!props.unstable_dataSource
67
60
  });
68
61
  if (availableAggregationFunctions.length === 0) {
69
62
  return columnMenuItems;
70
63
  }
71
64
  return [...columnMenuItems, 'columnMenuAggregationItem'];
72
- }, [props.aggregationFunctions, props.disableAggregation]);
65
+ }, [props.aggregationFunctions, props.disableAggregation, props.unstable_dataSource]);
73
66
  const stateExportPreProcessing = React.useCallback(prevState => {
74
67
  if (props.disableAggregation) {
75
68
  return prevState;
@@ -17,10 +17,10 @@ const AUTO_SCROLL_SPEED = 20; // The speed to scroll once the mouse enters the s
17
17
  export const useGridCellSelection = (apiRef, props) => {
18
18
  const hasRootReference = apiRef.current.rootElementRef.current !== null;
19
19
  const visibleRows = useGridVisibleRows(apiRef, props);
20
- const cellWithVirtualFocus = React.useRef();
21
- const lastMouseDownCell = React.useRef();
20
+ const cellWithVirtualFocus = React.useRef(null);
21
+ const lastMouseDownCell = React.useRef(null);
22
22
  const mousePosition = React.useRef(null);
23
- const autoScrollRAF = React.useRef();
23
+ const autoScrollRAF = React.useRef(null);
24
24
  const sortedRowIds = useGridSelector(apiRef, gridSortedRowIdsSelector);
25
25
  const dimensions = useGridSelector(apiRef, gridDimensionsSelector);
26
26
  const totalHeaderHeight = getTotalHeaderHeight(apiRef, props);
@@ -0,0 +1,3 @@
1
+ export function getKeyPremium(params) {
2
+ return JSON.stringify([params.filterModel, params.sortModel, params.groupKeys, params.groupFields, params.start, params.end, params.aggregationModel]);
3
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,53 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { useGridApiEventHandler as addEventHandler, useGridApiMethod, GRID_ROOT_GROUP_ID } from '@mui/x-data-grid-pro';
4
+ import { useGridDataSourceBase, useGridRegisterStrategyProcessor, useGridRegisterPipeProcessor } from '@mui/x-data-grid-pro/internals';
5
+ import { getKeyPremium } from "./cache.js";
6
+ const options = {
7
+ cacheOptions: {
8
+ getKey: getKeyPremium
9
+ }
10
+ };
11
+ export const useGridDataSourcePremium = (apiRef, props) => {
12
+ const {
13
+ api,
14
+ strategyProcessor,
15
+ events
16
+ } = useGridDataSourceBase(apiRef, props, options);
17
+ const aggregateRowRef = React.useRef({});
18
+ const processDataSourceRows = React.useCallback(({
19
+ params,
20
+ response
21
+ }, applyRowHydration) => {
22
+ if (response.aggregateRow) {
23
+ aggregateRowRef.current = response.aggregateRow;
24
+ }
25
+ if (Object.keys(params.aggregationModel || {}).length > 0) {
26
+ if (applyRowHydration) {
27
+ apiRef.current.requestPipeProcessorsApplication('hydrateRows');
28
+ }
29
+ apiRef.current.applyAggregation();
30
+ }
31
+ return {
32
+ params,
33
+ response
34
+ };
35
+ }, [apiRef]);
36
+ const resolveGroupAggregation = React.useCallback((groupId, field) => {
37
+ if (groupId === GRID_ROOT_GROUP_ID) {
38
+ return props.unstable_dataSource?.getAggregatedValue?.(aggregateRowRef.current, field);
39
+ }
40
+ const row = apiRef.current.getRow(groupId);
41
+ return props.unstable_dataSource?.getAggregatedValue?.(row, field);
42
+ }, [apiRef, props.unstable_dataSource]);
43
+ const privateApi = _extends({}, api.private, {
44
+ resolveGroupAggregation
45
+ });
46
+ useGridApiMethod(apiRef, api.public, 'public');
47
+ useGridApiMethod(apiRef, privateApi, 'private');
48
+ useGridRegisterStrategyProcessor(apiRef, strategyProcessor.strategyName, strategyProcessor.group, strategyProcessor.processor);
49
+ useGridRegisterPipeProcessor(apiRef, 'processDataSourceRows', processDataSourceRows);
50
+ Object.entries(events).forEach(([event, handler]) => {
51
+ addEventHandler(apiRef, event, handler);
52
+ });
53
+ };
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTczNTE2NDAwMDAwMA==";
3
+ const releaseInfo = "MTczNjM3NzIwMDAwMA==";
4
4
  if (process.env.NODE_ENV !== 'production') {
5
5
  // A simple hack to set the value in the test environment (has no build step).
6
6
  // eslint-disable-next-line no-useless-concat
@@ -1,10 +1,11 @@
1
1
  import * as React from 'react';
2
- import { GridApiPremium } from '../../../models/gridApiPremium';
2
+ import { GridPrivateApiPremium } from '../../../models/gridApiPremium';
3
3
  import { DataGridPremiumProcessedProps } from '../../../models/dataGridPremiumProps';
4
- import { GridAggregationFunction, GridAggregationLookup } from './gridAggregationInterfaces';
5
- export declare const createAggregationLookup: ({ apiRef, aggregationFunctions, aggregationRowsScope, getAggregationPosition, }: {
6
- apiRef: React.MutableRefObject<GridApiPremium>;
7
- aggregationFunctions: Record<string, GridAggregationFunction>;
4
+ import { GridAggregationFunction, GridAggregationFunctionDataSource, GridAggregationLookup } from './gridAggregationInterfaces';
5
+ export declare const createAggregationLookup: ({ apiRef, aggregationFunctions, aggregationRowsScope, getAggregationPosition, isDataSource, }: {
6
+ apiRef: React.MutableRefObject<GridPrivateApiPremium>;
7
+ aggregationFunctions: Record<string, GridAggregationFunction> | Record<string, GridAggregationFunctionDataSource>;
8
8
  aggregationRowsScope: DataGridPremiumProcessedProps["aggregationRowsScope"];
9
9
  getAggregationPosition: DataGridPremiumProcessedProps["getAggregationPosition"];
10
+ isDataSource: boolean;
10
11
  }) => GridAggregationLookup;
@@ -7,18 +7,13 @@ exports.createAggregationLookup = void 0;
7
7
  var _xDataGridPro = require("@mui/x-data-grid-pro");
8
8
  var _gridAggregationUtils = require("./gridAggregationUtils");
9
9
  var _gridAggregationSelectors = require("./gridAggregationSelectors");
10
- const getAggregationCellValue = ({
11
- apiRef,
12
- groupId,
13
- field,
14
- aggregationFunction,
15
- aggregationRowsScope
16
- }) => {
17
- const filteredRowsLookup = (0, _xDataGridPro.gridFilteredRowsLookupSelector)(apiRef);
10
+ const getGroupAggregatedValue = (groupId, apiRef, aggregationRowsScope, aggregatedFields, aggregationRules, position) => {
11
+ const groupAggregationLookup = {};
12
+ const aggregatedValues = [];
18
13
  const rowIds = apiRef.current.getRowGroupChildren({
19
14
  groupId
20
15
  });
21
- const values = [];
16
+ const filteredRowsLookup = (0, _xDataGridPro.gridFilteredRowsLookupSelector)(apiRef);
22
17
  rowIds.forEach(rowId => {
23
18
  if (aggregationRowsScope === 'filtered' && filteredRowsLookup[rowId] === false) {
24
19
  return;
@@ -35,42 +30,53 @@ const getAggregationCellValue = ({
35
30
  if (rowNode.type === 'group') {
36
31
  return;
37
32
  }
38
- if (typeof aggregationFunction.getCellValue === 'function') {
39
- const row = apiRef.current.getRow(rowId);
40
- values.push(aggregationFunction.getCellValue({
41
- row
42
- }));
43
- } else {
44
- values.push(apiRef.current.getCellValue(rowId, field));
33
+ const row = apiRef.current.getRow(rowId);
34
+ for (let j = 0; j < aggregatedFields.length; j += 1) {
35
+ const aggregatedField = aggregatedFields[j];
36
+ const columnAggregationRules = aggregationRules[aggregatedField];
37
+ const aggregationFunction = columnAggregationRules.aggregationFunction;
38
+ const field = aggregatedField;
39
+ if (aggregatedValues[j] === undefined) {
40
+ aggregatedValues[j] = {
41
+ aggregatedField,
42
+ values: []
43
+ };
44
+ }
45
+ if (typeof aggregationFunction.getCellValue === 'function') {
46
+ aggregatedValues[j].values.push(aggregationFunction.getCellValue({
47
+ row
48
+ }));
49
+ } else {
50
+ const colDef = apiRef.current.getColumn(field);
51
+ aggregatedValues[j].values.push(apiRef.current.getRowValue(row, colDef));
52
+ }
45
53
  }
46
54
  });
47
- return aggregationFunction.apply({
48
- values,
49
- groupId,
50
- field // Added per user request in https://github.com/mui/mui-x/issues/6995#issuecomment-1327423455
51
- });
55
+ for (let i = 0; i < aggregatedValues.length; i += 1) {
56
+ const {
57
+ aggregatedField,
58
+ values
59
+ } = aggregatedValues[i];
60
+ const aggregationFunction = aggregationRules[aggregatedField].aggregationFunction;
61
+ const value = aggregationFunction.apply({
62
+ values,
63
+ groupId,
64
+ field: aggregatedField // Added per user request in https://github.com/mui/mui-x/issues/6995#issuecomment-1327423455
65
+ });
66
+ groupAggregationLookup[aggregatedField] = {
67
+ position,
68
+ value
69
+ };
70
+ }
71
+ return groupAggregationLookup;
52
72
  };
53
- const getGroupAggregatedValue = ({
54
- groupId,
55
- apiRef,
56
- aggregationRowsScope,
57
- aggregatedFields,
58
- aggregationRules,
59
- position
60
- }) => {
73
+ const getGroupAggregatedValueDataSource = (groupId, apiRef, aggregatedFields, position) => {
61
74
  const groupAggregationLookup = {};
62
75
  for (let j = 0; j < aggregatedFields.length; j += 1) {
63
76
  const aggregatedField = aggregatedFields[j];
64
- const columnAggregationRules = aggregationRules[aggregatedField];
65
77
  groupAggregationLookup[aggregatedField] = {
66
78
  position,
67
- value: getAggregationCellValue({
68
- apiRef,
69
- groupId,
70
- field: aggregatedField,
71
- aggregationFunction: columnAggregationRules.aggregationFunction,
72
- aggregationRowsScope
73
- })
79
+ value: apiRef.current.resolveGroupAggregation(groupId, aggregatedField)
74
80
  };
75
81
  }
76
82
  return groupAggregationLookup;
@@ -79,13 +85,10 @@ const createAggregationLookup = ({
79
85
  apiRef,
80
86
  aggregationFunctions,
81
87
  aggregationRowsScope,
82
- getAggregationPosition
88
+ getAggregationPosition,
89
+ isDataSource
83
90
  }) => {
84
- const aggregationRules = (0, _gridAggregationUtils.getAggregationRules)({
85
- columnsLookup: (0, _xDataGridPro.gridColumnLookupSelector)(apiRef),
86
- aggregationModel: (0, _gridAggregationSelectors.gridAggregationModelSelector)(apiRef),
87
- aggregationFunctions
88
- });
91
+ const aggregationRules = (0, _gridAggregationUtils.getAggregationRules)((0, _xDataGridPro.gridColumnLookupSelector)(apiRef), (0, _gridAggregationSelectors.gridAggregationModelSelector)(apiRef), aggregationFunctions, isDataSource);
89
92
  const aggregatedFields = Object.keys(aggregationRules);
90
93
  if (aggregatedFields.length === 0) {
91
94
  return {};
@@ -100,18 +103,12 @@ const createAggregationLookup = ({
100
103
  createGroupAggregationLookup(childNode);
101
104
  }
102
105
  }
103
- const hasAggregableChildren = groupNode.children.length;
104
- if (hasAggregableChildren) {
105
- const position = getAggregationPosition(groupNode);
106
- if (position != null) {
107
- aggregationLookup[groupNode.id] = getGroupAggregatedValue({
108
- groupId: groupNode.id,
109
- apiRef,
110
- aggregatedFields,
111
- aggregationRowsScope,
112
- aggregationRules,
113
- position
114
- });
106
+ const position = getAggregationPosition(groupNode);
107
+ if (position !== null) {
108
+ if (isDataSource) {
109
+ aggregationLookup[groupNode.id] = getGroupAggregatedValueDataSource(groupNode.id, apiRef, aggregatedFields, position);
110
+ } else if (groupNode.children.length) {
111
+ aggregationLookup[groupNode.id] = getGroupAggregatedValue(groupNode.id, apiRef, aggregationRowsScope, aggregatedFields, aggregationRules, position);
115
112
  }
116
113
  }
117
114
  };
@@ -17,6 +17,12 @@ export interface GridAggregationApi {
17
17
  */
18
18
  setAggregationModel: (model: GridAggregationModel) => void;
19
19
  }
20
+ export interface GridAggregationPrivateApi {
21
+ /**
22
+ * Applies the aggregation to the rows.
23
+ */
24
+ applyAggregation: () => void;
25
+ }
20
26
  export interface GridAggregationGetCellValueParams {
21
27
  /**
22
28
  * The row model of the row that the current cell belongs to.
@@ -38,7 +44,7 @@ export interface GridAggregationFunction<V = any, AV = V> {
38
44
  apply: (params: GridAggregationParams<V>) => AV | null | undefined;
39
45
  /**
40
46
  * Label of the aggregation function.
41
- * Will be used to add a label on the footer of the grouping column when this aggregation function is the only one being used.
47
+ * Used for adding a label to the footer of the grouping column when this aggregation function is the only one being used.
42
48
  * @default apiRef.current.getLocaleText('aggregationFunctionLabel{capitalize(name)})
43
49
  */
44
50
  label?: string;
@@ -48,12 +54,12 @@ export interface GridAggregationFunction<V = any, AV = V> {
48
54
  */
49
55
  columnTypes?: string[];
50
56
  /**
51
- * Function that allows to apply a formatter to the aggregated value.
52
- * If not defined, the grid will use the formatter of the column.
57
+ * Function for applying a formatter to the aggregated value.
58
+ * If not defined, the grid uses the formatter of the column.
53
59
  */
54
60
  valueFormatter?: GridValueFormatter;
55
61
  /**
56
- * Indicates if the aggregated value have the same unit as the cells used to generate it.
62
+ * Indicates if the aggregated value has the same unit as the cells used to generate it.
57
63
  * It can be used to apply a custom cell renderer only if the aggregated value has the same unit.
58
64
  * @default true
59
65
  */
@@ -67,6 +73,13 @@ export interface GridAggregationFunction<V = any, AV = V> {
67
73
  */
68
74
  getCellValue?: (params: GridAggregationGetCellValueParams) => V;
69
75
  }
76
+ /**
77
+ * Grid aggregation function data source definition interface.
78
+ * @demos
79
+ * - [Server-side aggregation](/x/react-data-grid/server-side-data/aggregation/)
80
+ */
81
+ export interface GridAggregationFunctionDataSource extends Omit<GridAggregationFunction, 'apply' | 'getCellValue'> {
82
+ }
70
83
  export interface GridAggregationParams<V = any> {
71
84
  values: (V | undefined)[];
72
85
  groupId: GridRowId;
@@ -102,7 +115,7 @@ export interface GridAggregationHeaderMeta {
102
115
  }
103
116
  export interface GridAggregationRule {
104
117
  aggregationFunctionName: string;
105
- aggregationFunction: GridAggregationFunction;
118
+ aggregationFunction: GridAggregationFunction | GridAggregationFunctionDataSource;
106
119
  }
107
120
  /**
108
121
  * Object containing all the aggregation rules that must be applied to the current columns.