@mui/x-data-grid-generator 8.13.1 → 8.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@ import { getCommodityColumns } from "../columns/commodities.columns.js";
9
9
  import { getEmployeeColumns } from "../columns/employees.columns.js";
10
10
  import { getRealGridData } from "../services/real-data-service.js";
11
11
  import { addTreeDataOptionsToDemoData } from "../services/tree-data-generator.js";
12
- import { loadServerRows, processTreeDataRows, processRowGroupingRows, DEFAULT_SERVER_OPTIONS } from "./serverUtils.js";
12
+ import { loadServerRows, processTreeDataRows, processRowGroupingRows, processPivotingRows, DEFAULT_SERVER_OPTIONS } from "./serverUtils.js";
13
13
  import { randomInt } from "../services/index.js";
14
14
  import { getMovieRows, getMovieColumns } from "./useMovieData.js";
15
15
  const dataCache = new LRUCache({
@@ -17,11 +17,11 @@ const dataCache = new LRUCache({
17
17
  ttl: 60 * 5 * 1e3 // 5 minutes
18
18
  });
19
19
  export const BASE_URL = 'https://mui.com/x/api/data-grid';
20
- const GET_DEFAULT_DATASET_OPTIONS = isRowGrouping => ({
21
- dataSet: isRowGrouping ? 'Movies' : 'Commodity',
22
- rowLength: isRowGrouping ? getMovieRows().length : 100,
20
+ const GET_DEFAULT_DATASET_OPTIONS = {
21
+ dataSet: 'Commodity',
22
+ rowLength: 100,
23
23
  maxColumns: 6
24
- });
24
+ };
25
25
  const getColumnsFromOptions = options => {
26
26
  let columns;
27
27
  switch (options.dataSet) {
@@ -45,6 +45,28 @@ const getColumnsFromOptions = options => {
45
45
  if (options.maxColumns) {
46
46
  columns = columns.slice(0, options.maxColumns);
47
47
  }
48
+ if (options.derivedColumns) {
49
+ columns = columns.reduce((acc, col) => {
50
+ acc.push(col);
51
+ if (col.type === 'date' || col.type === 'dateTime') {
52
+ acc.push({
53
+ type: 'date',
54
+ field: `${col.field}-year`,
55
+ generateData: row => new Date(row[col.field].getFullYear(), 0, 1),
56
+ editable: false,
57
+ derivedFrom: col.field
58
+ });
59
+ acc.push({
60
+ type: 'date',
61
+ field: `${col.field}-month`,
62
+ generateData: row => new Date(row[col.field].getFullYear(), row[col.field].getMonth(), 1),
63
+ editable: false,
64
+ derivedFrom: col.field
65
+ });
66
+ }
67
+ return acc;
68
+ }, []);
69
+ }
48
70
  return columns;
49
71
  };
50
72
  function decodeParams(url) {
@@ -95,19 +117,20 @@ export const useMockServer = (dataSetOptions, serverOptions, shouldRequestsFail,
95
117
  shouldRequestsFailRef.current = shouldRequestsFail;
96
118
  }
97
119
  }, [shouldRequestsFail]);
98
- const isRowGrouping = dataSetOptions?.rowGrouping ?? false;
99
- const options = _extends({}, GET_DEFAULT_DATASET_OPTIONS(isRowGrouping), dataSetOptions);
120
+ const options = _extends({}, GET_DEFAULT_DATASET_OPTIONS, dataSetOptions);
100
121
  const isTreeData = options.treeData?.groupingField != null;
101
122
  const columns = React.useMemo(() => {
102
123
  return getColumnsFromOptions({
103
124
  dataSet: options.dataSet,
104
125
  editable: options.editable,
105
126
  maxColumns: options.maxColumns,
106
- visibleFields: options.visibleFields
127
+ visibleFields: options.visibleFields,
128
+ derivedColumns: options.derivedColumns
107
129
  });
108
- }, [options.dataSet, options.editable, options.maxColumns, options.visibleFields]);
130
+ }, [options.dataSet, options.editable, options.maxColumns, options.visibleFields, options.derivedColumns]);
109
131
  const initialState = React.useMemo(() => getInitialState(columns, options.treeData?.groupingField), [columns, options.treeData?.groupingField]);
110
- const columnsWithDefaultColDef = React.useMemo(() => columns.map(column => _extends({}, defaultColDef[column.type || 'string'], column)), [columns]);
132
+ const columnsWithDerivedColDef = React.useMemo(() => columns.map(column => _extends({}, defaultColDef[column.type || 'string'], column)), [columns]);
133
+ const columnsWithDefaultColDef = React.useMemo(() => columnsWithDerivedColDef.filter(column => !column.derivedFrom), [columnsWithDerivedColDef]);
111
134
  const getGroupKey = React.useMemo(() => {
112
135
  if (isTreeData) {
113
136
  return row => row[options.treeData.groupingField];
@@ -146,7 +169,7 @@ export const useMockServer = (dataSetOptions, serverOptions, shouldRequestsFail,
146
169
  (async () => {
147
170
  let rowData;
148
171
  const rowLength = options.rowLength;
149
- if (rowLength > 1000) {
172
+ if (rowLength > 1000 && !options.derivedColumns) {
150
173
  rowData = await getRealGridData(1000, columns);
151
174
  rowData = await extrapolateSeed(rowLength, rowData);
152
175
  } else {
@@ -172,9 +195,25 @@ export const useMockServer = (dataSetOptions, serverOptions, shouldRequestsFail,
172
195
  return () => {
173
196
  active = false;
174
197
  };
175
- }, [columns, isTreeData, options.rowLength, options.treeData?.maxDepth, options.treeData?.groupingField, options.treeData?.averageChildren, options.dataSet, options.maxColumns, index]);
198
+ }, [columns, isTreeData, options.rowLength, options.treeData?.maxDepth, options.treeData?.groupingField, options.treeData?.averageChildren, options.dataSet, options.maxColumns, options.derivedColumns, index]);
176
199
  const fetchRows = React.useCallback(async requestUrl => {
177
- if (!requestUrl || !isDataReady) {
200
+ let dataDelay = 0;
201
+ const waitInterval = 10;
202
+ const waitTimeout = 500 * waitInterval; // 5 seconds
203
+ // wait until data is ready
204
+ while (dataRef.current === null) {
205
+ // prevent infinite loop with a timeout
206
+ if (dataDelay > waitTimeout) {
207
+ return sendEmptyResponse();
208
+ }
209
+
210
+ // eslint-disable-next-line no-await-in-loop
211
+ await new Promise(resolve => {
212
+ setTimeout(resolve, waitInterval);
213
+ });
214
+ dataDelay += waitInterval;
215
+ }
216
+ if (!requestUrl) {
178
217
  return sendEmptyResponse();
179
218
  }
180
219
  const params = decodeParams(requestUrl);
@@ -191,10 +230,9 @@ export const useMockServer = (dataSetOptions, serverOptions, shouldRequestsFail,
191
230
  useCursorPagination: serverOptions?.useCursorPagination ?? DEFAULT_SERVER_OPTIONS.useCursorPagination
192
231
  };
193
232
  if (shouldRequestsFailRef.current) {
194
- const {
195
- minDelay,
196
- maxDelay
197
- } = serverOptionsWithDefault;
233
+ // substract the delay made by waiting for data to be ready
234
+ const minDelay = Math.max(0, serverOptionsWithDefault.minDelay - dataDelay);
235
+ const maxDelay = Math.max(0, serverOptionsWithDefault.maxDelay - dataDelay);
198
236
  const delay = randomInt(minDelay, maxDelay);
199
237
  return new Promise((_, reject) => {
200
238
  if (verbose) {
@@ -217,7 +255,20 @@ export const useMockServer = (dataSetOptions, serverOptions, shouldRequestsFail,
217
255
  }, aggregateRow ? {
218
256
  aggregateRow
219
257
  } : {});
220
- } else if (isRowGrouping) {
258
+ } else if (typeof params.pivotModel === 'object' && params.pivotModel.columns && params.pivotModel.rows && params.pivotModel.values) {
259
+ const {
260
+ rows,
261
+ rootRowCount,
262
+ pivotColumns,
263
+ aggregateRow
264
+ } = await processPivotingRows(dataRef.current?.rows ?? [], params, serverOptionsWithDefault, columnsWithDerivedColDef);
265
+ getRowsResponse = {
266
+ rows: rows.slice(),
267
+ rowCount: rootRowCount,
268
+ pivotColumns,
269
+ aggregateRow
270
+ };
271
+ } else if (params.groupFields && params.groupFields.length > 0) {
221
272
  const {
222
273
  rows,
223
274
  rootRowCount,
@@ -254,7 +305,7 @@ export const useMockServer = (dataSetOptions, serverOptions, shouldRequestsFail,
254
305
  }
255
306
  resolve(getRowsResponse);
256
307
  });
257
- }, [dataRef, isDataReady, serverOptions?.verbose, serverOptions?.minDelay, serverOptions?.maxDelay, serverOptions?.useCursorPagination, isTreeData, columnsWithDefaultColDef, nestedPagination, isRowGrouping]);
308
+ }, [dataRef, serverOptions?.verbose, serverOptions?.minDelay, serverOptions?.maxDelay, serverOptions?.useCursorPagination, isTreeData, columnsWithDefaultColDef, columnsWithDerivedColDef, nestedPagination]);
258
309
  const editRow = React.useCallback(async (rowId, updatedRow) => {
259
310
  return new Promise((resolve, reject) => {
260
311
  const minDelay = serverOptions?.minDelay ?? DEFAULT_SERVER_OPTIONS.minDelay;
@@ -56,6 +56,7 @@ export declare const createFakeServer: (dataSetOptions?: Partial<UseDemoDataOpti
56
56
  generateData?: (row: any, context: import("../index.js").GridDataGeneratorContext) => any;
57
57
  dataGeneratorUniquenessEnabled?: boolean;
58
58
  hide?: boolean;
59
+ derivedFrom?: string;
59
60
  } | {
60
61
  type: "actions";
61
62
  getActions: (params: import("@mui/x-data-grid").GridRowParams<any>) => readonly React.ReactElement<import("@mui/x-data-grid").GridActionsCellItemProps>[];
@@ -109,6 +110,7 @@ export declare const createFakeServer: (dataSetOptions?: Partial<UseDemoDataOpti
109
110
  generateData?: (row: any, context: import("../index.js").GridDataGeneratorContext) => any;
110
111
  dataGeneratorUniquenessEnabled?: boolean;
111
112
  hide?: boolean;
113
+ derivedFrom?: string;
112
114
  } | {
113
115
  type: "singleSelect";
114
116
  valueOptions?: import("@mui/x-data-grid").ValueOptions[] | ((params: import("@mui/x-data-grid").GridValueOptionsParams<any>) => Array<import("@mui/x-data-grid").ValueOptions>) | undefined;
@@ -164,6 +166,7 @@ export declare const createFakeServer: (dataSetOptions?: Partial<UseDemoDataOpti
164
166
  generateData?: (row: any, context: import("../index.js").GridDataGeneratorContext) => any;
165
167
  dataGeneratorUniquenessEnabled?: boolean;
166
168
  hide?: boolean;
169
+ derivedFrom?: string;
167
170
  })[];
168
171
  initialState: {
169
172
  columns: {
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-generator v8.13.1
2
+ * @mui/x-data-grid-generator v8.14.1
3
3
  *
4
4
  * @license UNLICENSED
5
5
  * This source code is licensed under the UNLICENSED license found in the
@@ -1,3 +1,3 @@
1
1
  import * as React from 'react';
2
2
  import { GridRenderCellParams } from '@mui/x-data-grid-premium';
3
- export declare function renderProgress(params: GridRenderCellParams<any, number, any>): "" | React.JSX.Element | null;
3
+ export declare function renderProgress(params: GridRenderCellParams<any, number, any>): string | React.JSX.Element | null;
@@ -57,6 +57,9 @@ export function renderProgress(params) {
57
57
  if (params.value == null) {
58
58
  return '';
59
59
  }
60
+ if (params.rowNode.type === 'group') {
61
+ return `${(params.value * 100).toLocaleString()} %`;
62
+ }
60
63
 
61
64
  // If the aggregated value does not have the same unit as the other cell
62
65
  // Then we fall back to the default rendering based on `valueGetter` instead of rendering a progress bar.
@@ -14,9 +14,17 @@ const Value = styled('div')(({
14
14
  alignItems: 'center',
15
15
  justifyContent: 'flex-end',
16
16
  '&.good': {
17
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette.success.mainChannel} / 0.3)` : alpha(theme.palette.success.main, 0.3)
17
+ color: theme.vars ? `rgb(${theme.vars.palette.success.mainChannel})` : theme.palette.success.main
18
18
  },
19
19
  '&.bad': {
20
+ color: theme.vars ? `rgb(${theme.vars.palette.error.mainChannel})` : theme.palette.error.main
21
+ },
22
+ '&.filled.good': {
23
+ color: 'inherit',
24
+ backgroundColor: theme.vars ? `rgba(${theme.vars.palette.success.mainChannel} / 0.3)` : alpha(theme.palette.success.main, 0.3)
25
+ },
26
+ '&.filled.bad': {
27
+ color: 'inherit',
20
28
  backgroundColor: theme.vars ? `rgba(${theme.vars.palette.error.mainChannel} / 0.3)` : alpha(theme.palette.error.main, 0.3)
21
29
  }
22
30
  }));
@@ -26,10 +34,11 @@ const currencyFormatter = new Intl.NumberFormat('en-US', {
26
34
  });
27
35
  const TotalPrice = /*#__PURE__*/React.memo(function TotalPrice(props) {
28
36
  const {
29
- value
37
+ value,
38
+ grouped
30
39
  } = props;
31
40
  return /*#__PURE__*/_jsx(Value, {
32
- className: clsx(value > 1000000 && "good", value < 1000000 && "bad"),
41
+ className: clsx(value > 1000000 && "good", value < 1000000 && "bad", !grouped && "filled"),
33
42
  children: currencyFormatter.format(value)
34
43
  });
35
44
  });
@@ -45,6 +54,7 @@ export function renderTotalPrice(params) {
45
54
  return null;
46
55
  }
47
56
  return /*#__PURE__*/_jsx(TotalPrice, {
48
- value: params.value
57
+ value: params.value,
58
+ grouped: params.rowNode.type === 'group'
49
59
  });
50
60
  }
@@ -20,4 +20,8 @@ export type GridColDefGenerator = GridColDef & {
20
20
  * If `true`, the column will be marked as hidden in the `columnVisibilityModel`.
21
21
  */
22
22
  hide?: boolean;
23
+ /**
24
+ * Reference to the field this column was derived from.
25
+ */
26
+ derivedFrom?: string;
23
27
  };
@@ -1,4 +1,4 @@
1
- import { GridRowModel, GridFilterModel, GridSortModel, GridColDef, GridRowId, GridPaginationModel, GridValidRowModel, GridAggregationModel } from '@mui/x-data-grid-premium';
1
+ import { GridRowModel, GridFilterModel, GridSortModel, GridColDef, GridRowId, GridPaginationModel, GridValidRowModel, GridAggregationModel, GridPivotModel, GridGetRowsResponse } from '@mui/x-data-grid-premium';
2
2
  export interface FakeServerResponse {
3
3
  returnedRows: GridRowModel[];
4
4
  aggregateRow?: GridValidRowModel;
@@ -13,7 +13,15 @@ export interface PageInfo {
13
13
  pageSize?: number;
14
14
  }
15
15
  export interface DefaultServerOptions {
16
+ /**
17
+ * The minimum response delay in milliseconds.
18
+ * For a large dataset, the response delay can be larger than the minimum delay.
19
+ */
16
20
  minDelay: number;
21
+ /**
22
+ * The maximum response delay in milliseconds
23
+ * For a large dataset, the response delay can be larger than the maximum delay.
24
+ */
17
25
  maxDelay: number;
18
26
  useCursorPagination?: boolean;
19
27
  }
@@ -38,6 +46,15 @@ export interface ServerSideQueryOptions {
38
46
  start?: number;
39
47
  end?: number;
40
48
  groupFields?: string[];
49
+ pivotModel?: GridPivotModel;
50
+ }
51
+ interface NestedDataRowsResponse {
52
+ rows: GridRowModel[];
53
+ rootRowCount: number;
54
+ aggregateRow?: GridRowModel;
55
+ }
56
+ interface PivotingDataRowsResponse extends NestedDataRowsResponse {
57
+ pivotColumns: GridGetRowsResponse['pivotColumns'];
41
58
  }
42
59
  export declare const disableDelay: any;
43
60
  export declare const DEFAULT_SERVER_OPTIONS: DefaultServerOptions;
@@ -45,11 +62,6 @@ export declare const DEFAULT_SERVER_OPTIONS: DefaultServerOptions;
45
62
  * Simulates server data loading
46
63
  */
47
64
  export declare const loadServerRows: (rows: GridRowModel[], queryOptions: QueryOptions, serverOptions: ServerOptions, columnsWithDefaultColDef: GridColDef[]) => Promise<FakeServerResponse>;
48
- interface NestedDataRowsResponse {
49
- rows: GridRowModel[];
50
- rootRowCount: number;
51
- aggregateRow?: GridRowModel;
52
- }
53
65
  /**
54
66
  * Simulates server data for tree-data feature
55
67
  */
@@ -58,4 +70,8 @@ export declare const processTreeDataRows: (rows: GridRowModel[], queryOptions: S
58
70
  * Simulates server data for row grouping feature
59
71
  */
60
72
  export declare const processRowGroupingRows: (rows: GridValidRowModel[], queryOptions: ServerSideQueryOptions, serverOptions: ServerOptions, columnsWithDefaultColDef: GridColDef[]) => Promise<NestedDataRowsResponse>;
73
+ /**
74
+ * Simulates server data for pivoting feature
75
+ */
76
+ export declare const processPivotingRows: (rows: GridValidRowModel[], queryOptions: ServerSideQueryOptions, serverOptions: ServerOptions, columnsWithDefaultColDef: GridColDef[]) => Promise<PivotingDataRowsResponse>;
61
77
  export {};