@mui/x-data-grid-pro 5.6.1 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +71 -1
  2. package/DataGridPro/DataGridPro.js +20 -15
  3. package/DataGridPro/useDataGridProComponent.js +12 -10
  4. package/components/DataGridProColumnHeaders.js +10 -10
  5. package/components/DataGridProVirtualScroller.js +6 -6
  6. package/hooks/features/rowGrouping/gridRowGroupingInterfaces.d.ts +6 -0
  7. package/hooks/features/rowGrouping/gridRowGroupingUtils.d.ts +4 -1
  8. package/hooks/features/rowGrouping/gridRowGroupingUtils.js +18 -3
  9. package/hooks/features/rowGrouping/useGridRowGrouping.js +44 -165
  10. package/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.d.ts +1 -1
  11. package/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +130 -3
  12. package/hooks/features/treeData/gridTreeDataUtils.d.ts +1 -0
  13. package/hooks/features/treeData/gridTreeDataUtils.js +2 -0
  14. package/hooks/features/treeData/useGridTreeData.d.ts +1 -5
  15. package/hooks/features/treeData/useGridTreeData.js +3 -82
  16. package/hooks/features/treeData/useGridTreeDataPreProcessors.d.ts +1 -1
  17. package/hooks/features/treeData/useGridTreeDataPreProcessors.js +72 -3
  18. package/index.js +1 -1
  19. package/legacy/DataGridPro/DataGridPro.js +20 -15
  20. package/legacy/DataGridPro/useDataGridProComponent.js +12 -10
  21. package/legacy/components/DataGridProColumnHeaders.js +10 -10
  22. package/legacy/components/DataGridProVirtualScroller.js +6 -6
  23. package/legacy/hooks/features/rowGrouping/gridRowGroupingUtils.js +19 -2
  24. package/legacy/hooks/features/rowGrouping/useGridRowGrouping.js +46 -170
  25. package/legacy/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +137 -3
  26. package/legacy/hooks/features/treeData/gridTreeDataUtils.js +2 -0
  27. package/legacy/hooks/features/treeData/useGridTreeData.js +3 -90
  28. package/legacy/hooks/features/treeData/useGridTreeDataPreProcessors.js +84 -3
  29. package/legacy/index.js +1 -1
  30. package/legacy/utils/releaseInfo.js +15 -0
  31. package/modern/DataGridPro/DataGridPro.js +20 -15
  32. package/modern/DataGridPro/useDataGridProComponent.js +10 -10
  33. package/modern/components/DataGridProColumnHeaders.js +10 -10
  34. package/modern/components/DataGridProVirtualScroller.js +6 -6
  35. package/modern/hooks/features/rowGrouping/gridRowGroupingUtils.js +18 -3
  36. package/modern/hooks/features/rowGrouping/useGridRowGrouping.js +44 -165
  37. package/modern/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +130 -3
  38. package/modern/hooks/features/treeData/gridTreeDataUtils.js +2 -0
  39. package/modern/hooks/features/treeData/useGridTreeData.js +3 -82
  40. package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +72 -3
  41. package/modern/index.js +1 -1
  42. package/modern/utils/releaseInfo.js +15 -0
  43. package/node/DataGridPro/DataGridPro.js +18 -14
  44. package/node/DataGridPro/useDataGridProComponent.js +12 -10
  45. package/node/components/DataGridProColumnHeaders.js +10 -10
  46. package/node/components/DataGridProVirtualScroller.js +6 -6
  47. package/node/hooks/features/rowGrouping/gridRowGroupingUtils.js +24 -5
  48. package/node/hooks/features/rowGrouping/useGridRowGrouping.js +40 -163
  49. package/node/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +133 -0
  50. package/node/hooks/features/treeData/gridTreeDataUtils.js +5 -2
  51. package/node/hooks/features/treeData/useGridTreeData.js +2 -91
  52. package/node/hooks/features/treeData/useGridTreeDataPreProcessors.js +74 -2
  53. package/node/index.js +1 -1
  54. package/node/utils/releaseInfo.js +25 -0
  55. package/package.json +3 -3
  56. package/utils/releaseInfo.d.ts +1 -0
  57. package/utils/releaseInfo.js +15 -0
  58. package/utils/tree/buildRowTree.d.ts +3 -3
  59. package/components/Watermark.d.ts +0 -2
  60. package/components/Watermark.js +0 -43
  61. package/legacy/components/Watermark.js +0 -43
  62. package/modern/components/Watermark.js +0 -43
  63. package/node/components/Watermark.js +0 -56
