drf-react-by-schema 0.3.0 → 0.3.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 (83) hide show
  1. package/dist/api.d.ts +84 -0
  2. package/dist/api.js +613 -0
  3. package/dist/components/DataGridBySchemaEditable/ConfirmDialog.d.ts +8 -0
  4. package/dist/components/DataGridBySchemaEditable/ConfirmDialog.js +21 -0
  5. package/dist/components/DataGridBySchemaEditable/CustomToolbar.d.ts +16 -0
  6. package/dist/components/DataGridBySchemaEditable/CustomToolbar.js +77 -0
  7. package/dist/components/DataGridBySchemaEditable/FooterToolbar.d.ts +16 -0
  8. package/dist/components/DataGridBySchemaEditable/FooterToolbar.js +41 -0
  9. package/dist/components/DataGridBySchemaEditable/GridDecimalInput.d.ts +8 -0
  10. package/dist/components/DataGridBySchemaEditable/GridDecimalInput.js +32 -0
  11. package/dist/components/DataGridBySchemaEditable/GridPatternInput.d.ts +8 -0
  12. package/dist/components/DataGridBySchemaEditable/GridPatternInput.js +30 -0
  13. package/dist/components/DataGridBySchemaEditable/InputInterval.d.ts +3 -0
  14. package/dist/components/DataGridBySchemaEditable/InputInterval.js +105 -0
  15. package/dist/components/DataGridBySchemaEditable/SelectEditInputCell.d.ts +33 -0
  16. package/dist/components/DataGridBySchemaEditable/SelectEditInputCell.js +140 -0
  17. package/dist/components/DataGridBySchemaEditable/utils.d.ts +15 -0
  18. package/{src/components/DataGridBySchemaEditable/utils.ts → dist/components/DataGridBySchemaEditable/utils.js} +32 -50
  19. package/dist/components/DataGridBySchemaEditable.d.ts +34 -0
  20. package/dist/components/DataGridBySchemaEditable.js +549 -0
  21. package/dist/components/DataTotals.d.ts +14 -0
  22. package/dist/components/DataTotals.js +23 -0
  23. package/dist/components/DialogActions.d.ts +10 -0
  24. package/dist/components/DialogActions.js +17 -0
  25. package/dist/components/DialogJSONSchemaForm.d.ts +12 -0
  26. package/dist/components/DialogJSONSchemaForm.js +20 -0
  27. package/dist/components/FormButtons.d.ts +14 -0
  28. package/dist/components/FormButtons.js +39 -0
  29. package/dist/components/GenericModelList.d.ts +19 -0
  30. package/dist/components/GenericModelList.js +113 -0
  31. package/dist/components/GenericRelatedModelList.d.ts +25 -0
  32. package/dist/components/GenericRelatedModelList.js +111 -0
  33. package/dist/components/TextFieldBySchema.js +39 -0
  34. package/dist/context/APIWrapper.d.ts +12 -0
  35. package/dist/context/APIWrapper.js +341 -0
  36. package/{src/context/APIWrapperContext.tsx → dist/context/APIWrapperContext.d.ts} +22 -31
  37. package/dist/context/APIWrapperContext.js +15 -0
  38. package/{src/context/DRFReactBySchemaContext.tsx → dist/context/DRFReactBySchemaContext.d.ts} +4 -17
  39. package/dist/context/DRFReactBySchemaContext.js +19 -0
  40. package/dist/context/DRFReactBySchemaProvider.d.ts +13 -0
  41. package/dist/context/DRFReactBySchemaProvider.js +53 -0
  42. package/dist/context/Form.d.ts +11 -0
  43. package/dist/context/Form.js +82 -0
  44. package/dist/context/Overlays.d.ts +4 -0
  45. package/dist/context/Overlays.js +87 -0
  46. package/dist/index.d.ts +11 -0
  47. package/{src/styles/index.ts → dist/styles/index.d.ts} +0 -1
  48. package/dist/styles/index.js +28 -0
  49. package/dist/styles/layout.d.ts +107 -0
  50. package/dist/styles/layout.js +56 -0
  51. package/dist/styles/theme.d.ts +21 -0
  52. package/dist/styles/theme.js +139 -0
  53. package/dist/utils.d.ts +75 -0
  54. package/dist/utils.js +268 -0
  55. package/package.json +11 -2
  56. package/.eslintrc.js +0 -14
  57. package/.gitlab-ci.yml +0 -14
  58. package/src/api.ts +0 -727
  59. package/src/components/DataGridBySchemaEditable/ConfirmDialog.tsx +0 -41
  60. package/src/components/DataGridBySchemaEditable/CustomToolbar.tsx +0 -93
  61. package/src/components/DataGridBySchemaEditable/FooterToolbar.tsx +0 -77
  62. package/src/components/DataGridBySchemaEditable/GridDecimalInput.tsx +0 -41
  63. package/src/components/DataGridBySchemaEditable/GridPatternInput.tsx +0 -37
  64. package/src/components/DataGridBySchemaEditable/InputInterval.tsx +0 -194
  65. package/src/components/DataGridBySchemaEditable/SelectEditInputCell.tsx +0 -154
  66. package/src/components/DataGridBySchemaEditable.md +0 -50
  67. package/src/components/DataGridBySchemaEditable.tsx +0 -758
  68. package/src/components/DataTotals.tsx +0 -57
  69. package/src/components/DialogActions.tsx +0 -33
  70. package/src/components/DialogJSONSchemaForm.tsx +0 -40
  71. package/src/components/GenericModelList.tsx +0 -165
  72. package/src/components/GenericRelatedModelList.tsx +0 -168
  73. package/src/context/APIWrapper.tsx +0 -447
  74. package/src/context/DRFReactBySchemaProvider.md +0 -57
  75. package/src/context/DRFReactBySchemaProvider.tsx +0 -72
  76. package/src/context/Overlays.tsx +0 -94
  77. package/src/index.ts +0 -77
  78. package/src/styles/layout.ts +0 -104
  79. package/src/styles/theme.ts +0 -190
  80. package/src/utils.ts +0 -327
  81. package/styleguide.config.js +0 -13
  82. package/tsconfig.json +0 -104
  83. package/webpack.config.js +0 -24
