drf-react-by-schema 0.13.1 → 0.14.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.
- package/dist/api.d.ts +1 -1
- package/dist/components/DataGridBySchemaEditable/CustomToolbar.d.ts +9 -4
- package/dist/components/DataGridBySchemaEditable/CustomToolbar.js +16 -2
- package/dist/components/DataGridBySchemaEditable/FooterToolbar.d.ts +2 -12
- package/dist/components/DataGridBySchemaEditable/FooterToolbar.js +2 -21
- package/dist/components/DataGridBySchemaEditable.js +102 -8
- package/dist/context/APIWrapper.js +4 -0
- package/dist/context/APIWrapperContext.d.ts +2 -1
- package/dist/context/APIWrapperContext.js +1 -0
- package/dist/utils.d.ts +12 -2
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Item, SchemaType, modelOptionsType, DataSchemaColumnsType, ItemSchemaCo
|
|
|
3
3
|
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid';
|
|
4
4
|
import { AlertColor } from '@mui/material/Alert';
|
|
5
5
|
type Id = string | number | null;
|
|
6
|
-
interface TargetApiParams {
|
|
6
|
+
export interface TargetApiParams {
|
|
7
7
|
path: string;
|
|
8
8
|
serverEndPoint: serverEndPointType | null;
|
|
9
9
|
data: Item;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
3
|
-
import { GridEnrichedBySchemaColDef, OnSelectActions } from '../../utils';
|
|
2
|
+
import { BulkDeleteData, BulkUpdateData, GridEnrichedBySchemaColDef, Id, Item, OnSelectActions } from '../../utils';
|
|
4
3
|
type CustomToolbarProps = {
|
|
5
4
|
preparedColumns: GridEnrichedBySchemaColDef[];
|
|
6
5
|
setPreparedColumns: (p: null | GridEnrichedBySchemaColDef[]) => void;
|
|
7
6
|
onSelectActions?: OnSelectActions[];
|
|
8
|
-
selectionModel:
|
|
7
|
+
selectionModel: Item[];
|
|
8
|
+
bulkUpdateData: BulkUpdateData;
|
|
9
|
+
bulkDeleteData: BulkDeleteData;
|
|
10
|
+
bulkCreateData: (p: Id[]) => void;
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
13
|
*
|
|
@@ -15,8 +17,11 @@ type CustomToolbarProps = {
|
|
|
15
17
|
* setPreparedColumns,
|
|
16
18
|
* onSelectActions,
|
|
17
19
|
* selectionModel,
|
|
20
|
+
* bulkUpdateData,
|
|
21
|
+
* bulkDeleteData,
|
|
22
|
+
* bulkCreateData,
|
|
18
23
|
* }
|
|
19
24
|
* @returns Custom Toolbar for the grid
|
|
20
25
|
*/
|
|
21
|
-
export declare const CustomToolbar: ({ preparedColumns, setPreparedColumns, onSelectActions, selectionModel, }: CustomToolbarProps) => JSX.Element;
|
|
26
|
+
export declare const CustomToolbar: ({ preparedColumns, setPreparedColumns, onSelectActions, selectionModel, bulkUpdateData, bulkDeleteData, bulkCreateData, }: CustomToolbarProps) => JSX.Element;
|
|
22
27
|
export {};
|
|
@@ -43,10 +43,13 @@ const utils_1 = require("./utils");
|
|
|
43
43
|
* setPreparedColumns,
|
|
44
44
|
* onSelectActions,
|
|
45
45
|
* selectionModel,
|
|
46
|
+
* bulkUpdateData,
|
|
47
|
+
* bulkDeleteData,
|
|
48
|
+
* bulkCreateData,
|
|
46
49
|
* }
|
|
47
50
|
* @returns Custom Toolbar for the grid
|
|
48
51
|
*/
|
|
49
|
-
const CustomToolbar = ({ preparedColumns, setPreparedColumns, onSelectActions, selectionModel, }) => {
|
|
52
|
+
const CustomToolbar = ({ preparedColumns, setPreparedColumns, onSelectActions, selectionModel, bulkUpdateData, bulkDeleteData, bulkCreateData, }) => {
|
|
50
53
|
const apiRef = (0, x_data_grid_1.useGridApiContext)();
|
|
51
54
|
const [resizeMenuAnchorEl, setResizeMenuAnchorEl] = (0, react_1.useState)(null);
|
|
52
55
|
const isResizeMenuOpen = Boolean(resizeMenuAnchorEl);
|
|
@@ -74,7 +77,18 @@ const CustomToolbar = ({ preparedColumns, setPreparedColumns, onSelectActions, s
|
|
|
74
77
|
")"),
|
|
75
78
|
react_1.default.createElement(Menu_1.default, { anchorEl: actionsMenuAnchorEl, open: isActionsMenuOpen, onClose: closeActionsMenu }, onSelectActions.map((selectAction, index) => (react_1.default.createElement(MenuItem_1.default, { key: `onSelectAction_${index}`, onClick: () => {
|
|
76
79
|
closeActionsMenu();
|
|
77
|
-
selectAction.action
|
|
80
|
+
if (typeof selectAction.action === 'string') {
|
|
81
|
+
const ids = selectionModel.map((item) => item.id);
|
|
82
|
+
if (selectAction.action === 'bulkDelete') {
|
|
83
|
+
bulkDeleteData(ids);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (selectAction.action === 'bulkCreate') {
|
|
87
|
+
bulkCreateData(ids);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
selectAction.action(selectionModel, bulkUpdateData);
|
|
78
92
|
} }, selectAction.title)))))),
|
|
79
93
|
react_1.default.createElement(x_data_grid_1.GridToolbarColumnsButton, { sx: { ml: '10px', fontSize: '13px' } }),
|
|
80
94
|
react_1.default.createElement(x_data_grid_1.GridToolbarFilterButton, { sx: { ml: '10px', fontSize: '13px' } }),
|
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { Item } from '../../utils';
|
|
3
2
|
type FooterToolbarProps = {
|
|
4
|
-
name: string;
|
|
5
|
-
setRowModesModel: (p: any) => any;
|
|
6
|
-
dataGrid: {
|
|
7
|
-
data: Item[];
|
|
8
|
-
};
|
|
9
|
-
setDataGrid: (p: any) => any;
|
|
10
|
-
emptyItem: {
|
|
11
|
-
current: Record<string, any>;
|
|
12
|
-
};
|
|
13
|
-
indexField: string;
|
|
14
3
|
isEditable: boolean;
|
|
4
|
+
handleAddItem: () => void;
|
|
15
5
|
};
|
|
16
|
-
export declare const FooterToolbar: ({
|
|
6
|
+
export declare const FooterToolbar: ({ isEditable, handleAddItem }: FooterToolbarProps) => JSX.Element;
|
|
17
7
|
export {};
|
|
@@ -8,28 +8,9 @@ const react_1 = __importDefault(require("react"));
|
|
|
8
8
|
const x_data_grid_1 = require("@mui/x-data-grid");
|
|
9
9
|
const Button_1 = __importDefault(require("@mui/material/Button"));
|
|
10
10
|
const Add_1 = __importDefault(require("@mui/icons-material/Add"));
|
|
11
|
-
const
|
|
12
|
-
const FooterToolbar = ({ name, setRowModesModel, dataGrid, setDataGrid, emptyItem, indexField, isEditable, }) => {
|
|
13
|
-
const handleClick = () => {
|
|
14
|
-
const id = (0, utils_1.getTmpId)();
|
|
15
|
-
emptyItem.current.id = id;
|
|
16
|
-
const newData = [Object.assign({}, emptyItem.current), ...dataGrid.data];
|
|
17
|
-
setDataGrid({
|
|
18
|
-
data: newData,
|
|
19
|
-
});
|
|
20
|
-
setRowModesModel((oldModel) => (Object.assign(Object.assign({}, oldModel), { [id]: { mode: x_data_grid_1.GridRowModes.Edit, fieldToFocus: indexField } })));
|
|
21
|
-
// Ugly hack to scroll to top, since scroll to cell is only available in Pro
|
|
22
|
-
const el = document.querySelector(`.dataGrid_${name} .MuiDataGrid-virtualScroller`);
|
|
23
|
-
// console.log(el, name);
|
|
24
|
-
if (el) {
|
|
25
|
-
el.scrollTop = 0;
|
|
26
|
-
setTimeout(() => {
|
|
27
|
-
el.scrollTop = 0;
|
|
28
|
-
}, 10);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
11
|
+
const FooterToolbar = ({ isEditable, handleAddItem }) => {
|
|
31
12
|
return (react_1.default.createElement(x_data_grid_1.GridFooterContainer, null,
|
|
32
|
-
isEditable && (react_1.default.createElement(Button_1.default, { color: "primary", startIcon: react_1.default.createElement(Add_1.default, null), onClick:
|
|
13
|
+
isEditable && (react_1.default.createElement(Button_1.default, { color: "primary", startIcon: react_1.default.createElement(Add_1.default, null), onClick: handleAddItem, sx: { ml: 2 } }, "Adicionar")),
|
|
33
14
|
react_1.default.createElement(x_data_grid_1.GridFooter, { sx: isEditable ? { border: 'none' } : { width: '100%' } })));
|
|
34
15
|
};
|
|
35
16
|
exports.FooterToolbar = FooterToolbar;
|
|
@@ -92,6 +92,7 @@ const DataGridBySchemaEditable = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
92
92
|
const [rowModesModel, setRowModesModel] = (0, react_1.useState)({});
|
|
93
93
|
const [dialogOpen, setDialogOpen] = (0, react_1.useState)(false);
|
|
94
94
|
const [selectionModel, setSelectionModel] = (0, react_1.useState)([]);
|
|
95
|
+
const [selectionModelIds, setSelectionModelIds] = (0, react_1.useState)([]);
|
|
95
96
|
const optionsAC = (0, react_1.useRef)(null);
|
|
96
97
|
const emptyItem = (0, react_1.useRef)({});
|
|
97
98
|
const yupValidationSchema = (0, react_1.useRef)(null);
|
|
@@ -388,6 +389,99 @@ const DataGridBySchemaEditable = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
388
389
|
});
|
|
389
390
|
setPreparedColumns(cols);
|
|
390
391
|
};
|
|
392
|
+
const handleAddItems = (numberOfRows = 1) => {
|
|
393
|
+
const newRows = [];
|
|
394
|
+
for (let i = 0; i < numberOfRows; i++) {
|
|
395
|
+
const id = (0, utils_1.getTmpId)();
|
|
396
|
+
newRows.push(Object.assign(Object.assign({}, emptyItem.current), { id }));
|
|
397
|
+
}
|
|
398
|
+
const newData = [...newRows, ...dataGrid.data];
|
|
399
|
+
setDataGrid({
|
|
400
|
+
data: newData,
|
|
401
|
+
});
|
|
402
|
+
setRowModesModel((oldModel) => {
|
|
403
|
+
const newModel = Object.assign({}, oldModel);
|
|
404
|
+
newRows.map((newRow) => {
|
|
405
|
+
newModel[newRow.id] = { mode: x_data_grid_1.GridRowModes.Edit, fieldToFocus: indexField };
|
|
406
|
+
});
|
|
407
|
+
return newModel;
|
|
408
|
+
});
|
|
409
|
+
// Ugly hack to scroll to top, since scroll to cell is only available in Pro
|
|
410
|
+
const el = document.querySelector(`.dataGrid_${name} .MuiDataGrid-virtualScroller`);
|
|
411
|
+
// console.log(el, name);
|
|
412
|
+
if (el) {
|
|
413
|
+
el.scrollTop = 0;
|
|
414
|
+
setTimeout(() => {
|
|
415
|
+
el.scrollTop = 0;
|
|
416
|
+
}, 10);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
const bulkUpdateData = (newData) => __awaiter(void 0, void 0, void 0, function* () {
|
|
420
|
+
const promises = [];
|
|
421
|
+
const ids = [];
|
|
422
|
+
newData.map((item) => {
|
|
423
|
+
promises.push((0, api_1.updateDataBySchema)({
|
|
424
|
+
model,
|
|
425
|
+
modelObjectId: item.id,
|
|
426
|
+
serverEndPoint,
|
|
427
|
+
data: item,
|
|
428
|
+
schema,
|
|
429
|
+
}));
|
|
430
|
+
ids.push(item.id);
|
|
431
|
+
});
|
|
432
|
+
const results = yield Promise.all(promises);
|
|
433
|
+
setSelectionModel([]);
|
|
434
|
+
setSelectionModelIds([]);
|
|
435
|
+
setDataGrid({
|
|
436
|
+
data: newData,
|
|
437
|
+
});
|
|
438
|
+
setSnackBar({
|
|
439
|
+
open: true,
|
|
440
|
+
severity: 'success',
|
|
441
|
+
msg: 'Alterações salvas com sucesso',
|
|
442
|
+
});
|
|
443
|
+
return results.map((result, index) => {
|
|
444
|
+
return {
|
|
445
|
+
id: ids[index],
|
|
446
|
+
success: typeof result !== 'object' && !isNaN(parseInt(result)),
|
|
447
|
+
};
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
const bulkDeleteData = (ids) => __awaiter(void 0, void 0, void 0, function* () {
|
|
451
|
+
const promises = [];
|
|
452
|
+
ids.map((id) => {
|
|
453
|
+
promises.push((0, api_1.deleteData)(model, serverEndPoint, id));
|
|
454
|
+
});
|
|
455
|
+
setDataGridLoading(true);
|
|
456
|
+
const results = yield Promise.all(promises);
|
|
457
|
+
setSelectionModel([]);
|
|
458
|
+
setSelectionModelIds([]);
|
|
459
|
+
setDataGrid({
|
|
460
|
+
data: data.filter((item) => !ids.includes(item.id)),
|
|
461
|
+
});
|
|
462
|
+
setDataGridLoading(false);
|
|
463
|
+
setSnackBar({
|
|
464
|
+
open: true,
|
|
465
|
+
severity: 'success',
|
|
466
|
+
msg: 'Itens apagados com sucesso',
|
|
467
|
+
});
|
|
468
|
+
return results.map((result, index) => {
|
|
469
|
+
return {
|
|
470
|
+
id: ids[index],
|
|
471
|
+
success: result,
|
|
472
|
+
};
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
const bulkCreateData = (ids) => __awaiter(void 0, void 0, void 0, function* () {
|
|
476
|
+
handleAddItems(ids.length);
|
|
477
|
+
setSelectionModel([]);
|
|
478
|
+
setSelectionModelIds([]);
|
|
479
|
+
setSnackBar({
|
|
480
|
+
open: true,
|
|
481
|
+
severity: 'success',
|
|
482
|
+
msg: 'Linhas adicionadas com sucesso',
|
|
483
|
+
});
|
|
484
|
+
});
|
|
391
485
|
const handleDialogClose = () => {
|
|
392
486
|
setDialogOpen(false);
|
|
393
487
|
};
|
|
@@ -617,8 +711,10 @@ const DataGridBySchemaEditable = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
617
711
|
(preparedColumns.find((col) => col.field === indexField) &&
|
|
618
712
|
Object.prototype.hasOwnProperty.call(preparedColumns.find((col) => col.field === indexField), 'valueFormatter'))))));
|
|
619
713
|
}, checkboxSelection: checkboxSelection, onSelectionModelChange: (newSelectionModel) => {
|
|
620
|
-
|
|
621
|
-
|
|
714
|
+
const selectedData = dataGrid.data.filter((item) => newSelectionModel.includes(item.id));
|
|
715
|
+
setSelectionModel(selectedData);
|
|
716
|
+
setSelectionModelIds(newSelectionModel);
|
|
717
|
+
}, selectionModel: selectionModelIds, disableRowSelectionOnClick: disableRowSelectionOnClick, rowModesModel: rowModesModel, onRowEditStart: handleRowEditStart, onRowEditStop: handleRowEditStop, processRowUpdate: processRowUpdate, onProcessRowUpdateError: (e) => {
|
|
622
718
|
setDataGridLoading(false);
|
|
623
719
|
if (processingRow.current) {
|
|
624
720
|
setRowModesModel(Object.assign(Object.assign({}, rowModesModel), { [processingRow.current]: {
|
|
@@ -647,15 +743,13 @@ const DataGridBySchemaEditable = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
647
743
|
},
|
|
648
744
|
selectionModel,
|
|
649
745
|
onSelectActions,
|
|
746
|
+
bulkUpdateData,
|
|
747
|
+
bulkDeleteData,
|
|
748
|
+
bulkCreateData,
|
|
650
749
|
},
|
|
651
750
|
footer: {
|
|
652
|
-
name,
|
|
653
|
-
setRowModesModel,
|
|
654
|
-
dataGrid,
|
|
655
|
-
setDataGrid,
|
|
656
|
-
emptyItem,
|
|
657
|
-
indexField,
|
|
658
751
|
isEditable,
|
|
752
|
+
handleAddItem: handleAddItems,
|
|
659
753
|
},
|
|
660
754
|
filterPanel: {
|
|
661
755
|
sx: {
|
|
@@ -403,6 +403,9 @@ function APIWrapper({ handleLoading, setSnackBar, setDialog, children }) {
|
|
|
403
403
|
return yield (0, api_1.getSignUpOptions)(serverEndPoint);
|
|
404
404
|
});
|
|
405
405
|
}
|
|
406
|
+
function localUpdateModel(params) {
|
|
407
|
+
return (0, api_1.updateData)(Object.assign(Object.assign({}, params), { serverEndPoint }));
|
|
408
|
+
}
|
|
406
409
|
return (react_1.default.createElement(APIWrapperContext_1.APIWrapperContext.Provider, { value: {
|
|
407
410
|
usuaria,
|
|
408
411
|
updateUsuaria,
|
|
@@ -430,6 +433,7 @@ function APIWrapper({ handleLoading, setSnackBar, setDialog, children }) {
|
|
|
430
433
|
// Remove after integrating new "onEditModel" to package:
|
|
431
434
|
serverEndPoint,
|
|
432
435
|
editModel,
|
|
436
|
+
updateModel: localUpdateModel,
|
|
433
437
|
populateOptionsAC,
|
|
434
438
|
} }, children));
|
|
435
439
|
}
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { FieldValues, SubmitHandler, UseFormGetValues, UseFormSetValue } from 'react-hook-form';
|
|
3
3
|
import { AxiosResponse } from 'axios';
|
|
4
4
|
import { ItemSchemaColumnsType, Id, Item, SchemaType, DataSchemaColumnsType } from '../utils';
|
|
5
|
-
import { GetGenericModelListProps } from '../api';
|
|
5
|
+
import { GetGenericModelListProps, TargetApiParams } from '../api';
|
|
6
6
|
import { serverEndPointType } from './DRFReactBySchemaContext';
|
|
7
7
|
export interface LoadSinglePageDataProps {
|
|
8
8
|
model: string;
|
|
@@ -92,6 +92,7 @@ export interface APIWrapperContextType {
|
|
|
92
92
|
} | undefined>;
|
|
93
93
|
serverEndPoint: serverEndPointType;
|
|
94
94
|
editModel: React.MutableRefObject<Item>;
|
|
95
|
+
updateModel: (p: Omit<TargetApiParams, 'serverEndPoint'>) => Promise<boolean>;
|
|
95
96
|
populateOptionsAC: (optionsACModels: string[]) => void;
|
|
96
97
|
}
|
|
97
98
|
export declare const APIWrapperContext: React.Context<APIWrapperContextType>;
|
|
@@ -41,6 +41,7 @@ exports.APIWrapperContext = react_1.default.createContext({
|
|
|
41
41
|
// Remove after integrating new "onEditModel" to package:
|
|
42
42
|
serverEndPoint: { url: '', apiTokenUrl: '' },
|
|
43
43
|
editModel: { current: {} },
|
|
44
|
+
updateModel: () => __awaiter(void 0, void 0, void 0, function* () { return false; }),
|
|
44
45
|
populateOptionsAC: () => undefined,
|
|
45
46
|
});
|
|
46
47
|
const useAPIWrapper = () => {
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { CalendarPickerView } from '@mui/x-date-pickers/CalendarPicker';
|
|
3
|
-
import { GridActionsColDef, GridColDef, GridFilterModel, GridSortModel
|
|
3
|
+
import { GridActionsColDef, GridColDef, GridFilterModel, GridSortModel } from '@mui/x-data-grid';
|
|
4
4
|
import { Control, FieldValues, UseFormGetValues, UseFormSetValue } from 'react-hook-form';
|
|
5
5
|
import { AutocompleteRenderOptionState, SxProps } from '@mui/material';
|
|
6
6
|
import { OnEditModelType } from './context/APIWrapperContext';
|
|
@@ -157,8 +157,18 @@ export declare const slugToCamelCase: (str: string) => string;
|
|
|
157
157
|
export declare const slugify: (text: string) => string;
|
|
158
158
|
export declare function mergeFilterItems(defaultFilter: GridFilterModel | undefined, filter: GridFilterModel | undefined): any;
|
|
159
159
|
export type ActionType = 'editInline' | 'remove' | 'edit' | 'view';
|
|
160
|
+
export type BulkUpdateData = (newData: Item[]) => Promise<{
|
|
161
|
+
id: Id;
|
|
162
|
+
success: boolean;
|
|
163
|
+
}[]>;
|
|
164
|
+
export type BulkDeleteData = (ids: Id[]) => Promise<{
|
|
165
|
+
id: Id;
|
|
166
|
+
success: boolean;
|
|
167
|
+
}[]>;
|
|
168
|
+
export type OnSelectActionCustom = (selectedData: Item[], bulkUpdateData: BulkUpdateData) => void;
|
|
169
|
+
export type OnSelectActionTypes = OnSelectActionCustom | 'bulkDelete' | 'bulkCreate';
|
|
160
170
|
export type OnSelectActions = {
|
|
161
171
|
title: string;
|
|
162
|
-
action:
|
|
172
|
+
action: OnSelectActionTypes;
|
|
163
173
|
};
|
|
164
174
|
export {};
|
package/package.json
CHANGED