drf-react-by-schema 0.2.1 → 0.3.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/.gitlab-ci.yml +2 -2
- package/README.md +7 -1
- package/dist/index.js +14 -27
- package/package.json +6 -2
- package/src/api.ts +21 -27
- package/src/components/DataGridBySchemaEditable/SelectEditInputCell.tsx +12 -11
- package/src/components/DataGridBySchemaEditable.md +2 -2
- package/src/components/DataGridBySchemaEditable.tsx +38 -27
- package/src/components/DataTotals.tsx +4 -3
- package/src/components/DialogActions.tsx +33 -0
- package/src/components/DialogJSONSchemaForm.tsx +40 -0
- package/src/components/GenericModelList.tsx +24 -14
- package/src/components/GenericRelatedModelList.tsx +168 -0
- package/src/context/APIWrapper.tsx +447 -0
- package/src/context/APIWrapperContext.tsx +84 -0
- package/src/context/DRFReactBySchemaContext.tsx +33 -0
- package/src/context/DRFReactBySchemaProvider.md +30 -23
- package/src/context/DRFReactBySchemaProvider.tsx +27 -33
- package/src/context/Overlays.tsx +94 -0
- package/src/index.ts +15 -2
- package/src/styles/theme.ts +2 -2
- package/src/utils.ts +11 -5
- package/styleguide.config.js +2 -7
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import Box from '@mui/material/Box';
|
|
3
|
+
import { GridRowId } from '@mui/x-data-grid';
|
|
3
4
|
|
|
4
5
|
import DataGridBySchemaEditable from './DataGridBySchemaEditable';
|
|
5
6
|
import DataTotals, { SumRowsType } from './DataTotals';
|
|
6
7
|
import { Layout } from '../styles';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { GridEnrichedBySchemaColDef, Item, SchemaType, DataSchemaColumnsType } from '../utils';
|
|
9
|
+
import { getGenericModelList, getGenericModelListProps } from '../api';
|
|
10
|
+
import { DRFReactBySchemaContext } from '../context/DRFReactBySchemaContext';
|
|
11
|
+
import { APIWrapperContext } from '../context/APIWrapperContext';
|
|
11
12
|
|
|
12
13
|
interface GenericModelListProps {
|
|
13
14
|
columnFields: string[];
|
|
@@ -20,9 +21,8 @@ interface GenericModelListProps {
|
|
|
20
21
|
sumRows?: SumRowsType;
|
|
21
22
|
isAutoHeight?: boolean;
|
|
22
23
|
model: string;
|
|
23
|
-
handleLoading: (p: any) => void;
|
|
24
24
|
forceReload: boolean;
|
|
25
|
-
LinkComponent
|
|
25
|
+
LinkComponent?: React.ReactNode;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const GenericModelList = ({
|
|
@@ -36,24 +36,30 @@ const GenericModelList = ({
|
|
|
36
36
|
sumRows,
|
|
37
37
|
isAutoHeight = true,
|
|
38
38
|
model,
|
|
39
|
-
handleLoading,
|
|
40
39
|
forceReload = false,
|
|
41
40
|
LinkComponent = null
|
|
42
41
|
}: GenericModelListProps) => {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (!serverEndPoint) {
|
|
42
|
+
const context = React.useContext(DRFReactBySchemaContext);
|
|
43
|
+
const apiContext = React.useContext(APIWrapperContext);
|
|
44
|
+
if (!context.serverEndPoint || !apiContext) {
|
|
47
45
|
console.error('Error: There is no endpoint defined in DRFReactBySchemaProvider!');
|
|
48
46
|
return (<></>);
|
|
49
47
|
}
|
|
48
|
+
const {
|
|
49
|
+
serverEndPoint,
|
|
50
|
+
isInBatches,
|
|
51
|
+
firstBatchLength
|
|
52
|
+
} = context;
|
|
53
|
+
const {
|
|
54
|
+
handleLoading
|
|
55
|
+
} = apiContext;
|
|
50
56
|
interface dataProps {
|
|
51
57
|
data: Item[];
|
|
52
58
|
schema: SchemaType;
|
|
53
59
|
columns: GridEnrichedBySchemaColDef[]
|
|
54
60
|
};
|
|
55
61
|
const [data, setData] = useState<DataSchemaColumnsType | boolean>(false);
|
|
56
|
-
const [visibleRows, setVisibleRows] = useState<
|
|
62
|
+
const [visibleRows, setVisibleRows] = useState<GridRowId[]>([]);
|
|
57
63
|
const [hideFooterPagination, setHideFooterPagination] = useState(false);
|
|
58
64
|
|
|
59
65
|
const finalCustomColumnOperations = (column: GridEnrichedBySchemaColDef) => {
|
|
@@ -116,7 +122,7 @@ const GenericModelList = ({
|
|
|
116
122
|
|
|
117
123
|
return (
|
|
118
124
|
<>
|
|
119
|
-
{
|
|
125
|
+
{typeof data !== 'boolean' && data.columns &&
|
|
120
126
|
<>
|
|
121
127
|
<Box sx={Layout.dataGridWithTabs}>
|
|
122
128
|
<DataGridBySchemaEditable
|
|
@@ -131,7 +137,11 @@ const GenericModelList = ({
|
|
|
131
137
|
hideFooterPagination={hideFooterPagination}
|
|
132
138
|
customColumnOperations={finalCustomColumnOperations}
|
|
133
139
|
customLinkDestination={customLinkDestination}
|
|
134
|
-
setVisibleRows={
|
|
140
|
+
setVisibleRows={(newVisibleRows:GridRowId[]) => {
|
|
141
|
+
if (JSON.stringify(newVisibleRows) !== JSON.stringify(visibleRows)) {
|
|
142
|
+
setVisibleRows(newVisibleRows);
|
|
143
|
+
}
|
|
144
|
+
}}
|
|
135
145
|
onDataChange={newData => {
|
|
136
146
|
setData({
|
|
137
147
|
...data,
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import Box from '@mui/material/Box';
|
|
3
|
+
import { GridRowId } from '@mui/x-data-grid';
|
|
4
|
+
|
|
5
|
+
import DataGridBySchemaEditable from './DataGridBySchemaEditable';
|
|
6
|
+
import DataTotals from './DataTotals';
|
|
7
|
+
import { DRFReactBySchemaContext } from '../context/DRFReactBySchemaContext';
|
|
8
|
+
import { APIWrapperContext } from '../context/APIWrapperContext';
|
|
9
|
+
import { DataSchemaColumnsType, GridEnrichedBySchemaColDef, Id, Item } from '../utils';
|
|
10
|
+
import { getGenericModelList } from '../api';
|
|
11
|
+
import { SumRowsType } from './DataTotals';
|
|
12
|
+
import { Layout } from '../styles';
|
|
13
|
+
|
|
14
|
+
interface GenericRelatedModelListProps {
|
|
15
|
+
model: string;
|
|
16
|
+
id: Id;
|
|
17
|
+
relatedModel: string;
|
|
18
|
+
columnFields: string[];
|
|
19
|
+
creatableFields: string[];
|
|
20
|
+
hiddenFields: string[];
|
|
21
|
+
usuaria?: Item | null;
|
|
22
|
+
minWidthFields?: Record<string, number>;
|
|
23
|
+
indexField?: string;
|
|
24
|
+
addExistingModel?: string;
|
|
25
|
+
onProcessRow?: (p: any) => void;
|
|
26
|
+
sumRows?: SumRowsType;
|
|
27
|
+
customColumnOperations?: (column: GridEnrichedBySchemaColDef) => GridEnrichedBySchemaColDef;
|
|
28
|
+
isEditable?: boolean;
|
|
29
|
+
isAutoHeight?: boolean;
|
|
30
|
+
isInBatches?: boolean;
|
|
31
|
+
indexFieldBasePath?: string;
|
|
32
|
+
LinkComponent?: React.ReactNode;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default function GenericRelatedModelList ({
|
|
36
|
+
model,
|
|
37
|
+
id,
|
|
38
|
+
relatedModel,
|
|
39
|
+
columnFields,
|
|
40
|
+
creatableFields,
|
|
41
|
+
hiddenFields,
|
|
42
|
+
usuaria,
|
|
43
|
+
minWidthFields,
|
|
44
|
+
indexField = '',
|
|
45
|
+
addExistingModel = '',
|
|
46
|
+
onProcessRow,
|
|
47
|
+
sumRows,
|
|
48
|
+
customColumnOperations,
|
|
49
|
+
isEditable = true,
|
|
50
|
+
isAutoHeight = false,
|
|
51
|
+
indexFieldBasePath,
|
|
52
|
+
LinkComponent
|
|
53
|
+
}:GenericRelatedModelListProps) {
|
|
54
|
+
const context = React.useContext(DRFReactBySchemaContext);
|
|
55
|
+
const apiContext = React.useContext(APIWrapperContext);
|
|
56
|
+
if (!context.serverEndPoint || !apiContext) {
|
|
57
|
+
console.error('Error: There is no endpoint defined in DRFReactBySchemaProvider!');
|
|
58
|
+
return (<></>);
|
|
59
|
+
}
|
|
60
|
+
const {
|
|
61
|
+
serverEndPoint,
|
|
62
|
+
isInBatches,
|
|
63
|
+
firstBatchLength,
|
|
64
|
+
} = context;
|
|
65
|
+
const {
|
|
66
|
+
onEditRelatedModelSave,
|
|
67
|
+
onDeleteRelatedModel
|
|
68
|
+
} = apiContext;
|
|
69
|
+
|
|
70
|
+
const [data, setData] = useState<DataSchemaColumnsType | boolean>(false);
|
|
71
|
+
const [visibleRows, setVisibleRows] = useState<GridRowId[]>([]);
|
|
72
|
+
const [hideFooterPagination, setHideFooterPagination] = useState(false);
|
|
73
|
+
|
|
74
|
+
const finalCustomColumnOperations = (column:GridEnrichedBySchemaColDef) => {
|
|
75
|
+
if (minWidthFields) {
|
|
76
|
+
if (Object.prototype.hasOwnProperty.call(minWidthFields, column.field)) {
|
|
77
|
+
column.minWidth = minWidthFields[column.field];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (customColumnOperations) {
|
|
82
|
+
return customColumnOperations(column);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return column;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const loadObjectList = async () => {
|
|
89
|
+
const loadParams = {
|
|
90
|
+
model,
|
|
91
|
+
serverEndPoint,
|
|
92
|
+
id,
|
|
93
|
+
relatedModel,
|
|
94
|
+
columnFields,
|
|
95
|
+
hiddenFields,
|
|
96
|
+
creatableFields,
|
|
97
|
+
isInBatches
|
|
98
|
+
};
|
|
99
|
+
const loadedData = await getGenericModelList(loadParams);
|
|
100
|
+
if (loadedData) {
|
|
101
|
+
setData(loadedData);
|
|
102
|
+
if (isInBatches && loadedData.data.length === firstBatchLength) {
|
|
103
|
+
setHideFooterPagination(true);
|
|
104
|
+
getGenericModelList({
|
|
105
|
+
...loadParams,
|
|
106
|
+
loadedSchema: loadedData.schema
|
|
107
|
+
}).then(lastBatchData => {
|
|
108
|
+
if (lastBatchData) {
|
|
109
|
+
setData({
|
|
110
|
+
...loadedData,
|
|
111
|
+
data: [
|
|
112
|
+
...loadedData.data,
|
|
113
|
+
...lastBatchData.data
|
|
114
|
+
]
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
setHideFooterPagination(false);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
console.log('error retrieving data!');
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
loadObjectList();
|
|
127
|
+
}, []);
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<>
|
|
131
|
+
{typeof data !== 'boolean' && data.columns &&
|
|
132
|
+
<>
|
|
133
|
+
<Box sx={Layout.dataGridFixedHeight}>
|
|
134
|
+
<DataGridBySchemaEditable
|
|
135
|
+
data={data.data}
|
|
136
|
+
columns={data.columns}
|
|
137
|
+
schema={data.schema}
|
|
138
|
+
model={relatedModel}
|
|
139
|
+
indexField={indexField}
|
|
140
|
+
indexFieldBasePath={indexFieldBasePath}
|
|
141
|
+
addExistingModel={addExistingModel}
|
|
142
|
+
isEditable={isEditable}
|
|
143
|
+
modelParent={model}
|
|
144
|
+
modelParentId={id}
|
|
145
|
+
customColumnOperations={finalCustomColumnOperations}
|
|
146
|
+
setVisibleRows={setVisibleRows}
|
|
147
|
+
isAutoHeight={isAutoHeight}
|
|
148
|
+
hideFooterPagination={hideFooterPagination}
|
|
149
|
+
onProcessRow={onProcessRow}
|
|
150
|
+
onDataChange={newData => {
|
|
151
|
+
setData({
|
|
152
|
+
...data,
|
|
153
|
+
data: newData
|
|
154
|
+
});
|
|
155
|
+
}}
|
|
156
|
+
LinkComponent={LinkComponent}
|
|
157
|
+
/>
|
|
158
|
+
</Box>
|
|
159
|
+
<DataTotals
|
|
160
|
+
data={data.data}
|
|
161
|
+
sumRows={sumRows}
|
|
162
|
+
visibleRows={visibleRows}
|
|
163
|
+
/>
|
|
164
|
+
</>
|
|
165
|
+
}
|
|
166
|
+
</>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import React, { useState, useReducer, useEffect, useRef } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Id,
|
|
4
|
+
Item,
|
|
5
|
+
reducer,
|
|
6
|
+
SchemaType,
|
|
7
|
+
populateValues,
|
|
8
|
+
buildGenericYupValidationSchema,
|
|
9
|
+
getTmpId,
|
|
10
|
+
isTmpId
|
|
11
|
+
} from '../utils';
|
|
12
|
+
|
|
13
|
+
import DialogJSONSchemaForm from '../components/DialogJSONSchemaForm';
|
|
14
|
+
import DialogActions from '../components/DialogActions';
|
|
15
|
+
import { DRFReactBySchemaContext, DRFReactBySchemaContextType } from './DRFReactBySchemaContext';
|
|
16
|
+
import {
|
|
17
|
+
isLoggedIn,
|
|
18
|
+
getAutoComplete,
|
|
19
|
+
getGenericModel,
|
|
20
|
+
updateDataBySchema,
|
|
21
|
+
addExistingRelatedModel,
|
|
22
|
+
deleteData,
|
|
23
|
+
getJSONSchema,
|
|
24
|
+
createOrUpdateJSONSchema
|
|
25
|
+
} from '../api';
|
|
26
|
+
import { AxiosResponse } from 'axios';
|
|
27
|
+
import {
|
|
28
|
+
APIWrapperContext,
|
|
29
|
+
DialogType,
|
|
30
|
+
LoadSinglePageDataProps,
|
|
31
|
+
OnDeleteRelatedModelType,
|
|
32
|
+
OnEditModelType,
|
|
33
|
+
OnEditRelatedModelType,
|
|
34
|
+
PageFormType,
|
|
35
|
+
SnackBarType
|
|
36
|
+
} from './APIWrapperContext';
|
|
37
|
+
|
|
38
|
+
interface APIWrapperProps {
|
|
39
|
+
setLoading: React.Dispatch<React.SetStateAction<boolean>>;
|
|
40
|
+
handleLoading: (p: boolean) => void;
|
|
41
|
+
setSnackBar: React.Dispatch<React.SetStateAction<SnackBarType>>;
|
|
42
|
+
setDialog: React.Dispatch<React.SetStateAction<DialogType>>;
|
|
43
|
+
children: React.ReactNode;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
function APIWrapper ({
|
|
47
|
+
setLoading,
|
|
48
|
+
handleLoading,
|
|
49
|
+
setSnackBar,
|
|
50
|
+
setDialog,
|
|
51
|
+
children
|
|
52
|
+
}:APIWrapperProps) {
|
|
53
|
+
const { serverEndPoint } = DRFReactBySchemaContext
|
|
54
|
+
? React.useContext(DRFReactBySchemaContext) as DRFReactBySchemaContextType
|
|
55
|
+
: { serverEndPoint: null };
|
|
56
|
+
if (!serverEndPoint) {
|
|
57
|
+
return (
|
|
58
|
+
<>
|
|
59
|
+
{children}
|
|
60
|
+
</>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const [usuaria, setUsuaria] = useState<Item | null>(null);
|
|
65
|
+
const [optionsAC, setOptionsAC] = useReducer(reducer, {});
|
|
66
|
+
const initialPageForm:PageFormType = {
|
|
67
|
+
id: '',
|
|
68
|
+
schema: null,
|
|
69
|
+
initialValues: null,
|
|
70
|
+
validationSchema: null
|
|
71
|
+
};
|
|
72
|
+
const [pageForm, setPageForm] = useReducer(reducer, initialPageForm);
|
|
73
|
+
const editModel = useRef<Item>({});
|
|
74
|
+
const jsonSchemaFormRef = useRef<any>(null);
|
|
75
|
+
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
setUsuaria(null);
|
|
78
|
+
isLoggedIn(serverEndPoint).then(usuaria => {
|
|
79
|
+
setUsuaria(usuaria || { erro: 'token inválido' });
|
|
80
|
+
});
|
|
81
|
+
}, []);
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
setPageForm(initialPageForm);
|
|
85
|
+
}, []);
|
|
86
|
+
|
|
87
|
+
const onTriggerSnackBar = ({ msg, severity = 'info' }:SnackBarType) => {
|
|
88
|
+
setSnackBar({
|
|
89
|
+
open: true,
|
|
90
|
+
msg,
|
|
91
|
+
severity
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const loadSinglePageData = async ({
|
|
96
|
+
model,
|
|
97
|
+
objId,
|
|
98
|
+
objTitleField = 'nome',
|
|
99
|
+
optionsACModels,
|
|
100
|
+
basePath = '/',
|
|
101
|
+
formPath = null,
|
|
102
|
+
extraValidators = {}
|
|
103
|
+
}: LoadSinglePageDataProps) => {
|
|
104
|
+
setLoading(true);
|
|
105
|
+
if (objId === 'novo') {
|
|
106
|
+
objId = getTmpId();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const object = await getGenericModel({
|
|
110
|
+
model,
|
|
111
|
+
serverEndPoint,
|
|
112
|
+
id: isTmpId(objId) ? null : objId
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (object === false) {
|
|
116
|
+
setPageForm({ schema: false, id: '' });
|
|
117
|
+
console.log('Houve um erro ao tentar carregar os dados!');
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
setLoading(false);
|
|
122
|
+
|
|
123
|
+
populateOptionsAC(optionsACModels);
|
|
124
|
+
|
|
125
|
+
const values = populateInitialValues({
|
|
126
|
+
model,
|
|
127
|
+
id: objId,
|
|
128
|
+
extraValidators,
|
|
129
|
+
...object
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return values;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const onSubmit = async (
|
|
136
|
+
model:string,
|
|
137
|
+
id:Id,
|
|
138
|
+
data:Item,
|
|
139
|
+
e:React.SyntheticEvent<HTMLButtonElement, SubmitEvent>
|
|
140
|
+
) => {
|
|
141
|
+
setLoading(true);
|
|
142
|
+
const response = await updateDataBySchema({
|
|
143
|
+
model,
|
|
144
|
+
modelObjectId: id,
|
|
145
|
+
serverEndPoint,
|
|
146
|
+
data,
|
|
147
|
+
schema: pageForm.schema
|
|
148
|
+
});
|
|
149
|
+
setLoading(false);
|
|
150
|
+
if (!['number', 'string'].includes(typeof response)) {
|
|
151
|
+
onTriggerSnackBar({
|
|
152
|
+
msg: 'Houve um problema ao salvar seus dados! Por favor, entre em contato',
|
|
153
|
+
severity: 'error'
|
|
154
|
+
});
|
|
155
|
+
console.log({
|
|
156
|
+
msg: 'Error saving model',
|
|
157
|
+
errors: response,
|
|
158
|
+
data
|
|
159
|
+
});
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
onTriggerSnackBar({
|
|
164
|
+
msg: (id)
|
|
165
|
+
? 'Dados atualizados com sucesso!'
|
|
166
|
+
: 'Criado com sucesso!'
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return response as Id;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const populateOptionsAC = (optionsACModels:string[]) => {
|
|
173
|
+
for (const model of optionsACModels) {
|
|
174
|
+
getAutoComplete({ model, serverEndPoint }).then(options => {
|
|
175
|
+
setOptionsAC({ [model]: options });
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
interface PopulateInitialValuesProps {
|
|
181
|
+
model: string;
|
|
182
|
+
id: Id;
|
|
183
|
+
data: Item;
|
|
184
|
+
schema: SchemaType;
|
|
185
|
+
extraValidators: Item;
|
|
186
|
+
isEditModel?: boolean;
|
|
187
|
+
};
|
|
188
|
+
const populateInitialValues = ({
|
|
189
|
+
model,
|
|
190
|
+
id,
|
|
191
|
+
isEditModel,
|
|
192
|
+
extraValidators,
|
|
193
|
+
...object
|
|
194
|
+
}:PopulateInitialValuesProps) => {
|
|
195
|
+
const values = populateValues(object);
|
|
196
|
+
const yupSchema = buildGenericYupValidationSchema({ ...object, data: values, extraValidators });
|
|
197
|
+
setPageForm({
|
|
198
|
+
model,
|
|
199
|
+
id,
|
|
200
|
+
schema: object.schema,
|
|
201
|
+
initialValues: values,
|
|
202
|
+
validationSchema: yupSchema
|
|
203
|
+
});
|
|
204
|
+
return values;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const onEditModel = ({
|
|
208
|
+
fieldKey,
|
|
209
|
+
index,
|
|
210
|
+
model,
|
|
211
|
+
id,
|
|
212
|
+
labelKey,
|
|
213
|
+
setValue,
|
|
214
|
+
getValues
|
|
215
|
+
}: OnEditModelType) => {
|
|
216
|
+
setDialog({
|
|
217
|
+
open: true,
|
|
218
|
+
loading: true
|
|
219
|
+
});
|
|
220
|
+
getJSONSchema({ model, serverEndPoint, id }).then(data => {
|
|
221
|
+
const jsonSchemaSubmit = async (e:React.SyntheticEvent<HTMLElement, SubmitEvent>) => {
|
|
222
|
+
jsonSchemaFormRef.current.onSubmit(e);
|
|
223
|
+
return true;
|
|
224
|
+
};
|
|
225
|
+
setDialog({
|
|
226
|
+
loading: false,
|
|
227
|
+
title: 'Editar',
|
|
228
|
+
Body: <DialogJSONSchemaForm
|
|
229
|
+
jsonSchemaFormRef = {jsonSchemaFormRef}
|
|
230
|
+
schema = {data.serializer.schema}
|
|
231
|
+
uiSchema = {data.serializer.uiSchema}
|
|
232
|
+
formData = {data.formData}
|
|
233
|
+
onSubmit = {onEditModelSave}
|
|
234
|
+
/>,
|
|
235
|
+
Actions: <DialogActions
|
|
236
|
+
setDialog = {setDialog}
|
|
237
|
+
handleSave = {jsonSchemaSubmit}
|
|
238
|
+
/>
|
|
239
|
+
} as DialogType);
|
|
240
|
+
editModel.current = {
|
|
241
|
+
fieldKey,
|
|
242
|
+
index,
|
|
243
|
+
model,
|
|
244
|
+
id,
|
|
245
|
+
labelKey,
|
|
246
|
+
setValue,
|
|
247
|
+
getValues
|
|
248
|
+
};
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
const onEditModelSave = async ({ formData }:{ formData: Item }) => {
|
|
253
|
+
setDialog({ open: false });
|
|
254
|
+
setLoading(true);
|
|
255
|
+
const {
|
|
256
|
+
fieldKey,
|
|
257
|
+
index,
|
|
258
|
+
model,
|
|
259
|
+
id,
|
|
260
|
+
labelKey,
|
|
261
|
+
setValue,
|
|
262
|
+
getValues
|
|
263
|
+
} = editModel.current;
|
|
264
|
+
const newModelId = await createOrUpdateJSONSchema({
|
|
265
|
+
model,
|
|
266
|
+
serverEndPoint,
|
|
267
|
+
id,
|
|
268
|
+
formData
|
|
269
|
+
});
|
|
270
|
+
if (newModelId.errors) {
|
|
271
|
+
console.log(newModelId.errors);
|
|
272
|
+
onTriggerSnackBar({
|
|
273
|
+
msg: 'Houve um problema ao salvar a alteração! Por favor, entre em contato.',
|
|
274
|
+
severity: 'error'
|
|
275
|
+
});
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
onTriggerSnackBar({
|
|
279
|
+
msg: 'Alterações salvas com sucesso!',
|
|
280
|
+
severity: 'info'
|
|
281
|
+
});
|
|
282
|
+
const targetKey = (fieldKey && index >= 0)
|
|
283
|
+
? `${fieldKey}.${index}.${model}`
|
|
284
|
+
: model;
|
|
285
|
+
const newValue = {
|
|
286
|
+
...getValues(targetKey),
|
|
287
|
+
...formData,
|
|
288
|
+
label: formData[labelKey]
|
|
289
|
+
};
|
|
290
|
+
setValue(targetKey, newValue);
|
|
291
|
+
populateOptionsAC([model]);
|
|
292
|
+
setLoading(false);
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const onDeleteModel = (model:string, id:Id, onSuccess:()=>void | null) => {
|
|
296
|
+
setDialog({
|
|
297
|
+
open: true,
|
|
298
|
+
loading: false,
|
|
299
|
+
title: 'Apagar',
|
|
300
|
+
Body: 'Tem certeza de que deseja apagar este item?',
|
|
301
|
+
Actions: <DialogActions
|
|
302
|
+
setDialog = {setDialog}
|
|
303
|
+
handleSave = {(e:React.SyntheticEvent) => {
|
|
304
|
+
return onDeleteModelSave(model, id, onSuccess);
|
|
305
|
+
}}
|
|
306
|
+
btnConfirm = "Sim, apagar"
|
|
307
|
+
/>
|
|
308
|
+
});
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
const onDeleteModelSave = async (model:string, id:Id, onSuccess:()=>void | null) => {
|
|
312
|
+
setDialog({ open: false });
|
|
313
|
+
setLoading(true);
|
|
314
|
+
const ret = await deleteData(model, serverEndPoint, id);
|
|
315
|
+
if (ret !== false) {
|
|
316
|
+
onTriggerSnackBar({
|
|
317
|
+
msg: 'Apagado com com sucesso!',
|
|
318
|
+
severity: 'info'
|
|
319
|
+
});
|
|
320
|
+
if (onSuccess !== null) {
|
|
321
|
+
onSuccess();
|
|
322
|
+
}
|
|
323
|
+
return true;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
setLoading(false);
|
|
327
|
+
onTriggerSnackBar({
|
|
328
|
+
msg: 'Houve um problema ao remover o item! Por favor, entre em contato.',
|
|
329
|
+
severity: 'error'
|
|
330
|
+
});
|
|
331
|
+
return false;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
const onEditRelatedModelSave = async ({
|
|
335
|
+
model,
|
|
336
|
+
id,
|
|
337
|
+
relatedModel,
|
|
338
|
+
relatedModelId,
|
|
339
|
+
newRow,
|
|
340
|
+
schema,
|
|
341
|
+
onlyAddExisting
|
|
342
|
+
}:OnEditRelatedModelType) => {
|
|
343
|
+
const updateUrl = `${model}/${id}/${relatedModel}`;
|
|
344
|
+
if (onlyAddExisting) {
|
|
345
|
+
const response = await addExistingRelatedModel({
|
|
346
|
+
model,
|
|
347
|
+
id,
|
|
348
|
+
serverEndPoint,
|
|
349
|
+
data: {
|
|
350
|
+
onlyAddExisting: {
|
|
351
|
+
key: relatedModel,
|
|
352
|
+
value: newRow.id_to_add
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
if (Object.prototype.hasOwnProperty.call(response, 'errors')) {
|
|
357
|
+
console.log(response);
|
|
358
|
+
onTriggerSnackBar({
|
|
359
|
+
msg: 'Houve um problema ao salvar a alteração! Por favor, entre em contato.',
|
|
360
|
+
severity: 'error'
|
|
361
|
+
});
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
onTriggerSnackBar({
|
|
365
|
+
msg: 'Alterações salvas com sucesso!',
|
|
366
|
+
severity: 'info'
|
|
367
|
+
});
|
|
368
|
+
const object = await getGenericModel({
|
|
369
|
+
model,
|
|
370
|
+
id,
|
|
371
|
+
serverEndPoint,
|
|
372
|
+
relatedModel,
|
|
373
|
+
relatedModelId: newRow.id_to_add
|
|
374
|
+
});
|
|
375
|
+
return object;
|
|
376
|
+
}
|
|
377
|
+
// This is important for related data
|
|
378
|
+
if (schema[model] && !newRow[model]) {
|
|
379
|
+
newRow[model] = id;
|
|
380
|
+
}
|
|
381
|
+
const response = await updateDataBySchema({
|
|
382
|
+
model: relatedModel,
|
|
383
|
+
modelObjectId: newRow.id,
|
|
384
|
+
serverEndPoint,
|
|
385
|
+
data: newRow,
|
|
386
|
+
schema,
|
|
387
|
+
path: updateUrl
|
|
388
|
+
});
|
|
389
|
+
if (response && !Object.prototype.hasOwnProperty.call(response, 'errors')) {
|
|
390
|
+
onTriggerSnackBar({
|
|
391
|
+
msg: 'Alterações salvas com sucesso!',
|
|
392
|
+
severity: 'info'
|
|
393
|
+
});
|
|
394
|
+
return response as Id;
|
|
395
|
+
}
|
|
396
|
+
onTriggerSnackBar({
|
|
397
|
+
msg: 'Não foi possível salvar os dados. Confira os erros.',
|
|
398
|
+
severity: 'error'
|
|
399
|
+
});
|
|
400
|
+
return false;
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
const onDeleteRelatedModel = async ({
|
|
404
|
+
model,
|
|
405
|
+
id,
|
|
406
|
+
relatedModel,
|
|
407
|
+
relatedModelId
|
|
408
|
+
}:OnDeleteRelatedModelType) => {
|
|
409
|
+
const deleteUrl = `${model}/${id}/${relatedModel}`;
|
|
410
|
+
const response = await deleteData(deleteUrl, serverEndPoint, relatedModelId);
|
|
411
|
+
if (response) {
|
|
412
|
+
onTriggerSnackBar({
|
|
413
|
+
msg: 'Alterações salvas com sucesso!',
|
|
414
|
+
severity: 'info'
|
|
415
|
+
});
|
|
416
|
+
return response;
|
|
417
|
+
}
|
|
418
|
+
onTriggerSnackBar({
|
|
419
|
+
msg: 'Houve um problema ao remover o item! Por favor, entre em contato.',
|
|
420
|
+
severity: 'error'
|
|
421
|
+
});
|
|
422
|
+
return false;
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
return (
|
|
426
|
+
<APIWrapperContext.Provider
|
|
427
|
+
value = {{
|
|
428
|
+
usuaria,
|
|
429
|
+
onSubmit,
|
|
430
|
+
loadSinglePageData,
|
|
431
|
+
handleLoading,
|
|
432
|
+
optionsACState: [optionsAC, setOptionsAC],
|
|
433
|
+
pageFormState: [pageForm, setPageForm],
|
|
434
|
+
onEditModel,
|
|
435
|
+
onDeleteModel,
|
|
436
|
+
onEditRelatedModelSave,
|
|
437
|
+
onDeleteRelatedModel,
|
|
438
|
+
onTriggerSnackBar,
|
|
439
|
+
setDialog
|
|
440
|
+
}}
|
|
441
|
+
>
|
|
442
|
+
{children}
|
|
443
|
+
</APIWrapperContext.Provider>
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export default React.memo(APIWrapper);
|