@mui/x-data-grid-premium 8.0.0-alpha.5 → 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.
- package/CHANGELOG.md +206 -1
- package/DataGridPremium/DataGridPremium.js +6 -4
- package/DataGridPremium/useDataGridPremiumComponent.d.ts +1 -1
- package/DataGridPremium/useDataGridPremiumComponent.js +2 -1
- package/DataGridPremium/useDataGridPremiumProps.js +3 -1
- package/components/GridColumnMenuAggregationItem.js +53 -20
- package/components/GridDataSourceGroupingCriteriaCell.js +1 -2
- package/components/GridPremiumColumnMenu.d.ts +1 -1
- package/components/GridPremiumColumnMenu.js +5 -5
- package/esm/DataGridPremium/DataGridPremium.js +6 -4
- package/esm/DataGridPremium/useDataGridPremiumComponent.js +3 -2
- package/esm/DataGridPremium/useDataGridPremiumProps.js +3 -1
- package/esm/components/GridColumnMenuAggregationItem.js +51 -18
- package/esm/components/GridDataSourceGroupingCriteriaCell.js +1 -2
- package/esm/components/GridPremiumColumnMenu.js +5 -5
- package/esm/hooks/features/aggregation/createAggregationLookup.js +52 -55
- package/esm/hooks/features/aggregation/gridAggregationUtils.js +17 -13
- package/esm/hooks/features/aggregation/index.js +0 -1
- package/esm/hooks/features/aggregation/useGridAggregation.js +22 -10
- package/esm/hooks/features/aggregation/useGridAggregationPreProcessors.js +7 -14
- package/esm/hooks/features/cellSelection/useGridCellSelection.js +3 -3
- package/esm/hooks/features/dataSource/cache.js +3 -0
- package/esm/hooks/features/dataSource/models.js +1 -0
- package/esm/hooks/features/dataSource/useGridDataSourcePremium.js +53 -0
- package/esm/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +9 -4
- package/esm/utils/releaseInfo.js +1 -1
- package/hooks/features/aggregation/createAggregationLookup.d.ts +6 -5
- package/hooks/features/aggregation/createAggregationLookup.js +52 -55
- package/hooks/features/aggregation/gridAggregationInterfaces.d.ts +18 -5
- package/hooks/features/aggregation/gridAggregationUtils.d.ts +9 -10
- package/hooks/features/aggregation/gridAggregationUtils.js +17 -13
- package/hooks/features/aggregation/index.d.ts +1 -1
- package/hooks/features/aggregation/index.js +0 -12
- package/hooks/features/aggregation/useGridAggregation.d.ts +1 -1
- package/hooks/features/aggregation/useGridAggregation.js +22 -10
- package/hooks/features/aggregation/useGridAggregationPreProcessors.d.ts +1 -1
- package/hooks/features/aggregation/useGridAggregationPreProcessors.js +7 -14
- package/hooks/features/cellSelection/useGridCellSelection.d.ts +1 -1
- package/hooks/features/cellSelection/useGridCellSelection.js +3 -3
- package/hooks/features/dataSource/cache.d.ts +2 -0
- package/hooks/features/dataSource/cache.js +9 -0
- package/hooks/features/dataSource/models.d.ts +47 -0
- package/hooks/features/dataSource/models.js +5 -0
- package/hooks/features/dataSource/useGridDataSourcePremium.d.ts +4 -0
- package/hooks/features/dataSource/useGridDataSourcePremium.js +62 -0
- package/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +9 -4
- package/hooks/utils/useGridApiRef.d.ts +1 -1
- package/index.d.ts +2 -0
- package/index.js +1 -1
- package/models/dataGridPremiumProps.d.ts +6 -4
- package/models/gridApiPremium.d.ts +5 -3
- package/modern/DataGridPremium/DataGridPremium.js +6 -4
- package/modern/DataGridPremium/useDataGridPremiumComponent.js +3 -2
- package/modern/DataGridPremium/useDataGridPremiumProps.js +3 -1
- package/modern/components/GridColumnMenuAggregationItem.js +51 -18
- package/modern/components/GridDataSourceGroupingCriteriaCell.js +1 -2
- package/modern/components/GridPremiumColumnMenu.js +5 -5
- package/modern/hooks/features/aggregation/createAggregationLookup.js +52 -55
- package/modern/hooks/features/aggregation/gridAggregationUtils.js +17 -13
- package/modern/hooks/features/aggregation/index.js +0 -1
- package/modern/hooks/features/aggregation/useGridAggregation.js +22 -10
- package/modern/hooks/features/aggregation/useGridAggregationPreProcessors.js +7 -14
- package/modern/hooks/features/cellSelection/useGridCellSelection.js +3 -3
- package/modern/hooks/features/dataSource/cache.js +3 -0
- package/modern/hooks/features/dataSource/models.js +1 -0
- package/modern/hooks/features/dataSource/useGridDataSourcePremium.js +53 -0
- package/modern/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +9 -4
- package/modern/index.js +1 -1
- package/modern/utils/releaseInfo.js +1 -1
- package/package.json +5 -5
- package/utils/releaseInfo.js +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
2
|
import _toPropertyKey from "@babel/runtime/helpers/esm/toPropertyKey";
|
|
3
|
+
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
4
|
+
const _excluded = ["native"];
|
|
4
5
|
import * as React from 'react';
|
|
5
6
|
import PropTypes from 'prop-types';
|
|
6
7
|
import { useGridSelector } from '@mui/x-data-grid-pro';
|
|
@@ -12,18 +13,27 @@ import { useGridRootProps } from "../hooks/utils/useGridRootProps.js";
|
|
|
12
13
|
import { canColumnHaveAggregationFunction, getAggregationFunctionLabel, getAvailableAggregationFunctions } from "../hooks/features/aggregation/gridAggregationUtils.js";
|
|
13
14
|
import { gridAggregationModelSelector } from "../hooks/features/aggregation/gridAggregationSelectors.js";
|
|
14
15
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
|
+
import { createElement as _createElement } from "react";
|
|
15
17
|
function GridColumnMenuAggregationItem(props) {
|
|
16
18
|
const {
|
|
17
19
|
colDef
|
|
18
20
|
} = props;
|
|
19
21
|
const apiRef = useGridApiContext();
|
|
22
|
+
const inputRef = React.useRef(null);
|
|
20
23
|
const rootProps = useGridRootProps();
|
|
21
24
|
const id = useId();
|
|
22
25
|
const aggregationModel = useGridSelector(apiRef, gridAggregationModelSelector);
|
|
23
26
|
const availableAggregationFunctions = React.useMemo(() => getAvailableAggregationFunctions({
|
|
24
27
|
aggregationFunctions: rootProps.aggregationFunctions,
|
|
25
|
-
colDef
|
|
26
|
-
|
|
28
|
+
colDef,
|
|
29
|
+
isDataSource: !!rootProps.unstable_dataSource
|
|
30
|
+
}), [colDef, rootProps.aggregationFunctions, rootProps.unstable_dataSource]);
|
|
31
|
+
const _ref = rootProps.slotProps?.baseSelect || {},
|
|
32
|
+
{
|
|
33
|
+
native: isBaseSelectNative = false
|
|
34
|
+
} = _ref,
|
|
35
|
+
baseSelectProps = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
36
|
+
const baseSelectOptionProps = rootProps.slotProps?.baseSelectOption || {};
|
|
27
37
|
const selectedAggregationRule = React.useMemo(() => {
|
|
28
38
|
if (!colDef || !aggregationModel[colDef.field]) {
|
|
29
39
|
return '';
|
|
@@ -32,12 +42,13 @@ function GridColumnMenuAggregationItem(props) {
|
|
|
32
42
|
if (canColumnHaveAggregationFunction({
|
|
33
43
|
colDef,
|
|
34
44
|
aggregationFunctionName,
|
|
35
|
-
aggregationFunction: rootProps.aggregationFunctions[aggregationFunctionName]
|
|
45
|
+
aggregationFunction: rootProps.aggregationFunctions[aggregationFunctionName],
|
|
46
|
+
isDataSource: !!rootProps.unstable_dataSource
|
|
36
47
|
})) {
|
|
37
48
|
return aggregationFunctionName;
|
|
38
49
|
}
|
|
39
50
|
return '';
|
|
40
|
-
}, [rootProps.aggregationFunctions, aggregationModel, colDef]);
|
|
51
|
+
}, [rootProps.aggregationFunctions, rootProps.unstable_dataSource, aggregationModel, colDef]);
|
|
41
52
|
const handleAggregationItemChange = event => {
|
|
42
53
|
const newAggregationItem = event.target?.value || undefined;
|
|
43
54
|
const currentModel = gridAggregationModelSelector(apiRef);
|
|
@@ -50,11 +61,22 @@ function GridColumnMenuAggregationItem(props) {
|
|
|
50
61
|
apiRef.current.hideColumnMenu();
|
|
51
62
|
};
|
|
52
63
|
const label = apiRef.current.getLocaleText('aggregationMenuItemHeader');
|
|
64
|
+
const handleMenuItemKeyDown = React.useCallback(event => {
|
|
65
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
66
|
+
inputRef.current.focus();
|
|
67
|
+
}
|
|
68
|
+
}, []);
|
|
69
|
+
const handleSelectKeyDown = React.useCallback(event => {
|
|
70
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === ' ') {
|
|
71
|
+
event.stopPropagation();
|
|
72
|
+
}
|
|
73
|
+
}, []);
|
|
53
74
|
return /*#__PURE__*/_jsx(rootProps.slots.baseMenuItem, {
|
|
54
75
|
inert: true,
|
|
55
76
|
iconStart: /*#__PURE__*/_jsx(rootProps.slots.columnMenuAggregationIcon, {
|
|
56
77
|
fontSize: "small"
|
|
57
78
|
}),
|
|
79
|
+
onKeyDown: handleMenuItemKeyDown,
|
|
58
80
|
children: /*#__PURE__*/_jsxs(FormControl, {
|
|
59
81
|
size: "small",
|
|
60
82
|
fullWidth: true,
|
|
@@ -63,30 +85,41 @@ function GridColumnMenuAggregationItem(props) {
|
|
|
63
85
|
},
|
|
64
86
|
children: [/*#__PURE__*/_jsx(InputLabel, {
|
|
65
87
|
id: `${id}-label`,
|
|
88
|
+
htmlFor: `${id}-input`,
|
|
66
89
|
children: label
|
|
67
|
-
}), /*#__PURE__*/_jsxs(rootProps.slots.baseSelect, {
|
|
90
|
+
}), /*#__PURE__*/_jsxs(rootProps.slots.baseSelect, _extends({
|
|
68
91
|
labelId: `${id}-label`,
|
|
92
|
+
inputRef: inputRef,
|
|
69
93
|
id: `${id}-input`,
|
|
70
94
|
value: selectedAggregationRule,
|
|
71
95
|
label: label,
|
|
72
96
|
color: "primary",
|
|
73
97
|
onChange: handleAggregationItemChange,
|
|
98
|
+
MenuProps: {
|
|
99
|
+
PaperProps: {
|
|
100
|
+
onKeyDown: handleSelectKeyDown
|
|
101
|
+
}
|
|
102
|
+
},
|
|
74
103
|
onBlur: event => event.stopPropagation(),
|
|
75
|
-
|
|
76
|
-
|
|
104
|
+
native: isBaseSelectNative,
|
|
105
|
+
fullWidth: true
|
|
106
|
+
}, baseSelectProps, {
|
|
107
|
+
children: [/*#__PURE__*/_jsx(rootProps.slots.baseSelectOption, _extends({}, baseSelectOptionProps, {
|
|
108
|
+
native: isBaseSelectNative,
|
|
77
109
|
value: "",
|
|
78
110
|
children: "..."
|
|
79
|
-
}), availableAggregationFunctions.map(aggFunc => /*#__PURE__*/
|
|
111
|
+
})), availableAggregationFunctions.map(aggFunc => /*#__PURE__*/_createElement(rootProps.slots.baseSelectOption, _extends({}, baseSelectOptionProps, {
|
|
112
|
+
key: aggFunc,
|
|
80
113
|
value: aggFunc,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
})]
|
|
114
|
+
native: isBaseSelectNative
|
|
115
|
+
}), getAggregationFunctionLabel({
|
|
116
|
+
apiRef,
|
|
117
|
+
aggregationRule: {
|
|
118
|
+
aggregationFunctionName: aggFunc,
|
|
119
|
+
aggregationFunction: rootProps.aggregationFunctions[aggFunc]
|
|
120
|
+
}
|
|
121
|
+
})))]
|
|
122
|
+
}))]
|
|
90
123
|
})
|
|
91
124
|
});
|
|
92
125
|
}
|
|
@@ -2,7 +2,6 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { unstable_composeClasses as composeClasses } from '@mui/utils';
|
|
4
4
|
import Box from '@mui/material/Box';
|
|
5
|
-
import CircularProgress from '@mui/material/CircularProgress';
|
|
6
5
|
import { useGridPrivateApiContext } from '@mui/x-data-grid-pro/internals';
|
|
7
6
|
import { useGridSelector, getDataGridUtilityClass } from '@mui/x-data-grid-pro';
|
|
8
7
|
import { useGridApiContext } from "../hooks/utils/useGridApiContext.js";
|
|
@@ -47,7 +46,7 @@ function GridGroupingCriteriaCellIcon(props) {
|
|
|
47
46
|
if (isDataLoading) {
|
|
48
47
|
return /*#__PURE__*/_jsx("div", {
|
|
49
48
|
className: classes.loadingContainer,
|
|
50
|
-
children: /*#__PURE__*/_jsx(
|
|
49
|
+
children: /*#__PURE__*/_jsx(rootProps.slots.baseCircularProgress, {
|
|
51
50
|
size: "1rem",
|
|
52
51
|
color: "inherit"
|
|
53
52
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { GridGenericColumnMenu, GRID_COLUMN_MENU_SLOTS, GRID_COLUMN_MENU_SLOT_PROPS } from '@mui/x-data-grid-pro';
|
|
4
|
+
import { forwardRef } from '@mui/x-internals/forwardRef';
|
|
4
5
|
import { GridColumnMenuAggregationItem } from "./GridColumnMenuAggregationItem.js";
|
|
5
6
|
import { isGroupingColumn } from "../hooks/features/rowGrouping/index.js";
|
|
6
7
|
import { GridColumnMenuRowGroupItem } from "./GridColumnMenuRowGroupItem.js";
|
|
@@ -27,11 +28,10 @@ export const GRID_COLUMN_MENU_SLOT_PROPS_PREMIUM = _extends({}, GRID_COLUMN_MENU
|
|
|
27
28
|
displayOrder: 27
|
|
28
29
|
}
|
|
29
30
|
});
|
|
30
|
-
export const GridPremiumColumnMenu =
|
|
31
|
-
return /*#__PURE__*/_jsx(GridGenericColumnMenu, _extends({
|
|
32
|
-
ref: ref
|
|
33
|
-
}, props, {
|
|
31
|
+
export const GridPremiumColumnMenu = forwardRef(function GridPremiumColumnMenuSimple(props, ref) {
|
|
32
|
+
return /*#__PURE__*/_jsx(GridGenericColumnMenu, _extends({}, props, {
|
|
34
33
|
defaultSlots: GRID_COLUMN_MENU_SLOTS_PREMIUM,
|
|
35
|
-
defaultSlotProps: GRID_COLUMN_MENU_SLOT_PROPS_PREMIUM
|
|
34
|
+
defaultSlotProps: GRID_COLUMN_MENU_SLOT_PROPS_PREMIUM,
|
|
35
|
+
ref: ref
|
|
36
36
|
}));
|
|
37
37
|
});
|
|
@@ -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
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
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:
|
|
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
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
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
|
-
|
|
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,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
|
-
|
|
72
|
-
|
|
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 @@
|
|
|
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
|
+
};
|
|
@@ -48,10 +48,13 @@ export const useGridRowGroupingPreProcessors = (apiRef, props) => {
|
|
|
48
48
|
const groupingColDefs = getGroupingColDefs(columnsState);
|
|
49
49
|
let newColumnFields = [];
|
|
50
50
|
const newColumnsLookup = {};
|
|
51
|
+
const prevGroupingfields = [];
|
|
51
52
|
|
|
52
53
|
// We only keep the non-grouping columns
|
|
53
54
|
columnsState.orderedFields.forEach(field => {
|
|
54
|
-
if (
|
|
55
|
+
if (isGroupingColumn(field)) {
|
|
56
|
+
prevGroupingfields.push(field);
|
|
57
|
+
} else {
|
|
55
58
|
newColumnFields.push(field);
|
|
56
59
|
newColumnsLookup[field] = columnsState.lookup[field];
|
|
57
60
|
}
|
|
@@ -66,9 +69,11 @@ export const useGridRowGroupingPreProcessors = (apiRef, props) => {
|
|
|
66
69
|
}
|
|
67
70
|
newColumnsLookup[groupingColDef.field] = groupingColDef;
|
|
68
71
|
});
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
if (prevGroupingfields.length !== groupingColDefs.length) {
|
|
73
|
+
const startIndex = newColumnFields[0] === GRID_CHECKBOX_SELECTION_FIELD ? 1 : 0;
|
|
74
|
+
newColumnFields = [...newColumnFields.slice(0, startIndex), ...groupingColDefs.map(colDef => colDef.field), ...newColumnFields.slice(startIndex)];
|
|
75
|
+
columnsState.orderedFields = newColumnFields;
|
|
76
|
+
}
|
|
72
77
|
columnsState.lookup = newColumnsLookup;
|
|
73
78
|
return columnsState;
|
|
74
79
|
}, [getGroupingColDefs]);
|
package/esm/utils/releaseInfo.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ponyfillGlobal } from '@mui/utils';
|
|
2
2
|
export const getReleaseInfo = () => {
|
|
3
|
-
const releaseInfo = "
|
|
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
|