package/CHANGELOG.md CHANGED
@@ -3,13 +3,83 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 5.7.0
7
+
8
+ _Mar 24, 2022_
9
+
10
+ We'd like to offer a big thanks to the 12 contributors who made this release possible. Here are some highlights ✨:
11
+
12
+ - ✏ Add a new editing API with better support for server-side persistence and validation (#3963, #4060) @m4theushw
13
+
14
+ The new API is stable, but to avoid any breaking changes or conflicts with the old API, you must add the following flag to access it:
15
+
16
+ ```tsx
17
+ <DataGrid experimentalFeatures={{ newEditingApi: true }} />
18
+ ```
19
+
20
+ ⚠ Users relying on the old API (legacy) don't need to worry as it will continue to work until v6.
21
+
22
+ The new API also features brand new documentation with more useful demos and guides explaining how to create custom edit components.
23
+ Visit the new [documentation](https://mui.com/components/data-grid/editing/) for more information.
24
+
25
+ - 📚 Documentation improvements
26
+ - 🐞 Bug and typo fixes
27
+
28
+ ### `@mui/x-data-grid@v5.7.0` / `@mui/x-data-grid-pro@v5.7.0`
29
+
30
+ #### Changes
31
+
32
+ - [DataGrid] Add column order and dimensions to the portable state (#3816) @flaviendelangle
33
+ - [DataGrid] Add new editing API (#3963) @m4theushw
34
+ - [DataGrid] Allow to customize `ColumnsPanel` with `componentsProps` prop (#4207) @alexfauquette
35
+ - [DataGrid] Do not unselect row when <kbd>Shift</kbd> + click on the last selected row of a range (#4196) @flaviendelangle
36
+ - [DataGrid] Fix `showCellRightBorder` not working in the last row (#4140) @cherniavskii
37
+ - [DataGrid] Fix error overlay not visible when `autoHeight` is enabled (#4110) @cherniavskii
38
+ - [DataGrid] Fix white blank when scrolling (#4158) @alexfauquette
39
+ - [DataGrid] Adjust type of the `description` prop in `GridColumnHeaderTitle` (#4247) @baahrens
40
+ - [DataGrid] Fix focus after stopping row edit mode (#4252) @m4theushw
41
+ - [DataGridPro] Fix pinned columns edge overflow with custom `borderRadius` (#4188) @socramm9
42
+ - [DataGridPro] Fix tab switching order with pinned columns and `editMode="row"` (#4198) @cherniavskii
43
+ - [l10n] Improve Persian (fa-IR) locale (#4227) @SaeedZhiany
44
+ - [l10n] Improve Polish (pl-PL) locale (#4153) @pbmchc
45
+ - [l10n] Improve Arabic (ar-SD) locale (#4212) @shadigaafar
46
+ - [l10n] Improve Korean (ko-KR) locale (#4245) @kyeongsoosoo
47
+
48
+ ### Docs
49
+
50
+ - [docs] Clean demo (#4073) @alexfauquette
51
+ - [docs] Delete restore state demos (#4220) @flaviendelangle
52
+ - [docs] Document Print export `X-Frame-Options` limitation (#4222) @DanailH
53
+ - [docs] Add docs for the new editing API (#4060) @m4theushw
54
+ - [docs] Explain how to use `printOptions.pageStyle` (#4138) @alexfauquette
55
+ - [docs] Fix 301 links (#4165) @oliviertassinari
56
+ - [docs] Fix 404 API links (#4164) @oliviertassinari
57
+ - [docs] Fix broken anchor links (#4162) @alexfauquette
58
+ - [docs] Remove useless `apiRef` from demos (#4221) @flaviendelangle
59
+ - [docs] Sync the headers with core (#4195) @oliviertassinari
60
+
61
+ ### Core
62
+
63
+ - [core] Add CLI to decode license key (#4126) @flaviendelangle
64
+ - [core] Fix Lerna package change detection (#4202) @oliviertassinari
65
+ - [core] Implement strategy pattern for pre-processors (#4030) @flaviendelangle
66
+ - [core] Keep same reference to the column visibility model if no column has changed (#4154) @m4theushw
67
+ - [core] Prepare `@mui/x-license-pro` for date pickers (#4123) @flaviendelangle
68
+ - [core] Remove datagen from `@mui/x-data-grid-generator` bundle (#4163) @m4theushw
69
+ - [core] Remove lodash `isDeepEqual` (#4159) @flaviendelangle
70
+ - [core] Use a pipe processor for `GridPreferencePanel` children (#4216) @flaviendelangle
71
+ - [core] Add markdown documentation for contributors (#3447) @alexfauquette
72
+ - [test] Add regression test for `showCellRightBorder` (#4191) @cherniavskii
73
+ - [test] Mock `getComputedStyle` to speed up unit tests (#4142) @m4theushw
74
+ - [test] Upgrade CircleCI convenience image (#4143) @m4theushw
75
+
6
76
  ## 5.6.1
7
77
 
8
78
  _Mar 10, 2022_
9
79
 
10
80
  We'd like to offer a big thanks to the 8 contributors who made this release possible. Here are some highlights ✨:
11
81
 
12
- - [DataGrid] Allow to add margins or borders between rows (#3848) @m4theushw
82
+ - Allow to add margins or borders between rows (#3848) @m4theushw
13
83
 
14
84
  ```tsx
15
85
  <DataGrid getRowSpacing={() => ({ top: 10, bottom: 10 })} />
@@ -1,28 +1,20 @@
1
1
  import * as React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { LicenseInfo } from '@mui/x-license-pro';
4
- import { chainPropTypes, ponyfillGlobal } from '@mui/utils';
3
+ import { useLicenseVerifier, Watermark } from '@mui/x-license-pro';
4
+ import { chainPropTypes } from '@mui/utils';
5
5
  import { GridBody, GridErrorHandler, GridFooterPlaceholder, GridHeaderPlaceholder, GridRoot, GridContextProvider } from '@mui/x-data-grid';
6
6
  import { useDataGridProComponent } from './useDataGridProComponent';
7
- import { Watermark } from '../components/Watermark';
8
7
  import { useDataGridProProps } from './useDataGridProProps';
9
8
  import { DataGridProVirtualScroller } from '../components/DataGridProVirtualScroller';
10
- import { DataGridProColumnHeaders } from '../components/DataGridProColumnHeaders'; // This is the package release date. Each package version should update this const
11
- // automatically when a new version is published on npm.
12
-
9
+ import { DataGridProColumnHeaders } from '../components/DataGridProColumnHeaders';
10
+ import { getReleaseInfo } from '../utils/releaseInfo';
13
11
  import { jsx as _jsx } from "react/jsx-runtime";
14
12
  import { jsxs as _jsxs } from "react/jsx-runtime";
15
- let RELEASE_INFO = "MTY0Njg2NjgwMDAwMA=="; // eslint-disable-next-line no-useless-concat
16
-
17
- if (process.env.NODE_ENV !== 'production' && RELEASE_INFO === '__RELEASE' + '_INFO__') {
18
- // eslint-disable-next-line no-underscore-dangle
19
- RELEASE_INFO = ponyfillGlobal.__MUI_RELEASE_INFO__;
20
- }
21
-
22
- LicenseInfo.setReleaseInfo(RELEASE_INFO);
13
+ const releaseInfo = getReleaseInfo();
23
14
  const DataGridProRaw = /*#__PURE__*/React.forwardRef(function DataGridPro(inProps, ref) {
24
15
  const props = useDataGridProProps(inProps);
25
16
  const apiRef = useDataGridProComponent(props.apiRef, props);
17
+ useLicenseVerifier('x-data-grid-pro', releaseInfo);
26
18
  return /*#__PURE__*/_jsx(GridContextProvider, {
27
19
  apiRef: apiRef,
28
20
  props: props,
@@ -35,7 +27,10 @@ const DataGridProRaw = /*#__PURE__*/React.forwardRef(function DataGridPro(inProp
35
27
  children: [/*#__PURE__*/_jsx(GridHeaderPlaceholder, {}), /*#__PURE__*/_jsx(GridBody, {
36
28
  ColumnHeadersComponent: DataGridProColumnHeaders,
37
29
  VirtualScrollerComponent: DataGridProVirtualScroller,
38
- children: /*#__PURE__*/_jsx(Watermark, {})
30
+ children: /*#__PURE__*/_jsx(Watermark, {
31
+ packageName: "x-data-grid-pro",
32
+ releaseInfo: releaseInfo
33
+ })
39
34
  }), /*#__PURE__*/_jsx(GridFooterPlaceholder, {})]
40
35
  })
41
36
  })
@@ -274,6 +269,7 @@ DataGridProRaw.propTypes = {
274
269
  * For each feature, if the flag is not explicitly set to `true`, the feature will be fully disabled and any property / method call will not have any effect.
275
270
  */
276
271
  experimentalFeatures: PropTypes.shape({
272
+ newEditingApi: PropTypes.bool,
277
273
  preventCommitWhileValidating: PropTypes.bool,
278
274
  rowGrouping: PropTypes.bool,
279
275
  warnIfFocusStateIsNotSynced: PropTypes.bool
@@ -787,6 +783,15 @@ DataGridProRaw.propTypes = {
787
783
  right: PropTypes.arrayOf(PropTypes.string)
788
784
  }),
789
785
 
786
+ /**
787
+ * Callback called before updating a row with new values in the row and cell editing.
788
+ * Only applied if `props.experimentalFeatures.newEditingApi: true`.
789
+ * @param {GridRowModel} newRow Row object with the new values.
790
+ * @param {GridRowModel} oldRow Row object with the old values.
791
+ * @returns {Promise<GridRowModel> | GridRowModel} The final values to update the row.
792
+ */
793
+ processRowUpdate: PropTypes.func,
794
+
790
795
  /**
791
796
  * Number of extra rows to be rendered before/after the visible slice.
792
797
  * @default 3
@@ -1,4 +1,4 @@
1
- import { useGridInitialization, useGridInitializeState, useGridClipboard, useGridColumnMenu, useGridColumns, columnsStateInitializer, useGridDensity, useGridCsvExport, useGridPrintExport, useGridFilter, filterStateInitializer, useGridFocus, useGridKeyboard, useGridKeyboardNavigation, useGridPagination, paginationStateInitializer, useGridPreferencesPanel, useGridEditing, useGridRows, rowsStateInitializer, useGridRowsMeta, useGridParamsApi, useGridSelection, useGridSorting, sortingStateInitializer, useGridScroll, useGridEvents, useGridDimensions, useGridStatePersistence, useGridSelectionPreProcessors, columnMenuStateInitializer, densityStateInitializer, editingStateInitializer, focusStateInitializer, preferencePanelStateInitializer, rowsMetaStateInitializer, selectionStateInitializer } from '@mui/x-data-grid/internals';
1
+ import { useGridInitialization, useGridInitializeState, useGridClipboard, useGridColumnMenu, useGridColumns, columnsStateInitializer, useGridDensity, useGridCsvExport, useGridPrintExport, useGridFilter, filterStateInitializer, useGridFocus, useGridKeyboard, useGridKeyboardNavigation, useGridPagination, paginationStateInitializer, useGridPreferencesPanel, useGridEditing_new, useGridEditing_old, editingStateInitializer_old, editingStateInitializer_new, useGridRows, useGridRowsPreProcessors, rowsStateInitializer, useGridRowsMeta, useGridParamsApi, useGridSelection, useGridSorting, sortingStateInitializer, useGridScroll, useGridEvents, useGridDimensions, useGridStatePersistence, useGridSelectionPreProcessors, columnMenuStateInitializer, densityStateInitializer, focusStateInitializer, preferencePanelStateInitializer, rowsMetaStateInitializer, selectionStateInitializer } from '@mui/x-data-grid/internals';
2
2
  // Pro-only features
3
3
  import { useGridInfiniteLoader } from '../hooks/features/infiniteLoader/useGridInfiniteLoader';
4
4
  import { useGridColumnReorder, columnReorderStateInitializer } from '../hooks/features/columnReorder/useGridColumnReorder';
@@ -13,6 +13,8 @@ import { useGridDetailPanel, detailPanelStateInitializer } from '../hooks/featur
13
13
  import { useGridDetailPanelCache } from '../hooks/features/detailPanel/useGridDetailPanelCache';
14
14
  import { useGridDetailPanelPreProcessors } from '../hooks/features/detailPanel/useGridDetailPanelPreProcessors';
15
15
  export const useDataGridProComponent = (inputApiRef, props) => {
16
+ var _props$experimentalFe, _props$experimentalFe2;
17
+
16
18
  const apiRef = useGridInitialization(inputApiRef, props);
17
19
  /**
18
20
  * Register all pre-processors called during state initialization here.
@@ -21,25 +23,22 @@ export const useDataGridProComponent = (inputApiRef, props) => {
21
23
  useGridSelectionPreProcessors(apiRef, props);
22
24
  useGridRowGroupingPreProcessors(apiRef, props);
23
25
  useGridTreeDataPreProcessors(apiRef, props);
24
- useGridDetailPanelPreProcessors(apiRef, props);
25
- useGridColumnPinningPreProcessors(apiRef, props); // Must be the last because it changes the order of the columns.
26
+ useGridDetailPanelPreProcessors(apiRef, props); // The column pinning `hydrateColumns` pre-processor must be after every other `hydrateColumns` pre-processors
27
+ // Because it changes the order of the columns.
26
28
 
29
+ useGridColumnPinningPreProcessors(apiRef, props);
30
+ useGridRowsPreProcessors(apiRef);
27
31
  /**
28
32
  * Register all state initializers here.
29
33
  */
30
34
 
35
+ useGridInitializeState(rowGroupingStateInitializer, apiRef, props);
31
36
  useGridInitializeState(selectionStateInitializer, apiRef, props);
32
37
  useGridInitializeState(detailPanelStateInitializer, apiRef, props);
33
38
  useGridInitializeState(columnPinningStateInitializer, apiRef, props);
34
- useGridInitializeState(rowGroupingStateInitializer, apiRef, props); // FIXME Call in the same relative position that useGridRowGrouping is called
35
-
36
39
  useGridInitializeState(columnsStateInitializer, apiRef, props);
37
- useGridRowGrouping(apiRef, props); // FIXME Needs to be called before the rows state initialization because it registers a rows group builder
38
-
39
- useGridTreeData(apiRef, props); // FIXME Needs to be called before the rows state initialization because it registers a rows group builder
40
-
41
40
  useGridInitializeState(rowsStateInitializer, apiRef, props);
42
- useGridInitializeState(editingStateInitializer, apiRef, props);
41
+ useGridInitializeState((_props$experimentalFe = props.experimentalFeatures) != null && _props$experimentalFe.newEditingApi ? editingStateInitializer_new : editingStateInitializer_old, apiRef, props);
43
42
  useGridInitializeState(focusStateInitializer, apiRef, props);
44
43
  useGridInitializeState(sortingStateInitializer, apiRef, props);
45
44
  useGridInitializeState(preferencePanelStateInitializer, apiRef, props);
@@ -50,6 +49,8 @@ export const useDataGridProComponent = (inputApiRef, props) => {
50
49
  useGridInitializeState(paginationStateInitializer, apiRef, props);
51
50
  useGridInitializeState(rowsMetaStateInitializer, apiRef, props);
52
51
  useGridInitializeState(columnMenuStateInitializer, apiRef, props);
52
+ useGridRowGrouping(apiRef, props);
53
+ useGridTreeData(apiRef);
53
54
  useGridSelection(apiRef, props);
54
55
  useGridDetailPanel(apiRef, props);
55
56
  useGridColumnPinning(apiRef, props);
@@ -57,6 +58,7 @@ export const useDataGridProComponent = (inputApiRef, props) => {
57
58
  useGridRows(apiRef, props);
58
59
  useGridParamsApi(apiRef);
59
60
  useGridDetailPanelCache(apiRef, props);
61
+ const useGridEditing = (_props$experimentalFe2 = props.experimentalFeatures) != null && _props$experimentalFe2.newEditingApi ? useGridEditing_new : useGridEditing_old;
60
62
  useGridEditing(apiRef, props);
61
63
  useGridFocus(apiRef, props);
62
64
  useGridSorting(apiRef, props);
@@ -136,7 +136,15 @@ export const DataGridProColumnHeaders = /*#__PURE__*/React.forwardRef(function D
136
136
  }, {
137
137
  disableReorder: true
138
138
  })
139
- }), rightRenderContext && /*#__PURE__*/_jsx(GridColumnHeadersPinnedColumnHeaders, {
139
+ }), /*#__PURE__*/_jsx(GridColumnHeadersInner, _extends({
140
+ isDragging: isDragging
141
+ }, getInnerProps(), {
142
+ children: getColumns({
143
+ renderContext,
144
+ minFirstColumn: leftPinnedColumns.length,
145
+ maxLastColumn: visibleColumnFields.length - rightPinnedColumns.length
146
+ })
147
+ })), rightRenderContext && /*#__PURE__*/_jsx(GridColumnHeadersPinnedColumnHeaders, {
140
148
  ownerState: {
141
149
  side: GridPinnedPosition.right
142
150
  },
@@ -152,14 +160,6 @@ export const DataGridProColumnHeaders = /*#__PURE__*/React.forwardRef(function D
152
160
  disableReorder: true,
153
161
  separatorSide: GridColumnHeaderSeparatorSides.Left
154
162
  })
155
- }), /*#__PURE__*/_jsx(GridColumnHeadersInner, _extends({
156
- isDragging: isDragging
157
- }, getInnerProps(), {
158
- children: getColumns({
159
- renderContext,
160
- minFirstColumn: leftPinnedColumns.length,
161
- maxLastColumn: visibleColumnFields.length - rightPinnedColumns.length
162
- })
163
- }))]
163
+ })]
164
164
  }));
165
165
  });
@@ -243,7 +243,11 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
243
243
  maxLastColumn: leftRenderContext.lastColumnIndex,
244
244
  availableSpace: 0
245
245
  })
246
- }), rightRenderContext && /*#__PURE__*/_jsx(VirtualScrollerPinnedColumns, {
246
+ }), /*#__PURE__*/_jsx(GridVirtualScrollerRenderZone, _extends({}, getRenderZoneProps(), {
247
+ children: getRows({
248
+ renderContext
249
+ })
250
+ })), rightRenderContext && /*#__PURE__*/_jsx(VirtualScrollerPinnedColumns, {
247
251
  ref: rightColumns,
248
252
  ownerState: {
249
253
  side: GridPinnedPosition.right
@@ -256,11 +260,7 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
256
260
  maxLastColumn: rightRenderContext.lastColumnIndex,
257
261
  availableSpace: 0
258
262
  })
259
- }), /*#__PURE__*/_jsx(GridVirtualScrollerRenderZone, _extends({}, getRenderZoneProps(), {
260
- children: getRows({
261
- renderContext
262
- })
263
- })), detailPanels.length > 0 && /*#__PURE__*/_jsx(VirtualScrollerDetailPanels, {
263
+ }), detailPanels.length > 0 && /*#__PURE__*/_jsx(VirtualScrollerDetailPanels, {
264
264
  className: classes.detailPanels,
265
265
  children: detailPanels
266
266
  })]
@@ -1,6 +1,12 @@
1
1
  export declare type GridRowGroupingModel = string[];
2
2
  export interface GridRowGroupingState {
3
3
  model: GridRowGroupingModel;
4
+ /**
5
+ * Tracks the model on the last pre-processing
6
+ * Allows to check if we need to re-build the grouping columns when the grid upserts a column.
7
+ * TODO: Move outside of the state
8
+ */
9
+ unstable_sanitizedModelOnLastRowTreeCreation: GridRowGroupingModel;
4
10
  }
5
11
  export interface GridRowGroupingInitialState {
6
12
  model?: GridRowGroupingModel;
@@ -1,10 +1,12 @@
1
+ import * as React from 'react';
1
2
  import { GridRowTreeConfig, GridFilterState } from '@mui/x-data-grid';
2
3
  import { GridAggregatedFilterItemApplier } from '@mui/x-data-grid/internals';
3
4
  import { DataGridProProcessedProps } from '../../../models/dataGridProProps';
4
5
  import { GridRowGroupingModel } from './gridRowGroupingInterfaces';
5
6
  import { GridStatePro } from '../../../models/gridStatePro';
7
+ import { GridApiPro } from '../../../models/gridApiPro';
6
8
  export declare const GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD = "__row_group_by_columns_group__";
7
- export declare const GROUPING_COLUMNS_FEATURE_NAME = "grouping-columns";
9
+ export declare const ROW_GROUPING_STRATEGY = "grouping-columns";
8
10
  export declare const getRowGroupingFieldFromGroupingCriteria: (groupingCriteria: string | null) => string;
9
11
  export declare const getRowGroupingCriteriaFromGroupingField: (groupingColDefField: string) => string | null;
10
12
  export declare const isGroupingColumn: (field: string) => boolean;
@@ -21,4 +23,5 @@ interface FilterRowTreeFromTreeDataParams {
21
23
  export declare const filterRowTreeFromGroupingColumns: (params: FilterRowTreeFromTreeDataParams) => Omit<GridFilterState, 'filterModel'>;
22
24
  export declare const getColDefOverrides: (groupingColDefProp: DataGridProProcessedProps['groupingColDef'], fields: string[]) => import("../../..").GridGroupingColDefOverride | null | undefined;
23
25
  export declare const mergeStateWithRowGroupingModel: (rowGroupingModel: GridRowGroupingModel) => (state: GridStatePro) => GridStatePro;
26
+ export declare const setStrategyAvailability: (apiRef: React.MutableRefObject<GridApiPro>, disableRowGrouping: boolean) => void;
24
27
  export {};
@@ -1,6 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import { gridRowGroupingSanitizedModelSelector } from './gridRowGroupingSelector';
2
3
  export const GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD = '__row_group_by_columns_group__';
3
- export const GROUPING_COLUMNS_FEATURE_NAME = 'grouping-columns';
4
+ export const ROW_GROUPING_STRATEGY = 'grouping-columns';
4
5
  export const getRowGroupingFieldFromGroupingCriteria = groupingCriteria => {
5
6
  if (groupingCriteria === null) {
6
7
  return GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD;
@@ -110,7 +111,7 @@ export const filterRowTreeFromGroupingColumns = params => {
110
111
  export const getColDefOverrides = (groupingColDefProp, fields) => {
111
112
  if (typeof groupingColDefProp === 'function') {
112
113
  return groupingColDefProp({
113
- groupingName: GROUPING_COLUMNS_FEATURE_NAME,
114
+ groupingName: ROW_GROUPING_STRATEGY,
114
115
  fields
115
116
  });
116
117
  }
@@ -121,4 +122,18 @@ export const mergeStateWithRowGroupingModel = rowGroupingModel => state => _exte
121
122
  rowGrouping: _extends({}, state.rowGrouping, {
122
123
  model: rowGroupingModel
123
124
  })
124
- });
125
+ });
126
+ export const setStrategyAvailability = (apiRef, disableRowGrouping) => {
127
+ let isAvailable;
128
+
129
+ if (disableRowGrouping) {
130
+ isAvailable = () => false;
131
+ } else {
132
+ isAvailable = () => {
133
+ const rowGroupingSanitizedModel = gridRowGroupingSanitizedModelSelector(apiRef);
134
+ return rowGroupingSanitizedModel.length > 0;
135
+ };
136
+ }
137
+
138
+ apiRef.current.unstable_setStrategyAvailability('rowTree', ROW_GROUPING_STRATEGY, isAvailable);
139
+ };
@@ -1,12 +1,10 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import Divider from '@mui/material/Divider';
4
- import { GridEvents, gridRowIdsSelector, gridRowTreeSelector, useGridApiEventHandler, useGridApiMethod, gridColumnLookupSelector, gridFilteredDescendantCountLookupSelector, useFirstRender } from '@mui/x-data-grid';
5
- import { useGridRegisterPreProcessor, useGridRegisterSortingMethod, useGridRegisterFilteringMethod, isDeepEqual } from '@mui/x-data-grid/internals';
6
- import { buildRowTree } from '../../../utils/tree/buildRowTree';
7
- import { gridRowGroupingModelSelector, gridRowGroupingSanitizedModelSelector } from './gridRowGroupingSelector';
8
- import { filterRowTreeFromGroupingColumns, getRowGroupingFieldFromGroupingCriteria, GROUPING_COLUMNS_FEATURE_NAME, isGroupingColumn, mergeStateWithRowGroupingModel } from './gridRowGroupingUtils';
9
- import { sortRowTree } from '../../../utils/tree/sortRowTree';
4
+ import { GridEvents, useGridApiEventHandler, useGridApiMethod, gridFilteredDescendantCountLookupSelector } from '@mui/x-data-grid';
5
+ import { useGridRegisterPreProcessor, isDeepEqual } from '@mui/x-data-grid/internals';
6
+ import { gridRowGroupingModelSelector, gridRowGroupingSanitizedModelSelector, gridRowGroupingStateSelector } from './gridRowGroupingSelector';
7
+ import { getRowGroupingFieldFromGroupingCriteria, ROW_GROUPING_STRATEGY, isGroupingColumn, mergeStateWithRowGroupingModel, setStrategyAvailability } from './gridRowGroupingUtils';
10
8
  import { GridRowGroupableColumnMenuItems } from '../../../components/GridRowGroupableColumnMenuItems';
11
9
  import { GridRowGroupingColumnMenuItems } from '../../../components/GridRowGroupingColumnMenuItems';
12
10
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -15,7 +13,8 @@ export const rowGroupingStateInitializer = (state, props) => {
15
13
 
16
14
  return _extends({}, state, {
17
15
  rowGrouping: {
18
- model: (_ref = (_props$rowGroupingMod = props.rowGroupingModel) != null ? _props$rowGroupingMod : (_props$initialState = props.initialState) == null ? void 0 : (_props$initialState$r = _props$initialState.rowGrouping) == null ? void 0 : _props$initialState$r.model) != null ? _ref : []
16
+ model: (_ref = (_props$rowGroupingMod = props.rowGroupingModel) != null ? _props$rowGroupingMod : (_props$initialState = props.initialState) == null ? void 0 : (_props$initialState$r = _props$initialState.rowGrouping) == null ? void 0 : _props$initialState$r.model) != null ? _ref : [],
17
+ unstable_sanitizedModelOnLastRowTreeCreation: []
19
18
  }
20
19
  });
21
20
  };
@@ -35,158 +34,6 @@ export const useGridRowGrouping = (apiRef, props) => {
35
34
  stateSelector: gridRowGroupingModelSelector,
36
35
  changeEvent: GridEvents.rowGroupingModelChange
37
36
  });
38
- /**
39
- * ROW GROUPING
40
- */
41
- // Tracks the model on the last pre-processing to check if we need to re-build the grouping columns when the grid upserts a column.
42
-
43
- const sanitizedModelOnLastRowPreProcessing = React.useRef([]);
44
- const updateRowGrouping = React.useCallback(() => {
45
- const groupRows = params => {
46
- const rowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
47
- const columnsLookup = gridColumnLookupSelector(apiRef);
48
- sanitizedModelOnLastRowPreProcessing.current = rowGroupingModel;
49
-
50
- if (props.disableRowGrouping || rowGroupingModel.length === 0) {
51
- return null;
52
- }
53
-
54
- const distinctValues = Object.fromEntries(rowGroupingModel.map(groupingField => [groupingField, {
55
- lookup: {},
56
- list: []
57
- }]));
58
-
59
- const getCellGroupingCriteria = ({
60
- row,
61
- id,
62
- colDef
63
- }) => {
64
- let key;
65
-
66
- if (colDef.groupingValueGetter) {
67
- const groupingValueGetterParams = {
68
- colDef,
69
- field: colDef.field,
70
- value: row[colDef.field],
71
- id,
72
- row,
73
- rowNode: {
74
- isAutoGenerated: false,
75
- id
76
- }
77
- };
78
- key = colDef.groupingValueGetter(groupingValueGetterParams);
79
- } else {
80
- key = row[colDef.field];
81
- }
82
-
83
- return {
84
- key,
85
- field: colDef.field
86
- };
87
- };
88
-
89
- params.ids.forEach(rowId => {
90
- const row = params.idRowsLookup[rowId];
91
- rowGroupingModel.forEach(groupingCriteria => {
92
- const {
93
- key
94
- } = getCellGroupingCriteria({
95
- row,
96
- id: rowId,
97
- colDef: columnsLookup[groupingCriteria]
98
- });
99
- const groupingFieldsDistinctKeys = distinctValues[groupingCriteria];
100
-
101
- if (key != null && !groupingFieldsDistinctKeys.lookup[key.toString()]) {
102
- groupingFieldsDistinctKeys.lookup[key.toString()] = true;
103
- groupingFieldsDistinctKeys.list.push(key);
104
- }
105
- });
106
- });
107
- const rows = params.ids.map(rowId => {
108
- const row = params.idRowsLookup[rowId];
109
- const parentPath = rowGroupingModel.map(groupingField => getCellGroupingCriteria({
110
- row,
111
- id: rowId,
112
- colDef: columnsLookup[groupingField]
113
- })).filter(cell => cell.key != null);
114
- const leafGroupingCriteria = {
115
- key: rowId.toString(),
116
- field: null
117
- };
118
- return {
119
- path: [...parentPath, leafGroupingCriteria],
120
- id: rowId
121
- };
122
- });
123
- return buildRowTree(_extends({}, params, {
124
- rows,
125
- defaultGroupingExpansionDepth: props.defaultGroupingExpansionDepth,
126
- isGroupExpandedByDefault: props.isGroupExpandedByDefault,
127
- groupingName: GROUPING_COLUMNS_FEATURE_NAME
128
- }));
129
- };
130
-
131
- return apiRef.current.unstable_registerRowGroupsBuilder('rowGrouping', groupRows);
132
- }, [apiRef, props.defaultGroupingExpansionDepth, props.isGroupExpandedByDefault, props.disableRowGrouping]);
133
- useFirstRender(() => {
134
- updateRowGrouping();
135
- });
136
- const isFirstRender = React.useRef(true);
137
- React.useEffect(() => {
138
- if (isFirstRender.current) {
139
- isFirstRender.current = false;
140
- return () => {};
141
- }
142
-
143
- return updateRowGrouping();
144
- }, [updateRowGrouping]);
145
- /**
146
- * PRE-PROCESSING
147
- */
148
-
149
- const addColumnMenuButtons = React.useCallback((initialValue, columns) => {
150
- if (props.disableRowGrouping) {
151
- return initialValue;
152
- }
153
-
154
- let menuItems;
155
-
156
- if (isGroupingColumn(columns.field)) {
157
- menuItems = /*#__PURE__*/_jsx(GridRowGroupingColumnMenuItems, {});
158
- } else if (columns.groupable) {
159
- menuItems = /*#__PURE__*/_jsx(GridRowGroupableColumnMenuItems, {});
160
- } else {
161
- menuItems = null;
162
- }
163
-
164
- if (menuItems == null) {
165
- return initialValue;
166
- }
167
-
168
- return [...initialValue, /*#__PURE__*/_jsx(Divider, {}), menuItems];
169
- }, [props.disableRowGrouping]);
170
- const filteringMethod = React.useCallback(params => {
171
- const rowTree = gridRowTreeSelector(apiRef);
172
- return filterRowTreeFromGroupingColumns({
173
- rowTree,
174
- isRowMatchingFilters: params.isRowMatchingFilters
175
- });
176
- }, [apiRef]);
177
- const sortingMethod = React.useCallback(params => {
178
- const rowTree = gridRowTreeSelector(apiRef);
179
- const rowIds = gridRowIdsSelector(apiRef);
180
- return sortRowTree({
181
- rowTree,
182
- rowIds,
183
- sortRowList: params.sortRowList,
184
- disableChildrenSorting: false
185
- });
186
- }, [apiRef]);
187
- useGridRegisterPreProcessor(apiRef, 'columnMenu', addColumnMenuButtons);
188
- useGridRegisterFilteringMethod(apiRef, GROUPING_COLUMNS_FEATURE_NAME, filteringMethod);
189
- useGridRegisterSortingMethod(apiRef, GROUPING_COLUMNS_FEATURE_NAME, sortingMethod);
190
37
  /**
191
38
  * API METHODS
192
39
  */
@@ -196,10 +43,10 @@ export const useGridRowGrouping = (apiRef, props) => {
196
43
 
197
44
  if (currentModel !== model) {
198
45
  apiRef.current.setState(mergeStateWithRowGroupingModel(model));
199
- updateRowGrouping();
46
+ setStrategyAvailability(apiRef, props.disableRowGrouping);
200
47
  apiRef.current.forceUpdate();
201
48
  }
202
- }, [apiRef, updateRowGrouping]);
49
+ }, [apiRef, props.disableRowGrouping]);
203
50
  const addRowGroupingCriteria = React.useCallback((field, groupingIndex) => {
204
51
  const currentModel = gridRowGroupingModelSelector(apiRef);
205
52
 
@@ -243,6 +90,27 @@ export const useGridRowGrouping = (apiRef, props) => {
243
90
  * PRE-PROCESSING
244
91
  */
245
92
 
93
+ const addColumnMenuButtons = React.useCallback((initialValue, columns) => {
94
+ if (props.disableRowGrouping) {
95
+ return initialValue;
96
+ }
97
+
98
+ let menuItems;
99
+
100
+ if (isGroupingColumn(columns.field)) {
101
+ menuItems = /*#__PURE__*/_jsx(GridRowGroupingColumnMenuItems, {});
102
+ } else if (columns.groupable) {
103
+ menuItems = /*#__PURE__*/_jsx(GridRowGroupableColumnMenuItems, {});
104
+ } else {
105
+ menuItems = null;
106
+ }
107
+
108
+ if (menuItems == null) {
109
+ return initialValue;
110
+ }
111
+
112
+ return [...initialValue, /*#__PURE__*/_jsx(Divider, {}), menuItems];
113
+ }, [props.disableRowGrouping]);
246
114
  const stateExportPreProcessing = React.useCallback(prevState => {
247
115
  if (props.disableRowGrouping) {
248
116
  return prevState;
@@ -275,6 +143,7 @@ export const useGridRowGrouping = (apiRef, props) => {
275
143
 
276
144
  return params;
277
145
  }, [apiRef, props.disableRowGrouping]);
146
+ useGridRegisterPreProcessor(apiRef, 'columnMenu', addColumnMenuButtons);
278
147
  useGridRegisterPreProcessor(apiRef, 'exportState', stateExportPreProcessing);
279
148
  useGridRegisterPreProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
280
149
  /**
@@ -301,15 +170,25 @@ export const useGridRowGrouping = (apiRef, props) => {
301
170
  }, [apiRef, props.rowGroupingColumnMode]);
302
171
  const checkGroupingColumnsModelDiff = React.useCallback(() => {
303
172
  const rowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
304
- const lastGroupingColumnsModelApplied = sanitizedModelOnLastRowPreProcessing.current;
173
+ const lastGroupingColumnsModelApplied = gridRowGroupingStateSelector(apiRef.current.state).unstable_sanitizedModelOnLastRowTreeCreation;
305
174
 
306
175
  if (!isDeepEqual(lastGroupingColumnsModelApplied, rowGroupingModel)) {
307
- sanitizedModelOnLastRowPreProcessing.current = rowGroupingModel; // Refresh the column pre-processing
176
+ apiRef.current.setState(state => _extends({}, state, {
177
+ rowGrouping: _extends({}, state.rowGrouping, {
178
+ unstable_sanitizedModelOnLastRowTreeCreation: rowGroupingModel
179
+ })
180
+ })); // Refresh the column pre-processing
181
+ // TODO: Add a clean way to re-run a pipe processing without faking a change
308
182
 
309
183
  apiRef.current.updateColumns([]);
310
- updateRowGrouping();
184
+ setStrategyAvailability(apiRef, props.disableRowGrouping); // Refresh the row tree creation strategy processing
185
+ // TODO: Add a clean way to re-run a strategy processing without publishing a private event
186
+
187
+ if (apiRef.current.unstable_getActiveStrategy('rowTree') === ROW_GROUPING_STRATEGY) {
188
+ apiRef.current.publishEvent(GridEvents.activeStrategyProcessorChange, 'rowTreeCreation');
189
+ }
311
190
  }
312
- }, [apiRef, updateRowGrouping]);
191
+ }, [apiRef, props.disableRowGrouping]);
313
192
  useGridApiEventHandler(apiRef, GridEvents.cellKeyDown, handleCellKeyDown);
314
193
  useGridApiEventHandler(apiRef, GridEvents.columnsChange, checkGroupingColumnsModelDiff);
315
194
  useGridApiEventHandler(apiRef, GridEvents.rowGroupingModelChange, checkGroupingColumnsModelDiff);
@@ -1,4 +1,4 @@
1
1
  import * as React from 'react';
2
2
  import { DataGridProProcessedProps } from '../../../models/dataGridProProps';
3
3
  import { GridApiPro } from '../../../models/gridApiPro';
4
- export declare const useGridRowGroupingPreProcessors: (apiRef: React.MutableRefObject<GridApiPro>, props: Pick<DataGridProProcessedProps, 'disableRowGrouping' | 'groupingColDef' | 'rowGroupingColumnMode'>) => void;
4
+ export declare const useGridRowGroupingPreProcessors: (apiRef: React.MutableRefObject<GridApiPro>, props: Pick<DataGridProProcessedProps, 'disableRowGrouping' | 'groupingColDef' | 'rowGroupingColumnMode' | 'defaultGroupingExpansionDepth' | 'isGroupExpandedByDefault'>) => void;