@mui/x-data-grid-premium 7.22.3 → 8.0.0-alpha.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +348 -12
  2. package/README.md +4 -4
  3. package/components/GridColumnMenuAggregationItem.js +4 -6
  4. package/components/GridColumnMenuRowGroupItem.js +1 -2
  5. package/components/GridColumnMenuRowUngroupItem.js +2 -3
  6. package/components/GridExcelExportMenuItem.js +3 -2
  7. package/components/index.d.ts +1 -0
  8. package/components/index.js +12 -0
  9. package/components/promptControl/GridToolbarPromptControl.d.ts +26 -0
  10. package/components/promptControl/GridToolbarPromptControl.js +209 -0
  11. package/components/promptControl/RecordButton.d.ts +16 -0
  12. package/components/promptControl/RecordButton.js +119 -0
  13. package/components/promptControl/index.d.ts +1 -0
  14. package/components/promptControl/index.js +12 -0
  15. package/esm/components/GridColumnMenuAggregationItem.js +4 -6
  16. package/esm/components/GridColumnMenuRowGroupItem.js +1 -2
  17. package/esm/components/GridColumnMenuRowUngroupItem.js +2 -3
  18. package/esm/components/GridExcelExportMenuItem.js +3 -2
  19. package/esm/components/index.js +1 -0
  20. package/esm/components/promptControl/GridToolbarPromptControl.js +202 -0
  21. package/esm/components/promptControl/RecordButton.js +111 -0
  22. package/esm/components/promptControl/index.js +1 -0
  23. package/esm/hooks/features/cellSelection/useGridCellSelection.js +2 -1
  24. package/esm/hooks/features/index.js +2 -1
  25. package/esm/hooks/features/promptControl/api.js +22 -0
  26. package/esm/hooks/features/promptControl/index.js +1 -0
  27. package/esm/hooks/features/promptControl/types.js +1 -0
  28. package/esm/material/icons.js +7 -1
  29. package/esm/material/index.js +4 -2
  30. package/esm/utils/releaseInfo.js +1 -1
  31. package/hooks/features/aggregation/wrapColumnWithAggregation.d.ts +1 -0
  32. package/hooks/features/cellSelection/useGridCellSelection.js +7 -6
  33. package/hooks/features/index.d.ts +1 -0
  34. package/hooks/features/index.js +11 -0
  35. package/hooks/features/promptControl/api.d.ts +2 -0
  36. package/hooks/features/promptControl/api.js +28 -0
  37. package/hooks/features/promptControl/index.d.ts +2 -0
  38. package/hooks/features/promptControl/index.js +12 -0
  39. package/hooks/features/promptControl/types.d.ts +25 -0
  40. package/hooks/features/promptControl/types.js +5 -0
  41. package/index.js +1 -1
  42. package/material/icons.d.ts +6 -0
  43. package/material/icons.js +8 -2
  44. package/material/index.d.ts +2 -0
  45. package/material/index.js +3 -1
  46. package/models/gridPremiumIconSlotsComponent.d.ts +10 -0
  47. package/modern/components/GridColumnMenuAggregationItem.js +4 -6
  48. package/modern/components/GridColumnMenuRowGroupItem.js +1 -2
  49. package/modern/components/GridColumnMenuRowUngroupItem.js +2 -3
  50. package/modern/components/GridExcelExportMenuItem.js +3 -2
  51. package/modern/components/index.js +1 -0
  52. package/modern/components/promptControl/GridToolbarPromptControl.js +202 -0
  53. package/modern/components/promptControl/RecordButton.js +111 -0
  54. package/modern/components/promptControl/index.js +1 -0
  55. package/modern/hooks/features/cellSelection/useGridCellSelection.js +2 -1
  56. package/modern/hooks/features/index.js +2 -1
  57. package/modern/hooks/features/promptControl/api.js +22 -0
  58. package/modern/hooks/features/promptControl/index.js +1 -0
  59. package/modern/hooks/features/promptControl/types.js +1 -0
  60. package/modern/index.js +1 -1
  61. package/modern/material/icons.js +7 -1
  62. package/modern/material/index.js +4 -2
  63. package/modern/utils/releaseInfo.js +1 -1
  64. package/package.json +8 -8
  65. package/utils/releaseInfo.js +1 -1
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.GridToolbarPromptControl = GridToolbarPromptControl;
9
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
+ var React = _interopRequireWildcard(require("react"));
11
+ var _styles = require("@mui/material/styles");
12
+ var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
13
+ var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
14
+ var _xDataGrid = require("@mui/x-data-grid");
15
+ var _internals = require("@mui/x-data-grid/internals");
16
+ var _useGridApiContext = require("../../hooks/utils/useGridApiContext");
17
+ var _useGridRootProps = require("../../hooks/utils/useGridRootProps");
18
+ var _RecordButton = require("./RecordButton");
19
+ var _jsxRuntime = require("react/jsx-runtime");
20
+ const supportsSpeechRecognition = !!_RecordButton.BrowserSpeechRecognition;
21
+ const useUtilityClasses = (ownerState, recording) => {
22
+ const {
23
+ classes
24
+ } = ownerState;
25
+ const slots = {
26
+ root: ['toolbarPromptControl', recording && 'toolbarPromptControl--recording'],
27
+ recordingIndicator: ['toolbarPromptControlRecordingIndicator'],
28
+ recordButton: ['toolbarPromptControlRecordButton'],
29
+ sendButton: ['toolbarPromptControlSendButton']
30
+ };
31
+ return (0, _composeClasses.default)(slots, _xDataGrid.getDataGridUtilityClass, classes);
32
+ };
33
+ const GridToolbarPromptControlRoot = (0, _styles.styled)('div', {
34
+ name: 'MuiDataGrid',
35
+ slot: 'ToolbarPromptControl',
36
+ overridesResolver: (_, styles) => styles.toolbarPromptControl
37
+ })({
38
+ flex: 1,
39
+ display: 'flex',
40
+ flexDirection: 'row'
41
+ });
42
+ function sampleData(apiRef) {
43
+ const columns = (0, _xDataGrid.gridColumnDefinitionsSelector)(apiRef);
44
+ const rows = Object.values((0, _xDataGrid.gridRowsLookupSelector)(apiRef));
45
+ const columnExamples = {};
46
+ columns.forEach(column => {
47
+ columnExamples[column.field] = Array.from({
48
+ length: Math.min(5, rows.length)
49
+ }).map(() => {
50
+ const row = rows[Math.floor(Math.random() * rows.length)];
51
+ if (column.valueGetter) {
52
+ return column.valueGetter(row[column.field], row, column, apiRef);
53
+ }
54
+ return row[column.field];
55
+ });
56
+ });
57
+ return columnExamples;
58
+ }
59
+ function generateContext(apiRef, examples) {
60
+ const columns = (0, _xDataGrid.gridColumnDefinitionsSelector)(apiRef);
61
+ const columnsContext = columns.map(column => ({
62
+ field: column.field,
63
+ description: column.description ?? null,
64
+ examples: examples?.[column.field] ?? column.unstable_examples ?? [],
65
+ type: column.type ?? 'string',
66
+ allowedOperators: column.filterOperators?.map(operator => operator.value) ?? []
67
+ }));
68
+ return `The columns are described by the following JSON:\n${JSON.stringify(columnsContext)}`;
69
+ }
70
+ function GridToolbarPromptControl(props) {
71
+ const apiRef = (0, _useGridApiContext.useGridApiContext)();
72
+ const rootProps = (0, _useGridRootProps.useGridRootProps)();
73
+ const {
74
+ onPrompt,
75
+ lang,
76
+ allowDataSampling = false
77
+ } = props;
78
+ const [isLoading, setLoading] = React.useState(false);
79
+ const [error, setError] = React.useState(null);
80
+ const [isRecording, setRecording] = React.useState(false);
81
+ const [query, setQuery] = React.useState('');
82
+ const classes = useUtilityClasses(rootProps, isRecording);
83
+ const examplesFromData = React.useMemo(() => allowDataSampling ? sampleData(apiRef) : undefined, [apiRef, allowDataSampling]);
84
+ const processPrompt = React.useCallback(() => {
85
+ const context = generateContext(apiRef, examplesFromData);
86
+ const columnsByField = (0, _xDataGrid.gridColumnLookupSelector)(apiRef);
87
+ setLoading(true);
88
+ setError(null);
89
+ apiRef.current.setLoading(true);
90
+ onPrompt(context, query).then(result => {
91
+ const interestColumns = [];
92
+ apiRef.current.setFilterModel({
93
+ items: result.filters.map((filter, index) => {
94
+ const item = {
95
+ id: index,
96
+ field: filter.column,
97
+ operator: filter.operator,
98
+ value: filter.value
99
+ };
100
+ const column = columnsByField[filter.column];
101
+ if (column.type === 'singleSelect') {
102
+ const options = (0, _internals.getValueOptions)(column) ?? [];
103
+ const found = options.find(option => typeof option === 'object' && option.label === filter.value);
104
+ if (found) {
105
+ item.value = found.value;
106
+ }
107
+ }
108
+ return item;
109
+ }),
110
+ logicOperator: result.filterOperator ?? _xDataGrid.GridLogicOperator.And,
111
+ quickFilterValues: []
112
+ });
113
+ apiRef.current.setRowGroupingModel(result.grouping.map(g => g.column));
114
+ apiRef.current.setAggregationModel(result.aggregation);
115
+ apiRef.current.setSortModel(result.sorting.map(s => ({
116
+ field: s.column,
117
+ sort: s.direction
118
+ })));
119
+ const rows = (0, _internals.getVisibleRows)(apiRef, rootProps);
120
+ const selectedRowIds = result.select === -1 ? [] : rows.rows.slice(0, result.select).map(r => {
121
+ return apiRef.current.getRowId(r);
122
+ });
123
+ apiRef.current.setRowSelectionModel(selectedRowIds);
124
+ const columns = apiRef.current.getAllColumns();
125
+ const targetIndex = Number(columns.find(c => c.field === _xDataGrid.GRID_CHECKBOX_SELECTION_FIELD) !== undefined) + Number(result.grouping.length);
126
+ interestColumns.push(...Object.keys(result.aggregation));
127
+ interestColumns.push(...result.filters.map(f => f.column));
128
+ interestColumns.reverse().forEach(c => apiRef.current.setColumnIndex(c, targetIndex));
129
+ }).catch(_ => {
130
+ setError(apiRef.current.getLocaleText('toolbarPromptControlErrorMessage'));
131
+ }).finally(() => {
132
+ setLoading(false);
133
+ apiRef.current.setState(state => (0, _extends2.default)({}, state, {
134
+ rows: (0, _extends2.default)({}, state.rows, {
135
+ loading: false
136
+ })
137
+ }));
138
+ });
139
+ }, [apiRef, rootProps, onPrompt, examplesFromData, query]);
140
+ const handleChange = (0, _useEventCallback.default)(event => {
141
+ setQuery(event.target.value);
142
+ });
143
+ const handleKeyDown = (0, _useEventCallback.default)(event => {
144
+ if (event.code === 'Enter') {
145
+ processPrompt();
146
+ }
147
+ });
148
+ const handleDone = (0, _useEventCallback.default)(value => {
149
+ setQuery(value);
150
+ if (value) {
151
+ processPrompt();
152
+ }
153
+ });
154
+ const placeholder = supportsSpeechRecognition ? apiRef.current.getLocaleText('toolbarPromptControlWithRecordingPlaceholder') : apiRef.current.getLocaleText('toolbarPromptControlPlaceholder');
155
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridToolbarPromptControlRoot, {
156
+ ownerState: rootProps,
157
+ className: classes.root,
158
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTextField, {
159
+ variant: "outlined",
160
+ placeholder: isRecording ? apiRef.current.getLocaleText('toolbarPromptControlRecordingPlaceholder') : placeholder,
161
+ "aria-label": apiRef.current.getLocaleText('toolbarPromptControlLabel'),
162
+ disabled: isLoading,
163
+ value: query,
164
+ style: {
165
+ flex: 1
166
+ },
167
+ onChange: handleChange,
168
+ size: "small",
169
+ onKeyDown: handleKeyDown,
170
+ error: !!error,
171
+ helperText: error,
172
+ InputProps: {
173
+ startAdornment: supportsSpeechRecognition && /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseInputAdornment, {
174
+ position: "start",
175
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RecordButton.RecordButton, {
176
+ className: classes.recordButton,
177
+ lang: lang,
178
+ recording: isRecording,
179
+ setRecording: setRecording,
180
+ disabled: isLoading,
181
+ onUpdate: setQuery,
182
+ onDone: handleDone,
183
+ onError: setError
184
+ })
185
+ }),
186
+ endAdornment: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseInputAdornment, {
187
+ position: "end",
188
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
189
+ title: apiRef.current.getLocaleText('toolbarPromptControlSendActionLabel'),
190
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
191
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseIconButton, {
192
+ className: classes.sendButton,
193
+ disabled: isLoading || isRecording || query === '',
194
+ color: "primary",
195
+ onClick: processPrompt,
196
+ size: "small",
197
+ "aria-label": apiRef.current.getLocaleText('toolbarPromptControlSendActionAriaLabel'),
198
+ edge: "end",
199
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.toolbarPromptSendIcon, {
200
+ fontSize: "small"
201
+ })
202
+ })
203
+ })
204
+ })
205
+ })
206
+ }
207
+ })
208
+ });
209
+ }
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ export declare const BrowserSpeechRecognition: any;
3
+ type SpeechRecognitionOptions = {
4
+ onUpdate: (value: string) => void;
5
+ onDone: (value: string) => void;
6
+ onError: (error: string) => void;
7
+ };
8
+ interface RecordButtonProps extends SpeechRecognitionOptions {
9
+ disabled: boolean;
10
+ lang?: string;
11
+ recording: boolean;
12
+ setRecording: (value: boolean) => void;
13
+ className: string;
14
+ }
15
+ declare function RecordButton(props: RecordButtonProps): React.JSX.Element;
16
+ export { RecordButton };
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.BrowserSpeechRecognition = void 0;
9
+ exports.RecordButton = RecordButton;
10
+ var React = _interopRequireWildcard(require("react"));
11
+ var _useTimeout = require("@mui/utils/useTimeout");
12
+ var _useLazyRef = _interopRequireDefault(require("@mui/utils/useLazyRef"));
13
+ var _useGridApiContext = require("../../hooks/utils/useGridApiContext");
14
+ var _useGridRootProps = require("../../hooks/utils/useGridRootProps");
15
+ var _jsxRuntime = require("react/jsx-runtime");
16
+ const BrowserSpeechRecognition = exports.BrowserSpeechRecognition = globalThis.SpeechRecognition || globalThis.webkitSpeechRecognition;
17
+ function RecordButton(props) {
18
+ const apiRef = (0, _useGridApiContext.useGridApiContext)();
19
+ const rootProps = (0, _useGridRootProps.useGridRootProps)();
20
+ const {
21
+ lang,
22
+ recording,
23
+ setRecording,
24
+ disabled,
25
+ className,
26
+ onDone,
27
+ onUpdate,
28
+ onError
29
+ } = props;
30
+ const buttonRef = React.useRef(null);
31
+ const recognition = (0, _useLazyRef.default)(() => {
32
+ if (!BrowserSpeechRecognition) {
33
+ return {
34
+ start: () => {},
35
+ abort: () => {}
36
+ };
37
+ }
38
+ const timeout = new _useTimeout.Timeout();
39
+ const instance = new BrowserSpeechRecognition();
40
+ instance.continuous = true;
41
+ instance.interimResults = true;
42
+ instance.lang = lang;
43
+ let finalResult = '';
44
+ let interimResult = '';
45
+ function start(options) {
46
+ if (recording) {
47
+ return;
48
+ }
49
+ setRecording(true);
50
+ instance.onresult = event => {
51
+ finalResult = '';
52
+ interimResult = '';
53
+ if (typeof event.results === 'undefined') {
54
+ instance.stop();
55
+ return;
56
+ }
57
+ for (let i = event.resultIndex; i < event.results.length; i += 1) {
58
+ if (event.results[i].isFinal) {
59
+ finalResult += event.results[i][0].transcript;
60
+ } else {
61
+ interimResult += event.results[i][0].transcript;
62
+ }
63
+ }
64
+ if (finalResult === '') {
65
+ options.onUpdate(interimResult);
66
+ }
67
+ timeout.start(1000, () => instance.stop());
68
+ };
69
+ instance.onsoundend = () => {
70
+ instance.stop();
71
+ };
72
+ instance.onend = () => {
73
+ options.onDone(finalResult);
74
+ setRecording(false);
75
+ };
76
+ instance.onerror = error => {
77
+ options.onError(error.message);
78
+ instance.stop();
79
+ setRecording(false);
80
+ };
81
+ instance.start();
82
+ }
83
+ function abort() {
84
+ instance.abort();
85
+ }
86
+ return {
87
+ start,
88
+ abort
89
+ };
90
+ }).current;
91
+ const handleClick = () => {
92
+ if (!recording) {
93
+ recognition.start({
94
+ onDone,
95
+ onUpdate,
96
+ onError
97
+ });
98
+ return;
99
+ }
100
+ recognition.abort();
101
+ };
102
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
103
+ title: recording ? apiRef.current.getLocaleText('toolbarPromptControlRecordButtonActiveLabel') : apiRef.current.getLocaleText('toolbarPromptControlRecordButtonDefaultLabel'),
104
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
105
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseIconButton, {
106
+ color: recording ? 'primary' : 'default',
107
+ className: className,
108
+ disabled: disabled,
109
+ onClick: handleClick,
110
+ ref: buttonRef,
111
+ size: "small",
112
+ edge: "start",
113
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.toolbarPromptRecordIcon, {
114
+ fontSize: "small"
115
+ })
116
+ })
117
+ })
118
+ });
119
+ }
@@ -0,0 +1 @@
1
+ export { GridToolbarPromptControl as Unstable_GridToolbarPromptControl } from './GridToolbarPromptControl';
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "Unstable_GridToolbarPromptControl", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _GridToolbarPromptControl.GridToolbarPromptControl;
10
+ }
11
+ });
12
+ var _GridToolbarPromptControl = require("./GridToolbarPromptControl");
@@ -4,13 +4,11 @@ import _toPropertyKey from "@babel/runtime/helpers/esm/toPropertyKey";
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { useGridSelector } from '@mui/x-data-grid-pro';
7
- import MenuItem from '@mui/material/MenuItem';
8
7
  import ListItemIcon from '@mui/material/ListItemIcon';
