@mui/x-data-grid-premium 8.15.0 → 8.16.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 (28) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/DataGridPremium/DataGridPremium.js +3 -1
  3. package/DataGridPremium/useDataGridPremiumComponent.js +1 -1
  4. package/esm/DataGridPremium/DataGridPremium.js +3 -1
  5. package/esm/DataGridPremium/useDataGridPremiumComponent.js +1 -1
  6. package/esm/hooks/features/chartsIntegration/gridChartsIntegrationSelectors.d.ts +6 -0
  7. package/esm/hooks/features/chartsIntegration/gridChartsIntegrationSelectors.js +1 -0
  8. package/esm/hooks/features/chartsIntegration/useGridChartsIntegration.d.ts +1 -1
  9. package/esm/hooks/features/chartsIntegration/useGridChartsIntegration.js +74 -11
  10. package/esm/hooks/features/dataSource/useGridDataSourcePremium.js +20 -4
  11. package/esm/hooks/features/dataSource/utils.d.ts +3 -2
  12. package/esm/hooks/features/dataSource/utils.js +13 -1
  13. package/esm/hooks/features/editing/useGridCellEditable.d.ts +8 -0
  14. package/esm/hooks/features/editing/useGridCellEditable.js +35 -0
  15. package/esm/hooks/features/rowGrouping/createGroupingColDef.js +3 -3
  16. package/esm/index.js +1 -1
  17. package/hooks/features/chartsIntegration/gridChartsIntegrationSelectors.d.ts +6 -0
  18. package/hooks/features/chartsIntegration/gridChartsIntegrationSelectors.js +2 -1
  19. package/hooks/features/chartsIntegration/useGridChartsIntegration.d.ts +1 -1
  20. package/hooks/features/chartsIntegration/useGridChartsIntegration.js +73 -10
  21. package/hooks/features/dataSource/useGridDataSourcePremium.js +17 -1
  22. package/hooks/features/dataSource/utils.d.ts +3 -2
  23. package/hooks/features/dataSource/utils.js +15 -2
  24. package/hooks/features/editing/useGridCellEditable.d.ts +8 -0
  25. package/hooks/features/editing/useGridCellEditable.js +41 -0
  26. package/hooks/features/rowGrouping/createGroupingColDef.js +3 -3
  27. package/index.js +1 -1
  28. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -5,6 +5,106 @@
5
5
  All notable changes to this project will be documented in this file.
6
6
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
7
7
 