@@ -1,758 +0,0 @@
1
- import React, { useEffect, useState, useRef, forwardRef } from 'react';
2
- import moment from 'moment';
3
- import {
4
- DataGrid,
5
- GridEditInputCell,
6
- GridRowModes,
7
- GridActionsCellItem,
8
- gridStringOrNumberComparator,
9
- GridRowId
10
- } from '@mui/x-data-grid';
11
- import * as Yup from 'yup';
12
- import Box from '@mui/material/Box';
13
- import CircularProgress from '@mui/material/CircularProgress';
14
- import EditIcon from '@mui/icons-material/Edit';
15
- import ClearIcon from '@mui/icons-material/Clear';
16
- import CheckIcon from '@mui/icons-material/Check';
17
- import UndoIcon from '@mui/icons-material/Undo';
18
- import Snackbar from '@mui/material/Snackbar';
19
- import Alert from '@mui/material/Alert';
20
-
21
- import { Layout } from '../styles';
22
- import { getAutoComplete } from '../api';
23
- import {
24
- Item,
25
- SchemaType,
26
- Choice,
27
- Id,
28
- GridEnrichedBySchemaColDef,
29
- isTmpId,
30
- emptyByType,
31
- buildGenericYupValidationSchema,
32
- ItemSchemaColumnsType
33
- } from '../utils';
34
- import { SxProps } from '@mui/material';
35
- import { DRFReactBySchemaContext, DRFReactBySchemaContextType } from '../context/DRFReactBySchemaContext';
36
- import { quantityOnlyOperators } from './DataGridBySchemaEditable/utils';
37
- import { CustomToolbar } from './DataGridBySchemaEditable/CustomToolbar';
38
- import { SelectEditInputCell } from './DataGridBySchemaEditable/SelectEditInputCell';
39
- import { GridDecimalInput } from './DataGridBySchemaEditable/GridDecimalInput';
40
- import { GridPatternInput } from './DataGridBySchemaEditable/GridPatternInput';
41
- import { FooterToolbar } from './DataGridBySchemaEditable/FooterToolbar';
42
- import { ConfirmDialog } from './DataGridBySchemaEditable/ConfirmDialog';
43
- import { APIWrapperContext } from '../context/APIWrapperContext';
44
-
45
- const stringMask = require('string-mask');
46
-
47
- interface DataGridBySchemaEditableProps {
48
- schema: SchemaType;
49
- data: Item[];
50
- columns: GridEnrichedBySchemaColDef[];
51
- model: string;
52
- fieldKey?: string;
53
- labelKey?: string;
54
- index?: number;
55
- name?: string;
56
- indexField?: string;
57
- addExistingModel?: string;
58
- indexFieldMinWidth?: number;
59
- indexFieldBasePath?: string;
60
- stateToLink?: object;
61
- minWidth?: number;
62
-
63
- modelParentId?: Id;
64
- modelParent?: string;
65
-
66
- customColumnOperations?: (p: any) => GridEnrichedBySchemaColDef;
67
- customLinkDestination?: (p: any) => string;
68
- LinkComponent?: any;
69
- onProcessRow?: (p: any) => void;
70
- onDataChange?: (p: any) => void;
71
- isEditable?: boolean;
72
- sx?: SxProps;
73
- isAutoHeight?: boolean;
74
- defaultValues?: Item;
75
- hideFooterPagination?: boolean;
76
- setVisibleRows?: (p: any) => void;
77
- };
78
-
79
- const DataGridBySchemaEditable = forwardRef((
80
- {
81
- schema,
82
- data,
83
- columns,
84
- model,
85
- fieldKey,
86
- labelKey = 'nome',
87
- index,
88
- name = Math.floor(Math.random() * 1000000).toString(),
89
- indexField = 'nome',
90
- addExistingModel,
91
- indexFieldMinWidth = 350,
92
- indexFieldBasePath = '',
93
- stateToLink = {},
94
- minWidth = 80,
95
- modelParent,
96
- modelParentId,
97
- customColumnOperations,
98
- customLinkDestination,
99
- LinkComponent,
100
- onProcessRow,
101
- onDataChange,
102
- isEditable = false,
103
- sx = { mr: 2 },
104
- isAutoHeight = false,
105
- defaultValues = {},
106
- hideFooterPagination = false,
107
- setVisibleRows,
108
- ...other
109
- }: DataGridBySchemaEditableProps,
110
- ref
111
- ) => {
112
- const { serverEndPoint } = DRFReactBySchemaContext
113
- ? React.useContext(DRFReactBySchemaContext) as DRFReactBySchemaContextType
114
- : { serverEndPoint: null };
115
-
116
- const apiContext = React.useContext(APIWrapperContext);
117
-
118
- const initialSnackBar:Item = {
119
- open: false,
120
- msg: '',
121
- severity: 'info'
122
- };
123
- const [snackBar, setSnackBar] = useState(initialSnackBar);
124
- const [dataGrid, setDataGrid] = useState<{ data:Item[] }>({ data: [] });
125
- const [preparedColumns, setPreparedColumns] = useState<null | GridEnrichedBySchemaColDef[]>(null);
126
- const [dataGridLoading, setDataGridLoading] = useState(false);
127
- const [rowModesModel, setRowModesModel] = useState<Record<string, any>>({});
128
- const [dialogOpen, setDialogOpen] = useState(false);
129
- const optionsAC = useRef<Record<string, Item[]> | null>(null);
130
- const emptyItem = useRef<Item>({});
131
- const yupValidationSchema = useRef<Yup.AnySchema | null>(null);
132
- const processingRow = useRef<number | string | null>(null);
133
- const idToRemove = useRef<Id | null>(null);
134
-
135
- const updateOptionsAC = async () => {
136
- optionsAC.current = {};
137
- for (const col of columns) {
138
- if (!schema[col.field]) {
139
- continue;
140
- }
141
- if (['field', 'nested object'].includes(schema[col.field].type) && !(col.field in optionsAC.current)) {
142
- const options = await getAutoComplete({ model: col.field, serverEndPoint });
143
- if (options) {
144
- optionsAC.current[col.field] = options;
145
- continue;
146
- }
147
- console.log(`Couldn't load autocomplete options from '${col.field}'`);
148
- continue;
149
- }
150
- if (schema[col.field].type === 'choice' && !(col.field in optionsAC.current)) {
151
- optionsAC.current[col.field] = schema[col.field].choices as Choice[];
152
- continue;
153
- }
154
- if (col.field === indexField && addExistingModel && !optionsAC.current[col.field]) {
155
- const options = await getAutoComplete({ model: addExistingModel, serverEndPoint });
156
- if (options) {
157
- optionsAC.current[col.field] = options;
158
- continue;
159
- }
160
- if (!(col.field in optionsAC.current)) {
161
- delete optionsAC.current[col.field];
162
- }
163
- }
164
- }
165
- };
166
-
167
- const initColumns = () => {
168
- let cols:GridEnrichedBySchemaColDef[] = [];
169
- if (isEditable) {
170
- cols.push({
171
- field: 'actions',
172
- headerName: '',
173
- type: 'actions',
174
- getActions: ({ id }: { id: Id }) => {
175
- const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
176
- if (isInEditMode) {
177
- return [
178
- <GridActionsCellItem
179
- key={`save_${id}`}
180
- icon={<CheckIcon />}
181
- label="Salvar"
182
- onClick={handleSaveClick(id)}
183
- color="success"
184
- />,
185
- <GridActionsCellItem
186
- key={`cancel_${id}`}
187
- icon={<UndoIcon />}
188
- label="Cancelar"
189
- onClick={handleCancelClick(id)}
190
- color="inherit"
191
- />
192
- ];
193
- }
194
-
195
- return [
196
- <GridActionsCellItem
197
- key={`edit_${id}`}
198
- icon={<EditIcon />}
199
- label="Edit"
200
- onClick={handleEditClick(id)}
201
- color="inherit"
202
- />,
203
- <GridActionsCellItem
204
- key={`remove_${id}`}
205
- icon={<ClearIcon />}
206
- label="Delete"
207
- onClick={handleDeleteClick(id)}
208
- color="error"
209
- />
210
- ];
211
- }
212
- });
213
- }
214
- cols = [...cols, ...columns];
215
- cols = cols.map(col => {
216
- if (!schema[col.field]) {
217
- return col;
218
- }
219
- const isIndexField = (indexField !== '' && (col.field === indexField));
220
- let column = col;
221
- if (isIndexField) {
222
- col.isIndexField = true;
223
- }
224
- column.editable = (isEditable) && (
225
- !schema[col.field].read_only || ['field', 'nested object'].includes(schema[col.field].type)
226
- );
227
- switch (schema[col.field].type) {
228
- case 'date':
229
- column.type = 'date';
230
- column.valueFormatter = params => params.value
231
- ? moment(params.value).format('DD/MM/YYYY')
232
- : '';
233
- column.filterOperators = quantityOnlyOperators({ type: 'date' });
234
- break;
235
- case 'datetime':
236
- column.type = 'dateTime';
237
- column.minWidth = 180;
238
- column.valueFormatter = params => params.value
239
- ? moment(params.value).format('DD/MM/YYYY HH:mm')
240
- : '';
241
- break;
242
- case 'nested object':
243
- column.minWidth = 150;
244
- if (isEditable) {
245
- column.valueFormatter = params => {
246
- return (!params.value) ? '' : params.value.label;
247
- };
248
- column.filterable = false;
249
- column.sortComparator = (v1, v2, param1, param2) => {
250
- return gridStringOrNumberComparator(v1.label, v2.label, param1, param2);
251
- };
252
- column.renderEditCell = (params) => <SelectEditInputCell
253
- {...params}
254
- column={column}
255
- type={schema[col.field].type}
256
- optionsAC={optionsAC}
257
- isIndexField={isIndexField}
258
- />;
259
- break;
260
- }
261
-
262
- column.valueGetter = params => {
263
- return (!params.value) ? '' : params.value.label;
264
- };
265
- break;
266
- case 'field':
267
- column.orderable = false;
268
-
269
- if (isEditable) {
270
- column.minWidth = 300;
271
- column.valueFormatter = params => {
272
- return (!params.value || !Array.isArray(params.value))
273
- ? ''
274
- : params.value.map(val => val.label).join(', ');
275
- };
276
- column.filterable = false;
277
- column.renderEditCell = (params) => <SelectEditInputCell
278
- {...params}
279
- column={column}
280
- type={schema[col.field].type}
281
- optionsAC={optionsAC}
282
- isIndexField={isIndexField}
283
- multiple={true}
284
- />;
285
- break;
286
- }
287
-
288
- column.valueGetter = params => {
289
- return (!params.value || !Array.isArray(params.value))
290
- ? ''
291
- : params.value.map(val => val.label).join(', ');
292
- };
293
- break;
294
- case 'choice':
295
- if (isEditable) {
296
- column.minWidth = 150;
297
- column.valueFormatter = params => {
298
- return (!params.value) ? '' : params.value.display_name;
299
- };
300
- column.filterable = false;
301
- column.sortComparator = (v1, v2, param1, param2) => {
302
- return gridStringOrNumberComparator(v1.display_name, v2.display_name, param1, param2);
303
- };
304
- column.renderEditCell = (params) => <SelectEditInputCell
305
- {...params}
306
- column={column}
307
- type={schema[col.field].type}
308
- optionsAC={optionsAC}
309
- isIndexField={isIndexField}
310
- />;
311
- break;
312
- }
313
-
314
- column.valueGetter = params => {
315
- return (!params.value) ? '' : params.value.display_name;
316
- };
317
- break;
318
- case 'decimal':
319
- case 'float':
320
- column.type = 'number';
321
- column.valueFormatter = params => {
322
- return (!params.value)
323
- ? ''
324
- : parseFloat(params.value).toLocaleString('pt-BR', {
325
- minimumFractionDigits: 2,
326
- maximumFractionDigits: 2
327
- });
328
- };
329
- if (isEditable) {
330
- column.renderEditCell = (params) => <GridDecimalInput
331
- {...params}
332
- column={column}
333
- />;
334
- }
335
- column.filterOperators = quantityOnlyOperators({ type: 'float' });
336
- break;
337
- case 'number':
338
- case 'integer':
339
- column.type = 'number';
340
- column.filterOperators = quantityOnlyOperators({ type: 'number' });
341
- break;
342
- }
343
-
344
- if (indexFieldMinWidth && !column.minWidth) {
345
- column.minWidth = (col.field === indexField) ? indexFieldMinWidth : minWidth;
346
- }
347
- if (indexField) {
348
- if (col.field === indexField) {
349
- column.flex = 1;
350
- column.renderCell = params => {
351
- if (LinkComponent && customLinkDestination) {
352
- return (
353
- <LinkComponent to={`${customLinkDestination(params)}`} state={stateToLink}>
354
- {params.formattedValue}
355
- </LinkComponent>
356
- );
357
- }
358
-
359
- if (
360
- !LinkComponent ||
361
- !indexFieldBasePath ||
362
- (
363
- ['field', 'nested object'].includes(schema[col.field].type) &&
364
- (!params.row[col.field] || !params.row[col.field].id)
365
- )
366
- ) {
367
- return (<>{params.formattedValue}</>);
368
- }
369
-
370
- const targetId = (['field', 'nested object'].includes(schema[col.field].type))
371
- ? params.row[col.field].id.toString()
372
- : params.row.id.toString();
373
-
374
- return (
375
- <LinkComponent to={`${indexFieldBasePath}${targetId}`} state={stateToLink}>
376
- {params.formattedValue}
377
- </LinkComponent>
378
- );
379
- };
380
- if (
381
- isEditable &&
382
- optionsAC.current &&
383
- col.field in optionsAC.current &&
384
- addExistingModel
385
- ) {
386
- column.renderEditCell = (params) => {
387
- if (!isTmpId(params.id)) {
388
- return (
389
- <GridEditInputCell
390
- {...params}
391
- />
392
- );
393
- }
394
- return (
395
- <SelectEditInputCell
396
- {...params}
397
- column={column}
398
- type={schema[col.field].type}
399
- optionsAC={optionsAC}
400
- isIndexField={true}
401
- />
402
- );
403
- };
404
- }
405
- }
406
- }
407
-
408
- // Custom column operations:
409
- if (customColumnOperations) {
410
- column = customColumnOperations(column);
411
- }
412
-
413
- // format numbers:
414
- if (column.patternFormat) {
415
- column.valueFormatter = params => {
416
- if (!params.value || typeof params.value !== 'string') {
417
- return params.value;
418
- }
419
- const formattedValue = new stringMask(column.patternFormat, {}).apply(params.value);
420
- return formattedValue;
421
- };
422
- if (isEditable) {
423
- column.renderEditCell = params => <GridPatternInput
424
- {...params}
425
- patternFormat={column.patternFormat}
426
- />;
427
- }
428
- }
429
-
430
- // Finally!
431
- return column;
432
- });
433
- setPreparedColumns(cols);
434
- };
435
-
436
- const handleDialogClose = () => {
437
- setDialogOpen(false);
438
- };
439
-
440
- const handleRowEditStart = (params: any, event: any) => {
441
- event.defaultMuiPrevented = true;
442
- };
443
-
444
- const handleRowEditStop = (params: any, event: any) => {
445
- event.defaultMuiPrevented = true;
446
- };
447
-
448
- const handleEditClick = (id: Id) => () => {
449
- setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } });
450
- };
451
-
452
- const handleSaveClick = (id: Id) => () => {
453
- setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } });
454
- };
455
-
456
- const handleDeleteClick = (id: Id) => () => {
457
- idToRemove.current = id;
458
- setDialogOpen(true);
459
- };
460
-
461
- const handleDeleteSave = () => {
462
- if (idToRemove.current === null) {
463
- setDialogOpen(false);
464
- return;
465
- }
466
- const newData = dataGrid.data.filter(row => row.id !== idToRemove.current);
467
- setDataGrid({
468
- ...dataGrid,
469
- data: newData
470
- });
471
- if (modelParent && modelParentId && apiContext) {
472
- apiContext.onDeleteRelatedModel({
473
- model: modelParent,
474
- id: modelParentId,
475
- relatedModel: model,
476
- relatedModelId: idToRemove.current
477
- });
478
- }
479
-
480
- // Reflect changes to the outside, for example for doing global calculations over multiple rows:
481
- if (onDataChange) {
482
- onDataChange(newData);
483
- }
484
- idToRemove.current = null;
485
- setDialogOpen(false);
486
- };
487
-
488
- const handleCancelClick = (id: Id) => () => {
489
- setRowModesModel({
490
- ...rowModesModel,
491
- [id]: { mode: GridRowModes.View, ignoreModifications: true }
492
- });
493
-
494
- const editedRow = dataGrid.data.find(row => row.id === id);
495
- if (editedRow && editedRow.isNew) {
496
- setDataGrid({
497
- ...dataGrid,
498
- data: dataGrid.data.filter(row => row.id !== id)
499
- });
500
- }
501
- };
502
-
503
- useEffect(() => {
504
- if (!columns) {
505
- setDataGrid({ data: [] });
506
- return;
507
- }
508
-
509
- if (isEditable) {
510
- for (const col of columns) {
511
- if (schema[col.field].model_default) {
512
- emptyItem.current[col.field] = schema[col.field].model_default;
513
- continue;
514
- }
515
- if (Object.prototype.hasOwnProperty.call(defaultValues, col.field)) {
516
- emptyItem.current[col.field] = defaultValues[col.field];
517
- continue;
518
- }
519
- emptyItem.current[col.field] = (schema[col.field])
520
- ? emptyByType(schema[col.field])
521
- : null;
522
- }
523
- }
524
-
525
- const skipFields = [];
526
- if (indexField && addExistingModel) {
527
- skipFields.push(indexField);
528
- }
529
- yupValidationSchema.current = buildGenericYupValidationSchema({
530
- data: emptyItem.current,
531
- schema,
532
- skipFields
533
- });
534
-
535
- setDataGrid({
536
- data
537
- });
538
- }, [data]);
539
-
540
- useEffect(() => {
541
- if (optionsAC.current) {
542
- initColumns();
543
- return;
544
- }
545
-
546
- updateOptionsAC().then(() => {
547
- initColumns();
548
- });
549
- }, [rowModesModel]);
550
-
551
- const processRowUpdate = async (newRow: Item) => {
552
- if (!preparedColumns || !yupValidationSchema.current) {
553
- return false;
554
- }
555
- setDataGridLoading(true);
556
- const indexCol = preparedColumns.find(col => col.field === indexField);
557
- processingRow.current = newRow.id;
558
- await yupValidationSchema.current.validate(newRow);
559
- const onlyAddExisting = (
560
- indexField &&
561
- isTmpId(newRow.id) &&
562
- (newRow[indexField] && !isTmpId(newRow[indexField].id)) &&
563
- (!indexCol || !indexCol.valueFormatter)
564
- );
565
- const createNewItem = (indexField && isTmpId(newRow.id) && newRow[indexField] && isTmpId(newRow[indexField].id));
566
- if (onlyAddExisting) {
567
- const row:Item = {};
568
- row.id_to_add = newRow[indexField].id;
569
- for (const [key, value] of Object.entries(newRow[indexField])) {
570
- if (key === 'id') {
571
- row[key] = newRow.id;
572
- continue;
573
- }
574
- row[key] = value;
575
- }
576
- newRow = { ...row };
577
- }
578
- if (createNewItem && newRow[indexField]) {
579
- if (newRow[indexField].inputValue) {
580
- newRow[indexField] = newRow[indexField].inputValue;
581
- }
582
- if (addExistingModel) {
583
- newRow[indexField] = newRow[indexField].label;
584
- }
585
- }
586
-
587
- if (modelParent && modelParentId && apiContext) {
588
- const response = await apiContext.onEditRelatedModelSave({
589
- model: modelParent,
590
- id: modelParentId,
591
- relatedModel: model,
592
- relatedModelId: newRow.id,
593
- newRow,
594
- schema,
595
- onlyAddExisting
596
- });
597
-
598
- const responseAsData = response as ItemSchemaColumnsType;
599
- if (
600
- (onlyAddExisting && typeof response != 'boolean') ||
601
- (parseInt(response as string) && (createNewItem || !onlyAddExisting))
602
- ) {
603
- updateOptionsAC();
604
- const data = [...dataGrid.data];
605
- for (const i in data) {
606
- if (data[i].id === newRow.id) {
607
- data[i] = onlyAddExisting ? responseAsData.data : newRow;
608
- if (isTmpId(newRow.id)) {
609
- const newId = parseInt(response as string);
610
- data[i].id = newId || responseAsData.data.id;
611
- }
612
-
613
- // This is for cases where users want to do custom operations after saving the row,
614
- // like for example make calculations among columns.
615
- if (onProcessRow) {
616
- onProcessRow(data[i]);
617
- }
618
-
619
- // Reflect the changes to the outside, for example for global calculations over all data
620
- if (onDataChange) {
621
- onDataChange(data);
622
- }
623
-
624
- setDataGrid({ data });
625
- break;
626
- }
627
- }
628
- setDataGridLoading(false);
629
- return newRow;
630
- }
631
- }
632
- setDataGridLoading(false);
633
- return false;
634
- };
635
-
636
- const customPaddings = (isAutoHeight)
637
- ? {
638
- '&.MuiDataGrid-root--densityCompact .MuiDataGrid-cell': { py: '8px' },
639
- '&.MuiDataGrid-root--densityStandard .MuiDataGrid-cell': { py: '15px' },
640
- '&.MuiDataGrid-root--densityComfortable .MuiDataGrid-cell': { py: '22px' }
641
- }
642
- : undefined;
643
-
644
- return (
645
- <Box className={`dataGrid_${name}`} sx={{ height: '100%' }}>
646
- {preparedColumns === null
647
- ? <Box sx={Layout.loadingBox}>
648
- <CircularProgress />
649
- </Box>
650
- : <DataGrid
651
- rows={dataGrid.data}
652
- columns={preparedColumns}
653
- onStateChange={(state) => {
654
- if (setVisibleRows) {
655
- const newVisibleRows = Object.entries(state.filter.visibleRowsLookup)
656
- .filter(entry => { return entry[1] === true; })
657
- .map((entry:Item) => { return entry[0]; }) as GridRowId[];
658
- setVisibleRows(newVisibleRows);
659
- }
660
- }}
661
- editMode="row"
662
- loading={dataGridLoading}
663
- hideFooterPagination={hideFooterPagination}
664
- getRowHeight={() => {
665
- if (isAutoHeight) {
666
- return 'auto';
667
- }
668
- return null;
669
- }}
670
- isCellEditable={params => (
671
- rowModesModel[params.row.id as string]?.mode === GridRowModes.Edit &&
672
- (
673
- !isTmpId(params.row.id) ||
674
- (
675
- isTmpId(params.row.id) &&
676
- (
677
- params.field === indexField ||
678
- !optionsAC.current ||
679
- !Object.prototype.hasOwnProperty.call(optionsAC.current, indexField) ||
680
- (
681
- preparedColumns.find(col => col.field === indexField) &&
682
- Object.prototype.hasOwnProperty.call(preparedColumns.find(col => col.field === indexField), 'valueFormatter')
683
- )
684
- )
685
- )
686
- )
687
- ) as boolean}
688
- rowModesModel={rowModesModel}
689
- onRowEditStart={handleRowEditStart}
690
- onRowEditStop={handleRowEditStop}
691
- processRowUpdate={processRowUpdate}
692
- onProcessRowUpdateError={(e) => {
693
- setDataGridLoading(false);
694
- if (processingRow.current) {
695
- setRowModesModel({
696
- ...rowModesModel,
697
- [processingRow.current]: { mode: GridRowModes.Edit }
698
- });
699
- }
700
- const msg = `Erro em "${e.path}": ${e.errors}`;
701
- setSnackBar({
702
- open: true,
703
- severity: 'error',
704
- msg
705
- });
706
- console.log(e);
707
- }}
708
- components={{ Toolbar: CustomToolbar, Footer: FooterToolbar }}
709
- componentsProps={
710
- {
711
- toolbar: {
712
- preparedColumns,
713
- setPreparedColumns,
714
- showQuickFilter: true,
715
- quickFilterProps: { debounceMs: 500 }
716
- },
717
- footer: {
718
- name,
719
- setRowModesModel,
720
- dataGrid,
721
- setDataGrid,
722
- emptyItem,
723
- indexField,
724
- isEditable
725
- },
726
- filterPanel: {
727
- sx: {
728
- '& .MuiDataGrid-filterFormValueInput': { width: 300 }
729
- }
730
- }
731
- }
732
- }
733
- experimentalFeatures={{ newEditingApi: isEditable }}
734
- sx={customPaddings}
735
- />
736
- }
737
- <ConfirmDialog
738
- open={dialogOpen}
739
- onClose={handleDialogClose}
740
- onConfirm={handleDeleteSave}
741
- />
742
- <Snackbar
743
- open={snackBar.open}
744
- autoHideDuration={5000}
745
- onClose={() => { setSnackBar({ ...initialSnackBar, open: false }); }}
746
- anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
747
- >
748
- <Alert severity={snackBar.severity}>
749
- {snackBar.msg}
750
- </Alert>
751
- </Snackbar>
752
- </Box>
753
- );
754
- });
755
-
756
- DataGridBySchemaEditable.displayName = 'DataGridBySchemaEditable';
757
-
758
- export default DataGridBySchemaEditable;