@mui/x-data-grid-premium 5.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4052 -0
- package/DataGridPremium/DataGridPremium.d.ts +9 -0
- package/DataGridPremium/DataGridPremium.js +986 -0
- package/DataGridPremium/index.d.ts +2 -0
- package/DataGridPremium/index.js +2 -0
- package/DataGridPremium/package.json +6 -0
- package/DataGridPremium/useDataGridPremiumComponent.d.ts +4 -0
- package/DataGridPremium/useDataGridPremiumComponent.js +78 -0
- package/DataGridPremium/useDataGridPremiumProps.d.ts +6 -0
- package/DataGridPremium/useDataGridPremiumProps.js +37 -0
- package/LICENSE +12 -0
- package/README.md +31 -0
- package/components/GridExcelExportMenuItem.d.ts +9 -0
- package/components/GridExcelExportMenuItem.js +32 -0
- package/components/GridGroupingColumnLeafCell.d.ts +4 -0
- package/components/GridGroupingColumnLeafCell.js +22 -0
- package/components/GridGroupingCriteriaCell.d.ts +7 -0
- package/components/GridGroupingCriteriaCell.js +78 -0
- package/components/GridRowGroupableColumnMenuItems.d.ts +11 -0
- package/components/GridRowGroupableColumnMenuItems.js +63 -0
- package/components/GridRowGroupingColumnMenuItems.d.ts +11 -0
- package/components/GridRowGroupingColumnMenuItems.js +58 -0
- package/components/index.d.ts +1 -0
- package/components/index.js +1 -0
- package/components/package.json +6 -0
- package/hooks/features/export/gridExcelExportInterface.d.ts +58 -0
- package/hooks/features/export/gridExcelExportInterface.js +1 -0
- package/hooks/features/export/index.d.ts +1 -0
- package/hooks/features/export/index.js +1 -0
- package/hooks/features/export/serializer/excelSerializer.d.ts +14 -0
- package/hooks/features/export/serializer/excelSerializer.js +218 -0
- package/hooks/features/export/useGridExcelExport.d.ts +10 -0
- package/hooks/features/export/useGridExcelExport.js +77 -0
- package/hooks/features/index.d.ts +2 -0
- package/hooks/features/index.js +3 -0
- package/hooks/features/rowGrouping/createGroupingColDef.d.ts +42 -0
- package/hooks/features/rowGrouping/createGroupingColDef.js +318 -0
- package/hooks/features/rowGrouping/gridRowGroupingInterfaces.d.ts +37 -0
- package/hooks/features/rowGrouping/gridRowGroupingInterfaces.js +1 -0
- package/hooks/features/rowGrouping/gridRowGroupingSelector.d.ts +4 -0
- package/hooks/features/rowGrouping/gridRowGroupingSelector.js +5 -0
- package/hooks/features/rowGrouping/gridRowGroupingUtils.d.ts +27 -0
- package/hooks/features/rowGrouping/gridRowGroupingUtils.js +139 -0
- package/hooks/features/rowGrouping/index.d.ts +3 -0
- package/hooks/features/rowGrouping/index.js +3 -0
- package/hooks/features/rowGrouping/useGridRowGrouping.d.ts +11 -0
- package/hooks/features/rowGrouping/useGridRowGrouping.js +200 -0
- package/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.d.ts +4 -0
- package/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +201 -0
- package/hooks/index.d.ts +2 -0
- package/hooks/index.js +3 -0
- package/hooks/package.json +6 -0
- package/hooks/utils/index.d.ts +1 -0
- package/hooks/utils/index.js +1 -0
- package/hooks/utils/useGridApiContext.d.ts +4 -0
- package/hooks/utils/useGridApiContext.js +2 -0
- package/hooks/utils/useGridApiRef.d.ts +4 -0
- package/hooks/utils/useGridApiRef.js +2 -0
- package/hooks/utils/useGridRootProps.d.ts +2 -0
- package/hooks/utils/useGridRootProps.js +2 -0
- package/hooks/utils/useKeepGroupedColumnsHidden.d.ts +12 -0
- package/hooks/utils/useKeepGroupedColumnsHidden.js +50 -0
- package/index.d.ts +22 -0
- package/index.js +25 -0
- package/legacy/DataGridPremium/DataGridPremium.js +986 -0
- package/legacy/DataGridPremium/index.js +2 -0
- package/legacy/DataGridPremium/useDataGridPremiumComponent.js +78 -0
- package/legacy/DataGridPremium/useDataGridPremiumProps.js +46 -0
- package/legacy/components/GridExcelExportMenuItem.js +30 -0
- package/legacy/components/GridGroupingColumnLeafCell.js +20 -0
- package/legacy/components/GridGroupingCriteriaCell.js +74 -0
- package/legacy/components/GridRowGroupableColumnMenuItems.js +61 -0
- package/legacy/components/GridRowGroupingColumnMenuItems.js +56 -0
- package/legacy/components/index.js +1 -0
- package/legacy/hooks/features/export/gridExcelExportInterface.js +1 -0
- package/legacy/hooks/features/export/index.js +1 -0
- package/legacy/hooks/features/export/serializer/excelSerializer.js +260 -0
- package/legacy/hooks/features/export/useGridExcelExport.js +111 -0
- package/legacy/hooks/features/index.js +3 -0
- package/legacy/hooks/features/rowGrouping/createGroupingColDef.js +319 -0
- package/legacy/hooks/features/rowGrouping/gridRowGroupingInterfaces.js +1 -0
- package/legacy/hooks/features/rowGrouping/gridRowGroupingSelector.js +13 -0
- package/legacy/hooks/features/rowGrouping/gridRowGroupingUtils.js +147 -0
- package/legacy/hooks/features/rowGrouping/index.js +3 -0
- package/legacy/hooks/features/rowGrouping/useGridRowGrouping.js +206 -0
- package/legacy/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +215 -0
- package/legacy/hooks/index.js +3 -0
- package/legacy/hooks/utils/index.js +1 -0
- package/legacy/hooks/utils/useGridApiContext.js +2 -0
- package/legacy/hooks/utils/useGridApiRef.js +2 -0
- package/legacy/hooks/utils/useGridRootProps.js +2 -0
- package/legacy/hooks/utils/useKeepGroupedColumnsHidden.js +50 -0
- package/legacy/index.js +25 -0
- package/legacy/models/dataGridPremiumProps.js +1 -0
- package/legacy/models/gridApiPremium.js +1 -0
- package/legacy/models/gridGroupingValueGetterParams.js +1 -0
- package/legacy/models/gridStatePremium.js +1 -0
- package/legacy/models/index.js +1 -0
- package/legacy/typeOverloads/index.js +1 -0
- package/legacy/typeOverloads/modules.js +33 -0
- package/legacy/typeOverloads/reexports.js +6 -0
- package/legacy/utils/releaseInfo.js +15 -0
- package/models/dataGridPremiumProps.d.ts +64 -0
- package/models/dataGridPremiumProps.js +1 -0
- package/models/gridApiPremium.d.ts +13 -0
- package/models/gridApiPremium.js +1 -0
- package/models/gridGroupingValueGetterParams.d.ts +31 -0
- package/models/gridGroupingValueGetterParams.js +1 -0
- package/models/gridStatePremium.d.ts +14 -0
- package/models/gridStatePremium.js +1 -0
- package/models/index.d.ts +1 -0
- package/models/index.js +1 -0
- package/models/package.json +6 -0
- package/modern/DataGridPremium/DataGridPremium.js +986 -0
- package/modern/DataGridPremium/index.js +2 -0
- package/modern/DataGridPremium/useDataGridPremiumComponent.js +76 -0
- package/modern/DataGridPremium/useDataGridPremiumProps.js +37 -0
- package/modern/components/GridExcelExportMenuItem.js +32 -0
- package/modern/components/GridGroupingColumnLeafCell.js +20 -0
- package/modern/components/GridGroupingCriteriaCell.js +76 -0
- package/modern/components/GridRowGroupableColumnMenuItems.js +61 -0
- package/modern/components/GridRowGroupingColumnMenuItems.js +56 -0
- package/modern/components/index.js +1 -0
- package/modern/hooks/features/export/gridExcelExportInterface.js +1 -0
- package/modern/hooks/features/export/index.js +1 -0
- package/modern/hooks/features/export/serializer/excelSerializer.js +216 -0
- package/modern/hooks/features/export/useGridExcelExport.js +73 -0
- package/modern/hooks/features/index.js +3 -0
- package/modern/hooks/features/rowGrouping/createGroupingColDef.js +302 -0
- package/modern/hooks/features/rowGrouping/gridRowGroupingInterfaces.js +1 -0
- package/modern/hooks/features/rowGrouping/gridRowGroupingSelector.js +5 -0
- package/modern/hooks/features/rowGrouping/gridRowGroupingUtils.js +137 -0
- package/modern/hooks/features/rowGrouping/index.js +3 -0
- package/modern/hooks/features/rowGrouping/useGridRowGrouping.js +192 -0
- package/modern/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +201 -0
- package/modern/hooks/index.js +3 -0
- package/modern/hooks/utils/index.js +1 -0
- package/modern/hooks/utils/useGridApiContext.js +2 -0
- package/modern/hooks/utils/useGridApiRef.js +2 -0
- package/modern/hooks/utils/useGridRootProps.js +2 -0
- package/modern/hooks/utils/useKeepGroupedColumnsHidden.js +46 -0
- package/modern/index.js +25 -0
- package/modern/models/dataGridPremiumProps.js +1 -0
- package/modern/models/gridApiPremium.js +1 -0
- package/modern/models/gridGroupingValueGetterParams.js +1 -0
- package/modern/models/gridStatePremium.js +1 -0
- package/modern/models/index.js +1 -0
- package/modern/typeOverloads/index.js +1 -0
- package/modern/typeOverloads/modules.js +33 -0
- package/modern/typeOverloads/reexports.js +6 -0
- package/modern/utils/releaseInfo.js +15 -0
- package/node/DataGridPremium/DataGridPremium.js +1009 -0
- package/node/DataGridPremium/index.js +30 -0
- package/node/DataGridPremium/useDataGridPremiumComponent.js +91 -0
- package/node/DataGridPremium/useDataGridPremiumProps.js +57 -0
- package/node/components/GridExcelExportMenuItem.js +49 -0
- package/node/components/GridGroupingColumnLeafCell.js +38 -0
- package/node/components/GridGroupingCriteriaCell.js +99 -0
- package/node/components/GridRowGroupableColumnMenuItems.js +82 -0
- package/node/components/GridRowGroupingColumnMenuItems.js +78 -0
- package/node/components/index.js +18 -0
- package/node/hooks/features/export/gridExcelExportInterface.js +5 -0
- package/node/hooks/features/export/index.js +18 -0
- package/node/hooks/features/export/serializer/excelSerializer.js +233 -0
- package/node/hooks/features/export/useGridExcelExport.js +95 -0
- package/node/hooks/features/index.js +31 -0
- package/node/hooks/features/rowGrouping/createGroupingColDef.js +341 -0
- package/node/hooks/features/rowGrouping/gridRowGroupingInterfaces.js +5 -0
- package/node/hooks/features/rowGrouping/gridRowGroupingSelector.js +18 -0
- package/node/hooks/features/rowGrouping/gridRowGroupingUtils.js +172 -0
- package/node/hooks/features/rowGrouping/index.js +51 -0
- package/node/hooks/features/rowGrouping/useGridRowGrouping.js +228 -0
- package/node/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +223 -0
- package/node/hooks/index.js +31 -0
- package/node/hooks/utils/index.js +18 -0
- package/node/hooks/utils/useGridApiContext.js +11 -0
- package/node/hooks/utils/useGridApiRef.js +11 -0
- package/node/hooks/utils/useGridRootProps.js +11 -0
- package/node/hooks/utils/useKeepGroupedColumnsHidden.js +66 -0
- package/node/index.js +272 -0
- package/node/models/dataGridPremiumProps.js +5 -0
- package/node/models/gridApiPremium.js +5 -0
- package/node/models/gridGroupingValueGetterParams.js +5 -0
- package/node/models/gridStatePremium.js +5 -0
- package/node/models/index.js +18 -0
- package/node/typeOverloads/index.js +3 -0
- package/node/typeOverloads/modules.js +34 -0
- package/node/typeOverloads/reexports.js +29 -0
- package/node/utils/releaseInfo.js +25 -0
- package/package.json +63 -0
- package/typeOverloads/index.d.ts +1 -0
- package/typeOverloads/index.js +1 -0
- package/typeOverloads/modules.d.ts +0 -0
- package/typeOverloads/modules.js +33 -0
- package/typeOverloads/package.json +6 -0
- package/typeOverloads/reexports.d.ts +22 -0
- package/typeOverloads/reexports.js +6 -0
- package/utils/releaseInfo.d.ts +1 -0
- package/utils/releaseInfo.js +15 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { useGridApiMethod, useGridLogger } from '@mui/x-data-grid';
|
|
6
|
+
import { useGridRegisterPipeProcessor, exportAs, getColumnsToExport, defaultGetRowsToExport } from '@mui/x-data-grid/internals';
|
|
7
|
+
import { buildExcel } from './serializer/excelSerializer';
|
|
8
|
+
import { GridExcelExportMenuItem } from '../../../components';
|
|
9
|
+
/**
|
|
10
|
+
* @requires useGridColumns (state)
|
|
11
|
+
* @requires useGridFilter (state)
|
|
12
|
+
* @requires useGridSorting (state)
|
|
13
|
+
* @requires useGridSelection (state)
|
|
14
|
+
* @requires useGridParamsApi (method)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
18
|
+
export var useGridExcelExport = function useGridExcelExport(apiRef) {
|
|
19
|
+
var logger = useGridLogger(apiRef, 'useGridExcelExport');
|
|
20
|
+
var getDataAsExcel = React.useCallback(function () {
|
|
21
|
+
var _options$getRowsToExp, _options$includeHeade;
|
|
22
|
+
|
|
23
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
24
|
+
logger.debug("Get data as excel");
|
|
25
|
+
var getRowsToExport = (_options$getRowsToExp = options.getRowsToExport) != null ? _options$getRowsToExp : defaultGetRowsToExport;
|
|
26
|
+
var exportedRowIds = getRowsToExport({
|
|
27
|
+
apiRef: apiRef
|
|
28
|
+
});
|
|
29
|
+
var exportedColumns = getColumnsToExport({
|
|
30
|
+
apiRef: apiRef,
|
|
31
|
+
options: options
|
|
32
|
+
});
|
|
33
|
+
return buildExcel({
|
|
34
|
+
columns: exportedColumns,
|
|
35
|
+
rowIds: exportedRowIds,
|
|
36
|
+
includeHeaders: (_options$includeHeade = options.includeHeaders) != null ? _options$includeHeade : true,
|
|
37
|
+
valueOptionsSheetName: (options == null ? void 0 : options.valueOptionsSheetName) || 'Options',
|
|
38
|
+
columnsStyles: options == null ? void 0 : options.columnsStyles,
|
|
39
|
+
exceljsPreProcess: options == null ? void 0 : options.exceljsPreProcess,
|
|
40
|
+
exceljsPostProcess: options == null ? void 0 : options.exceljsPostProcess
|
|
41
|
+
}, apiRef.current);
|
|
42
|
+
}, [logger, apiRef]);
|
|
43
|
+
var exportDataAsExcel = React.useCallback( /*#__PURE__*/function () {
|
|
44
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(options) {
|
|
45
|
+
var workbook, content, blob;
|
|
46
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
47
|
+
while (1) {
|
|
48
|
+
switch (_context.prev = _context.next) {
|
|
49
|
+
case 0:
|
|
50
|
+
logger.debug("Export data as excel");
|
|
51
|
+
_context.next = 3;
|
|
52
|
+
return getDataAsExcel(options);
|
|
53
|
+
|
|
54
|
+
case 3:
|
|
55
|
+
workbook = _context.sent;
|
|
56
|
+
|
|
57
|
+
if (!(workbook === null)) {
|
|
58
|
+
_context.next = 6;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return _context.abrupt("return");
|
|
63
|
+
|
|
64
|
+
case 6:
|
|
65
|
+
_context.next = 8;
|
|
66
|
+
return workbook.xlsx.writeBuffer();
|
|
67
|
+
|
|
68
|
+
case 8:
|
|
69
|
+
content = _context.sent;
|
|
70
|
+
blob = new Blob([content], {
|
|
71
|
+
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
72
|
+
});
|
|
73
|
+
exportAs(blob, 'xlsx', options == null ? void 0 : options.fileName);
|
|
74
|
+
|
|
75
|
+
case 11:
|
|
76
|
+
case "end":
|
|
77
|
+
return _context.stop();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}, _callee);
|
|
81
|
+
}));
|
|
82
|
+
|
|
83
|
+
return function (_x) {
|
|
84
|
+
return _ref.apply(this, arguments);
|
|
85
|
+
};
|
|
86
|
+
}(), [logger, getDataAsExcel]);
|
|
87
|
+
var excelExportApi = {
|
|
88
|
+
getDataAsExcel: getDataAsExcel,
|
|
89
|
+
exportDataAsExcel: exportDataAsExcel
|
|
90
|
+
};
|
|
91
|
+
useGridApiMethod(apiRef, excelExportApi, 'GridExcelExportApi');
|
|
92
|
+
/**
|
|
93
|
+
* PRE-PROCESSING
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
var addExportMenuButtons = React.useCallback(function (initialValue, options) {
|
|
97
|
+
var _options$excelOptions;
|
|
98
|
+
|
|
99
|
+
if ((_options$excelOptions = options.excelOptions) != null && _options$excelOptions.disableToolbarButton) {
|
|
100
|
+
return initialValue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return [].concat(_toConsumableArray(initialValue), [{
|
|
104
|
+
component: /*#__PURE__*/_jsx(GridExcelExportMenuItem, {
|
|
105
|
+
options: options.excelOptions
|
|
106
|
+
}),
|
|
107
|
+
componentName: 'excelExport'
|
|
108
|
+
}]);
|
|
109
|
+
}, []);
|
|
110
|
+
useGridRegisterPipeProcessor(apiRef, 'exportMenu', addExportMenuButtons);
|
|
111
|
+
};
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
3
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
|
+
var _excluded = ["leafField", "mainGroupingCriteria", "hideDescendantCount"],
|
|
5
|
+
_excluded2 = ["leafField", "mainGroupingCriteria", "hideDescendantCount"];
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import { GRID_STRING_COL_DEF } from '@mui/x-data-grid-pro';
|
|
8
|
+
import { GridGroupingCriteriaCell } from '../../../components/GridGroupingCriteriaCell';
|
|
9
|
+
import { GridGroupingColumnLeafCell } from '../../../components/GridGroupingColumnLeafCell';
|
|
10
|
+
import { getRowGroupingFieldFromGroupingCriteria, GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD } from './gridRowGroupingUtils';
|
|
11
|
+
import { gridRowGroupingSanitizedModelSelector } from './gridRowGroupingSelector';
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
|
|
14
|
+
var GROUPING_COL_DEF_DEFAULT_PROPERTIES = _extends({}, GRID_STRING_COL_DEF, {
|
|
15
|
+
disableReorder: true
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
var GROUPING_COL_DEF_FORCED_PROPERTIES = {
|
|
19
|
+
type: 'rowGroupByColumnsGroup',
|
|
20
|
+
editable: false,
|
|
21
|
+
groupable: false
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* When sorting two cells with different grouping criteria, we consider that the cell with the grouping criteria coming first in the model should be displayed below.
|
|
25
|
+
* This can occur when some rows don't have all the fields. In which case we want the rows with the missing field to be displayed above.
|
|
26
|
+
* TODO: Make this index comparator depth invariant, the logic should not be inverted when sorting in the "desc" direction (but the current return format of `sortComparator` does not support this behavior).
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
var groupingFieldIndexComparator = function groupingFieldIndexComparator(v1, v2, cellParams1, cellParams2) {
|
|
30
|
+
var model = gridRowGroupingSanitizedModelSelector(cellParams1.api.state, cellParams1.api.instanceId);
|
|
31
|
+
var groupingField1 = cellParams1.rowNode.groupingField;
|
|
32
|
+
var groupingField2 = cellParams2.rowNode.groupingField;
|
|
33
|
+
|
|
34
|
+
if (groupingField1 === groupingField2) {
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (groupingField1 == null) {
|
|
39
|
+
return -1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (groupingField2 == null) {
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (model.indexOf(groupingField1) < model.indexOf(groupingField2)) {
|
|
47
|
+
return -1;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return 1;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
var getLeafProperties = function getLeafProperties(leafColDef) {
|
|
54
|
+
var _leafColDef$headerNam, _leafColDef$filterOpe;
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
headerName: (_leafColDef$headerNam = leafColDef.headerName) != null ? _leafColDef$headerNam : leafColDef.field,
|
|
58
|
+
sortable: leafColDef.sortable,
|
|
59
|
+
filterable: leafColDef.filterable,
|
|
60
|
+
filterOperators: (_leafColDef$filterOpe = leafColDef.filterOperators) == null ? void 0 : _leafColDef$filterOpe.map(function (operator) {
|
|
61
|
+
return _extends({}, operator, {
|
|
62
|
+
getApplyFilterFn: function getApplyFilterFn(filterItem, column) {
|
|
63
|
+
var originalFn = operator.getApplyFilterFn(filterItem, column);
|
|
64
|
+
|
|
65
|
+
if (!originalFn) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return function (params) {
|
|
70
|
+
// We only want to filter leaves
|
|
71
|
+
if (params.rowNode.groupingField != null) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return originalFn(params);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}),
|
|
80
|
+
sortComparator: function sortComparator(v1, v2, cellParams1, cellParams2) {
|
|
81
|
+
// We only want to sort the leaves
|
|
82
|
+
if (cellParams1.rowNode.groupingField === null && cellParams2.rowNode.groupingField === null) {
|
|
83
|
+
return leafColDef.sortComparator(v1, v2, cellParams1, cellParams2);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return groupingFieldIndexComparator(v1, v2, cellParams1, cellParams2);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
var getGroupingCriteriaProperties = function getGroupingCriteriaProperties(groupedByColDef, applyHeaderName) {
|
|
92
|
+
var _groupedByColDef$filt;
|
|
93
|
+
|
|
94
|
+
var properties = {
|
|
95
|
+
sortable: groupedByColDef.sortable,
|
|
96
|
+
filterable: groupedByColDef.filterable,
|
|
97
|
+
sortComparator: function sortComparator(v1, v2, cellParams1, cellParams2) {
|
|
98
|
+
// We only want to sort the groups of the current grouping criteria
|
|
99
|
+
if (cellParams1.rowNode.groupingField === groupedByColDef.field && cellParams2.rowNode.groupingField === groupedByColDef.field) {
|
|
100
|
+
return groupedByColDef.sortComparator(v1, v2, cellParams1, cellParams2);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return groupingFieldIndexComparator(v1, v2, cellParams1, cellParams2);
|
|
104
|
+
},
|
|
105
|
+
filterOperators: (_groupedByColDef$filt = groupedByColDef.filterOperators) == null ? void 0 : _groupedByColDef$filt.map(function (operator) {
|
|
106
|
+
return _extends({}, operator, {
|
|
107
|
+
getApplyFilterFn: function getApplyFilterFn(filterItem, column) {
|
|
108
|
+
var originalFn = operator.getApplyFilterFn(filterItem, column);
|
|
109
|
+
|
|
110
|
+
if (!originalFn) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return function (params) {
|
|
115
|
+
// We only want to filter the groups of the current grouping criteria
|
|
116
|
+
if (params.rowNode.groupingField !== groupedByColDef.field) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return originalFn(params);
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
})
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
if (applyHeaderName) {
|
|
128
|
+
var _groupedByColDef$head;
|
|
129
|
+
|
|
130
|
+
properties.headerName = (_groupedByColDef$head = groupedByColDef.headerName) != null ? _groupedByColDef$head : groupedByColDef.field;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return properties;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Creates the `GridColDef` for a grouping column that only takes care of a single grouping criteria
|
|
138
|
+
*/
|
|
139
|
+
export var createGroupingColDefForOneGroupingCriteria = function createGroupingColDefForOneGroupingCriteria(_ref) {
|
|
140
|
+
var _groupedByColDef$widt, _leafColDef$width;
|
|
141
|
+
|
|
142
|
+
var columnsLookup = _ref.columnsLookup,
|
|
143
|
+
groupedByColDef = _ref.groupedByColDef,
|
|
144
|
+
groupingCriteria = _ref.groupingCriteria,
|
|
145
|
+
colDefOverride = _ref.colDefOverride;
|
|
146
|
+
|
|
147
|
+
var _ref2 = colDefOverride != null ? colDefOverride : {},
|
|
148
|
+
leafField = _ref2.leafField,
|
|
149
|
+
mainGroupingCriteria = _ref2.mainGroupingCriteria,
|
|
150
|
+
hideDescendantCount = _ref2.hideDescendantCount,
|
|
151
|
+
colDefOverrideProperties = _objectWithoutProperties(_ref2, _excluded);
|
|
152
|
+
|
|
153
|
+
var leafColDef = leafField ? columnsLookup[leafField] : null; // The properties that do not depend on the presence of a `leafColDef` and that can be overridden by `colDefOverride`
|
|
154
|
+
|
|
155
|
+
var commonProperties = {
|
|
156
|
+
width: Math.max(((_groupedByColDef$widt = groupedByColDef.width) != null ? _groupedByColDef$widt : GRID_STRING_COL_DEF.width) + 40, (_leafColDef$width = leafColDef == null ? void 0 : leafColDef.width) != null ? _leafColDef$width : 0),
|
|
157
|
+
renderCell: function renderCell(params) {
|
|
158
|
+
// Render leaves
|
|
159
|
+
if (params.rowNode.groupingField == null) {
|
|
160
|
+
if (leafColDef) {
|
|
161
|
+
var leafParams = _extends({}, params.api.getCellParams(params.id, leafField), {
|
|
162
|
+
api: params.api
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
if (leafColDef.renderCell) {
|
|
166
|
+
return leafColDef.renderCell(leafParams);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return /*#__PURE__*/_jsx(GridGroupingColumnLeafCell, _extends({}, leafParams));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return '';
|
|
173
|
+
} // Render current grouping criteria groups
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
if (params.rowNode.groupingField === groupingCriteria) {
|
|
177
|
+
return /*#__PURE__*/_jsx(GridGroupingCriteriaCell, _extends({}, params, {
|
|
178
|
+
hideDescendantCount: hideDescendantCount
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return '';
|
|
183
|
+
},
|
|
184
|
+
valueGetter: function valueGetter(params) {
|
|
185
|
+
if (!params.rowNode) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (params.rowNode.groupingField == null) {
|
|
190
|
+
if (leafColDef) {
|
|
191
|
+
return params.api.getCellValue(params.id, leafField);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (params.rowNode.groupingField === groupingCriteria) {
|
|
198
|
+
return params.rowNode.groupingKey;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
}; // If we have a `mainGroupingCriteria` defined and matching the `groupingCriteria`
|
|
204
|
+
// Then we apply the sorting / filtering on the groups of this column's grouping criteria based on the properties of `groupedByColDef`.
|
|
205
|
+
// It can be useful to define a `leafField` for leaves rendering but still use the grouping criteria for the sorting / filtering
|
|
206
|
+
//
|
|
207
|
+
// If we have a `leafField` defined and matching an existing column
|
|
208
|
+
// Then we apply the sorting / filtering on the leaves based on the properties of `leavesColDef`
|
|
209
|
+
//
|
|
210
|
+
// By default, we apply the sorting / filtering on the groups of this column's grouping criteria based on the properties of `groupedColDef`.
|
|
211
|
+
|
|
212
|
+
var sourceProperties;
|
|
213
|
+
|
|
214
|
+
if (mainGroupingCriteria && mainGroupingCriteria === groupingCriteria) {
|
|
215
|
+
sourceProperties = getGroupingCriteriaProperties(groupedByColDef, true);
|
|
216
|
+
} else if (leafColDef) {
|
|
217
|
+
sourceProperties = getLeafProperties(leafColDef);
|
|
218
|
+
} else {
|
|
219
|
+
sourceProperties = getGroupingCriteriaProperties(groupedByColDef, true);
|
|
220
|
+
} // The properties that can't be overridden with `colDefOverride`
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
var forcedProperties = _extends({
|
|
224
|
+
field: getRowGroupingFieldFromGroupingCriteria(groupingCriteria)
|
|
225
|
+
}, GROUPING_COL_DEF_FORCED_PROPERTIES);
|
|
226
|
+
|
|
227
|
+
return _extends({}, GROUPING_COL_DEF_DEFAULT_PROPERTIES, commonProperties, sourceProperties, colDefOverrideProperties, forcedProperties);
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Creates the `GridColDef` for a grouping column that takes care of all the grouping criteria
|
|
232
|
+
*/
|
|
233
|
+
export var createGroupingColDefForAllGroupingCriteria = function createGroupingColDefForAllGroupingCriteria(_ref3) {
|
|
234
|
+
var _leafColDef$width2;
|
|
235
|
+
|
|
236
|
+
var apiRef = _ref3.apiRef,
|
|
237
|
+
columnsLookup = _ref3.columnsLookup,
|
|
238
|
+
rowGroupingModel = _ref3.rowGroupingModel,
|
|
239
|
+
colDefOverride = _ref3.colDefOverride;
|
|
240
|
+
|
|
241
|
+
var _ref4 = colDefOverride != null ? colDefOverride : {},
|
|
242
|
+
leafField = _ref4.leafField,
|
|
243
|
+
mainGroupingCriteria = _ref4.mainGroupingCriteria,
|
|
244
|
+
hideDescendantCount = _ref4.hideDescendantCount,
|
|
245
|
+
colDefOverrideProperties = _objectWithoutProperties(_ref4, _excluded2);
|
|
246
|
+
|
|
247
|
+
var leafColDef = leafField ? columnsLookup[leafField] : null; // The properties that do not depend on the presence of a `leafColDef` and that can be overridden by `colDefOverride`
|
|
248
|
+
|
|
249
|
+
var commonProperties = {
|
|
250
|
+
headerName: apiRef.current.getLocaleText('groupingColumnHeaderName'),
|
|
251
|
+
width: Math.max.apply(Math, _toConsumableArray(rowGroupingModel.map(function (field) {
|
|
252
|
+
var _columnsLookup$field$;
|
|
253
|
+
|
|
254
|
+
return ((_columnsLookup$field$ = columnsLookup[field].width) != null ? _columnsLookup$field$ : GRID_STRING_COL_DEF.width) + 40;
|
|
255
|
+
})).concat([(_leafColDef$width2 = leafColDef == null ? void 0 : leafColDef.width) != null ? _leafColDef$width2 : 0])),
|
|
256
|
+
renderCell: function renderCell(params) {
|
|
257
|
+
// Render the leaves
|
|
258
|
+
if (params.rowNode.groupingField == null) {
|
|
259
|
+
if (leafColDef) {
|
|
260
|
+
var leafParams = _extends({}, params.api.getCellParams(params.id, leafField), {
|
|
261
|
+
api: params.api
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
if (leafColDef.renderCell) {
|
|
265
|
+
return leafColDef.renderCell(leafParams);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return /*#__PURE__*/_jsx(GridGroupingColumnLeafCell, _extends({}, leafParams));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return '';
|
|
272
|
+
} // Render the groups
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
return /*#__PURE__*/_jsx(GridGroupingCriteriaCell, _extends({}, params, {
|
|
276
|
+
hideDescendantCount: hideDescendantCount
|
|
277
|
+
}));
|
|
278
|
+
},
|
|
279
|
+
valueGetter: function valueGetter(params) {
|
|
280
|
+
if (!params.rowNode) {
|
|
281
|
+
return undefined;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (params.rowNode.groupingField == null) {
|
|
285
|
+
if (leafColDef) {
|
|
286
|
+
return params.api.getCellValue(params.id, leafField);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return undefined;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return params.rowNode.groupingKey;
|
|
293
|
+
}
|
|
294
|
+
}; // If we have a `mainGroupingCriteria` defined and matching one of the `orderedGroupedByFields`
|
|
295
|
+
// Then we apply the sorting / filtering on the groups of this column's grouping criteria based on the properties of `columnsLookup[mainGroupingCriteria]`.
|
|
296
|
+
// It can be useful to use another grouping criteria than the top level one for the sorting / filtering
|
|
297
|
+
//
|
|
298
|
+
// If we have a `leafField` defined and matching an existing column
|
|
299
|
+
// Then we apply the sorting / filtering on the leaves based on the properties of `leavesColDef`
|
|
300
|
+
//
|
|
301
|
+
// By default, we apply the sorting / filtering on the groups of the top level grouping criteria based on the properties of `columnsLookup[orderedGroupedByFields[0]]`.
|
|
302
|
+
|
|
303
|
+
var sourceProperties;
|
|
304
|
+
|
|
305
|
+
if (mainGroupingCriteria && rowGroupingModel.includes(mainGroupingCriteria)) {
|
|
306
|
+
sourceProperties = getGroupingCriteriaProperties(columnsLookup[mainGroupingCriteria], true);
|
|
307
|
+
} else if (leafColDef) {
|
|
308
|
+
sourceProperties = getLeafProperties(leafColDef);
|
|
309
|
+
} else {
|
|
310
|
+
sourceProperties = getGroupingCriteriaProperties(columnsLookup[rowGroupingModel[0]], rowGroupingModel.length === 1);
|
|
311
|
+
} // The properties that can't be overridden with `colDefOverride`
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
var forcedProperties = _extends({
|
|
315
|
+
field: GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD
|
|
316
|
+
}, GROUPING_COL_DEF_FORCED_PROPERTIES);
|
|
317
|
+
|
|
318
|
+
return _extends({}, GROUPING_COL_DEF_DEFAULT_PROPERTIES, commonProperties, sourceProperties, colDefOverrideProperties, forcedProperties);
|
|
319
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { gridColumnLookupSelector } from '@mui/x-data-grid-pro';
|
|
2
|
+
import { createSelector } from '@mui/x-data-grid-pro/internals';
|
|
3
|
+
export var gridRowGroupingStateSelector = function gridRowGroupingStateSelector(state) {
|
|
4
|
+
return state.rowGrouping;
|
|
5
|
+
};
|
|
6
|
+
export var gridRowGroupingModelSelector = createSelector(gridRowGroupingStateSelector, function (rowGrouping) {
|
|
7
|
+
return rowGrouping.model;
|
|
8
|
+
});
|
|
9
|
+
export var gridRowGroupingSanitizedModelSelector = createSelector(gridRowGroupingModelSelector, gridColumnLookupSelector, function (model, columnsLookup) {
|
|
10
|
+
return model.filter(function (field) {
|
|
11
|
+
return !!columnsLookup[field] && columnsLookup[field].groupable;
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import { gridRowGroupingSanitizedModelSelector } from './gridRowGroupingSelector';
|
|
3
|
+
export var GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD = '__row_group_by_columns_group__';
|
|
4
|
+
export var ROW_GROUPING_STRATEGY = 'grouping-columns';
|
|
5
|
+
export var getRowGroupingFieldFromGroupingCriteria = function getRowGroupingFieldFromGroupingCriteria(groupingCriteria) {
|
|
6
|
+
if (groupingCriteria === null) {
|
|
7
|
+
return GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return "__row_group_by_columns_group_".concat(groupingCriteria, "__");
|
|
11
|
+
};
|
|
12
|
+
export var getRowGroupingCriteriaFromGroupingField = function getRowGroupingCriteriaFromGroupingField(groupingColDefField) {
|
|
13
|
+
var match = groupingColDefField.match(/^__row_group_by_columns_group_(.*)__$/);
|
|
14
|
+
|
|
15
|
+
if (!match) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return match[1];
|
|
20
|
+
};
|
|
21
|
+
export var isGroupingColumn = function isGroupingColumn(field) {
|
|
22
|
+
return field === GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD || getRowGroupingCriteriaFromGroupingField(field) !== null;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* When filtering a group, we only want to filter according to the items related to this grouping column.
|
|
27
|
+
*/
|
|
28
|
+
var shouldApplyFilterItemOnGroup = function shouldApplyFilterItemOnGroup(columnField, node) {
|
|
29
|
+
if (columnField === GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
var groupingCriteriaField = getRowGroupingCriteriaFromGroupingField(columnField);
|
|
34
|
+
return groupingCriteriaField === node.groupingField;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* A leaf is visible if it passed the filter
|
|
38
|
+
* A group is visible if all the following criteria are met:
|
|
39
|
+
* - One of its children is passing the filter
|
|
40
|
+
* - It is passing the filter
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
export var filterRowTreeFromGroupingColumns = function filterRowTreeFromGroupingColumns(params) {
|
|
45
|
+
var rowTree = params.rowTree,
|
|
46
|
+
isRowMatchingFilters = params.isRowMatchingFilters;
|
|
47
|
+
var visibleRowsLookup = {};
|
|
48
|
+
var filteredRowsLookup = {};
|
|
49
|
+
var filteredDescendantCountLookup = {};
|
|
50
|
+
|
|
51
|
+
var filterTreeNode = function filterTreeNode(node, areAncestorsPassingChildren, areAncestorsExpanded) {
|
|
52
|
+
var _node$children, _node$children2;
|
|
53
|
+
|
|
54
|
+
var isMatchingFilters;
|
|
55
|
+
|
|
56
|
+
if (!isRowMatchingFilters) {
|
|
57
|
+
isMatchingFilters = true;
|
|
58
|
+
} else {
|
|
59
|
+
var shouldApplyItem = node.isAutoGenerated ? function (columnField) {
|
|
60
|
+
return shouldApplyFilterItemOnGroup(columnField, node);
|
|
61
|
+
} : undefined;
|
|
62
|
+
isMatchingFilters = isRowMatchingFilters(node.id, shouldApplyItem);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var filteredDescendantCount = 0;
|
|
66
|
+
(_node$children = node.children) == null ? void 0 : _node$children.forEach(function (childId) {
|
|
67
|
+
var childNode = rowTree[childId];
|
|
68
|
+
var childSubTreeSize = filterTreeNode(childNode, areAncestorsPassingChildren && isMatchingFilters, areAncestorsExpanded && !!node.childrenExpanded);
|
|
69
|
+
filteredDescendantCount += childSubTreeSize;
|
|
70
|
+
});
|
|
71
|
+
var shouldPassFilters;
|
|
72
|
+
|
|
73
|
+
if (!areAncestorsPassingChildren) {
|
|
74
|
+
shouldPassFilters = false;
|
|
75
|
+
} else if ((_node$children2 = node.children) != null && _node$children2.length) {
|
|
76
|
+
shouldPassFilters = isMatchingFilters && filteredDescendantCount > 0;
|
|
77
|
+
} else {
|
|
78
|
+
shouldPassFilters = isMatchingFilters;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
visibleRowsLookup[node.id] = shouldPassFilters && areAncestorsExpanded;
|
|
82
|
+
filteredRowsLookup[node.id] = shouldPassFilters;
|
|
83
|
+
|
|
84
|
+
if (!shouldPassFilters) {
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
filteredDescendantCountLookup[node.id] = filteredDescendantCount;
|
|
89
|
+
|
|
90
|
+
if (!node.children) {
|
|
91
|
+
return filteredDescendantCount + 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return filteredDescendantCount;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
var nodes = Object.values(rowTree);
|
|
98
|
+
|
|
99
|
+
for (var i = 0; i < nodes.length; i += 1) {
|
|
100
|
+
var node = nodes[i];
|
|
101
|
+
|
|
102
|
+
if (node.depth === 0) {
|
|
103
|
+
filterTreeNode(node, true, true);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
visibleRowsLookup: visibleRowsLookup,
|
|
109
|
+
filteredRowsLookup: filteredRowsLookup,
|
|
110
|
+
filteredDescendantCountLookup: filteredDescendantCountLookup
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
export var getColDefOverrides = function getColDefOverrides(groupingColDefProp, fields) {
|
|
114
|
+
if (typeof groupingColDefProp === 'function') {
|
|
115
|
+
return groupingColDefProp({
|
|
116
|
+
groupingName: ROW_GROUPING_STRATEGY,
|
|
117
|
+
fields: fields
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return groupingColDefProp;
|
|
122
|
+
};
|
|
123
|
+
export var mergeStateWithRowGroupingModel = function mergeStateWithRowGroupingModel(rowGroupingModel) {
|
|
124
|
+
return function (state) {
|
|
125
|
+
return _extends({}, state, {
|
|
126
|
+
rowGrouping: _extends({}, state.rowGrouping, {
|
|
127
|
+
model: rowGroupingModel
|
|
128
|
+
})
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
export var setStrategyAvailability = function setStrategyAvailability(apiRef, disableRowGrouping) {
|
|
133
|
+
var isAvailable;
|
|
134
|
+
|
|
135
|
+
if (disableRowGrouping) {
|
|
136
|
+
isAvailable = function isAvailable() {
|
|
137
|
+
return false;
|
|
138
|
+
};
|
|
139
|
+
} else {
|
|
140
|
+
isAvailable = function isAvailable() {
|
|
141
|
+
var rowGroupingSanitizedModel = gridRowGroupingSanitizedModelSelector(apiRef);
|
|
142
|
+
return rowGroupingSanitizedModel.length > 0;
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
apiRef.current.unstable_setStrategyAvailability('rowTree', ROW_GROUPING_STRATEGY, isAvailable);
|
|
147
|
+
};
|