drf-react-by-schema 0.1.0 → 0.2.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.
- package/.eslintrc.js +5 -2
- package/.gitlab-ci.yml +14 -0
- package/README.md +9 -82
- package/dist/index.js +57 -1
- package/package.json +39 -10
- package/src/api.ts +380 -173
- package/src/components/DataGridBySchemaEditable/ConfirmDialog.tsx +41 -0
- package/src/components/DataGridBySchemaEditable/CustomToolbar.tsx +93 -0
- package/src/components/DataGridBySchemaEditable/FooterToolbar.tsx +77 -0
- package/src/components/DataGridBySchemaEditable/GridDecimalInput.tsx +41 -0
- package/src/components/DataGridBySchemaEditable/GridPatternInput.tsx +37 -0
- package/src/components/DataGridBySchemaEditable/InputInterval.tsx +194 -0
- package/src/components/DataGridBySchemaEditable/SelectEditInputCell.tsx +153 -0
- package/src/components/DataGridBySchemaEditable/utils.ts +118 -0
- package/src/components/DataGridBySchemaEditable.md +50 -0
- package/src/components/DataGridBySchemaEditable.tsx +72 -726
- package/src/components/DataTotals.tsx +56 -0
- package/src/components/GenericModelList.tsx +155 -0
- package/src/context/DRFReactBySchemaProvider.md +50 -0
- package/src/context/DRFReactBySchemaProvider.tsx +78 -0
- package/src/index.ts +62 -1
- package/src/utils.ts +5 -5
- package/styleguide.config.js +18 -0
- package/webpack.config.js +24 -0
package/src/api.ts
CHANGED
|
@@ -1,74 +1,83 @@
|
|
|
1
1
|
import axios, { AxiosError, AxiosResponse } from 'axios';
|
|
2
|
+
import { ServerResponse } from 'http';
|
|
3
|
+
import { string } from 'yup';
|
|
4
|
+
import { serverEndPointType } from './context/DRFReactBySchemaProvider';
|
|
2
5
|
import {
|
|
3
6
|
isTmpId,
|
|
4
7
|
emptyByType,
|
|
5
8
|
getChoiceByValue,
|
|
6
9
|
Field,
|
|
7
10
|
Item,
|
|
8
|
-
|
|
11
|
+
SchemaType,
|
|
12
|
+
GridEnrichedBySchemaColDef
|
|
9
13
|
} from './utils';
|
|
10
14
|
|
|
11
15
|
const moment = require('moment');
|
|
12
16
|
|
|
13
17
|
type Id = string | number | null;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Interface for CRUD on API
|
|
21
|
+
*
|
|
22
|
+
* @interface TargetApiParams
|
|
23
|
+
*/
|
|
14
24
|
interface TargetApiParams {
|
|
15
|
-
path:string
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
path:string;
|
|
26
|
+
serverEndPoint:serverEndPointType | null;
|
|
27
|
+
data:Item;
|
|
28
|
+
id:Id;
|
|
18
29
|
};
|
|
19
30
|
interface TargetApiParamsOptionalId {
|
|
20
|
-
path:string
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
interface Constants {
|
|
25
|
-
API: Record<string, string>
|
|
31
|
+
path:string;
|
|
32
|
+
serverEndPoint:serverEndPointType | null;
|
|
33
|
+
data:Item;
|
|
34
|
+
id?:Id;
|
|
26
35
|
};
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
getToken: ''
|
|
36
|
+
const getOptions = async (path:string, serverEndPoint:serverEndPointType | null) => {
|
|
37
|
+
if (!serverEndPoint) {
|
|
38
|
+
console.log('Não há definição de API (serverEndPoint!');
|
|
39
|
+
return false;
|
|
32
40
|
}
|
|
33
|
-
}
|
|
34
|
-
const getOptions = async (path:string) => {
|
|
35
|
-
const url = `${CONSTANTS.API.api}/${path}`;
|
|
41
|
+
const url = `${serverEndPoint.api}/${path}`;
|
|
36
42
|
try {
|
|
37
43
|
const { data } = await axios.options(url);
|
|
38
44
|
return data;
|
|
39
45
|
} catch (e) {
|
|
40
|
-
if (e
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
if ((<any>e).isAxiosError) {
|
|
47
|
+
const err = <AxiosError>e;
|
|
48
|
+
if (err.response?.status === 401) {
|
|
49
|
+
const isRefreshed = await refreshToken(serverEndPoint);
|
|
50
|
+
if (!isRefreshed) {
|
|
51
|
+
console.log('Token expirou! Deve-se fazer login de novo');
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const { data } = await axios.options(url);
|
|
56
|
+
return data;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.log(`Error fetching options from ${url}`, e);
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
52
61
|
}
|
|
62
|
+
console.log(`Error fetching options from ${url}`, e);
|
|
63
|
+
return false;
|
|
53
64
|
}
|
|
54
|
-
console.log(`Error fetching options from ${url}`, e);
|
|
55
|
-
return false;
|
|
56
65
|
}
|
|
57
66
|
};
|
|
58
67
|
|
|
59
|
-
const getSchema = async (path:string) => {
|
|
60
|
-
const options = await getOptions(path);
|
|
68
|
+
const getSchema = async (path:string, serverEndPoint:serverEndPointType | null) => {
|
|
69
|
+
const options = await getOptions(path, serverEndPoint);
|
|
61
70
|
if (!options || !options.actions || !options.actions.POST) {
|
|
62
71
|
return false;
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
// Special default value of "currentUser":
|
|
66
|
-
let usuaria;
|
|
75
|
+
let usuaria:Item | boolean = false;
|
|
67
76
|
const postActions:Record<string, Field> = options.actions.POST;
|
|
68
77
|
for (const [key, field] of Object.entries(postActions)) {
|
|
69
78
|
if (field.model_default === 'currentUser') {
|
|
70
79
|
if (!usuaria) {
|
|
71
|
-
usuaria = await isLoggedIn();
|
|
80
|
+
usuaria = await isLoggedIn(serverEndPoint);
|
|
72
81
|
}
|
|
73
82
|
if (usuaria) {
|
|
74
83
|
options.actions.POST[key].model_default = {
|
|
@@ -79,30 +88,37 @@ const getSchema = async (path:string) => {
|
|
|
79
88
|
}
|
|
80
89
|
}
|
|
81
90
|
|
|
82
|
-
return options.actions.POST;
|
|
91
|
+
return options.actions.POST as SchemaType;
|
|
83
92
|
};
|
|
84
93
|
|
|
85
94
|
const getData = async (
|
|
86
95
|
path:string,
|
|
96
|
+
serverEndPoint:serverEndPointType | null,
|
|
87
97
|
route:string = 'api'
|
|
88
98
|
) => {
|
|
89
|
-
|
|
99
|
+
if (!serverEndPoint) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const url = `${serverEndPoint[route as keyof serverEndPointType]}/${path}`;
|
|
90
103
|
try {
|
|
91
104
|
const { data } = await axios.get(url);
|
|
92
|
-
return data;
|
|
105
|
+
return data as Item[];
|
|
93
106
|
} catch (e) {
|
|
94
|
-
if (e
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
if ((<any>e).isAxiosError) {
|
|
108
|
+
const err = <AxiosError>e;
|
|
109
|
+
if (err.response?.status === 401) {
|
|
110
|
+
const isRefreshed = await refreshToken(serverEndPoint);
|
|
111
|
+
if (!isRefreshed) {
|
|
112
|
+
console.log('Token expirou! Deve-se fazer login de novo');
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const { data } = await axios.get(url);
|
|
117
|
+
return data as Item[];
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.log(`Error fetching data from ${url} after token refresh`, e);
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
106
122
|
}
|
|
107
123
|
}
|
|
108
124
|
console.log(`Error fetching data from ${url}`, e);
|
|
@@ -110,125 +126,152 @@ const getData = async (
|
|
|
110
126
|
}
|
|
111
127
|
};
|
|
112
128
|
|
|
113
|
-
|
|
114
|
-
|
|
129
|
+
/**
|
|
130
|
+
*
|
|
131
|
+
* @param param0
|
|
132
|
+
* @returns Id when succesfully updated, false otherwise
|
|
133
|
+
*/
|
|
134
|
+
export const updateData = async ({ path, serverEndPoint, data, id }: TargetApiParams) => {
|
|
135
|
+
if (!serverEndPoint) {
|
|
136
|
+
return ({ errors: 'Não há definição de API (serverEndPoint!' } as unknown) as AxiosResponse;
|
|
137
|
+
}
|
|
138
|
+
const url = `${serverEndPoint.api}/${path}/${id}/`;
|
|
115
139
|
try {
|
|
116
140
|
await axios.put(url, data);
|
|
117
141
|
return id;
|
|
118
142
|
} catch (e) {
|
|
119
|
-
if (e
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
143
|
+
if ((<any>e).isAxiosError) {
|
|
144
|
+
const err = <AxiosError>e;
|
|
145
|
+
if (err.response?.status === 401) {
|
|
146
|
+
const isRefreshed = await refreshToken(serverEndPoint);
|
|
147
|
+
if (!isRefreshed) {
|
|
148
|
+
console.log('Token expirou! Deve-se fazer login de novo');
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
await axios.put(url, data);
|
|
153
|
+
return true;
|
|
154
|
+
} catch (e) {
|
|
155
|
+
console.log(`Error updating data at ${url}`, data, e);
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
131
158
|
}
|
|
159
|
+
console.log(`Error updating data at ${url}`, data, err.response?.data);
|
|
160
|
+
return ({ errors: err.response?.data } as unknown) as AxiosResponse;
|
|
132
161
|
}
|
|
133
|
-
const err = e as AxiosError;
|
|
134
|
-
console.log(`Error updating data at ${url}`, data, err.response?.data);
|
|
135
|
-
return ({ errors: err.response?.data } as unknown) as AxiosResponse;
|
|
136
162
|
}
|
|
137
163
|
};
|
|
138
164
|
|
|
139
|
-
export const partialUpdateData = async ({ path, data, id }: TargetApiParams) => {
|
|
140
|
-
|
|
165
|
+
export const partialUpdateData = async ({ path, serverEndPoint, data, id }: TargetApiParams) => {
|
|
166
|
+
if (!serverEndPoint) {
|
|
167
|
+
return ({ errors: 'Não há definição de API (serverEndPoint!' } as unknown) as AxiosResponse;
|
|
168
|
+
}
|
|
169
|
+
const url = `${serverEndPoint.api}/${path}/${id}/`;
|
|
141
170
|
try {
|
|
142
171
|
await axios.patch(url, data);
|
|
143
172
|
// DEBUG console.log({ path, data, id });
|
|
144
173
|
return id;
|
|
145
174
|
} catch (e) {
|
|
146
|
-
if (e
|
|
147
|
-
const
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
175
|
+
if ((<any>e).isAxiosError) {
|
|
176
|
+
const err = <AxiosError>e;
|
|
177
|
+
if (err.response?.status === 401) {
|
|
178
|
+
const isRefreshed = await refreshToken(serverEndPoint);
|
|
179
|
+
if (!isRefreshed) {
|
|
180
|
+
console.log('Token expirou! Deve-se fazer login de novo');
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
await axios.patch(url, data);
|
|
185
|
+
return true;
|
|
186
|
+
} catch (e) {
|
|
187
|
+
console.log(`Error partial updating data at ${url}`, data, e);
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
158
190
|
}
|
|
191
|
+
console.log(`Error partial updating data at ${url}`, data, err.response?.data);
|
|
192
|
+
return ({ errors: err.response?.data } as unknown) as AxiosResponse;
|
|
159
193
|
}
|
|
160
|
-
const err = e as AxiosError;
|
|
161
|
-
console.log(`Error partial updating data at ${url}`, data, err.response?.data);
|
|
162
|
-
return ({ errors: err.response?.data } as unknown) as AxiosResponse;
|
|
163
194
|
}
|
|
164
195
|
};
|
|
165
196
|
|
|
166
|
-
export const createData = async ({ path, data }: Omit<TargetApiParams, 'id'>) => {
|
|
167
|
-
|
|
197
|
+
export const createData = async ({ path, serverEndPoint, data }: Omit<TargetApiParams, 'id'>) => {
|
|
198
|
+
if (!serverEndPoint) {
|
|
199
|
+
return ({ errors: 'Não há definição de API (serverEndPoint!' } as unknown) as AxiosResponse;
|
|
200
|
+
}
|
|
201
|
+
const url = `${serverEndPoint.api}/${path}/`;
|
|
168
202
|
try {
|
|
169
203
|
const ret = await axios.post(url, data);
|
|
170
204
|
return ret;
|
|
171
205
|
} catch (e) {
|
|
172
|
-
if (e
|
|
173
|
-
const
|
|
174
|
-
if (
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
206
|
+
if ((<any>e).isAxiosError) {
|
|
207
|
+
const err = <AxiosError>e;
|
|
208
|
+
if (err.response?.status === 401) {
|
|
209
|
+
const isRefreshed = await refreshToken(serverEndPoint);
|
|
210
|
+
if (!isRefreshed) {
|
|
211
|
+
console.log('Token expirou! Deve-se fazer login de novo');
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
const ret = await axios.post(url, data);
|
|
216
|
+
return ret;
|
|
217
|
+
} catch (e) {
|
|
218
|
+
console.log(`Error creating data at ${url}`, data, e);
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
184
221
|
}
|
|
222
|
+
console.log(`Error creating data at ${url}`, data, err.response?.data);
|
|
223
|
+
return ({ errors: err.response?.data } as unknown) as AxiosResponse;
|
|
185
224
|
}
|
|
186
|
-
const err = e as AxiosError;
|
|
187
|
-
console.log(`Error creating data at ${url}`, data, err.response?.data);
|
|
188
|
-
return ({ errors: err.response?.data } as unknown) as AxiosResponse;
|
|
189
225
|
}
|
|
190
226
|
};
|
|
191
227
|
|
|
192
|
-
export const deleteData = async (path:string, id:Id) => {
|
|
193
|
-
|
|
228
|
+
export const deleteData = async (path:string, serverEndPoint:serverEndPointType | null, id:Id) => {
|
|
229
|
+
if (!serverEndPoint) {
|
|
230
|
+
console.log ('Não há definição de API (serverEndPoint!');
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
const url = `${serverEndPoint.api}/${path}/${id}`;
|
|
194
234
|
try {
|
|
195
235
|
await axios.delete(url);
|
|
196
236
|
return true;
|
|
197
237
|
} catch (e) {
|
|
198
|
-
if (e
|
|
199
|
-
const
|
|
200
|
-
if (
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
238
|
+
if ((<any>e).isAxiosError) {
|
|
239
|
+
const err = <AxiosError>e;
|
|
240
|
+
if (err.response?.status === 401) {
|
|
241
|
+
const isRefreshed = await refreshToken(serverEndPoint);
|
|
242
|
+
if (!isRefreshed) {
|
|
243
|
+
console.log('Token expirou! Deve-se fazer login de novo');
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
await axios.delete(url);
|
|
248
|
+
return true;
|
|
249
|
+
} catch (e) {
|
|
250
|
+
console.log(`Error deleting data from ${url}`, e);
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
210
253
|
}
|
|
254
|
+
console.log(`Error deleting data from ${url}`, e);
|
|
255
|
+
return false;
|
|
211
256
|
}
|
|
212
|
-
console.log(`Error deleting data from ${url}`, e);
|
|
213
|
-
return false;
|
|
214
257
|
}
|
|
215
258
|
};
|
|
216
259
|
|
|
217
|
-
export const createOrUpdateData = async ({ path, data, id }: TargetApiParamsOptionalId) => {
|
|
260
|
+
export const createOrUpdateData = async ({ path, serverEndPoint, data, id }: TargetApiParamsOptionalId) => {
|
|
218
261
|
if (isTmpId(id)) {
|
|
219
262
|
id = null;
|
|
220
263
|
}
|
|
221
264
|
if (id) {
|
|
222
|
-
const responseUpdate = await updateData({ path, data, id });
|
|
265
|
+
const responseUpdate = await updateData({ path, serverEndPoint, data, id });
|
|
223
266
|
return responseUpdate;
|
|
224
267
|
}
|
|
225
268
|
|
|
226
|
-
const responseCreate = await createData({ path, data });
|
|
269
|
+
const responseCreate = await createData({ path, serverEndPoint, data });
|
|
227
270
|
if (!responseCreate || Object.prototype.hasOwnProperty.call(responseCreate, 'errors')) {
|
|
228
271
|
return responseCreate;
|
|
229
272
|
}
|
|
230
273
|
|
|
231
|
-
const responseUpdate = await updateData({ path, data, id: responseCreate.data.id });
|
|
274
|
+
const responseUpdate = await updateData({ path, serverEndPoint, data, id: responseCreate.data.id });
|
|
232
275
|
return responseUpdate;
|
|
233
276
|
};
|
|
234
277
|
|
|
@@ -238,7 +281,7 @@ const prepareDataBySchema = ({
|
|
|
238
281
|
parentIsField = false
|
|
239
282
|
}: {
|
|
240
283
|
data:Item,
|
|
241
|
-
schema:
|
|
284
|
+
schema:SchemaType,
|
|
242
285
|
parentIsField?:boolean
|
|
243
286
|
}) => {
|
|
244
287
|
// console.log('Entered prepareDataBySchema', schema);
|
|
@@ -288,14 +331,14 @@ const prepareDataBySchema = ({
|
|
|
288
331
|
|
|
289
332
|
// Date:
|
|
290
333
|
if (field.type === 'date') {
|
|
291
|
-
const date = moment
|
|
334
|
+
const date = moment(data[key]);
|
|
292
335
|
dbData[key] = date.format('YYYY-MM-DD');
|
|
293
336
|
continue;
|
|
294
337
|
}
|
|
295
338
|
|
|
296
339
|
// DateTime:
|
|
297
340
|
if (field.type === 'datetime') {
|
|
298
|
-
const date = moment
|
|
341
|
+
const date = moment(data[key]);
|
|
299
342
|
dbData[key] = date.format('YYYY-MM-DDTHH:mm');
|
|
300
343
|
continue;
|
|
301
344
|
}
|
|
@@ -309,14 +352,16 @@ const prepareDataBySchema = ({
|
|
|
309
352
|
export const updateDataBySchema = async ({
|
|
310
353
|
model,
|
|
311
354
|
modelObjectId,
|
|
355
|
+
serverEndPoint,
|
|
312
356
|
data,
|
|
313
357
|
schema,
|
|
314
358
|
path = null
|
|
315
359
|
}: {
|
|
316
360
|
model:string,
|
|
317
361
|
modelObjectId:Id,
|
|
362
|
+
serverEndPoint:serverEndPointType | null,
|
|
318
363
|
data:Item,
|
|
319
|
-
schema:
|
|
364
|
+
schema:SchemaType,
|
|
320
365
|
path:string | null
|
|
321
366
|
}) => {
|
|
322
367
|
// console.log({
|
|
@@ -333,6 +378,7 @@ export const updateDataBySchema = async ({
|
|
|
333
378
|
// DEBUG console.log({ model, modelObjectId, path, data, dbData });
|
|
334
379
|
const response = await createOrUpdateData({
|
|
335
380
|
path,
|
|
381
|
+
serverEndPoint,
|
|
336
382
|
data: dbData,
|
|
337
383
|
id: modelObjectId
|
|
338
384
|
});
|
|
@@ -347,20 +393,22 @@ export const updateDataBySchema = async ({
|
|
|
347
393
|
|
|
348
394
|
export const addExistingRelatedModel = async ({
|
|
349
395
|
model,
|
|
396
|
+
serverEndPoint,
|
|
350
397
|
id,
|
|
351
398
|
data
|
|
352
399
|
}: {
|
|
353
400
|
model:string,
|
|
401
|
+
serverEndPoint:serverEndPointType | null,
|
|
354
402
|
id:Id,
|
|
355
403
|
data:Item
|
|
356
404
|
}) => {
|
|
357
|
-
const response = await partialUpdateData({ path: model, data, id });
|
|
405
|
+
const response = await partialUpdateData({ path: model, serverEndPoint, data, id });
|
|
358
406
|
// DEBUG console.log({ model, id, data, response });
|
|
359
407
|
return response;
|
|
360
408
|
};
|
|
361
409
|
|
|
362
410
|
const getDataGridColumns = (
|
|
363
|
-
schema:
|
|
411
|
+
schema:SchemaType,
|
|
364
412
|
columnFields:string[] = [],
|
|
365
413
|
hiddenFields:string[] = [],
|
|
366
414
|
creatableFields:string[] = []
|
|
@@ -386,57 +434,72 @@ const getDataGridColumns = (
|
|
|
386
434
|
});
|
|
387
435
|
};
|
|
388
436
|
|
|
389
|
-
export const getAutoComplete = async (
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
437
|
+
export const getAutoComplete = async ({
|
|
438
|
+
model,
|
|
439
|
+
serverEndPoint
|
|
440
|
+
}: {
|
|
441
|
+
model: string,
|
|
442
|
+
serverEndPoint:serverEndPointType | null
|
|
443
|
+
}) => {
|
|
444
|
+
const data = await getData(model, serverEndPoint, 'autocomplete');
|
|
396
445
|
return data;
|
|
397
446
|
};
|
|
398
447
|
|
|
399
448
|
export const getJSONSchema = async ({
|
|
400
449
|
model,
|
|
450
|
+
serverEndPoint,
|
|
401
451
|
id = 'create'
|
|
402
452
|
}: {
|
|
403
453
|
model:string,
|
|
454
|
+
serverEndPoint:serverEndPointType | null,
|
|
404
455
|
id?:Id
|
|
405
456
|
}) => {
|
|
406
|
-
|
|
457
|
+
if (!serverEndPoint) {
|
|
458
|
+
console.log('Não há definição de API (serverEndPoint!');
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
const url = `${serverEndPoint.JSONSchema}/${model}/${id}/`;
|
|
407
462
|
try {
|
|
408
463
|
const { data } = await axios.get(url);
|
|
409
464
|
return data;
|
|
410
465
|
} catch (e) {
|
|
411
|
-
if (e
|
|
412
|
-
const
|
|
413
|
-
if (
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
466
|
+
if ((<any>e).isAxiosError) {
|
|
467
|
+
const err = <AxiosError>e;
|
|
468
|
+
if (err.response?.status === 401) {
|
|
469
|
+
const isRefreshed = await refreshToken(serverEndPoint);
|
|
470
|
+
if (!isRefreshed) {
|
|
471
|
+
console.log('Token expirou! Deve-se fazer login de novo');
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
try {
|
|
475
|
+
const { data } = await axios.get(url);
|
|
476
|
+
return data;
|
|
477
|
+
} catch (e) {
|
|
478
|
+
console.log(`Error fetching JSONSchema data from ${url}`, e);
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
423
481
|
}
|
|
482
|
+
console.log(`Error fetching JSONSchema data from ${url}`, e);
|
|
483
|
+
return false;
|
|
424
484
|
}
|
|
425
|
-
console.log(`Error fetching JSONSchema data from ${url}`, e);
|
|
426
|
-
return false;
|
|
427
485
|
}
|
|
428
486
|
};
|
|
429
487
|
|
|
430
488
|
export const createOrUpdateJSONSchema = async ({
|
|
431
489
|
model,
|
|
490
|
+
serverEndPoint,
|
|
432
491
|
id = 'create',
|
|
433
492
|
formData
|
|
434
493
|
}: {
|
|
435
494
|
model:string,
|
|
495
|
+
serverEndPoint:serverEndPointType | null,
|
|
436
496
|
id?:Id,
|
|
437
497
|
formData:Item
|
|
438
498
|
}) => {
|
|
439
|
-
|
|
499
|
+
if (!serverEndPoint) {
|
|
500
|
+
return { errors: 'Não há definição de API (serverEndPoint!' };
|
|
501
|
+
}
|
|
502
|
+
let url = `${serverEndPoint.JSONSchema}/${model}/`;
|
|
440
503
|
if (id !== 'create') {
|
|
441
504
|
url += `${id}/`;
|
|
442
505
|
}
|
|
@@ -446,29 +509,40 @@ export const createOrUpdateJSONSchema = async ({
|
|
|
446
509
|
: await axios.patch(url, formData);
|
|
447
510
|
return data;
|
|
448
511
|
} catch (e) {
|
|
449
|
-
if (e
|
|
450
|
-
const
|
|
451
|
-
if (
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
512
|
+
if ((<any>e).isAxiosError) {
|
|
513
|
+
const err = <AxiosError>e;
|
|
514
|
+
if (err.response?.status === 401) {
|
|
515
|
+
const isRefreshed = await refreshToken(serverEndPoint);
|
|
516
|
+
if (!isRefreshed) {
|
|
517
|
+
console.log('Token expirou! Deve-se fazer login de novo');
|
|
518
|
+
return { errors: 'Token expirou! Deve-se fazer login de novo!' };
|
|
519
|
+
}
|
|
520
|
+
try {
|
|
521
|
+
const { data } = (id === 'create')
|
|
522
|
+
? await axios.post(url, formData)
|
|
523
|
+
: await axios.patch(url, formData);
|
|
524
|
+
return data;
|
|
525
|
+
} catch (e) {
|
|
526
|
+
console.log(`Error partially updating or creating JSONSchema data from ${url}`, e);
|
|
527
|
+
return { errors: 'Erro ao salvar alterações em item!' };
|
|
528
|
+
}
|
|
463
529
|
}
|
|
530
|
+
console.log(`Error partially updating or creating JSONSchema data from ${url}`, e);
|
|
531
|
+
return { errors: 'Erro ao salvar alterações em item!' };
|
|
464
532
|
}
|
|
465
|
-
console.log(`Error partially updating or creating JSONSchema data from ${url}`, e);
|
|
466
|
-
return { errors: 'Erro ao salvar alterações em item!' };
|
|
467
533
|
}
|
|
468
534
|
};
|
|
469
535
|
|
|
470
|
-
export const loginByPayload = async (payload:Item) => {
|
|
471
|
-
|
|
536
|
+
export const loginByPayload = async (payload:Item, serverEndPoint:serverEndPointType | null) => {
|
|
537
|
+
if (!serverEndPoint) {
|
|
538
|
+
console.log('Não há definição de API (serverEndPoint!');
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
const url = serverEndPoint.getToken;
|
|
542
|
+
if (!url) {
|
|
543
|
+
console.log('Erro no loginByPayload: faltou a configuração de url getToken!');
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
472
546
|
try {
|
|
473
547
|
const { data } = await axios.post(url, payload);
|
|
474
548
|
localStorage.setItem('refreshToken', data.refresh);
|
|
@@ -492,7 +566,11 @@ export const setAuthToken = (token:string | null) => {
|
|
|
492
566
|
delete axios.defaults.headers.common.Authorization;
|
|
493
567
|
};
|
|
494
568
|
|
|
495
|
-
const refreshToken = async () => {
|
|
569
|
+
const refreshToken = async (serverEndPoint:serverEndPointType | null) => {
|
|
570
|
+
if (!serverEndPoint) {
|
|
571
|
+
console.log('Não há definição de API (serverEndPoint!');
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
496
574
|
const refreshToken = localStorage.getItem('refreshToken');
|
|
497
575
|
// console.log('entrou refreshToken', refreshToken);
|
|
498
576
|
setAuthToken(null);
|
|
@@ -500,7 +578,7 @@ const refreshToken = async () => {
|
|
|
500
578
|
return false;
|
|
501
579
|
}
|
|
502
580
|
try {
|
|
503
|
-
const { data } = await axios.post(`${
|
|
581
|
+
const { data } = await axios.post(`${serverEndPoint.refreshToken}`, {
|
|
504
582
|
refresh: refreshToken
|
|
505
583
|
});
|
|
506
584
|
setAuthToken(data.access);
|
|
@@ -511,16 +589,145 @@ const refreshToken = async () => {
|
|
|
511
589
|
}
|
|
512
590
|
};
|
|
513
591
|
|
|
514
|
-
export const isLoggedIn = async () => {
|
|
592
|
+
export const isLoggedIn = async (serverEndPoint:serverEndPointType | null) => {
|
|
515
593
|
const token = localStorage.getItem('token');
|
|
516
594
|
setAuthToken(token);
|
|
517
595
|
if (!token) {
|
|
518
596
|
return false;
|
|
519
597
|
}
|
|
520
|
-
const usuaria = await getData('minhaconta');
|
|
598
|
+
const usuaria = await getData('minhaconta', serverEndPoint);
|
|
521
599
|
if (!usuaria) {
|
|
522
600
|
console.log('Erro ao recuperar dados de usuária!');
|
|
523
601
|
return false;
|
|
524
602
|
}
|
|
525
603
|
return usuaria;
|
|
526
604
|
};
|
|
605
|
+
|
|
606
|
+
export interface getGenericModelListProps {
|
|
607
|
+
model:string;
|
|
608
|
+
serverEndPoint:serverEndPointType | null;
|
|
609
|
+
id?:Id;
|
|
610
|
+
relatedModel?:string;
|
|
611
|
+
relatedModelId?:Id;
|
|
612
|
+
columnFields:string[];
|
|
613
|
+
hiddenFields?:string[];
|
|
614
|
+
creatableFields?:string[];
|
|
615
|
+
isInBatches?:boolean;
|
|
616
|
+
loadedSchema?:SchemaType | boolean;
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
export interface DataSchemaColumnsType {
|
|
620
|
+
data: Item[];
|
|
621
|
+
schema?: SchemaType;
|
|
622
|
+
columns?: GridEnrichedBySchemaColDef[];
|
|
623
|
+
}
|
|
624
|
+
export const getGenericModelList = async ({
|
|
625
|
+
model,
|
|
626
|
+
serverEndPoint,
|
|
627
|
+
id = '',
|
|
628
|
+
relatedModel = '',
|
|
629
|
+
relatedModelId = '',
|
|
630
|
+
columnFields,
|
|
631
|
+
hiddenFields = ['id'],
|
|
632
|
+
creatableFields = [],
|
|
633
|
+
isInBatches = false,
|
|
634
|
+
loadedSchema
|
|
635
|
+
}: getGenericModelListProps) => {
|
|
636
|
+
let path = `${model}/${id}`;
|
|
637
|
+
let schemaPath = model;
|
|
638
|
+
let schema = loadedSchema;
|
|
639
|
+
let columns;
|
|
640
|
+
if (!isTmpId(id) && relatedModel) {
|
|
641
|
+
path += `/${relatedModel}/${relatedModelId}`;
|
|
642
|
+
schemaPath += `/${id}/${relatedModel}`;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// Only get schema and columns if not in batches or in first batch:
|
|
646
|
+
if (!schema) {
|
|
647
|
+
schema = await getSchema(schemaPath, serverEndPoint);
|
|
648
|
+
if (!schema) {
|
|
649
|
+
return false;
|
|
650
|
+
}
|
|
651
|
+
columns = getDataGridColumns(
|
|
652
|
+
schema,
|
|
653
|
+
columnFields,
|
|
654
|
+
hiddenFields,
|
|
655
|
+
creatableFields
|
|
656
|
+
);
|
|
657
|
+
if (!columns) {
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
let data:Item[] = [];
|
|
663
|
+
|
|
664
|
+
if (!id || (id && !relatedModelId)) {
|
|
665
|
+
if (isInBatches) {
|
|
666
|
+
path += (loadedSchema)
|
|
667
|
+
? '?is_last_batch=1'
|
|
668
|
+
: '?is_first_batch=1';
|
|
669
|
+
}
|
|
670
|
+
const ret = await getData(path, serverEndPoint);
|
|
671
|
+
if (ret === false) {
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
data = ret.map(row => {
|
|
676
|
+
const newRow:Item = {};
|
|
677
|
+
for (const [key, field] of Object.entries(schema as SchemaType)) {
|
|
678
|
+
if (!(key in row)) {
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
if (field.type === 'choice') {
|
|
682
|
+
newRow[key] = row[key]
|
|
683
|
+
? {
|
|
684
|
+
value: row[key],
|
|
685
|
+
display_name: getChoiceByValue(row[key], field.choices)
|
|
686
|
+
}
|
|
687
|
+
: emptyByType(field);
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
newRow[key] = (row[key])
|
|
691
|
+
? row[key]
|
|
692
|
+
: emptyByType(field);
|
|
693
|
+
}
|
|
694
|
+
return newRow;
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
if (loadedSchema) {
|
|
698
|
+
// DEBUG console.log({ path, data });
|
|
699
|
+
return { data } as DataSchemaColumnsType;
|
|
700
|
+
}
|
|
701
|
+
// DEBUG console.log({ path, data, columns, schema });
|
|
702
|
+
return { data, columns, schema } as DataSchemaColumnsType;
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
export const getGenericModel = async ({
|
|
706
|
+
model,
|
|
707
|
+
serverEndPoint,
|
|
708
|
+
id = '',
|
|
709
|
+
relatedModel = '',
|
|
710
|
+
relatedModelId = ''
|
|
711
|
+
}: {
|
|
712
|
+
model:string,
|
|
713
|
+
serverEndPoint:serverEndPointType | null,
|
|
714
|
+
id?:Id,
|
|
715
|
+
relatedModel?:string,
|
|
716
|
+
relatedModelId?:string
|
|
717
|
+
}) => {
|
|
718
|
+
let path = `${model}/${id}`;
|
|
719
|
+
let schemaPath = model;
|
|
720
|
+
if (id && relatedModel) {
|
|
721
|
+
path += `/${relatedModel}/${relatedModelId}`;
|
|
722
|
+
schemaPath += `/${id}/${relatedModel}`;
|
|
723
|
+
}
|
|
724
|
+
const schema = await getSchema(schemaPath, serverEndPoint);
|
|
725
|
+
if (!schema) {
|
|
726
|
+
return false;
|
|
727
|
+
}
|
|
728
|
+
const data = (!id || (id && relatedModel && !relatedModelId))
|
|
729
|
+
? {}
|
|
730
|
+
: await getData(path, serverEndPoint);
|
|
731
|
+
// console.log({ schema, data }); // DEBUG
|
|
732
|
+
return { schema, data };
|
|
733
|
+
};
|