9
8
  import ListItemText from '@mui/material/ListItemText';
10
9
  import FormControl from '@mui/material/FormControl';
11
10
  import InputLabel from '@mui/material/InputLabel';
12
11
  import { unstable_useId as useId } from '@mui/utils';
13
- import Select from '@mui/material/Select';
14
12
  import { useGridApiContext } from "../hooks/utils/useGridApiContext.js";
15
13
  import { useGridRootProps } from "../hooks/utils/useGridRootProps.js";
16
14
  import { canColumnHaveAggregationFunction, getAggregationFunctionLabel, getAvailableAggregationFunctions } from "../hooks/features/aggregation/gridAggregationUtils.js";
@@ -54,7 +52,7 @@ function GridColumnMenuAggregationItem(props) {
54
52
  apiRef.current.hideColumnMenu();
55
53
  };
56
54
  const label = apiRef.current.getLocaleText('aggregationMenuItemHeader');
57
- return /*#__PURE__*/_jsxs(MenuItem, {
55
+ return /*#__PURE__*/_jsxs(rootProps.slots.baseMenuItem, {
58
56
  disableRipple: true,
59
57
  children: [/*#__PURE__*/_jsx(ListItemIcon, {
60
58
  children: /*#__PURE__*/_jsx(rootProps.slots.columnMenuAggregationIcon, {
@@ -70,7 +68,7 @@ function GridColumnMenuAggregationItem(props) {
70
68
  children: [/*#__PURE__*/_jsx(InputLabel, {
71
69
  id: `${id}-label`,
72
70
  children: label
73
- }), /*#__PURE__*/_jsxs(Select, {
71
+ }), /*#__PURE__*/_jsxs(rootProps.slots.baseSelect, {
74
72
  labelId: `${id}-label`,
75
73
  id: `${id}-input`,
76
74
  value: selectedAggregationRule,
@@ -79,10 +77,10 @@ function GridColumnMenuAggregationItem(props) {
79
77
  onChange: handleAggregationItemChange,
80
78
  onBlur: event => event.stopPropagation(),
81
79
  fullWidth: true,
82
- children: [/*#__PURE__*/_jsx(MenuItem, {
80
+ children: [/*#__PURE__*/_jsx(rootProps.slots.baseMenuItem, {
83
81
  value: "",
84
82
  children: "..."
85
- }), availableAggregationFunctions.map(aggFunc => /*#__PURE__*/_jsx(MenuItem, {
83
+ }), availableAggregationFunctions.map(aggFunc => /*#__PURE__*/_jsx(rootProps.slots.baseMenuItem, {
86
84
  value: aggFunc,
87
85
  children: getAggregationFunctionLabel({
88
86
  apiRef,
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import MenuItem from '@mui/material/MenuItem';
3
2
  import ListItemIcon from '@mui/material/ListItemIcon';
4
3
  import ListItemText from '@mui/material/ListItemText';
5
4
  import { useGridSelector, gridColumnLookupSelector } from '@mui/x-data-grid-pro';
@@ -24,7 +23,7 @@ export function GridColumnMenuRowGroupItem(props) {
24
23
  };
25
24
  const groupedColumn = columnsLookup[field];
26
25
  const name = groupedColumn.headerName ?? field;
27
- return /*#__PURE__*/_jsxs(MenuItem, {
26
+ return /*#__PURE__*/_jsxs(rootProps.slots.baseMenuItem, {
28
27
  onClick: ungroupColumn,
29
28
  disabled: !groupedColumn.groupable,
30
29
  children: [/*#__PURE__*/_jsx(ListItemIcon, {
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import MenuItem from '@mui/material/MenuItem';
3
2
  import ListItemIcon from '@mui/material/ListItemIcon';
4
3
  import ListItemText from '@mui/material/ListItemText';
5
4
  import { gridColumnLookupSelector, useGridSelector } from '@mui/x-data-grid-pro';
@@ -29,7 +28,7 @@ export function GridColumnMenuRowUngroupItem(props) {
29
28
  };
30
29
  const name = columnsLookup[colDef.field].headerName ?? colDef.field;
31
30
  if (rowGroupingModel.includes(colDef.field)) {
32
- return /*#__PURE__*/_jsxs(MenuItem, {
31
+ return /*#__PURE__*/_jsxs(rootProps.slots.baseMenuItem, {
33
32
  onClick: ungroupColumn,
34
33
  children: [/*#__PURE__*/_jsx(ListItemIcon, {
35
34
  children: /*#__PURE__*/_jsx(rootProps.slots.columnMenuUngroupIcon, {
@@ -40,7 +39,7 @@ export function GridColumnMenuRowUngroupItem(props) {
40
39
  })]
41
40
  });
42
41
  }
43
- return /*#__PURE__*/_jsxs(MenuItem, {
42
+ return /*#__PURE__*/_jsxs(rootProps.slots.baseMenuItem, {
44
43
  onClick: groupColumn,
45
44
  children: [/*#__PURE__*/_jsx(ListItemIcon, {
46
45
  children: /*#__PURE__*/_jsx(rootProps.slots.columnMenuGroupIcon, {
@@ -3,17 +3,18 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
3
3
  const _excluded = ["hideMenu", "options"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
- import MenuItem from '@mui/material/MenuItem';
7
6
  import { useGridApiContext } from "../hooks/utils/useGridApiContext.js";
7
+ import { useGridRootProps } from "../hooks/utils/useGridRootProps.js";
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
9
9
  function GridExcelExportMenuItem(props) {
10
10
  const apiRef = useGridApiContext();
11
+ const rootProps = useGridRootProps();
11
12
  const {
12
13
  hideMenu,
13
14
  options
14
15
  } = props,
15
16
  other = _objectWithoutPropertiesLoose(props, _excluded);
16
- return /*#__PURE__*/_jsx(MenuItem, _extends({
17
+ return /*#__PURE__*/_jsx(rootProps.slots.baseMenuItem, _extends({
17
18
  onClick: () => {
18
19
  apiRef.current.exportDataAsExcel(options);
19
20
  hideMenu?.();
@@ -1,4 +1,5 @@
1
1
  export * from "./GridExcelExportMenuItem.js";
2
2
  export * from "../material/icons.js";
3
3
  export * from "./GridColumnMenuAggregationItem.js";
4
+ export * from "./promptControl/index.js";
4
5
  export { GridColumnMenuGroupingItem } from "./GridPremiumColumnMenu.js";
@@ -0,0 +1,202 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { styled } from '@mui/material/styles';
4
+ import composeClasses from '@mui/utils/composeClasses';
5
+ import useEventCallback from '@mui/utils/useEventCallback';
6
+ import { getDataGridUtilityClass, GRID_CHECKBOX_SELECTION_FIELD, gridColumnDefinitionsSelector, gridColumnLookupSelector, GridLogicOperator, gridRowsLookupSelector } from '@mui/x-data-grid';
7
+ import { getValueOptions, getVisibleRows } from '@mui/x-data-grid/internals';
8
+ import { useGridApiContext } from "../../hooks/utils/useGridApiContext.js";
9
+ import { useGridRootProps } from "../../hooks/utils/useGridRootProps.js";
10
+ import { RecordButton, BrowserSpeechRecognition } from "./RecordButton.js";
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ const supportsSpeechRecognition = !!BrowserSpeechRecognition;
13
+ const useUtilityClasses = (ownerState, recording) => {
14
+ const {
15
+ classes
16
+ } = ownerState;
17
+ const slots = {
18
+ root: ['toolbarPromptControl', recording && 'toolbarPromptControl--recording'],
19
+ recordingIndicator: ['toolbarPromptControlRecordingIndicator'],
20
+ recordButton: ['toolbarPromptControlRecordButton'],
21
+ sendButton: ['toolbarPromptControlSendButton']
22
+ };
23
+ return composeClasses(slots, getDataGridUtilityClass, classes);
24
+ };
25
+ const GridToolbarPromptControlRoot = styled('div', {
26
+ name: 'MuiDataGrid',
27
+ slot: 'ToolbarPromptControl',
28
+ overridesResolver: (_, styles) => styles.toolbarPromptControl
29
+ })({
30
+ flex: 1,
31
+ display: 'flex',
32
+ flexDirection: 'row'
33
+ });
34
+ function sampleData(apiRef) {
35
+ const columns = gridColumnDefinitionsSelector(apiRef);
36
+ const rows = Object.values(gridRowsLookupSelector(apiRef));
37
+ const columnExamples = {};
38
+ columns.forEach(column => {
39
+ columnExamples[column.field] = Array.from({
40
+ length: Math.min(5, rows.length)
41
+ }).map(() => {
42
+ const row = rows[Math.floor(Math.random() * rows.length)];
43
+ if (column.valueGetter) {
44
+ return column.valueGetter(row[column.field], row, column, apiRef);
45
+ }
46
+ return row[column.field];
47
+ });
48
+ });
49
+ return columnExamples;
50
+ }
51
+ function generateContext(apiRef, examples) {
52
+ const columns = gridColumnDefinitionsSelector(apiRef);
53
+ const columnsContext = columns.map(column => ({
54
+ field: column.field,
55
+ description: column.description ?? null,
56
+ examples: examples?.[column.field] ?? column.unstable_examples ?? [],
57
+ type: column.type ?? 'string',
58
+ allowedOperators: column.filterOperators?.map(operator => operator.value) ?? []
59
+ }));
60
+ return `The columns are described by the following JSON:\n${JSON.stringify(columnsContext)}`;
61
+ }
62
+ function GridToolbarPromptControl(props) {
63
+ const apiRef = useGridApiContext();
64
+ const rootProps = useGridRootProps();
65
+ const {
66
+ onPrompt,
67
+ lang,
68
+ allowDataSampling = false
69
+ } = props;
70
+ const [isLoading, setLoading] = React.useState(false);
71
+ const [error, setError] = React.useState(null);
72
+ const [isRecording, setRecording] = React.useState(false);
73
+ const [query, setQuery] = React.useState('');
74
+ const classes = useUtilityClasses(rootProps, isRecording);
75
+ const examplesFromData = React.useMemo(() => allowDataSampling ? sampleData(apiRef) : undefined, [apiRef, allowDataSampling]);
76
+ const processPrompt = React.useCallback(() => {
77
+ const context = generateContext(apiRef, examplesFromData);
78
+ const columnsByField = gridColumnLookupSelector(apiRef);
79
+ setLoading(true);
80
+ setError(null);
81
+ apiRef.current.setLoading(true);
82
+ onPrompt(context, query).then(result => {
83
+ const interestColumns = [];
84
+ apiRef.current.setFilterModel({
85
+ items: result.filters.map((filter, index) => {
86
+ const item = {
87
+ id: index,
88
+ field: filter.column,
89
+ operator: filter.operator,
90
+ value: filter.value
91
+ };
92
+ const column = columnsByField[filter.column];
93
+ if (column.type === 'singleSelect') {
94
+ const options = getValueOptions(column) ?? [];
95
+ const found = options.find(option => typeof option === 'object' && option.label === filter.value);
96
+ if (found) {
97
+ item.value = found.value;
98
+ }
99
+ }
100
+ return item;
101
+ }),
102
+ logicOperator: result.filterOperator ?? GridLogicOperator.And,
103
+ quickFilterValues: []
104
+ });
105
+ apiRef.current.setRowGroupingModel(result.grouping.map(g => g.column));
106
+ apiRef.current.setAggregationModel(result.aggregation);
107
+ apiRef.current.setSortModel(result.sorting.map(s => ({
108
+ field: s.column,
109
+ sort: s.direction
110
+ })));
111
+ const rows = getVisibleRows(apiRef, rootProps);
112
+ const selectedRowIds = result.select === -1 ? [] : rows.rows.slice(0, result.select).map(r => {
113
+ return apiRef.current.getRowId(r);
114
+ });
115
+ apiRef.current.setRowSelectionModel(selectedRowIds);
116
+ const columns = apiRef.current.getAllColumns();
117
+ const targetIndex = Number(columns.find(c => c.field === GRID_CHECKBOX_SELECTION_FIELD) !== undefined) + Number(result.grouping.length);
118
+ interestColumns.push(...Object.keys(result.aggregation));
119
+ interestColumns.push(...result.filters.map(f => f.column));
120
+ interestColumns.reverse().forEach(c => apiRef.current.setColumnIndex(c, targetIndex));
121
+ }).catch(_ => {
122
+ setError(apiRef.current.getLocaleText('toolbarPromptControlErrorMessage'));
123
+ }).finally(() => {
124
+ setLoading(false);
125
+ apiRef.current.setState(state => _extends({}, state, {
126
+ rows: _extends({}, state.rows, {
127
+ loading: false
128
+ })
129
+ }));
130
+ });
131
+ }, [apiRef, rootProps, onPrompt, examplesFromData, query]);
132
+ const handleChange = useEventCallback(event => {
133
+ setQuery(event.target.value);
134
+ });
135
+ const handleKeyDown = useEventCallback(event => {
136
+ if (event.code === 'Enter') {
137
+ processPrompt();
138
+ }
139
+ });
140
+ const handleDone = useEventCallback(value => {
141
+ setQuery(value);
142
+ if (value) {
143
+ processPrompt();
144
+ }
145
+ });
146
+ const placeholder = supportsSpeechRecognition ? apiRef.current.getLocaleText('toolbarPromptControlWithRecordingPlaceholder') : apiRef.current.getLocaleText('toolbarPromptControlPlaceholder');
147
+ return /*#__PURE__*/_jsx(GridToolbarPromptControlRoot, {
148
+ ownerState: rootProps,
149
+ className: classes.root,
150
+ children: /*#__PURE__*/_jsx(rootProps.slots.baseTextField, {
151
+ variant: "outlined",
152
+ placeholder: isRecording ? apiRef.current.getLocaleText('toolbarPromptControlRecordingPlaceholder') : placeholder,
153
+ "aria-label": apiRef.current.getLocaleText('toolbarPromptControlLabel'),
154
+ disabled: isLoading,
155
+ value: query,
156
+ style: {
157
+ flex: 1
158
+ },
159
+ onChange: handleChange,
160
+ size: "small",
161
+ onKeyDown: handleKeyDown,
162
+ error: !!error,
163
+ helperText: error,
164
+ InputProps: {
165
+ startAdornment: supportsSpeechRecognition && /*#__PURE__*/_jsx(rootProps.slots.baseInputAdornment, {
166
+ position: "start",
167
+ children: /*#__PURE__*/_jsx(RecordButton, {
168
+ className: classes.recordButton,
169
+ lang: lang,
170
+ recording: isRecording,
171
+ setRecording: setRecording,
172
+ disabled: isLoading,
173
+ onUpdate: setQuery,
174
+ onDone: handleDone,
175
+ onError: setError
176
+ })
177
+ }),
178
+ endAdornment: /*#__PURE__*/_jsx(rootProps.slots.baseInputAdornment, {
179
+ position: "end",
180
+ children: /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
181
+ title: apiRef.current.getLocaleText('toolbarPromptControlSendActionLabel'),
182
+ children: /*#__PURE__*/_jsx("div", {
183
+ children: /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, {
184
+ className: classes.sendButton,
185
+ disabled: isLoading || isRecording || query === '',
186
+ color: "primary",
187
+ onClick: processPrompt,
188
+ size: "small",
189
+ "aria-label": apiRef.current.getLocaleText('toolbarPromptControlSendActionAriaLabel'),
190
+ edge: "end",
191
+ children: /*#__PURE__*/_jsx(rootProps.slots.toolbarPromptSendIcon, {
192
+ fontSize: "small"
193
+ })
194
+ })
195
+ })
196
+ })
197
+ })
198
+ }
199
+ })
200
+ });
201
+ }
202
+ export { GridToolbarPromptControl };