@mui/x-data-grid-premium 5.13.1 → 5.15.1
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 +147 -6
- package/DataGridPremium/DataGridPremium.js +56 -0
- package/DataGridPremium/useDataGridPremiumComponent.js +10 -2
- package/DataGridPremium/useDataGridPremiumProps.js +17 -7
- package/components/GridAggregationColumnMenuItem.d.ts +9 -0
- package/components/GridAggregationColumnMenuItem.js +93 -0
- package/components/GridAggregationHeader.d.ts +4 -0
- package/components/GridAggregationHeader.js +94 -0
- package/components/GridExcelExportMenuItem.js +11 -4
- package/components/GridFooterCell.d.ts +9 -0
- package/components/GridFooterCell.js +51 -0
- package/components/GridGroupingColumnFooterCell.d.ts +4 -0
- package/components/GridGroupingColumnFooterCell.js +29 -0
- package/hooks/features/aggregation/createAggregationLookup.d.ts +10 -0
- package/hooks/features/aggregation/createAggregationLookup.js +128 -0
- package/hooks/features/aggregation/gridAggregationFunctions.d.ts +8 -0
- package/hooks/features/aggregation/gridAggregationFunctions.js +96 -0
- package/hooks/features/aggregation/gridAggregationInterfaces.d.ts +103 -0
- package/hooks/features/aggregation/gridAggregationInterfaces.js +1 -0
- package/hooks/features/aggregation/gridAggregationSelectors.d.ts +4 -0
- package/hooks/features/aggregation/gridAggregationSelectors.js +4 -0
- package/hooks/features/aggregation/gridAggregationUtils.d.ts +41 -0
- package/hooks/features/aggregation/gridAggregationUtils.js +188 -0
- package/hooks/features/aggregation/index.d.ts +4 -0
- package/hooks/features/aggregation/index.js +4 -0
- package/hooks/features/aggregation/useGridAggregation.d.ts +6 -0
- package/hooks/features/aggregation/useGridAggregation.js +94 -0
- package/hooks/features/aggregation/useGridAggregationPreProcessors.d.ts +4 -0
- package/hooks/features/aggregation/useGridAggregationPreProcessors.js +138 -0
- package/hooks/features/aggregation/wrapColumnWithAggregation.d.ts +29 -0
- package/hooks/features/aggregation/wrapColumnWithAggregation.js +257 -0
- package/hooks/features/export/serializer/excelSerializer.js +2 -1
- package/hooks/features/index.d.ts +1 -0
- package/hooks/features/index.js +1 -0
- package/hooks/features/rowGrouping/createGroupingColDef.js +13 -2
- package/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
- package/hooks/features/rowGrouping/useGridRowGrouping.d.ts +1 -1
- package/hooks/features/rowGrouping/useGridRowGrouping.js +20 -10
- package/index.js +1 -1
- package/legacy/DataGridPremium/DataGridPremium.js +56 -0
- package/legacy/DataGridPremium/useDataGridPremiumComponent.js +10 -2
- package/legacy/DataGridPremium/useDataGridPremiumProps.js +12 -2
- package/legacy/components/GridAggregationColumnMenuItem.js +95 -0
- package/legacy/components/GridAggregationHeader.js +95 -0
- package/legacy/components/GridExcelExportMenuItem.js +11 -4
- package/legacy/components/GridFooterCell.js +63 -0
- package/legacy/components/GridGroupingColumnFooterCell.js +27 -0
- package/legacy/hooks/features/aggregation/createAggregationLookup.js +127 -0
- package/legacy/hooks/features/aggregation/gridAggregationFunctions.js +94 -0
- package/legacy/hooks/features/aggregation/gridAggregationInterfaces.js +1 -0
- package/legacy/hooks/features/aggregation/gridAggregationSelectors.js +10 -0
- package/legacy/hooks/features/aggregation/gridAggregationUtils.js +200 -0
- package/legacy/hooks/features/aggregation/index.js +4 -0
- package/legacy/hooks/features/aggregation/useGridAggregation.js +95 -0
- package/legacy/hooks/features/aggregation/useGridAggregationPreProcessors.js +141 -0
- package/legacy/hooks/features/aggregation/wrapColumnWithAggregation.js +262 -0
- package/legacy/hooks/features/export/serializer/excelSerializer.js +2 -1
- package/legacy/hooks/features/index.js +1 -0
- package/legacy/hooks/features/rowGrouping/createGroupingColDef.js +13 -2
- package/legacy/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
- package/legacy/hooks/features/rowGrouping/useGridRowGrouping.js +24 -10
- package/legacy/index.js +1 -1
- package/legacy/typeOverloads/index.js +1 -1
- package/legacy/utils/releaseInfo.js +1 -1
- package/models/dataGridPremiumProps.d.ts +40 -1
- package/models/gridApiPremium.d.ts +3 -3
- package/models/gridStatePremium.d.ts +3 -1
- package/modern/DataGridPremium/DataGridPremium.js +56 -0
- package/modern/DataGridPremium/useDataGridPremiumComponent.js +10 -2
- package/modern/DataGridPremium/useDataGridPremiumProps.js +8 -2
- package/modern/components/GridAggregationColumnMenuItem.js +93 -0
- package/modern/components/GridAggregationHeader.js +92 -0
- package/modern/components/GridExcelExportMenuItem.js +11 -4
- package/modern/components/GridFooterCell.js +51 -0
- package/modern/components/GridGroupingColumnFooterCell.js +29 -0
- package/modern/hooks/features/aggregation/createAggregationLookup.js +122 -0
- package/modern/hooks/features/aggregation/gridAggregationFunctions.js +96 -0
- package/modern/hooks/features/aggregation/gridAggregationInterfaces.js +1 -0
- package/modern/hooks/features/aggregation/gridAggregationSelectors.js +4 -0
- package/modern/hooks/features/aggregation/gridAggregationUtils.js +186 -0
- package/modern/hooks/features/aggregation/index.js +4 -0
- package/modern/hooks/features/aggregation/useGridAggregation.js +92 -0
- package/modern/hooks/features/aggregation/useGridAggregationPreProcessors.js +136 -0
- package/modern/hooks/features/aggregation/wrapColumnWithAggregation.js +251 -0
- package/modern/hooks/features/export/serializer/excelSerializer.js +2 -1
- package/modern/hooks/features/index.js +1 -0
- package/modern/hooks/features/rowGrouping/createGroupingColDef.js +13 -2
- package/modern/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
- package/modern/hooks/features/rowGrouping/useGridRowGrouping.js +17 -11
- package/modern/index.js +1 -1
- package/modern/typeOverloads/index.js +1 -1
- package/modern/utils/releaseInfo.js +1 -1
- package/node/DataGridPremium/DataGridPremium.js +56 -0
- package/node/DataGridPremium/useDataGridPremiumComponent.js +11 -1
- package/node/DataGridPremium/useDataGridPremiumProps.js +17 -6
- package/node/components/GridAggregationColumnMenuItem.js +120 -0
- package/node/components/GridAggregationHeader.js +115 -0
- package/node/components/GridExcelExportMenuItem.js +12 -4
- package/node/components/GridFooterCell.js +73 -0
- package/node/components/GridGroupingColumnFooterCell.js +46 -0
- package/node/hooks/features/aggregation/createAggregationLookup.js +139 -0
- package/node/hooks/features/aggregation/gridAggregationFunctions.js +105 -0
- package/node/hooks/features/aggregation/gridAggregationInterfaces.js +5 -0
- package/node/hooks/features/aggregation/gridAggregationSelectors.js +16 -0
- package/node/hooks/features/aggregation/gridAggregationUtils.js +223 -0
- package/node/hooks/features/aggregation/index.js +65 -0
- package/node/hooks/features/aggregation/useGridAggregation.js +118 -0
- package/node/hooks/features/aggregation/useGridAggregationPreProcessors.js +162 -0
- package/node/hooks/features/aggregation/wrapColumnWithAggregation.js +279 -0
- package/node/hooks/features/export/serializer/excelSerializer.js +2 -1
- package/node/hooks/features/index.js +13 -0
- package/node/hooks/features/rowGrouping/createGroupingColDef.js +14 -2
- package/node/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
- package/node/hooks/features/rowGrouping/useGridRowGrouping.js +19 -10
- package/node/index.js +1 -1
- package/node/typeOverloads/index.js +16 -1
- package/node/utils/releaseInfo.js +1 -1
- package/package.json +4 -4
- package/typeOverloads/index.d.ts +1 -1
- package/typeOverloads/index.js +1 -1
- package/typeOverloads/modules.d.ts +32 -2
- package/utils/releaseInfo.js +1 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.useGridAggregation = exports.aggregationStateInitializer = void 0;
|
|
9
|
+
|
|
10
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
11
|
+
|
|
12
|
+
var React = _interopRequireWildcard(require("react"));
|
|
13
|
+
|
|
14
|
+
var _xDataGridPro = require("@mui/x-data-grid-pro");
|
|
15
|
+
|
|
16
|
+
var _gridAggregationSelectors = require("./gridAggregationSelectors");
|
|
17
|
+
|
|
18
|
+
var _gridAggregationUtils = require("./gridAggregationUtils");
|
|
19
|
+
|
|
20
|
+
var _createAggregationLookup = require("./createAggregationLookup");
|
|
21
|
+
|
|
22
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
23
|
+
|
|
24
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
25
|
+
|
|
26
|
+
const aggregationStateInitializer = (state, props, apiRef) => {
|
|
27
|
+
var _ref, _props$aggregationMod, _props$initialState, _props$initialState$a;
|
|
28
|
+
|
|
29
|
+
apiRef.current.unstable_caches.aggregation = {
|
|
30
|
+
rulesOnLastColumnHydration: {},
|
|
31
|
+
rulesOnLastRowHydration: {}
|
|
32
|
+
};
|
|
33
|
+
return (0, _extends2.default)({}, state, {
|
|
34
|
+
aggregation: {
|
|
35
|
+
model: (_ref = (_props$aggregationMod = props.aggregationModel) != null ? _props$aggregationMod : (_props$initialState = props.initialState) == null ? void 0 : (_props$initialState$a = _props$initialState.aggregation) == null ? void 0 : _props$initialState$a.model) != null ? _ref : {}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
exports.aggregationStateInitializer = aggregationStateInitializer;
|
|
41
|
+
|
|
42
|
+
const useGridAggregation = (apiRef, props) => {
|
|
43
|
+
apiRef.current.unstable_registerControlState({
|
|
44
|
+
stateId: 'aggregation',
|
|
45
|
+
propModel: props.aggregationModel,
|
|
46
|
+
propOnChange: props.onAggregationModelChange,
|
|
47
|
+
stateSelector: _gridAggregationSelectors.gridAggregationModelSelector,
|
|
48
|
+
changeEvent: 'aggregationModelChange'
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* API METHODS
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
const setAggregationModel = React.useCallback(model => {
|
|
55
|
+
const currentModel = (0, _gridAggregationSelectors.gridAggregationModelSelector)(apiRef);
|
|
56
|
+
|
|
57
|
+
if (currentModel !== model) {
|
|
58
|
+
apiRef.current.setState((0, _gridAggregationUtils.mergeStateWithAggregationModel)(model));
|
|
59
|
+
apiRef.current.forceUpdate();
|
|
60
|
+
}
|
|
61
|
+
}, [apiRef]);
|
|
62
|
+
const applyAggregation = React.useCallback(() => {
|
|
63
|
+
const aggregationLookup = (0, _createAggregationLookup.createAggregationLookup)({
|
|
64
|
+
apiRef,
|
|
65
|
+
getAggregationPosition: props.getAggregationPosition,
|
|
66
|
+
aggregationFunctions: props.aggregationFunctions,
|
|
67
|
+
aggregationRowsScope: props.aggregationRowsScope
|
|
68
|
+
});
|
|
69
|
+
apiRef.current.setState(state => (0, _extends2.default)({}, state, {
|
|
70
|
+
aggregation: (0, _extends2.default)({}, state.aggregation, {
|
|
71
|
+
lookup: aggregationLookup
|
|
72
|
+
})
|
|
73
|
+
}));
|
|
74
|
+
}, [apiRef, props.getAggregationPosition, props.aggregationFunctions, props.aggregationRowsScope]);
|
|
75
|
+
const aggregationApi = {
|
|
76
|
+
setAggregationModel
|
|
77
|
+
};
|
|
78
|
+
(0, _xDataGridPro.useGridApiMethod)(apiRef, aggregationApi, 'GridAggregationApi');
|
|
79
|
+
/**
|
|
80
|
+
* EVENTS
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
const checkAggregationRulesDiff = React.useCallback(() => {
|
|
84
|
+
const {
|
|
85
|
+
rulesOnLastRowHydration,
|
|
86
|
+
rulesOnLastColumnHydration
|
|
87
|
+
} = apiRef.current.unstable_caches.aggregation;
|
|
88
|
+
const aggregationRules = props.disableAggregation ? {} : (0, _gridAggregationUtils.getAggregationRules)({
|
|
89
|
+
columnsLookup: (0, _xDataGridPro.gridColumnLookupSelector)(apiRef),
|
|
90
|
+
aggregationModel: (0, _gridAggregationSelectors.gridAggregationModelSelector)(apiRef),
|
|
91
|
+
aggregationFunctions: props.aggregationFunctions
|
|
92
|
+
}); // Re-apply the row hydration to add / remove the aggregation footers
|
|
93
|
+
|
|
94
|
+
if ((0, _gridAggregationUtils.hasAggregationRulesChanged)(rulesOnLastRowHydration, aggregationRules)) {
|
|
95
|
+
apiRef.current.unstable_requestPipeProcessorsApplication('hydrateRows');
|
|
96
|
+
applyAggregation();
|
|
97
|
+
} // Re-apply the column hydration to wrap / unwrap the aggregated columns
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if ((0, _gridAggregationUtils.hasAggregationRulesChanged)(rulesOnLastColumnHydration, aggregationRules)) {
|
|
101
|
+
apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns');
|
|
102
|
+
}
|
|
103
|
+
}, [apiRef, applyAggregation, props.aggregationFunctions, props.disableAggregation]);
|
|
104
|
+
(0, _xDataGridPro.useGridApiEventHandler)(apiRef, 'aggregationModelChange', checkAggregationRulesDiff);
|
|
105
|
+
(0, _xDataGridPro.useGridApiEventHandler)(apiRef, 'columnsChange', checkAggregationRulesDiff);
|
|
106
|
+
(0, _xDataGridPro.useGridApiEventHandler)(apiRef, 'filteredRowsSet', applyAggregation);
|
|
107
|
+
/**
|
|
108
|
+
* EFFECTS
|
|
109
|
+
*/
|
|
110
|
+
|
|
111
|
+
React.useEffect(() => {
|
|
112
|
+
if (props.aggregationModel !== undefined) {
|
|
113
|
+
apiRef.current.setAggregationModel(props.aggregationModel);
|
|
114
|
+
}
|
|
115
|
+
}, [apiRef, props.aggregationModel]);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
exports.useGridAggregation = useGridAggregation;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.useGridAggregationPreProcessors = void 0;
|
|
9
|
+
|
|
10
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
11
|
+
|
|
12
|
+
var React = _interopRequireWildcard(require("react"));
|
|
13
|
+
|
|
14
|
+
var _Divider = _interopRequireDefault(require("@mui/material/Divider"));
|
|
15
|
+
|
|
16
|
+
var _xDataGridPro = require("@mui/x-data-grid-pro");
|
|
17
|
+
|
|
18
|
+
var _internals = require("@mui/x-data-grid-pro/internals");
|
|
19
|
+
|
|
20
|
+
var _gridAggregationUtils = require("./gridAggregationUtils");
|
|
21
|
+
|
|
22
|
+
var _wrapColumnWithAggregation = require("./wrapColumnWithAggregation");
|
|
23
|
+
|
|
24
|
+
var _GridAggregationColumnMenuItem = require("../../../components/GridAggregationColumnMenuItem");
|
|
25
|
+
|
|
26
|
+
var _gridAggregationSelectors = require("./gridAggregationSelectors");
|
|
27
|
+
|
|
28
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
29
|
+
|
|
30
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
31
|
+
|
|
32
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
33
|
+
|
|
34
|
+
const Divider = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_Divider.default, {
|
|
35
|
+
onClick: event => event.stopPropagation()
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const useGridAggregationPreProcessors = (apiRef, props) => {
|
|
39
|
+
const updateAggregatedColumns = React.useCallback(columnsState => {
|
|
40
|
+
const {
|
|
41
|
+
rulesOnLastColumnHydration
|
|
42
|
+
} = apiRef.current.unstable_caches.aggregation;
|
|
43
|
+
const aggregationRules = props.disableAggregation ? {} : (0, _gridAggregationUtils.getAggregationRules)({
|
|
44
|
+
columnsLookup: columnsState.lookup,
|
|
45
|
+
aggregationModel: (0, _gridAggregationSelectors.gridAggregationModelSelector)(apiRef),
|
|
46
|
+
aggregationFunctions: props.aggregationFunctions
|
|
47
|
+
});
|
|
48
|
+
columnsState.all.forEach(field => {
|
|
49
|
+
const shouldHaveAggregationValue = !!aggregationRules[field];
|
|
50
|
+
const haveAggregationColumnValue = !!rulesOnLastColumnHydration[field];
|
|
51
|
+
let column = columnsState.lookup[field];
|
|
52
|
+
|
|
53
|
+
if (haveAggregationColumnValue) {
|
|
54
|
+
column = (0, _wrapColumnWithAggregation.unwrapColumnFromAggregation)({
|
|
55
|
+
column
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (shouldHaveAggregationValue) {
|
|
60
|
+
column = (0, _wrapColumnWithAggregation.wrapColumnWithAggregationValue)({
|
|
61
|
+
column,
|
|
62
|
+
aggregationRule: aggregationRules[field],
|
|
63
|
+
apiRef
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
columnsState.lookup[field] = column;
|
|
68
|
+
});
|
|
69
|
+
apiRef.current.unstable_caches.aggregation.rulesOnLastColumnHydration = aggregationRules;
|
|
70
|
+
return columnsState;
|
|
71
|
+
}, [apiRef, props.aggregationFunctions, props.disableAggregation]);
|
|
72
|
+
const addGroupFooterRows = React.useCallback(groupingParams => {
|
|
73
|
+
let newGroupingParams;
|
|
74
|
+
let rulesOnLastRowHydration;
|
|
75
|
+
|
|
76
|
+
if (props.disableAggregation) {
|
|
77
|
+
newGroupingParams = groupingParams;
|
|
78
|
+
rulesOnLastRowHydration = {};
|
|
79
|
+
} else {
|
|
80
|
+
const aggregationRules = (0, _gridAggregationUtils.getAggregationRules)({
|
|
81
|
+
columnsLookup: (0, _xDataGridPro.gridColumnLookupSelector)(apiRef),
|
|
82
|
+
aggregationModel: (0, _gridAggregationSelectors.gridAggregationModelSelector)(apiRef),
|
|
83
|
+
aggregationFunctions: props.aggregationFunctions
|
|
84
|
+
});
|
|
85
|
+
rulesOnLastRowHydration = aggregationRules; // If no column have an aggregation rule
|
|
86
|
+
// Then don't create the footer rows
|
|
87
|
+
|
|
88
|
+
if (Object.values(aggregationRules).length === 0) {
|
|
89
|
+
newGroupingParams = groupingParams;
|
|
90
|
+
} else {
|
|
91
|
+
newGroupingParams = (0, _gridAggregationUtils.addFooterRows)({
|
|
92
|
+
groupingParams,
|
|
93
|
+
aggregationRules,
|
|
94
|
+
getAggregationPosition: props.getAggregationPosition,
|
|
95
|
+
apiRef
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
apiRef.current.unstable_caches.aggregation.rulesOnLastRowHydration = rulesOnLastRowHydration;
|
|
101
|
+
return newGroupingParams;
|
|
102
|
+
}, [apiRef, props.disableAggregation, props.getAggregationPosition, props.aggregationFunctions]);
|
|
103
|
+
const addColumnMenuButtons = React.useCallback((initialValue, column) => {
|
|
104
|
+
if (props.disableAggregation) {
|
|
105
|
+
return initialValue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const availableAggregationFunctions = (0, _gridAggregationUtils.getAvailableAggregationFunctions)({
|
|
109
|
+
aggregationFunctions: props.aggregationFunctions,
|
|
110
|
+
column
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (availableAggregationFunctions.length === 0) {
|
|
114
|
+
return initialValue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return [...initialValue, /*#__PURE__*/(0, _jsxRuntime.jsx)(Divider, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridAggregationColumnMenuItem.GridAggregationColumnMenuItem, {
|
|
118
|
+
column: column,
|
|
119
|
+
label: apiRef.current.getLocaleText('aggregationMenuItemHeader'),
|
|
120
|
+
availableAggregationFunctions: availableAggregationFunctions
|
|
121
|
+
})];
|
|
122
|
+
}, [apiRef, props.aggregationFunctions, props.disableAggregation]);
|
|
123
|
+
const stateExportPreProcessing = React.useCallback(prevState => {
|
|
124
|
+
if (props.disableAggregation) {
|
|
125
|
+
return prevState;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const aggregationModelToExport = (0, _gridAggregationSelectors.gridAggregationModelSelector)(apiRef);
|
|
129
|
+
|
|
130
|
+
if (Object.values(aggregationModelToExport).length === 0) {
|
|
131
|
+
return prevState;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return (0, _extends2.default)({}, prevState, {
|
|
135
|
+
aggregation: {
|
|
136
|
+
model: aggregationModelToExport
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}, [apiRef, props.disableAggregation]);
|
|
140
|
+
const stateRestorePreProcessing = React.useCallback((params, context) => {
|
|
141
|
+
var _context$stateToResto;
|
|
142
|
+
|
|
143
|
+
if (props.disableAggregation) {
|
|
144
|
+
return params;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const aggregationModel = (_context$stateToResto = context.stateToRestore.aggregation) == null ? void 0 : _context$stateToResto.model;
|
|
148
|
+
|
|
149
|
+
if (aggregationModel != null) {
|
|
150
|
+
apiRef.current.setState((0, _gridAggregationUtils.mergeStateWithAggregationModel)(aggregationModel));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return params;
|
|
154
|
+
}, [apiRef, props.disableAggregation]);
|
|
155
|
+
(0, _internals.useGridRegisterPipeProcessor)(apiRef, 'hydrateColumns', updateAggregatedColumns);
|
|
156
|
+
(0, _internals.useGridRegisterPipeProcessor)(apiRef, 'hydrateRows', addGroupFooterRows);
|
|
157
|
+
(0, _internals.useGridRegisterPipeProcessor)(apiRef, 'columnMenu', addColumnMenuButtons);
|
|
158
|
+
(0, _internals.useGridRegisterPipeProcessor)(apiRef, 'exportState', stateExportPreProcessing);
|
|
159
|
+
(0, _internals.useGridRegisterPipeProcessor)(apiRef, 'restoreState', stateRestorePreProcessing);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
exports.useGridAggregationPreProcessors = useGridAggregationPreProcessors;
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.wrapColumnWithAggregationValue = exports.unwrapColumnFromAggregation = void 0;
|
|
9
|
+
|
|
10
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
11
|
+
|
|
12
|
+
var React = _interopRequireWildcard(require("react"));
|
|
13
|
+
|
|
14
|
+
var _gridAggregationSelectors = require("./gridAggregationSelectors");
|
|
15
|
+
|
|
16
|
+
var _GridFooterCell = require("../../../components/GridFooterCell");
|
|
17
|
+
|
|
18
|
+
var _GridAggregationHeader = require("../../../components/GridAggregationHeader");
|
|
19
|
+
|
|
20
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
21
|
+
|
|
22
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
23
|
+
|
|
24
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
25
|
+
|
|
26
|
+
const AGGREGATION_WRAPPABLE_PROPERTIES = ['valueGetter', 'valueFormatter', 'renderCell', 'renderHeader', 'filterOperators'];
|
|
27
|
+
|
|
28
|
+
const getAggregationValueWrappedValueGetter = ({
|
|
29
|
+
value: valueGetter,
|
|
30
|
+
getCellAggregationResult
|
|
31
|
+
}) => {
|
|
32
|
+
const wrappedValueGetter = params => {
|
|
33
|
+
const cellAggregationResult = getCellAggregationResult(params.id, params.field);
|
|
34
|
+
|
|
35
|
+
if (cellAggregationResult != null) {
|
|
36
|
+
var _cellAggregationResul;
|
|
37
|
+
|
|
38
|
+
return (_cellAggregationResul = cellAggregationResult == null ? void 0 : cellAggregationResult.value) != null ? _cellAggregationResul : null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (valueGetter) {
|
|
42
|
+
return valueGetter(params);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return params.row[params.field];
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return wrappedValueGetter;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const getAggregationValueWrappedValueFormatter = ({
|
|
52
|
+
value: valueFormatter,
|
|
53
|
+
aggregationRule,
|
|
54
|
+
getCellAggregationResult
|
|
55
|
+
}) => {
|
|
56
|
+
// If neither the inline aggregation function nor the footer aggregation function have a custom value formatter,
|
|
57
|
+
// Then we don't wrap the column value formatter
|
|
58
|
+
if (!aggregationRule.aggregationFunction.valueFormatter) {
|
|
59
|
+
return valueFormatter;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const wrappedValueFormatter = params => {
|
|
63
|
+
if (params.id != null) {
|
|
64
|
+
const cellAggregationResult = getCellAggregationResult(params.id, params.field);
|
|
65
|
+
|
|
66
|
+
if (cellAggregationResult != null) {
|
|
67
|
+
return aggregationRule.aggregationFunction.valueFormatter(params);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (valueFormatter) {
|
|
72
|
+
return valueFormatter(params);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return params.value;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return wrappedValueFormatter;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const getAggregationValueWrappedRenderCell = ({
|
|
82
|
+
value: renderCell,
|
|
83
|
+
aggregationRule,
|
|
84
|
+
getCellAggregationResult
|
|
85
|
+
}) => {
|
|
86
|
+
const wrappedRenderCell = params => {
|
|
87
|
+
const cellAggregationResult = getCellAggregationResult(params.id, params.field);
|
|
88
|
+
|
|
89
|
+
if (cellAggregationResult != null) {
|
|
90
|
+
var _aggregationFunction$;
|
|
91
|
+
|
|
92
|
+
if (!renderCell) {
|
|
93
|
+
if (cellAggregationResult.position === 'footer') {
|
|
94
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridFooterCell.GridFooterCell, (0, _extends2.default)({}, params));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return params.formattedValue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const aggregationMeta = {
|
|
101
|
+
hasCellUnit: (_aggregationFunction$ = aggregationRule.aggregationFunction.hasCellUnit) != null ? _aggregationFunction$ : true,
|
|
102
|
+
aggregationFunctionName: aggregationRule.aggregationFunctionName
|
|
103
|
+
};
|
|
104
|
+
return renderCell((0, _extends2.default)({}, params, {
|
|
105
|
+
aggregation: aggregationMeta
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!renderCell) {
|
|
110
|
+
return params.formattedValue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return renderCell(params);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
return wrappedRenderCell;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Skips the filtering for aggregated rows
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
const getWrappedFilterOperators = ({
|
|
124
|
+
value: filterOperators,
|
|
125
|
+
getCellAggregationResult
|
|
126
|
+
}) => filterOperators.map(operator => {
|
|
127
|
+
return (0, _extends2.default)({}, operator, {
|
|
128
|
+
getApplyFilterFn: (filterItem, column) => {
|
|
129
|
+
const originalFn = operator.getApplyFilterFn(filterItem, column);
|
|
130
|
+
|
|
131
|
+
if (!originalFn) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return params => {
|
|
136
|
+
if (getCellAggregationResult(params.id, params.field) != null) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return originalFn(params);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
/**
|
|
146
|
+
* Add the aggregation method around the header name
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
const getWrappedRenderHeader = ({
|
|
151
|
+
value: renderHeader,
|
|
152
|
+
aggregationRule
|
|
153
|
+
}) => {
|
|
154
|
+
const wrappedRenderCell = params => {
|
|
155
|
+
const aggregationMeta = {
|
|
156
|
+
aggregationRule
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
if (!renderHeader) {
|
|
160
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridAggregationHeader.GridAggregationHeader, (0, _extends2.default)({}, params, {
|
|
161
|
+
aggregation: aggregationMeta
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return renderHeader((0, _extends2.default)({}, params, {
|
|
166
|
+
aggregation: aggregationMeta
|
|
167
|
+
}));
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
return wrappedRenderCell;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Add a wrapper around each wrappable property of the column to customize the behavior of the aggregation cells.
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
const wrapColumnWithAggregationValue = ({
|
|
178
|
+
column,
|
|
179
|
+
apiRef,
|
|
180
|
+
aggregationRule
|
|
181
|
+
}) => {
|
|
182
|
+
const getCellAggregationResult = (id, field) => {
|
|
183
|
+
var _parent, _gridAggregationLooku;
|
|
184
|
+
|
|
185
|
+
let cellAggregationPosition = null;
|
|
186
|
+
|
|
187
|
+
if (id.toString().startsWith('auto-generated-row-')) {
|
|
188
|
+
cellAggregationPosition = 'inline';
|
|
189
|
+
} else if (id.toString().startsWith('auto-generated-group-footer-')) {
|
|
190
|
+
cellAggregationPosition = 'footer';
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (cellAggregationPosition == null) {
|
|
194
|
+
return null;
|
|
195
|
+
} // TODO: Add custom root id
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
const groupId = cellAggregationPosition === 'inline' ? id : (_parent = apiRef.current.getRowNode(id).parent) != null ? _parent : '';
|
|
199
|
+
const aggregationResult = (_gridAggregationLooku = (0, _gridAggregationSelectors.gridAggregationLookupSelector)(apiRef)[groupId]) == null ? void 0 : _gridAggregationLooku[field];
|
|
200
|
+
|
|
201
|
+
if (!aggregationResult || aggregationResult.position !== cellAggregationPosition) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return aggregationResult;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const aggregationWrappedProperties = {};
|
|
209
|
+
const wrappedColumn = (0, _extends2.default)({}, column, {
|
|
210
|
+
aggregationWrappedProperties
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const wrapColumnProperty = (property, wrapper) => {
|
|
214
|
+
const originalValue = column[property];
|
|
215
|
+
const wrappedProperty = wrapper({
|
|
216
|
+
apiRef,
|
|
217
|
+
value: originalValue,
|
|
218
|
+
colDef: column,
|
|
219
|
+
aggregationRule,
|
|
220
|
+
getCellAggregationResult
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
if (wrappedProperty !== originalValue) {
|
|
224
|
+
aggregationWrappedProperties[property] = {
|
|
225
|
+
original: originalValue,
|
|
226
|
+
wrapped: wrappedProperty
|
|
227
|
+
};
|
|
228
|
+
wrappedColumn[property] = wrappedProperty;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
wrapColumnProperty('valueGetter', getAggregationValueWrappedValueGetter);
|
|
233
|
+
wrapColumnProperty('valueFormatter', getAggregationValueWrappedValueFormatter);
|
|
234
|
+
wrapColumnProperty('renderCell', getAggregationValueWrappedRenderCell);
|
|
235
|
+
wrapColumnProperty('renderHeader', getWrappedRenderHeader);
|
|
236
|
+
wrapColumnProperty('filterOperators', getWrappedFilterOperators);
|
|
237
|
+
|
|
238
|
+
if (Object.keys(aggregationWrappedProperties).length === 0) {
|
|
239
|
+
return column;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return wrappedColumn;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Remove the aggregation wrappers around the wrappable properties of the column.
|
|
246
|
+
*/
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
exports.wrapColumnWithAggregationValue = wrapColumnWithAggregationValue;
|
|
250
|
+
|
|
251
|
+
const unwrapColumnFromAggregation = ({
|
|
252
|
+
column
|
|
253
|
+
}) => {
|
|
254
|
+
if (!column.aggregationWrappedProperties) {
|
|
255
|
+
return column;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const originalProperties = Object.entries(column.aggregationWrappedProperties);
|
|
259
|
+
|
|
260
|
+
if (originalProperties.length === 0) {
|
|
261
|
+
return column;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const unwrappedColumn = (0, _extends2.default)({}, column);
|
|
265
|
+
originalProperties.forEach(([propertyName, {
|
|
266
|
+
original,
|
|
267
|
+
wrapped
|
|
268
|
+
}]) => {
|
|
269
|
+
// The value changed since we wrapped it
|
|
270
|
+
if (wrapped !== column[propertyName]) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
unwrappedColumn[propertyName] = original;
|
|
275
|
+
});
|
|
276
|
+
return unwrappedColumn;
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
exports.unwrapColumnFromAggregation = unwrapColumnFromAggregation;
|
|
@@ -61,7 +61,8 @@ const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
61
61
|
api.unstable_calculateColSpan({
|
|
62
62
|
rowId: id,
|
|
63
63
|
minFirstColumn: 0,
|
|
64
|
-
maxLastColumn: columns.length
|
|
64
|
+
maxLastColumn: columns.length,
|
|
65
|
+
columns
|
|
65
66
|
});
|
|
66
67
|
columns.forEach((column, colIndex) => {
|
|
67
68
|
const colSpanInfo = api.unstable_getCellColSpanInfo(id, colIndex);
|
|
@@ -4,6 +4,19 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
|
|
7
|
+
var _aggregation = require("./aggregation");
|
|
8
|
+
|
|
9
|
+
Object.keys(_aggregation).forEach(function (key) {
|
|
10
|
+
if (key === "default" || key === "__esModule") return;
|
|
11
|
+
if (key in exports && exports[key] === _aggregation[key]) return;
|
|
12
|
+
Object.defineProperty(exports, key, {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _aggregation[key];
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
7
20
|
var _rowGrouping = require("./rowGrouping");
|
|
8
21
|
|
|
9
22
|
Object.keys(_rowGrouping).forEach(function (key) {
|
|
@@ -15,6 +15,8 @@ var React = _interopRequireWildcard(require("react"));
|
|
|
15
15
|
|
|
16
16
|
var _xDataGridPro = require("@mui/x-data-grid-pro");
|
|
17
17
|
|
|
18
|
+
var _GridGroupingColumnFooterCell = require("../../../components/GridGroupingColumnFooterCell");
|
|
19
|
+
|
|
18
20
|
var _GridGroupingCriteriaCell = require("../../../components/GridGroupingCriteriaCell");
|
|
19
21
|
|
|
20
22
|
var _GridGroupingColumnLeafCell = require("../../../components/GridGroupingColumnLeafCell");
|
|
@@ -173,7 +175,12 @@ const createGroupingColDefForOneGroupingCriteria = ({
|
|
|
173
175
|
const commonProperties = {
|
|
174
176
|
width: Math.max(((_groupedByColDef$widt = groupedByColDef.width) != null ? _groupedByColDef$widt : _xDataGridPro.GRID_STRING_COL_DEF.width) + 40, (_leafColDef$width = leafColDef == null ? void 0 : leafColDef.width) != null ? _leafColDef$width : 0),
|
|
175
177
|
renderCell: params => {
|
|
176
|
-
// Render
|
|
178
|
+
// Render footer
|
|
179
|
+
if (params.rowNode.position === 'footer') {
|
|
180
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridGroupingColumnFooterCell.GridGroupingColumnFooterCell, (0, _extends2.default)({}, params));
|
|
181
|
+
} // Render leaves
|
|
182
|
+
|
|
183
|
+
|
|
177
184
|
if (params.rowNode.groupingField == null) {
|
|
178
185
|
if (leafColDef) {
|
|
179
186
|
const leafParams = (0, _extends2.default)({}, params.api.getCellParams(params.id, leafField), {
|
|
@@ -275,7 +282,12 @@ const createGroupingColDefForAllGroupingCriteria = ({
|
|
|
275
282
|
return ((_columnsLookup$field$ = columnsLookup[field].width) != null ? _columnsLookup$field$ : _xDataGridPro.GRID_STRING_COL_DEF.width) + 40;
|
|
276
283
|
}), (_leafColDef$width2 = leafColDef == null ? void 0 : leafColDef.width) != null ? _leafColDef$width2 : 0),
|
|
277
284
|
renderCell: params => {
|
|
278
|
-
// Render
|
|
285
|
+
// Render footer
|
|
286
|
+
if (params.rowNode.position === 'footer') {
|
|
287
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridGroupingColumnFooterCell.GridGroupingColumnFooterCell, (0, _extends2.default)({}, params));
|
|
288
|
+
} // Render the leaves
|
|
289
|
+
|
|
290
|
+
|
|
279
291
|
if (params.rowNode.groupingField == null) {
|
|
280
292
|
if (leafColDef) {
|
|
281
293
|
const leafParams = (0, _extends2.default)({}, params.api.getCellParams(params.id, leafField), {
|
|
@@ -101,13 +101,17 @@ const filterRowTreeFromGroupingColumns = params => {
|
|
|
101
101
|
visibleRowsLookup[node.id] = shouldPassFilters && areAncestorsExpanded;
|
|
102
102
|
filteredRowsLookup[node.id] = shouldPassFilters;
|
|
103
103
|
|
|
104
|
+
if (node.footerId != null) {
|
|
105
|
+
visibleRowsLookup[node.footerId] = shouldPassFilters && areAncestorsExpanded && !!node.childrenExpanded;
|
|
106
|
+
}
|
|
107
|
+
|
|
104
108
|
if (!shouldPassFilters) {
|
|
105
109
|
return 0;
|
|
106
110
|
}
|
|
107
111
|
|
|
108
112
|
filteredDescendantCountLookup[node.id] = filteredDescendantCount;
|
|
109
113
|
|
|
110
|
-
if (!node.children) {
|
|
114
|
+
if (!node.children && !node.isAutoGenerated) {
|
|
111
115
|
return filteredDescendantCount + 1;
|
|
112
116
|
}
|
|
113
117
|
|