UNPKG

drf-react-by-schema

Version:

Components and Tools for building a React App having Django Rest Framework (DRF) as server

760 lines (759 loc) 41.6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = __importStar(require("react")); const dayjs_1 = __importDefault(require("dayjs")); const x_data_grid_1 = require("@mui/x-data-grid"); const Box_1 = __importDefault(require("@mui/material/Box")); const CircularProgress_1 = __importDefault(require("@mui/material/CircularProgress")); const Edit_1 = __importDefault(require("@mui/icons-material/Edit")); const Bolt_1 = __importDefault(require("@mui/icons-material/Bolt")); const Visibility_1 = __importDefault(require("@mui/icons-material/Visibility")); const Clear_1 = __importDefault(require("@mui/icons-material/Clear")); const Check_1 = __importDefault(require("@mui/icons-material/Check")); const Undo_1 = __importDefault(require("@mui/icons-material/Undo")); const string_mask_1 = __importDefault(require("string-mask")); const styles_1 = require("../../styles"); const api_1 = require("../../api"); const utils_1 = require("../../utils"); const DRFReactBySchemaContext_1 = require("../../context/DRFReactBySchemaContext"); const utils_2 = require("./utils"); const CustomToolbar_1 = require("./CustomToolbar"); const SelectEditInputCell_1 = require("./SelectEditInputCell"); const GridDateInput_1 = require("./GridDateInput"); const GridDecimalInput_1 = require("./GridDecimalInput"); const GridPatternInput_1 = require("./GridPatternInput"); const BooleanInputCell_1 = require("./BooleanInputCell"); const FooterToolbar_1 = require("./FooterToolbar"); const APIWrapperContext_1 = require("../../context/APIWrapperContext"); const DataGridDesktop = (0, react_1.forwardRef)(({ schema, dataGrid, setDataGrid, rowCount = 0, columns, model, name = Math.floor(Math.random() * 1000000).toString(), indexField = 'nome', addExistingModel, indexFieldMinWidth = 350, indexFieldBasePath = '', indexFieldViewBasePath, stateToLink = {}, minWidth = 80, loading, modelParent, modelParentId, customColumnOperations, customFieldFormLayouts, customLinkDestination, LinkComponent, onProcessRow, onDataChange, onEditModel, isEditable = false, hasBulkSelect = false, onSelectActions, isAutoHeight = false, hideFooterPagination = false, setVisibleRows, paginationModel = undefined, setPaginationModel = undefined, hideFooterComponent, hideToolbarComponent, tableAutoHeight, actions = ['editInline', 'remove'], customActions, hideColumnsButton, hideFilterButton, hideDensityButton, hideExportButton, hideQuickFilterBar, optionsAC: optionsACExternal, emptyItem, handleDeleteClick, setSnackBar, }, _) => { const { serverEndPoint } = (0, DRFReactBySchemaContext_1.useDRFReactBySchema)(); const apiContext = (0, APIWrapperContext_1.useAPIWrapper)(); const [preparedColumns, setPreparedColumns] = (0, react_1.useState)(null); const [dataGridLoading, setDataGridLoading] = (0, react_1.useState)(false); const [rowModesModel, setRowModesModel] = (0, react_1.useState)(); const [selectionModel, setSelectionModel] = (0, react_1.useState)([]); const [selectionModelIds, setSelectionModelIds] = (0, react_1.useState)([]); const optionsAC = (0, react_1.useRef)(null); const yupValidationSchema = (0, react_1.useRef)(null); const processingRow = (0, react_1.useRef)(null); const visibleRows = (0, react_1.useRef)(''); if (!onEditModel) { onEditModel = apiContext.onEditModel; } const updateOptionsAC = () => __awaiter(void 0, void 0, void 0, function* () { optionsAC.current = {}; for (const col of columns) { if (optionsACExternal && col.field in optionsACExternal) { optionsAC.current[col.field] = optionsACExternal[col.field]; continue; } if (!schema[col.field]) { continue; } if (['field', 'nested object'].includes(schema[col.field].type) && !(col.field in optionsAC.current)) { const options = yield (0, api_1.getAutoComplete)({ model: col.field, serverEndPoint, }); if (options) { optionsAC.current[col.field] = options; continue; } console.log(`Couldn't load autocomplete options from '${col.field}'`); continue; } if (schema[col.field].type === 'choice' && !(col.field in optionsAC.current)) { optionsAC.current[col.field] = schema[col.field].choices; continue; } if (col.field === indexField && addExistingModel && !optionsAC.current[col.field]) { const options = yield (0, api_1.getAutoComplete)({ model: addExistingModel, serverEndPoint, }); if (options) { optionsAC.current[col.field] = options; continue; } if (!(col.field in optionsAC.current)) { delete optionsAC.current[col.field]; } } } }); const initColumns = () => __awaiter(void 0, void 0, void 0, function* () { const actionCols = []; if (isEditable) { const handleSaveClick = (id) => () => { if (id) { setRowModesModel(Object.assign(Object.assign({}, rowModesModel), { [id]: { mode: x_data_grid_1.GridRowModes.View } })); } }; const handleCancelClick = (id) => () => { if (id) { setRowModesModel(Object.assign(Object.assign({}, rowModesModel), { [id]: { mode: x_data_grid_1.GridRowModes.View, ignoreModifications: true } })); } setDataGrid((currentDataGrid) => { const editedRow = currentDataGrid.data.find((row) => row.id === id); if (editedRow && editedRow.isNew) { return Object.assign(Object.assign({}, currentDataGrid), { data: currentDataGrid.data.filter((row) => row.id !== id) }); } return currentDataGrid; }); }; const handleEditInlineClick = (id) => () => { if (id) { setRowModesModel(Object.assign(Object.assign({}, rowModesModel), { [id]: { mode: x_data_grid_1.GridRowModes.Edit } })); } }; actionCols.push({ field: 'actions', headerName: '', type: 'actions', getActions: ({ id }) => { var _a; if (!id) { return []; } const isInEditMode = ((_a = rowModesModel === null || rowModesModel === void 0 ? void 0 : rowModesModel[id]) === null || _a === void 0 ? void 0 : _a.mode) === x_data_grid_1.GridRowModes.Edit; if (isInEditMode) { return [ react_1.default.createElement(x_data_grid_1.GridActionsCellItem, { key: `save_${id}`, icon: react_1.default.createElement(Check_1.default, null), label: "Salvar", onClick: handleSaveClick(id), color: "success", showInMenu: false, placeholder: "", onResize: () => undefined, onResizeCapture: () => undefined, onPointerEnterCapture: () => undefined, onPointerLeaveCapture: () => undefined }), react_1.default.createElement(x_data_grid_1.GridActionsCellItem, { key: `cancel_${id}`, icon: react_1.default.createElement(Undo_1.default, null), label: "Cancelar", onClick: handleCancelClick(id), color: "inherit", showInMenu: false, placeholder: "", onResize: () => undefined, onResizeCapture: () => undefined, onPointerEnterCapture: () => undefined, onPointerLeaveCapture: () => undefined }), ]; } const actionItems = []; actions.forEach((action) => { switch (action) { case 'editInline': actionItems.push(react_1.default.createElement(x_data_grid_1.GridActionsCellItem, { key: `editInline_${id}`, icon: actions.includes('edit') ? react_1.default.createElement(Bolt_1.default, null) : react_1.default.createElement(Edit_1.default, null), label: "Edit inline", onClick: handleEditInlineClick(id), color: "inherit", showInMenu: false, placeholder: "", onResize: () => undefined, onResizeCapture: () => undefined, onPointerEnterCapture: () => undefined, onPointerLeaveCapture: () => undefined })); break; case 'remove': actionItems.push(react_1.default.createElement(x_data_grid_1.GridActionsCellItem, { key: `remove_${id}`, icon: react_1.default.createElement(Clear_1.default, null), label: "Delete", onClick: handleDeleteClick(id), color: "error", showInMenu: false, placeholder: "", onResize: () => undefined, onResizeCapture: () => undefined, onPointerEnterCapture: () => undefined, onPointerLeaveCapture: () => undefined })); break; case 'edit': if (!LinkComponent) { console.log('you must pass LinkComponent prop to navigate externally'); break; } actionItems.push(react_1.default.createElement(LinkComponent, { key: `edit_${id}`, to: `${indexFieldBasePath}${id}`, state: stateToLink }, react_1.default.createElement(x_data_grid_1.GridActionsCellItem, { icon: react_1.default.createElement(Edit_1.default, null), label: "Edit", color: "inherit", showInMenu: false, placeholder: "", onResize: () => undefined, onResizeCapture: () => undefined, onPointerEnterCapture: () => undefined, onPointerLeaveCapture: () => undefined }))); break; case 'view': if (!LinkComponent) { console.log('you must pass LinkComponent prop to navigate externally'); break; } if (!indexFieldViewBasePath) { console.log('For view action to work, you must supply indexFieldViewBasePath prop!'); break; } actionItems.push(react_1.default.createElement(LinkComponent, { key: `view_${id}`, to: `${indexFieldViewBasePath}${id}`, state: stateToLink }, react_1.default.createElement(x_data_grid_1.GridActionsCellItem, { icon: react_1.default.createElement(Visibility_1.default, null), label: "View", color: "inherit", showInMenu: false, placeholder: "", onResize: () => undefined, onResizeCapture: () => undefined, onPointerEnterCapture: () => undefined, onPointerLeaveCapture: () => undefined }))); break; } }); // React.ReactElement<any, string | React.JSXElementConstructor<any>> // React.ReactElement<any, string | React.JSXElementConstructor<any>> if (customActions) { customActions.forEach((customAction) => { actionItems.push(react_1.default.createElement(x_data_grid_1.GridActionsCellItem, { key: `${customAction.key}_${id}`, icon: customAction.icon, label: customAction.label, onClick: () => customAction.handleClick(dataGrid.data.find((row) => row.id === id)), showInMenu: false, placeholder: "", onResize: () => undefined, onResizeCapture: () => undefined, onPointerEnterCapture: () => undefined, onPointerLeaveCapture: () => undefined })); }); } return actionItems; }, }); } const cols = [...actionCols, ...columns]; const colsPromises = cols.map((col) => __awaiter(void 0, void 0, void 0, function* () { if (!schema[col.field]) { return col; } const isIndexField = indexField !== '' && col.field === indexField; let column = col; if (isIndexField) { col.isIndexField = true; } column.editable = isEditable && !col.disabled && (!schema[col.field].read_only || ['field', 'nested object'].includes(schema[col.field].type)); if (['field', 'nested object'].includes(schema[col.field].type)) { column.creatable = 'related_editable' in schema[col.field] ? schema[col.field].related_editable : column.creatable; } switch (schema[col.field].type) { case 'date': column.type = 'date'; const dateFormat = (0, utils_1.buildDateFormatBySchema)(schema[col.field].date_views); column.valueFormatter = (params) => params.value ? (0, dayjs_1.default)(params.value).format(dateFormat) : ''; column.filterOperators = (0, utils_2.quantityOnlyOperators)({ type: 'date', }); if (isEditable && !col.disabled) { column.renderEditCell = (params) => (react_1.default.createElement(GridDateInput_1.GridDateInput, Object.assign({}, params, { column: column, dateViews: schema[col.field].date_views }))); break; } break; case 'datetime': column.type = 'dateTime'; column.minWidth = 180; column.valueFormatter = (params) => params.value ? (0, dayjs_1.default)(params.value).format('DD/MM/YYYY HH:mm') : ''; column.filterOperators = (0, utils_2.quantityOnlyOperators)({ type: 'date', }); break; case 'nested object': column.minWidth = 150; if (isEditable && !col.disabled) { column.valueFormatter = (params) => { return !params.value ? '' : params.value.label; }; // column.filterable = false; column.sortComparator = (v1, v2, param1, param2) => { return (0, x_data_grid_1.gridStringOrNumberComparator)(v1.label, v2.label, param1, param2); }; column.renderEditCell = (params) => (react_1.default.createElement(SelectEditInputCell_1.SelectEditInputCell, Object.assign({}, params, { column: column, type: schema[col.field].type, options: optionsAC.current && col.field in optionsAC.current ? optionsAC.current[col.field] : [], isIndexField: isIndexField, onEditModel: onEditModel, fieldsLayout: customFieldFormLayouts && col.field in customFieldFormLayouts ? customFieldFormLayouts[col.field] : undefined, setDialog: apiContext.setDialog }))); break; } column.valueGetter = (params) => { return !params.value ? '' : params.value.label; }; break; case 'field': column.orderable = false; if (isEditable && !col.disabled) { column.minWidth = 300; column.valueFormatter = (params) => { return !params.value || !Array.isArray(params.value) ? '' : params.value.map((val) => val.label).join(', '); }; column.filterable = false; column.renderEditCell = (params) => (react_1.default.createElement(SelectEditInputCell_1.SelectEditInputCell, Object.assign({}, params, { column: column, type: schema[col.field].type, options: optionsAC.current && col.field in optionsAC.current ? optionsAC.current[col.field] : [], isIndexField: isIndexField, multiple: schema[col.field].many || false, setDialog: apiContext.setDialog }))); break; } column.valueGetter = (params) => { return !params.value || !Array.isArray(params.value) ? '' : params.value.map((val) => val.label).join(', '); }; break; case 'choice': if (isEditable && !col.disabled) { column.minWidth = 150; column.valueFormatter = (params) => { return !params.value ? '' : params.value.display_name; }; column.filterable = false; column.sortComparator = (v1, v2, param1, param2) => { return (0, x_data_grid_1.gridStringOrNumberComparator)(v1.display_name, v2.display_name, param1, param2); }; column.renderEditCell = (params) => (react_1.default.createElement(SelectEditInputCell_1.SelectEditInputCell, Object.assign({}, params, { column: column, type: schema[col.field].type, options: optionsAC.current && col.field in optionsAC.current ? optionsAC.current[col.field] : [], isIndexField: isIndexField, setDialog: apiContext.setDialog }))); break; } column.valueGetter = (params) => { return !params.value ? '' : params.value.display_name; }; break; case 'boolean': if (isEditable && !col.disabled) { column.valueFormatter = (params) => { return params.value ? 'Sim' : 'Não'; }; column.renderEditCell = (params) => react_1.default.createElement(BooleanInputCell_1.BooleanInputCell, Object.assign({}, params, { column: column })); break; } column.valueGetter = (params) => { return params.value ? 'Sim' : 'Não'; }; break; case 'decimal': case 'float': const decimalScale = schema[col.field].decimal_places || 2; const prefix = schema[col.field].prefix || ''; const suffix = schema[col.field].suffix || ''; const isCurrency = schema[col.field].is_currency; column.type = 'number'; column.valueFormatter = (params) => { return !params.value ? '' : parseFloat(params.value).toLocaleString('pt-BR', { minimumFractionDigits: decimalScale, maximumFractionDigits: decimalScale, }); }; if (isEditable && !col.disabled) { column.renderEditCell = (params) => (react_1.default.createElement(GridDecimalInput_1.GridDecimalInput, Object.assign({}, params, { decimalPlaces: decimalScale, isCurrency: isCurrency, prefix: prefix, suffix: suffix, column: column }))); } column.filterOperators = (0, utils_2.quantityOnlyOperators)({ type: 'float', }); break; case 'number': case 'integer': column.type = 'number'; column.filterOperators = (0, utils_2.quantityOnlyOperators)({ type: 'number', }); break; } if (indexFieldMinWidth && !column.minWidth) { column.minWidth = col.field === indexField ? indexFieldMinWidth : minWidth; } if (indexField) { if (col.field === indexField) { column.flex = 1; column.renderCell = (params) => { if (LinkComponent && customLinkDestination && !actions.includes('edit')) { return (react_1.default.createElement(LinkComponent, { to: `${customLinkDestination(params)}`, state: stateToLink }, params.formattedValue)); } if (!LinkComponent || !indexFieldBasePath || actions.includes('edit') || (['field', 'nested object'].includes(schema[col.field].type) && (!params.row[col.field] || !params.row[col.field].id))) { return react_1.default.createElement(react_1.default.Fragment, null, params.formattedValue); } const targetId = ['field', 'nested object'].includes(schema[col.field].type) ? params.row[col.field].id.toString() : params.row.id.toString(); return (react_1.default.createElement(LinkComponent, { to: `${indexFieldBasePath}${targetId}`, state: stateToLink }, params.formattedValue)); }; if (isEditable && !col.disabled && optionsAC.current && col.field in optionsAC.current && addExistingModel) { column.renderEditCell = (params) => { if (!(0, utils_1.isTmpId)(params.id)) { return react_1.default.createElement(x_data_grid_1.GridEditInputCell, Object.assign({}, params)); } return (react_1.default.createElement(SelectEditInputCell_1.SelectEditInputCell, Object.assign({}, params, { column: column, type: schema[col.field].type, options: optionsAC.current && col.field in optionsAC.current ? optionsAC.current[col.field] : [], isIndexField: true, setDialog: apiContext.setDialog }))); }; } } } // format numbers: if (column.patternFormat) { column.valueFormatter = (params) => { if (!params.value || typeof params.value !== 'string') { return params.value; } const formattedValue = new string_mask_1.default(column.patternFormat, {}).apply(params.value); return formattedValue; }; if (isEditable && !col.disabled) { column.renderEditCell = (params) => (react_1.default.createElement(GridPatternInput_1.GridPatternInput, Object.assign({}, params, { patternFormat: column.patternFormat }))); } } // Custom column operations: if (customColumnOperations) { column = yield customColumnOperations(column); } // Finally! return column; })); const finalCols = yield Promise.all(colsPromises); setPreparedColumns(finalCols); }); const handleAddItems = (numberOfRows = 1) => { const newRows = []; for (let i = 0; i < numberOfRows; i++) { const id = (0, utils_1.getTmpId)(); newRows.push(Object.assign(Object.assign({}, emptyItem), { id })); } const newData = tableAutoHeight ? [...dataGrid.data, ...newRows] : [...newRows, ...dataGrid.data]; setDataGrid({ data: newData, }); setRowModesModel((oldModel) => { const newModel = Object.assign({}, oldModel); newRows.map((newRow) => { newModel[newRow.id] = { mode: x_data_grid_1.GridRowModes.Edit, fieldToFocus: indexField }; }); return newModel; }); if (!tableAutoHeight) { // Ugly hack to scroll to top, since scroll to cell is only available in Pro const el = document.querySelector(`.dataGrid_${name} .MuiDataGrid-virtualScroller`); if (el) { el.scrollTop = 0; setTimeout(() => { el.scrollTop = 0; }, 10); } } }; const bulkUpdateData = (newData) => __awaiter(void 0, void 0, void 0, function* () { const promises = []; const ids = []; newData.map((item) => { promises.push((0, api_1.updateDataBySchema)({ model, modelObjectId: item.id, serverEndPoint, data: item, schema, })); ids.push(item.id); }); const results = yield Promise.all(promises); setSelectionModel([]); setSelectionModelIds([]); setDataGrid((currentData) => { const updatedData = currentData.data.map((item) => { const index = ids.indexOf(item.id); return index === -1 ? item : newData[index]; }); return { data: updatedData, }; }); setSnackBar({ open: true, severity: 'success', msg: 'Alterações salvas com sucesso', }); return results.map((result, index) => { return { id: ids[index], success: 'isAxiosError' in result, }; }); }); const bulkDeleteData = (ids) => __awaiter(void 0, void 0, void 0, function* () { const promises = []; ids.map((id) => { promises.push((0, api_1.deleteData)(model, serverEndPoint, id)); }); setDataGridLoading(true); const results = yield Promise.all(promises); setSelectionModel([]); setSelectionModelIds([]); setDataGrid({ data: dataGrid.data.filter((item) => !ids.includes(item.id)), }); setDataGridLoading(false); setSnackBar({ open: true, severity: 'success', msg: 'Itens apagados com sucesso', }); return results.map((result, index) => { return { id: ids[index], success: result === true, }; }); }); const bulkCreateData = (ids) => __awaiter(void 0, void 0, void 0, function* () { handleAddItems(ids.length); setSelectionModel([]); setSelectionModelIds([]); setSnackBar({ open: true, severity: 'success', msg: 'Linhas adicionadas com sucesso', }); }); (0, react_1.useEffect)(() => { updateOptionsAC().then(() => { initColumns(); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [rowModesModel, JSON.stringify(columns)]); const processRowUpdate = (editedRow) => __awaiter(void 0, void 0, void 0, function* () { if (!preparedColumns || !yupValidationSchema.current) { return false; } setDataGridLoading(true); const indexCol = preparedColumns.find((col) => col.field === indexField); processingRow.current = editedRow.id; yield yupValidationSchema.current.validate(editedRow); const onlyAddExisting = indexField && (0, utils_1.isTmpId)(editedRow.id) && editedRow[indexField] && !(0, utils_1.isTmpId)(editedRow[indexField].id) && (!indexCol || !indexCol.valueFormatter); const createNewItem = indexField && (0, utils_1.isTmpId)(editedRow.id) && editedRow[indexField] && (0, utils_1.isTmpId)(editedRow[indexField].id); if (onlyAddExisting) { const row = {}; row.id_to_add = editedRow[indexField].id; for (const [key, value] of Object.entries(editedRow[indexField])) { if (key === 'id') { row[key] = editedRow.id; continue; } row[key] = value; } editedRow = Object.assign({}, row); } if (createNewItem && editedRow[indexField]) { if (editedRow[indexField].inputValue) { editedRow[indexField] = editedRow[indexField].inputValue; } if (addExistingModel) { editedRow[indexField] = editedRow[indexField].label; } } if (modelParent && modelParentId && apiContext) { const response = yield apiContext.onEditRelatedModelSave({ model: modelParent, id: modelParentId, relatedModel: model, relatedModelId: editedRow.id, newRow: editedRow, schema, onlyAddExisting, }); if (response !== false && (onlyAddExisting || createNewItem || !onlyAddExisting)) { updateOptionsAC(); const data = [...dataGrid.data]; const newRow = 'data' in response && 'schema' in response ? response.data : response; for (const i in data) { if (data[i].id === editedRow.id) { data[i] = newRow; // This is for cases where users want to do custom operations after saving the row, // like for example make calculations among columns. if (onProcessRow) { onProcessRow(data[i]); } // Reflect the changes to the outside, for example for global calculations over all data if (onDataChange) { onDataChange(data); } setDataGrid({ data }); break; } } setDataGridLoading(false); return newRow; } setDataGridLoading(false); return false; } const response = yield apiContext.onEditModelDataGridSave({ model, id: editedRow.id, newRow: editedRow, schema, }); setDataGridLoading(false); if (response !== false) { updateOptionsAC(); const data = [...dataGrid.data]; const newRow = response; for (const i in data) { if (data[i].id === editedRow.id) { data[i] = newRow; // This is for cases where users want to do custom operations after saving the row, // like for example make calculations among columns. if (onProcessRow) { onProcessRow(data[i]); } // Reflect the changes to the outside, for example for global calculations over all data if (onDataChange) { onDataChange(data); } setDataGrid({ data }); break; } } return newRow; } return false; }); const customPaddings = isAutoHeight ? { '&.MuiDataGrid-root--densityCompact .MuiDataGrid-cell': { py: '8px', }, '&.MuiDataGrid-root--densityStandard .MuiDataGrid-cell': { py: '15px', }, '&.MuiDataGrid-root--densityComfortable .MuiDataGrid-cell': { py: '22px', }, } : undefined; const checkboxSelection = hasBulkSelect ? true : undefined; const disableRowSelectionOnClick = hasBulkSelect ? true : undefined; return (react_1.default.createElement(Box_1.default, { className: `dataGrid_${name}`, sx: { height: '100%' } }, preparedColumns === null ? (react_1.default.createElement(Box_1.default, { sx: styles_1.Layout.loadingBox }, react_1.default.createElement(CircularProgress_1.default, null))) : (react_1.default.createElement(x_data_grid_1.DataGrid, { rows: dataGrid.data, columns: preparedColumns, autoHeight: tableAutoHeight, onStateChange: (state) => { if (setVisibleRows) { const newVisibleRows = Object.entries(state.filter.visibleRowsLookup) .filter((entry) => { return entry[1] === true; }) .map((entry) => { return entry[0]; }); const newVisibleRowsJSON = JSON.stringify(newVisibleRows); if (newVisibleRowsJSON !== visibleRows.current) { setVisibleRows(newVisibleRows); visibleRows.current = newVisibleRowsJSON; } } }, editMode: "row", loading: dataGridLoading || loading, hideFooterPagination: hideFooterPagination, getRowHeight: () => { if (isAutoHeight) { return 'auto'; } return null; }, isCellEditable: (params) => { var _a; const isRowInEditMode = ((_a = rowModesModel === null || rowModesModel === void 0 ? void 0 : rowModesModel[params.row.id]) === null || _a === void 0 ? void 0 : _a.mode) === x_data_grid_1.GridRowModes.Edit; const isPermanentRow = !(0, utils_1.isTmpId)(params.row.id); const isIndexField = params.field === indexField; const indexColumn = preparedColumns.find((col) => col.field === indexField); const hasValueFormatter = (indexColumn === null || indexColumn === void 0 ? void 0 : indexColumn.valueFormatter) !== undefined; const isIndexFieldEditable = !optionsAC.current || !(indexField in optionsAC.current) || hasValueFormatter; return (isRowInEditMode && (isPermanentRow || ((0, utils_1.isTmpId)(params.row.id) && (isIndexField || isIndexFieldEditable)))); }, checkboxSelection: checkboxSelection, onSelectionModelChange: (newSelectionModel) => { const selectedData = dataGrid.data.filter((item) => newSelectionModel.includes(item.id)); setSelectionModel(selectedData); setSelectionModelIds(newSelectionModel); }, selectionModel: selectionModelIds, disableSelectionOnClick: disableRowSelectionOnClick, rowModesModel: rowModesModel, onRowEditStart: (params, event) => { event.defaultMuiPrevented = true; }, onRowEditStop: (params, event) => { event.defaultMuiPrevented = true; }, processRowUpdate: processRowUpdate, onProcessRowUpdateError: (e) => { setDataGridLoading(false); if (processingRow.current) { setRowModesModel(Object.assign(Object.assign({}, rowModesModel), { [processingRow.current]: { mode: x_data_grid_1.GridRowModes.Edit, } })); } const msg = `Erro em "${e.path}": ${e.errors}`; setSnackBar({ open: true, severity: 'error', msg, }); console.log(e); }, components: { Toolbar: hideToolbarComponent ? () => react_1.default.createElement(react_1.default.Fragment, null) : CustomToolbar_1.CustomToolbar, Footer: hideFooterComponent ? () => react_1.default.createElement(react_1.default.Fragment, null) : FooterToolbar_1.FooterToolbar, }, componentsProps: { toolbar: { preparedColumns, setPreparedColumns, showQuickFilter: true, quickFilterProps: { debounceMs: 500 }, // getRowsToExport: () => { // return []; // }, selectionModel, onSelectActions, bulkUpdateData, bulkDeleteData, bulkCreateData, hideColumnsButton, hideFilterButton, hideDensityButton, hideExportButton, hideQuickFilterBar, }, footer: { isEditable, handleAddItem: () => { handleAddItems(); }, }, filterPanel: { sx: { '& .MuiDataGrid-filterFormValueInput': { width: 300, }, }, }, }, experimentalFeatures: { newEditingApi: isEditable }, sx: customPaddings, paginationMode: paginationModel ? 'server' : 'client', onPageChange: (newPage) => { if (setPaginationModel && paginationModel) { setPaginationModel(Object.assign(Object.assign({}, paginationModel), { page: newPage })); } }, onPageSizeChange: (newPageSize) => { if (setPaginationModel && paginationModel) { setPaginationModel(Object.assign(Object.assign({}, paginationModel), { pageSize: newPageSize })); } }, rowCount: paginationModel && typeof rowCount !== 'undefined' ? rowCount : undefined, pageSize: paginationModel ? paginationModel.pageSize : 100, rowsPerPageOptions: paginationModel ? [paginationModel.pageSize] : [5, 10, 25, 50, 100], filterMode: paginationModel ? 'server' : 'client', onFilterModelChange: paginationModel ? (newFilter) => { if (setPaginationModel && paginationModel) { setPaginationModel(Object.assign(Object.assign({}, paginationModel), { filter: newFilter })); } } : undefined, sortingMode: paginationModel ? 'server' : 'client', onSortModelChange: paginationModel ? (newSorting) => { if (setPaginationModel && paginationModel) { setPaginationModel(Object.assign(Object.assign({}, paginationModel), { sort: newSorting })); } } : undefined })))); }); DataGridDesktop.displayName = 'DataGridDesktop'; exports.default = DataGridDesktop;