8
+ ## 8.16.0
9
+
10
+ _Oct 29, 2025_
11
+
12
+ We'd like to extend a big thank you to the 14 contributors who made this release possible. Here are some highlights ✨:
13
+
14
+ - 🖌️ Add `brush` zoom interaction to charts
15
+ - 🔁 [Server-side update](https://mui.com/x/react-data-grid/server-side-data/#updating-server-side-data) in a grid with tree data/row grouping and aggregation will trigger re-fetch for all parent levels of that row to update aggregated values. See the [demo](https://mui.com/x/react-data-grid/server-side-data/aggregation/#usage-with-tree-data).
16
+
17
+ Special thanks go out to the community members for their valuable contributions:
18
+ @felix-wg, @frncesc, @sai6855
19
+
20
+ The following are all team members who have contributed to this release:
21
+ @alexfauquette, @arminmeh, @bernardobelchior, @brijeshb42, @flaviendelangle, @JCQuintas, @MBilalShafi, @mbrookes, @michelengelen, @noraleonte, @rita-codes
22
+
23
+ ### Data Grid
24
+
25
+ #### `@mui/x-data-grid@8.16.0`
26
+
27
+ - [DataGrid] Ignore `Ctrl+A` key combination for the row selection in the community version (#20110) @felix-wg
28
+ - [DataGrid][l10n] Improve Spanish (es-ES) locale (#20134) @frncesc
29
+
30
+ #### `@mui/x-data-grid-pro@8.16.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
31
+
32
+ Same changes as in `@mui/x-data-grid@8.16.0`, plus:
33
+
34
+ - [DataGridPro] Add explicit return type to `getVisibleRowsLookup()` to fix the build with `tsc` (#20116) @arminmeh
35
+ - [DataGridPro] Retain the expansion state with expansion configuration props (#20126) @MBilalShafi
36
+
37
+ #### `@mui/x-data-grid-premium@8.16.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
38
+
39
+ Same changes as in `@mui/x-data-grid-pro@8.16.0`, plus:
40
+
41
+ - [DataGridPremium] Export and restore chart integration state (#20079) @arminmeh
42
+ - [DataGridPremium] Fix grouping column `valueFormatter()` crash (#20070) @sai6855
43
+ - [DataGridPremium] Refetch aggregation data after row update with server-side aggregation (#20039) @arminmeh
44
+
45
+ ### Date and Time Pickers
46
+
47
+ #### `@mui/x-date-pickers@8.16.0`
48
+
49
+ - [pickers] Prevent blur event propagation on individual sections (#19825) @michelengelen
50
+
51
+ #### `@mui/x-date-pickers-pro@8.16.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
52
+
53
+ Same changes as in `@mui/x-date-pickers@8.16.0`.
54
+
55
+ ### Charts
56
+
57
+ #### `@mui/x-charts@8.16.0`
58
+
59
+ - [charts] Allow tooltip to anchor items (#19954) @alexfauquette
60
+ - [charts] Fix behavior of grouped axis (#20118) @JCQuintas
61
+ - [charts] Move scale symlog inside scales (#20137) @JCQuintas
62
+ - [charts] Fix AreaChartConnectNulls demo height not correctly resizing (#20078) @sai6855
63
+ - [charts] Fix charts resizing overflow (#20080) @alexfauquette
64
+ - [charts] Fix tooltip not showing on first render (#20115) @bernardobelchior
65
+ - [charts] Handle `undefined` id and color in series (#20087) @bernardobelchior
66
+ - [charts] Remove `useMemo` from isZoomOn*Enabled and isPanOn*Enabled hooks (#20132) @Copilot
67
+ - [charts] Use static data for perf (#20072) @JCQuintas
68
+ - [charts] Move scale symlog inside scales (#20137) @JCQuintas
69
+
70
+ #### `@mui/x-charts-pro@8.16.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
71
+
72
+ Same changes as in `@mui/x-charts@8.16.0`, plus:
73
+
74
+ - [charts-pro] Add `brush` zoom interaction (#19899) @JCQuintas
75
+ - [charts-pro] Add sankey performance check (#20069) @JCQuintas
76
+
77
+ #### `@mui/x-charts-premium@8.16.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
78
+
79
+ Same changes as in `@mui/x-charts-pro@8.16.0`.
80
+
81
+ ### Tree View
82
+
83
+ #### `@mui/x-tree-view@8.16.0`
84
+
85
+ Internal changes.
86
+
87
+ #### `@mui/x-tree-view-pro@8.16.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
88
+
89
+ Same changes as in `@mui/x-tree-view@8.16.0`.
90
+
91
+ ### Codemod
92
+
93
+ #### `@mui/x-codemod@8.16.0`
94
+
95
+ Internal changes.
96
+
97
+ ### Core
98
+
99
+ - [code-infra] Setup eslint compat plugin (#20105) @brijeshb42
100
+ - [code-infra] Improve store types (#20129) @JCQuintas
101
+ - [docs] Update the callout in `rows` prop documentation (#20127) @MBilalShafi
102
+ - [docs-infra] Refine changelog contributor acknowledgment messages (#20123) @mbrookes
103
+
104
+ ### Miscellaneous
105
+
106
+ - [x-telemetry] Skip telemetry tests on browser mode (#20122) @bernardobelchior
107
+
8
108
  ## 8.15.0
9
109
 
10
110
  _Oct 23, 2025_
@@ -25,6 +25,7 @@ var _useGridApiContext = require("../hooks/utils/useGridApiContext");
25
25
  var _useGridRowsOverridableMethods = require("../hooks/features/rows/useGridRowsOverridableMethods");
26
26
  var _useGridParamsOverridableMethods = require("../hooks/features/rows/useGridParamsOverridableMethods");
27
27
  var _sidebar2 = require("../hooks/features/sidebar");
28
+ var _useGridCellEditable = require("../hooks/features/editing/useGridCellEditable");
28
29
  var _jsxRuntime = require("react/jsx-runtime");
29
30
  const configuration = {
30
31
  hooks: {
@@ -44,11 +45,12 @@ const configuration = {
44
45
  }
45
46
  return (0, _internals.getRowValue)(row, column, apiRef);
46
47
  },
48
+ useIsCellEditable: _useGridCellEditable.useIsCellEditable,
47
49
  useGridRowsOverridableMethods: _useGridRowsOverridableMethods.useGridRowsOverridableMethods,
48
50
  useGridParamsOverridableMethods: _useGridParamsOverridableMethods.useGridParamsOverridableMethods
49
51
  }
50
52
  };
51
- const releaseInfo = "MTc2MTE3NzYwMDAwMA==";
53
+ const releaseInfo = "MTc2MTY5NjAwMDAwMA==";
52
54
  const watermark = /*#__PURE__*/(0, _jsxRuntime.jsx)(_xLicense.Watermark, {
53
55
  packageName: "x-data-grid-premium",
54
56
  releaseInfo: releaseInfo
@@ -120,7 +120,7 @@ const useDataGridPremiumComponent = (apiRef, inProps, configuration) => {
120
120
  (0, _internals.useGridColumnSpanning)(apiRef);
121
121
  (0, _internals.useGridColumnGrouping)(apiRef, props);
122
122
  (0, _useGridClipboardImport.useGridClipboardImport)(apiRef, props);
123
- (0, _internals.useGridEditing)(apiRef, props);
123
+ (0, _internals.useGridEditing)(apiRef, props, configuration);
124
124
  (0, _internals.useGridFocus)(apiRef, props);
125
125
  (0, _internals.useGridPreferencesPanel)(apiRef, props);
126
126
  (0, _internals.useGridFilter)(apiRef, props, configuration);
@@ -18,6 +18,7 @@ import { useGridApiContext } from "../hooks/utils/useGridApiContext.js";
18
18
  import { useGridRowsOverridableMethods } from "../hooks/features/rows/useGridRowsOverridableMethods.js";
19
19
  import { useGridParamsOverridableMethods } from "../hooks/features/rows/useGridParamsOverridableMethods.js";
20
20
  import { gridSidebarOpenSelector } from "../hooks/features/sidebar/index.js";
21
+ import { useIsCellEditable } from "../hooks/features/editing/useGridCellEditable.js";
21
22
  import { jsx as _jsx } from "react/jsx-runtime";
22
23
  const configuration = {
23
24
  hooks: {
@@ -37,11 +38,12 @@ const configuration = {
37
38
  }
38
39
  return getRowValue(row, column, apiRef);
39
40
  },
41
+ useIsCellEditable,
40
42
  useGridRowsOverridableMethods,
41
43
  useGridParamsOverridableMethods
42
44
  }
43
45
  };
44
- const releaseInfo = "MTc2MTE3NzYwMDAwMA==";
46
+ const releaseInfo = "MTc2MTY5NjAwMDAwMA==";
45
47
  const watermark = /*#__PURE__*/_jsx(Watermark, {
46
48
  packageName: "x-data-grid-premium",
47
49
  releaseInfo: releaseInfo
@@ -112,7 +112,7 @@ export const useDataGridPremiumComponent = (apiRef, inProps, configuration) => {
112
112
  useGridColumnSpanning(apiRef);
113
113
  useGridColumnGrouping(apiRef, props);
114
114
  useGridClipboardImport(apiRef, props);
115
- useGridEditing(apiRef, props);
115
+ useGridEditing(apiRef, props, configuration);
116
116
  useGridFocus(apiRef, props);
117
117
  useGridPreferencesPanel(apiRef, props);
118
118
  useGridFilter(apiRef, props, configuration);
@@ -3,6 +3,12 @@ import { GridStatePremium } from "../../../models/gridStatePremium.js";
3
3
  export declare const gridChartsIntegrationActiveChartIdSelector: (args_0: import("react").RefObject<{
4
4
  state: GridStatePremium;
5
5
  } | null>) => string;
6
+ export declare const gridChartsIntegrationChartsLookupSelector: (args_0: import("react").RefObject<{
7
+ state: GridStatePremium;
8
+ } | null>) => Record<string, {
9
+ dimensions: import("./gridChartsIntegrationInterfaces.js").GridChartsIntegrationItem[];
10
+ values: import("./gridChartsIntegrationInterfaces.js").GridChartsIntegrationItem[];
11
+ }>;
6
12
  export declare const gridChartsPanelOpenSelector: (args_0: import("react").RefObject<{
7
13
  state: GridStatePremium;
8
14
  } | null>) => boolean;
@@ -3,6 +3,7 @@ import { gridSidebarStateSelector, GridSidebarValue } from "../sidebar/index.js"
3
3
  import { gridPivotModelSelector } from "../pivoting/gridPivotingSelectors.js";
4
4
  const gridChartsIntegrationStateSelector = createRootSelector(state => state.chartsIntegration);
5
5
  export const gridChartsIntegrationActiveChartIdSelector = createSelector(gridChartsIntegrationStateSelector, chartsIntegration => chartsIntegration.activeChartId);
6
+ export const gridChartsIntegrationChartsLookupSelector = createSelector(gridChartsIntegrationStateSelector, chartsIntegration => chartsIntegration.charts);
6
7
  export const gridChartsPanelOpenSelector = createSelector(gridSidebarStateSelector, sidebar => sidebar.value === GridSidebarValue.Charts && sidebar.open);
7
8
  export const gridChartableColumnsSelector = createSelectorMemoized(gridColumnLookupSelector, gridPivotActiveSelector, gridPivotModelSelector, (columns, pivotActive, pivotModel) => {
8
9
  let chartableColumns = Object.values(columns).filter(column => column.chartable);
@@ -1,7 +1,7 @@
1
1
  import { RefObject } from '@mui/x-internals/types';
2
2
  import { GridStateInitializer } from '@mui/x-data-grid-pro/internals';
3
3
  import type { DataGridPremiumProcessedProps } from "../../../models/dataGridPremiumProps.js";
4
- import { GridPrivateApiPremium } from "../../../models/gridApiPremium.js";
4
+ import type { GridPrivateApiPremium } from "../../../models/gridApiPremium.js";
5
5
  import { ChartState } from "../../../models/gridChartsIntegration.js";
6
6
  export declare const EMPTY_CHART_INTEGRATION_CONTEXT_STATE: ChartState;
7
7
  export declare const chartsIntegrationStateInitializer: GridStateInitializer<Pick<DataGridPremiumProcessedProps, 'chartsIntegration' | 'initialState' | 'activeChartId' | 'rowGroupingModel' | 'pivotModel' | 'experimentalFeatures'>, GridPrivateApiPremium>;
@@ -6,7 +6,7 @@ import debounce from '@mui/utils/debounce';
6
6
  import { gridColumnGroupsLookupSelector, gridColumnGroupsUnwrappedModelSelector, gridRowIdSelector, gridRowNodeSelector, gridRowTreeSelector } from '@mui/x-data-grid-pro';
7
7
  import { useGridApiMethod, useGridEvent, gridColumnLookupSelector, runIf, gridPivotActiveSelector, useGridRegisterPipeProcessor, gridColumnFieldsSelector, gridFilteredSortedDepthRowEntriesSelector, GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD } from '@mui/x-data-grid-pro/internals';
8
8
  import { getRowGroupingFieldFromGroupingCriteria } from "../rowGrouping/gridRowGroupingUtils.js";
9
- import { gridChartsPanelOpenSelector, gridChartsDimensionsSelector, gridChartsValuesSelector, gridChartsIntegrationActiveChartIdSelector, gridChartableColumnsSelector } from "./gridChartsIntegrationSelectors.js";
9
+ import { gridChartsPanelOpenSelector, gridChartsDimensionsSelector, gridChartsValuesSelector, gridChartsIntegrationActiveChartIdSelector, gridChartableColumnsSelector, gridChartsIntegrationChartsLookupSelector } from "./gridChartsIntegrationSelectors.js";
10
10
  import { useGridChartsIntegrationContext } from "../../utils/useGridChartIntegration.js";
11
11
  import { isBlockedForSection } from "./utils.js";
12
12
  import { gridRowGroupingSanitizedModelSelector } from "../rowGrouping/gridRowGroupingSelector.js";
@@ -150,19 +150,21 @@ export const useGridChartsIntegration = (apiRef, props) => {
150
150
  if (!pivotActive && visibleValues.current[activeChartId] && rowGroupingModel.length > 0) {
151
151
  // with row grouping add the aggregation model to the newly added value dataset
152
152
  const aggregatedFields = Object.keys(aggregationModel);
153
+ const aggregationsToAdd = {};
153
154
  visibleValues.current[activeChartId].forEach(item => {
154
155
  const hasAggregation = aggregatedFields.includes(item.field);
155
156
  if (!hasAggregation) {
156
- apiRef.current.setAggregationModel(_extends({}, aggregationModel, {
157
- // use the first available aggregation function
158
- [item.field]: getAvailableAggregationFunctions({
159
- aggregationFunctions: props.aggregationFunctions,
160
- colDef: item,
161
- isDataSource: !!props.dataSource
162
- })[0]
163
- }));
157
+ // use the first available aggregation function
158
+ aggregationsToAdd[item.field] = getAvailableAggregationFunctions({
159
+ aggregationFunctions: props.aggregationFunctions,
160
+ colDef: item,
161
+ isDataSource: !!props.dataSource
162
+ })[0];
164
163
  }
165
164
  });
165
+ if (Object.keys(aggregationsToAdd).length > 0) {
166
+ apiRef.current.setAggregationModel(_extends({}, aggregationModel, aggregationsToAdd));
167
+ }
166
168
  }
167
169
  }, [apiRef, props.aggregationFunctions, props.dataSource, activeChartId, pivotActive, aggregationModel]);
168
170
  const handleRowDataUpdate = React.useCallback(chartIds => {
@@ -296,8 +298,8 @@ export const useGridChartsIntegration = (apiRef, props) => {
296
298
  }
297
299
  });
298
300
  updateOtherModels();
299
- handleRowDataUpdate(chartIds);
300
- }, [apiRef, chartStateLookup, pivotActive, pivotModel, handleRowDataUpdate, updateOtherModels]);
301
+ debouncedHandleRowDataUpdate(chartIds);
302
+ }, [apiRef, chartStateLookup, pivotActive, pivotModel, debouncedHandleRowDataUpdate, updateOtherModels]);
301
303
  const debouncedHandleColumnDataUpdate = React.useMemo(() => debounce(handleColumnDataUpdate, 0), [handleColumnDataUpdate]);
302
304
  const setChartsPanelOpen = React.useCallback(callback => {
303
305
  if (!isChartsIntegrationAvailable) {
@@ -496,6 +498,67 @@ export const useGridChartsIntegration = (apiRef, props) => {
496
498
  useGridEvent(apiRef, 'pivotModeChange', runIf(isChartsIntegrationAvailable, () => debouncedHandleColumnDataUpdate(syncedChartIds)));
497
499
  useGridEvent(apiRef, 'filteredRowsSet', runIf(isChartsIntegrationAvailable, () => debouncedHandleRowDataUpdate(syncedChartIds)));
498
500
  useGridEvent(apiRef, 'sortedRowsSet', runIf(isChartsIntegrationAvailable, () => debouncedHandleRowDataUpdate(syncedChartIds)));
501
+ const stateExportPreProcessing = React.useCallback((prevState, exportContext) => {
502
+ if (!props.chartsIntegration || !props.experimentalFeatures?.charts) {
503
+ return prevState;
504
+ }
505
+ const currentActiveChartId = gridChartsIntegrationActiveChartIdSelector(apiRef);
506
+ const chartsLookup = gridChartsIntegrationChartsLookupSelector(apiRef);
507
+ const integrationContextToExport = Object.fromEntries(Object.entries(chartStateLookup).map(([chartId, chartState]) => [chartId,
508
+ // keep only the state that is controlled by the user, drop the data and labels
509
+ {
510
+ synced: chartState.synced,
511
+ type: chartState.type,
512
+ configuration: chartState.configuration
513
+ }]));
514
+ const shouldExportChartState =
515
+ // Always export if the `exportOnlyDirtyModels` property is not activated
516
+ !exportContext.exportOnlyDirtyModels ||
517
+ // Always export if the chart state has been initialized
518
+ props.initialState?.chartsIntegration != null ||
519
+ // Export if the chart model or context is not empty
520
+ Object.keys(chartsLookup).length > 0 || Object.keys(integrationContextToExport).length > 0;
521
+ if (!shouldExportChartState) {
522
+ return prevState;
523
+ }
524
+ const chartStateToExport = {
525
+ activeChartId: currentActiveChartId,
526
+ charts: chartsLookup,
527
+ // add a custom prop to keep the integration context in the exported state
528
+ integrationContext: integrationContextToExport
529
+ };
530
+ return _extends({}, prevState, {
531
+ chartsIntegration: chartStateToExport
532
+ });
533
+ }, [apiRef, chartStateLookup, props.chartsIntegration, props.experimentalFeatures?.charts, props.initialState?.chartsIntegration]);
534
+ const stateRestorePreProcessing = React.useCallback((params, restoreContext) => {
535
+ const chartsRestoreState = restoreContext.stateToRestore.chartsIntegration;
536
+ if (!chartsRestoreState) {
537
+ return params;
538
+ }
539
+ const {
540
+ activeChartId: activeChartIdToRestore,
541
+ charts: chartsToRestore,
542
+ integrationContext
543
+ } = chartsRestoreState;
544
+ if (activeChartIdToRestore === undefined || chartsToRestore === undefined || Object.keys(chartsToRestore).length === 0) {
545
+ return params;
546
+ }
547
+ apiRef.current.setState(_extends({}, apiRef.current.state, {
548
+ chartsIntegration: {
549
+ activeChartId: activeChartIdToRestore,
550
+ charts: chartsToRestore
551
+ }
552
+ }));
553
+
554
+ // restore the integration context for each chart
555
+ Object.entries(integrationContext).forEach(([chartId, chartContextState]) => {
556
+ setChartState(chartId, chartContextState);
557
+ });
558
+ return params;
559
+ }, [apiRef, setChartState]);
560
+ useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
561
+ useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
499
562
  React.useEffect(() => {
500
563
  if (!activeChartId && availableChartIds.length > 0) {
501
564
  setActiveChartId(availableChartIds[0]);
@@ -2,11 +2,13 @@
2
2
 
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
- import { useGridEvent as addEventHandler, useGridApiMethod, GRID_ROOT_GROUP_ID, useGridEvent } from '@mui/x-data-grid-pro';
6
- import { useGridDataSourceBasePro, useGridRegisterStrategyProcessor, useGridRegisterPipeProcessor, gridPivotInitialColumnsSelector, runIf, gridPivotActiveSelector, GridStrategyGroup, DataSourceRowsUpdateStrategy } from '@mui/x-data-grid-pro/internals';
5
+ import { isDeepEqual } from '@mui/x-internals/isDeepEqual';
6
+ import { useGridEvent as addEventHandler, useGridApiMethod, GRID_ROOT_GROUP_ID, useGridEvent, gridRowTreeSelector } from '@mui/x-data-grid-pro';
7
+ import { useGridDataSourceBasePro, useGridRegisterStrategyProcessor, useGridRegisterPipeProcessor, gridPivotInitialColumnsSelector, runIf, gridPivotActiveSelector, GridStrategyGroup, DataSourceRowsUpdateStrategy, getGroupKeys } from '@mui/x-data-grid-pro/internals';
7
8
  import { gridPivotModelSelector } from "../pivoting/gridPivotingSelectors.js";
8
- import { getPropsOverrides } from "./utils.js";
9
+ import { getPropsOverrides, fetchParents } from "./utils.js";
9
10
  import { gridRowGroupingSanitizedModelSelector } from "../rowGrouping/gridRowGroupingSelector.js";
11
+ import { gridAggregationModelSelector } from "../aggregation/gridAggregationSelectors.js";
10
12
  function getKeyPremium(params) {
11
13
  return JSON.stringify([params.filterModel, params.sortModel, params.groupKeys, params.groupFields, params.start, params.end, params.pivotModel ? {} : params.aggregationModel, params.pivotModel]);
12
14
  }
@@ -16,18 +18,32 @@ const options = {
16
18
  }
17
19
  };
18
20
  export const useGridDataSourcePremium = (apiRef, props) => {
21
+ const aggregationModel = gridAggregationModelSelector(apiRef);
19
22
  const groupingModelSize = gridRowGroupingSanitizedModelSelector(apiRef).length;
20
23
  const setStrategyAvailability = React.useCallback(() => {
21
24
  const targetStrategy = props.treeData || !props.disableRowGrouping && groupingModelSize > 0 ? DataSourceRowsUpdateStrategy.GroupedData : DataSourceRowsUpdateStrategy.Default;
22
25
  apiRef.current.setStrategyAvailability(GridStrategyGroup.DataSource, targetStrategy, props.dataSource && !props.lazyLoading ? () => true : () => false);
23
26
  }, [apiRef, props.dataSource, props.lazyLoading, props.treeData, props.disableRowGrouping, groupingModelSize]);
27
+ const handleEditRowWithAggregation = React.useCallback((params, updatedRow) => {
28
+ const rowTree = gridRowTreeSelector(apiRef);
29
+ if (updatedRow && !isDeepEqual(updatedRow, params.previousRow)) {
30
+ // Reset the outdated cache, only if the row is _actually_ updated
31
+ apiRef.current.dataSource.cache.clear();
32
+ }
33
+ const groupKeys = getGroupKeys(rowTree, params.rowId);
34
+ apiRef.current.updateNestedRows([updatedRow], groupKeys);
35
+ // To refresh the aggregation values of all parent rows and the footer row, recursively re-fetch all parent levels
36
+ fetchParents(rowTree, params.rowId, apiRef.current.dataSource.fetchRows);
37
+ }, [apiRef]);
24
38
  const {
25
39
  api,
26
40
  debouncedFetchRows,
27
41
  flatTreeStrategyProcessor,
28
42
  groupedDataStrategyProcessor,
29
43
  events
30
- } = useGridDataSourceBasePro(apiRef, props, options);
44
+ } = useGridDataSourceBasePro(apiRef, props, _extends({}, !props.disableAggregation && Object.keys(aggregationModel).length > 0 ? {
45
+ handleEditRow: handleEditRowWithAggregation
46
+ } : {}, options));
31
47
  const aggregateRowRef = React.useRef({});
32
48
  const initialColumns = gridPivotInitialColumnsSelector(apiRef);
33
49
  const pivotActive = gridPivotActiveSelector(apiRef);
@@ -1,6 +1,7 @@
1
1
  import type { RefObject } from '@mui/x-internals/types';
2
- import { GridColDef } from '@mui/x-data-grid-pro';
2
+ import { GridColDef, GridRowId, GridRowTreeConfig } from '@mui/x-data-grid-pro';
3
3
  import type { GridPrivateApiPremium } from "../../../models/gridApiPremium.js";
4
4
  import type { GridPivotingDynamicPropsOverrides, PivotingColDefCallback, GridPivotModel } from "../pivoting/gridPivotingInterfaces.js";
5
5
  import type { GridGetRowsResponsePivotColumn } from "./models.js";
6
- export declare const getPropsOverrides: (pivotColumns: GridGetRowsResponsePivotColumn[], pivotingColDef: PivotingColDefCallback, pivotModel: GridPivotModel, initialColumns: Map<string, GridColDef>, apiRef: RefObject<GridPrivateApiPremium>) => GridPivotingDynamicPropsOverrides;
6
+ export declare const getPropsOverrides: (pivotColumns: GridGetRowsResponsePivotColumn[], pivotingColDef: PivotingColDefCallback, pivotModel: GridPivotModel, initialColumns: Map<string, GridColDef>, apiRef: RefObject<GridPrivateApiPremium>) => GridPivotingDynamicPropsOverrides;
7
+ export declare const fetchParents: (rowTree: GridRowTreeConfig, rowId: GridRowId, fetchHandler: (id?: GridRowId) => Promise<void>) => Promise<void[]>;
@@ -1,5 +1,5 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import { gridStringOrNumberComparator } from '@mui/x-data-grid-pro';
2
+ import { gridStringOrNumberComparator, GRID_ROOT_GROUP_ID } from '@mui/x-data-grid-pro';
3
3
  export const getPropsOverrides = (pivotColumns, pivotingColDef, pivotModel, initialColumns, apiRef) => {
4
4
  const visiblePivotColumns = pivotModel.columns.filter(column => !column.hidden);
5
5
  const visiblePivotValues = pivotModel.values.filter(value => !value.hidden);
@@ -137,4 +137,16 @@ export const getPropsOverrides = (pivotColumns, pivotingColDef, pivotModel, init
137
137
  columnGroupingModel,
138
138
  aggregationModel
139
139
  };
140
+ };
141
+ export const fetchParents = (rowTree, rowId, fetchHandler) => {
142
+ const parents = [];
143
+
144
+ // collect all parents ids
145
+ let currentId = rowId;
146
+ while (currentId !== undefined && currentId !== GRID_ROOT_GROUP_ID) {
147
+ const parentId = rowTree[currentId].parent;
148
+ parents.push(parentId);
149
+ currentId = parentId;
150
+ }
151
+ return Promise.all(parents.reverse().map(fetchHandler));
140
152
  };
@@ -0,0 +1,8 @@
1
+ import { RefObject } from '@mui/x-internals/types';
2
+ import { CellEditableConditionFn } from '@mui/x-data-grid-pro/internals';
3
+ import { GridPrivateApiPremium } from "../../../models/gridApiPremium.js";
4
+ import { DataGridPremiumProcessedProps } from "../../../models/dataGridPremiumProps.js";
5
+ /**
6
+ * Implementation of the cell editable condition hook of the Data Grid Premium
7
+ */
8
+ export declare const useIsCellEditable: (apiRef: RefObject<GridPrivateApiPremium>, props: DataGridPremiumProcessedProps) => CellEditableConditionFn;
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { useIsCellEditable as useIsCellEditableCommunity } from '@mui/x-data-grid-pro/internals';
5
+ import { gridAggregationModelSelector } from "../aggregation/gridAggregationSelectors.js";
6
+
7
+ /**
8
+ * Implementation of the cell editable condition hook of the Data Grid Premium
9
+ */
10
+ export const useIsCellEditable = (apiRef, props) => {
11
+ const isCellEditableCommunity = useIsCellEditableCommunity();
12
+ return React.useCallback(params => {
13
+ const isCellEditable = isCellEditableCommunity(params);
14
+
15
+ // If the cell is not editable by the community hook, return false immediately
16
+ if (!isCellEditable) {
17
+ return false;
18
+ }
19
+
20
+ // If the data source is not used or aggregation is disabled or both tree data and row grouping are disabled, return the community hook result
21
+ if (!props.dataSource || props.disableAggregation || !props.treeData && props.disableRowGrouping) {
22
+ return isCellEditable;
23
+ }
24
+
25
+ // If the cell is not a part of the aggregation model, return the community hook result
26
+ const aggregationModelFields = Object.keys(gridAggregationModelSelector(apiRef));
27
+ if (!aggregationModelFields.includes(params.field)) {
28
+ return isCellEditable;
29
+ }
30
+
31
+ // The cell is a part of the aggregation model and it is retrieved from the server-side data.
32
+ // Allow editing only for the non-grouped rows.
33
+ return params.rowNode.type !== 'group';
34
+ }, [apiRef, props.dataSource, props.treeData, props.disableAggregation, props.disableRowGrouping, isCellEditableCommunity]);
35
+ };
@@ -84,12 +84,12 @@ function getGroupingCriteriaProperties(groupedByColDef, rowGroupingColumnMode, r
84
84
  const rowId = gridRowIdSelector(apiRef, row);
85
85
  const rowNode = gridRowNodeSelector(apiRef, rowId);
86
86
  if (rowNode?.type === 'group') {
87
- const originalColDef = columnsLookup[rowNode.groupingField];
88
- if (originalColDef.type === 'singleSelect') {
87
+ const originalColDef = rowNode.groupingField ? columnsLookup[rowNode.groupingField] : null;
88
+ if (originalColDef?.type === 'singleSelect') {
89
89
  // the default valueFormatter of a singleSelect colDef won't work with the grouping column values
90
90
  return value;
91
91
  }
92
- const columnValueFormatter = originalColDef.valueFormatter;
92
+ const columnValueFormatter = originalColDef?.valueFormatter;
93
93
  if (typeof columnValueFormatter === 'function') {
94
94
  return columnValueFormatter(value, row, column, apiRef);
95
95
  }
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-premium v8.15.0
2
+ * @mui/x-data-grid-premium v8.16.0
3
3
  *
4
4
  * @license SEE LICENSE IN LICENSE
5
5
  * This source code is licensed under the SEE LICENSE IN LICENSE license found in the
@@ -3,6 +3,12 @@ import { GridStatePremium } from "../../../models/gridStatePremium.js";
3
3
  export declare const gridChartsIntegrationActiveChartIdSelector: (args_0: import("react").RefObject<{
4
4
  state: GridStatePremium;
5
5
  } | null>) => string;
6
+ export declare const gridChartsIntegrationChartsLookupSelector: (args_0: import("react").RefObject<{
7
+ state: GridStatePremium;
8
+ } | null>) => Record<string, {
9
+ dimensions: import("./gridChartsIntegrationInterfaces.js").GridChartsIntegrationItem[];
10
+ values: import("./gridChartsIntegrationInterfaces.js").GridChartsIntegrationItem[];
11
+ }>;
6
12
  export declare const gridChartsPanelOpenSelector: (args_0: import("react").RefObject<{
7
13
  state: GridStatePremium;
8
14
  } | null>) => boolean;
@@ -3,12 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.gridChartsValuesSelector = exports.gridChartsPanelOpenSelector = exports.gridChartsIntegrationActiveChartIdSelector = exports.gridChartsDimensionsSelector = exports.gridChartableColumnsSelector = void 0;
6
+ exports.gridChartsValuesSelector = exports.gridChartsPanelOpenSelector = exports.gridChartsIntegrationChartsLookupSelector = exports.gridChartsIntegrationActiveChartIdSelector = exports.gridChartsDimensionsSelector = exports.gridChartableColumnsSelector = void 0;
7
7
  var _internals = require("@mui/x-data-grid-pro/internals");
8
8
  var _sidebar = require("../sidebar");
9
9
  var _gridPivotingSelectors = require("../pivoting/gridPivotingSelectors");
10
10
  const gridChartsIntegrationStateSelector = (0, _internals.createRootSelector)(state => state.chartsIntegration);
11
11
  const gridChartsIntegrationActiveChartIdSelector = exports.gridChartsIntegrationActiveChartIdSelector = (0, _internals.createSelector)(gridChartsIntegrationStateSelector, chartsIntegration => chartsIntegration.activeChartId);
12
+ const gridChartsIntegrationChartsLookupSelector = exports.gridChartsIntegrationChartsLookupSelector = (0, _internals.createSelector)(gridChartsIntegrationStateSelector, chartsIntegration => chartsIntegration.charts);
12
13
  const gridChartsPanelOpenSelector = exports.gridChartsPanelOpenSelector = (0, _internals.createSelector)(_sidebar.gridSidebarStateSelector, sidebar => sidebar.value === _sidebar.GridSidebarValue.Charts && sidebar.open);
13
14
  const gridChartableColumnsSelector = exports.gridChartableColumnsSelector = (0, _internals.createSelectorMemoized)(_internals.gridColumnLookupSelector, _internals.gridPivotActiveSelector, _gridPivotingSelectors.gridPivotModelSelector, (columns, pivotActive, pivotModel) => {
14
15
  let chartableColumns = Object.values(columns).filter(column => column.chartable);
@@ -1,7 +1,7 @@
1
1
  import { RefObject } from '@mui/x-internals/types';
2
2
  import { GridStateInitializer } from '@mui/x-data-grid-pro/internals';
3
3
  import type { DataGridPremiumProcessedProps } from "../../../models/dataGridPremiumProps.js";
4
- import { GridPrivateApiPremium } from "../../../models/gridApiPremium.js";
4
+ import type { GridPrivateApiPremium } from "../../../models/gridApiPremium.js";
5
5
  import { ChartState } from "../../../models/gridChartsIntegration.js";
6
6
  export declare const EMPTY_CHART_INTEGRATION_CONTEXT_STATE: ChartState;
7
7
  export declare const chartsIntegrationStateInitializer: GridStateInitializer<Pick<DataGridPremiumProcessedProps, 'chartsIntegration' | 'initialState' | 'activeChartId' | 'rowGroupingModel' | 'pivotModel' | 'experimentalFeatures'>, GridPrivateApiPremium>;
@@ -158,19 +158,21 @@ const useGridChartsIntegration = (apiRef, props) => {
158
158
  if (!pivotActive && visibleValues.current[activeChartId] && rowGroupingModel.length > 0) {
159
159
  // with row grouping add the aggregation model to the newly added value dataset
160
160
  const aggregatedFields = Object.keys(aggregationModel);
161
+ const aggregationsToAdd = {};
161
162
  visibleValues.current[activeChartId].forEach(item => {
162
163
  const hasAggregation = aggregatedFields.includes(item.field);
163
164
  if (!hasAggregation) {
164
- apiRef.current.setAggregationModel((0, _extends2.default)({}, aggregationModel, {
165
- // use the first available aggregation function
166
- [item.field]: (0, _gridAggregationUtils.getAvailableAggregationFunctions)({
167
- aggregationFunctions: props.aggregationFunctions,
168
- colDef: item,
169
- isDataSource: !!props.dataSource
170
- })[0]
171
- }));
165
+ // use the first available aggregation function
166
+ aggregationsToAdd[item.field] = (0, _gridAggregationUtils.getAvailableAggregationFunctions)({
167
+ aggregationFunctions: props.aggregationFunctions,
168
+ colDef: item,
169
+ isDataSource: !!props.dataSource
170
+ })[0];
172
171
  }
173
172
  });
173
+ if (Object.keys(aggregationsToAdd).length > 0) {
174
+ apiRef.current.setAggregationModel((0, _extends2.default)({}, aggregationModel, aggregationsToAdd));
175
+ }
174
176
  }
175
177
  }, [apiRef, props.aggregationFunctions, props.dataSource, activeChartId, pivotActive, aggregationModel]);
176
178
  const handleRowDataUpdate = React.useCallback(chartIds => {
@@ -304,8 +306,8 @@ const useGridChartsIntegration = (apiRef, props) => {
304
306
  }
305
307
  });
306
308
  updateOtherModels();
307
- handleRowDataUpdate(chartIds);
308
- }, [apiRef, chartStateLookup, pivotActive, pivotModel, handleRowDataUpdate, updateOtherModels]);
309
+ debouncedHandleRowDataUpdate(chartIds);
310
+ }, [apiRef, chartStateLookup, pivotActive, pivotModel, debouncedHandleRowDataUpdate, updateOtherModels]);
309
311
  const debouncedHandleColumnDataUpdate = React.useMemo(() => (0, _debounce.default)(handleColumnDataUpdate, 0), [handleColumnDataUpdate]);
310
312
  const setChartsPanelOpen = React.useCallback(callback => {
311
313
  if (!isChartsIntegrationAvailable) {
@@ -504,6 +506,67 @@ const useGridChartsIntegration = (apiRef, props) => {
504
506
  (0, _internals.useGridEvent)(apiRef, 'pivotModeChange', (0, _internals.runIf)(isChartsIntegrationAvailable, () => debouncedHandleColumnDataUpdate(syncedChartIds)));
505
507
  (0, _internals.useGridEvent)(apiRef, 'filteredRowsSet', (0, _internals.runIf)(isChartsIntegrationAvailable, () => debouncedHandleRowDataUpdate(syncedChartIds)));
506
508
  (0, _internals.useGridEvent)(apiRef, 'sortedRowsSet', (0, _internals.runIf)(isChartsIntegrationAvailable, () => debouncedHandleRowDataUpdate(syncedChartIds)));
509
+ const stateExportPreProcessing = React.useCallback((prevState, exportContext) => {
510
+ if (!props.chartsIntegration || !props.experimentalFeatures?.charts) {
511
+ return prevState;
512
+ }
513
+ const currentActiveChartId = (0, _gridChartsIntegrationSelectors.gridChartsIntegrationActiveChartIdSelector)(apiRef);
514
+ const chartsLookup = (0, _gridChartsIntegrationSelectors.gridChartsIntegrationChartsLookupSelector)(apiRef);
515
+ const integrationContextToExport = Object.fromEntries(Object.entries(chartStateLookup).map(([chartId, chartState]) => [chartId,
516
+ // keep only the state that is controlled by the user, drop the data and labels
517
+ {
518
+ synced: chartState.synced,
519
+ type: chartState.type,
520
+ configuration: chartState.configuration
521
+ }]));
522
+ const shouldExportChartState =
523
+ // Always export if the `exportOnlyDirtyModels` property is not activated
524
+ !exportContext.exportOnlyDirtyModels ||
525
+ // Always export if the chart state has been initialized
526
+ props.initialState?.chartsIntegration != null ||
527
+ // Export if the chart model or context is not empty
528
+ Object.keys(chartsLookup).length > 0 || Object.keys(integrationContextToExport).length > 0;
529
+ if (!shouldExportChartState) {
530
+ return prevState;
531
+ }
532
+ const chartStateToExport = {
533
+ activeChartId: currentActiveChartId,
534
+ charts: chartsLookup,
535
+ // add a custom prop to keep the integration context in the exported state
536
+ integrationContext: integrationContextToExport
537
+ };
538
+ return (0, _extends2.default)({}, prevState, {
539
+ chartsIntegration: chartStateToExport
540
+ });
541
+ }, [apiRef, chartStateLookup, props.chartsIntegration, props.experimentalFeatures?.charts, props.initialState?.chartsIntegration]);
542
+ const stateRestorePreProcessing = React.useCallback((params, restoreContext) => {
543
+ const chartsRestoreState = restoreContext.stateToRestore.chartsIntegration;
544
+ if (!chartsRestoreState) {
545
+ return params;
546
+ }
547
+ const {
548
+ activeChartId: activeChartIdToRestore,
549
+ charts: chartsToRestore,
550
+ integrationContext
551
+ } = chartsRestoreState;
552
+ if (activeChartIdToRestore === undefined || chartsToRestore === undefined || Object.keys(chartsToRestore).length === 0) {
553
+ return params;
554
+ }
555
+ apiRef.current.setState((0, _extends2.default)({}, apiRef.current.state, {
556
+ chartsIntegration: {
557
+ activeChartId: activeChartIdToRestore,
558
+ charts: chartsToRestore
559
+ }
560
+ }));
561
+
562
+ // restore the integration context for each chart
563
+ Object.entries(integrationContext).forEach(([chartId, chartContextState]) => {
564
+ setChartState(chartId, chartContextState);
565
+ });
566
+ return params;
567
+ }, [apiRef, setChartState]);
568
+ (0, _internals.useGridRegisterPipeProcessor)(apiRef, 'exportState', stateExportPreProcessing);
569
+ (0, _internals.useGridRegisterPipeProcessor)(apiRef, 'restoreState', stateRestorePreProcessing);
507
570
  React.useEffect(() => {
508
571
  if (!activeChartId && availableChartIds.length > 0) {
509
572
  setActiveChartId(availableChartIds[0]);
@@ -9,11 +9,13 @@ Object.defineProperty(exports, "__esModule", {
9
9
  exports.useGridDataSourcePremium = void 0;
10
10
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
11
  var React = _interopRequireWildcard(require("react"));
12
+ var _isDeepEqual = require("@mui/x-internals/isDeepEqual");
12
13
  var _xDataGridPro = require("@mui/x-data-grid-pro");
13
14
  var _internals = require("@mui/x-data-grid-pro/internals");
14
15
  var _gridPivotingSelectors = require("../pivoting/gridPivotingSelectors");
15
16
  var _utils = require("./utils");
16
17
  var _gridRowGroupingSelector = require("../rowGrouping/gridRowGroupingSelector");
18
+ var _gridAggregationSelectors = require("../aggregation/gridAggregationSelectors");
17
19
  function getKeyPremium(params) {
18
20
  return JSON.stringify([params.filterModel, params.sortModel, params.groupKeys, params.groupFields, params.start, params.end, params.pivotModel ? {} : params.aggregationModel, params.pivotModel]);
19
21
  }
@@ -23,18 +25,32 @@ const options = {
23
25
  }
24
26
  };
25
27
  const useGridDataSourcePremium = (apiRef, props) => {
28
+ const aggregationModel = (0, _gridAggregationSelectors.gridAggregationModelSelector)(apiRef);
26
29
  const groupingModelSize = (0, _gridRowGroupingSelector.gridRowGroupingSanitizedModelSelector)(apiRef).length;
27
30
  const setStrategyAvailability = React.useCallback(() => {
28
31
  const targetStrategy = props.treeData || !props.disableRowGrouping && groupingModelSize > 0 ? _internals.DataSourceRowsUpdateStrategy.GroupedData : _internals.DataSourceRowsUpdateStrategy.Default;
29
32
  apiRef.current.setStrategyAvailability(_internals.GridStrategyGroup.DataSource, targetStrategy, props.dataSource && !props.lazyLoading ? () => true : () => false);
30
33
  }, [apiRef, props.dataSource, props.lazyLoading, props.treeData, props.disableRowGrouping, groupingModelSize]);
34
+ const handleEditRowWithAggregation = React.useCallback((params, updatedRow) => {
35
+ const rowTree = (0, _xDataGridPro.gridRowTreeSelector)(apiRef);
36
+ if (updatedRow && !(0, _isDeepEqual.isDeepEqual)(updatedRow, params.previousRow)) {
37
+ // Reset the outdated cache, only if the row is _actually_ updated
38
+ apiRef.current.dataSource.cache.clear();
39
+ }
40
+ const groupKeys = (0, _internals.getGroupKeys)(rowTree, params.rowId);
41
+ apiRef.current.updateNestedRows([updatedRow], groupKeys);
42
+ // To refresh the aggregation values of all parent rows and the footer row, recursively re-fetch all parent levels
43
+ (0, _utils.fetchParents)(rowTree, params.rowId, apiRef.current.dataSource.fetchRows);
44
+ }, [apiRef]);
31
45
  const {
32
46
  api,
33
47
  debouncedFetchRows,
34
48
  flatTreeStrategyProcessor,
35
49
  groupedDataStrategyProcessor,
36
50
  events
37
- } = (0, _internals.useGridDataSourceBasePro)(apiRef, props, options);
51
+ } = (0, _internals.useGridDataSourceBasePro)(apiRef, props, (0, _extends2.default)({}, !props.disableAggregation && Object.keys(aggregationModel).length > 0 ? {
52
+ handleEditRow: handleEditRowWithAggregation
53
+ } : {}, options));
38
54
  const aggregateRowRef = React.useRef({});
39
55
  const initialColumns = (0, _internals.gridPivotInitialColumnsSelector)(apiRef);
40
56
  const pivotActive = (0, _internals.gridPivotActiveSelector)(apiRef);
@@ -1,6 +1,7 @@
1
1
  import type { RefObject } from '@mui/x-internals/types';
2
- import { GridColDef } from '@mui/x-data-grid-pro';
2
+ import { GridColDef, GridRowId, GridRowTreeConfig } from '@mui/x-data-grid-pro';
3
3
  import type { GridPrivateApiPremium } from "../../../models/gridApiPremium.js";
4
4
  import type { GridPivotingDynamicPropsOverrides, PivotingColDefCallback, GridPivotModel } from "../pivoting/gridPivotingInterfaces.js";
5
5
  import type { GridGetRowsResponsePivotColumn } from "./models.js";
6
- export declare const getPropsOverrides: (pivotColumns: GridGetRowsResponsePivotColumn[], pivotingColDef: PivotingColDefCallback, pivotModel: GridPivotModel, initialColumns: Map<string, GridColDef>, apiRef: RefObject<GridPrivateApiPremium>) => GridPivotingDynamicPropsOverrides;
6
+ export declare const getPropsOverrides: (pivotColumns: GridGetRowsResponsePivotColumn[], pivotingColDef: PivotingColDefCallback, pivotModel: GridPivotModel, initialColumns: Map<string, GridColDef>, apiRef: RefObject<GridPrivateApiPremium>) => GridPivotingDynamicPropsOverrides;
7
+ export declare const fetchParents: (rowTree: GridRowTreeConfig, rowId: GridRowId, fetchHandler: (id?: GridRowId) => Promise<void>) => Promise<void[]>;
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.getPropsOverrides = void 0;
7
+ exports.getPropsOverrides = exports.fetchParents = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var _xDataGridPro = require("@mui/x-data-grid-pro");
10
10
  const getPropsOverrides = (pivotColumns, pivotingColDef, pivotModel, initialColumns, apiRef) => {
@@ -145,4 +145,17 @@ const getPropsOverrides = (pivotColumns, pivotingColDef, pivotModel, initialColu
145
145
  aggregationModel
146
146
  };
147
147
  };
148
- exports.getPropsOverrides = getPropsOverrides;
148
+ exports.getPropsOverrides = getPropsOverrides;
149
+ const fetchParents = (rowTree, rowId, fetchHandler) => {
150
+ const parents = [];
151
+
152
+ // collect all parents ids
153
+ let currentId = rowId;
154
+ while (currentId !== undefined && currentId !== _xDataGridPro.GRID_ROOT_GROUP_ID) {
155
+ const parentId = rowTree[currentId].parent;
156
+ parents.push(parentId);
157
+ currentId = parentId;
158
+ }
159
+ return Promise.all(parents.reverse().map(fetchHandler));
160
+ };
161
+ exports.fetchParents = fetchParents;
@@ -0,0 +1,8 @@
1
+ import { RefObject } from '@mui/x-internals/types';
2
+ import { CellEditableConditionFn } from '@mui/x-data-grid-pro/internals';
3
+ import { GridPrivateApiPremium } from "../../../models/gridApiPremium.js";
4
+ import { DataGridPremiumProcessedProps } from "../../../models/dataGridPremiumProps.js";
5
+ /**
6
+ * Implementation of the cell editable condition hook of the Data Grid Premium
7
+ */
8
+ export declare const useIsCellEditable: (apiRef: RefObject<GridPrivateApiPremium>, props: DataGridPremiumProcessedProps) => CellEditableConditionFn;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ 'use client';
3
+
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.useIsCellEditable = void 0;
9
+ var React = _interopRequireWildcard(require("react"));
10
+ var _internals = require("@mui/x-data-grid-pro/internals");
11
+ var _gridAggregationSelectors = require("../aggregation/gridAggregationSelectors");
12
+ /**
13
+ * Implementation of the cell editable condition hook of the Data Grid Premium
14
+ */
15
+ const useIsCellEditable = (apiRef, props) => {
16
+ const isCellEditableCommunity = (0, _internals.useIsCellEditable)();
17
+ return React.useCallback(params => {
18
+ const isCellEditable = isCellEditableCommunity(params);
19
+
20
+ // If the cell is not editable by the community hook, return false immediately
21
+ if (!isCellEditable) {
22
+ return false;
23
+ }
24
+
25
+ // If the data source is not used or aggregation is disabled or both tree data and row grouping are disabled, return the community hook result
26
+ if (!props.dataSource || props.disableAggregation || !props.treeData && props.disableRowGrouping) {
27
+ return isCellEditable;
28
+ }
29
+
30
+ // If the cell is not a part of the aggregation model, return the community hook result
31
+ const aggregationModelFields = Object.keys((0, _gridAggregationSelectors.gridAggregationModelSelector)(apiRef));
32
+ if (!aggregationModelFields.includes(params.field)) {
33
+ return isCellEditable;
34
+ }
35
+
36
+ // The cell is a part of the aggregation model and it is retrieved from the server-side data.
37
+ // Allow editing only for the non-grouped rows.
38
+ return params.rowNode.type !== 'group';
39
+ }, [apiRef, props.dataSource, props.treeData, props.disableAggregation, props.disableRowGrouping, isCellEditableCommunity]);
40
+ };
41
+ exports.useIsCellEditable = useIsCellEditable;
@@ -92,12 +92,12 @@ function getGroupingCriteriaProperties(groupedByColDef, rowGroupingColumnMode, r
92
92
  const rowId = (0, _xDataGridPro.gridRowIdSelector)(apiRef, row);
93
93
  const rowNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, rowId);
94
94
  if (rowNode?.type === 'group') {
95
- const originalColDef = columnsLookup[rowNode.groupingField];
96
- if (originalColDef.type === 'singleSelect') {
95
+ const originalColDef = rowNode.groupingField ? columnsLookup[rowNode.groupingField] : null;
96
+ if (originalColDef?.type === 'singleSelect') {
97
97
  // the default valueFormatter of a singleSelect colDef won't work with the grouping column values
98
98
  return value;
99
99
  }
100
- const columnValueFormatter = originalColDef.valueFormatter;
100
+ const columnValueFormatter = originalColDef?.valueFormatter;
101
101
  if (typeof columnValueFormatter === 'function') {
102
102
  return columnValueFormatter(value, row, column, apiRef);
103
103
  }
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-premium v8.15.0
2
+ * @mui/x-data-grid-premium v8.16.0
3
3
  *
4
4
  * @license SEE LICENSE IN LICENSE
5
5
  * This source code is licensed under the SEE LICENSE IN LICENSE license found in the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-data-grid-premium",
3
- "version": "8.15.0",
3
+ "version": "8.16.0",
4
4
  "author": "MUI Team",
5
5
  "description": "The Premium plan edition of the MUI X Data Grid Components.",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -38,10 +38,10 @@
38
38
  "@mui/x-internal-exceljs-fork": "^4.4.1",
39
39
  "clsx": "^2.1.1",
40
40
  "prop-types": "^15.8.1",
41
- "@mui/x-internals": "8.14.0",
42
- "@mui/x-data-grid": "8.15.0",
43
- "@mui/x-data-grid-pro": "8.15.0",
44
- "@mui/x-license": "8.15.0"
41
+ "@mui/x-data-grid": "8.16.0",
42
+ "@mui/x-data-grid-pro": "8.16.0",
43
+ "@mui/x-license": "8.16.0",
44
+ "@mui/x-internals": "8.16.0"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@emotion/react": "^11.9.0",