trithuc-mvc-react 3.4.6 → 3.4.8
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/api/index.js +150 -261
- package/components/DataManagement/DataTable.jsx +69 -49
- package/components/DataManagement/DataTableSM.jsx +81 -51
- package/components/DataManagement/EditorForm.jsx +13 -8
- package/components/DataManagement/TableRowRenderSM.jsx +179 -78
- package/components/DataManagement/index.jsx +30 -39
- package/package.json +2 -2
package/api/index.js
CHANGED
|
@@ -87,49 +87,28 @@ export default api;
|
|
|
87
87
|
export const getDatasFromTable = async ({ tableName, page, pageSize, data }) => {
|
|
88
88
|
try {
|
|
89
89
|
let res;
|
|
90
|
-
|
|
90
|
+
// Trường hợp dùng tableName với MVC4
|
|
91
91
|
if (!apiUrl) {
|
|
92
|
-
// MVC4
|
|
93
92
|
res = await api.get(`${getBaseUrl()}/Admin/${tableName}/LoadData`, {
|
|
94
93
|
params: {
|
|
95
|
-
json: JSON.stringify(data
|
|
94
|
+
json: JSON.stringify(data),
|
|
96
95
|
page,
|
|
97
96
|
pageSize
|
|
98
97
|
}
|
|
99
98
|
});
|
|
100
99
|
} else {
|
|
101
|
-
// .NET Core
|
|
100
|
+
// Trường hợp dùng api .NET Core
|
|
102
101
|
res = await api.get(`${getBaseUrl()}/${apiUrl}/${tableName}`, {
|
|
103
102
|
params: {
|
|
104
103
|
PageNumber: page,
|
|
105
104
|
PageSize: pageSize,
|
|
106
|
-
...
|
|
105
|
+
...data
|
|
107
106
|
}
|
|
108
107
|
});
|
|
109
108
|
}
|
|
110
|
-
|
|
111
|
-
// 🔴 ĐIỂM FIX QUAN TRỌNG NHẤT
|
|
112
|
-
if (!res || res.data == null) {
|
|
113
|
-
// console.warn("API returned empty response:", {
|
|
114
|
-
// tableName,
|
|
115
|
-
// page,
|
|
116
|
-
// pageSize
|
|
117
|
-
// });
|
|
118
|
-
|
|
119
|
-
// ✅ RETURN OBJECT MẶC ĐỊNH – KHÔNG ĐƯỢC undefined
|
|
120
|
-
return {
|
|
121
|
-
data: [],
|
|
122
|
-
PermissionModel: {},
|
|
123
|
-
CountTrangThai: null,
|
|
124
|
-
status: false
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
109
|
return res.data;
|
|
129
110
|
} catch (error) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
// ✅ THROW → React Query onError xử lý
|
|
111
|
+
console.error("Error fetching data:", error);
|
|
133
112
|
throw error;
|
|
134
113
|
}
|
|
135
114
|
};
|
|
@@ -165,278 +144,188 @@ export const getDatasFromTableDropdownlist = async ({ tableName, page, pageSize,
|
|
|
165
144
|
|
|
166
145
|
export const getDataFromTable = async ({ tableName, id }) => {
|
|
167
146
|
try {
|
|
168
|
-
let res;
|
|
169
|
-
|
|
170
147
|
if (!apiUrl) {
|
|
171
|
-
|
|
172
|
-
res = await api.get(
|
|
173
|
-
params: {
|
|
148
|
+
const url = `${getBaseUrl()}/Admin/${tableName}/GetDetail`;
|
|
149
|
+
const res = await api.get(url, {
|
|
150
|
+
params: {
|
|
151
|
+
id
|
|
152
|
+
}
|
|
174
153
|
});
|
|
154
|
+
return res.data;
|
|
175
155
|
} else {
|
|
176
|
-
|
|
177
|
-
res = await api.get(
|
|
156
|
+
const url = `${getBaseUrl()}/${apiUrl}/${tableName}/${id}`;
|
|
157
|
+
const res = await api.get(url);
|
|
158
|
+
return res.data;
|
|
178
159
|
}
|
|
179
|
-
|
|
180
|
-
// 🔴 FIX CỐT LÕI: KHÔNG BAO GIỜ return undefined
|
|
181
|
-
if (!res || res.data == null) {
|
|
182
|
-
// console.warn("API returned empty detail:", { tableName, id });
|
|
183
|
-
|
|
184
|
-
return {
|
|
185
|
-
data: null,
|
|
186
|
-
status: false,
|
|
187
|
-
message: "Không tìm thấy dữ liệu"
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return res.data;
|
|
192
160
|
} catch (error) {
|
|
193
|
-
|
|
194
|
-
throw error;
|
|
161
|
+
console.error("Error fetching data:", error);
|
|
162
|
+
throw error;
|
|
195
163
|
}
|
|
196
164
|
};
|
|
197
165
|
|
|
198
166
|
export const deleteDataFromTable = async ({ tableName, id }) => {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// 🔴 FIX QUAN TRỌNG NHẤT
|
|
218
|
-
if (!res || res.data == null) {
|
|
219
|
-
// console.warn("Delete API returned empty response:", { tableName, id });
|
|
220
|
-
|
|
221
|
-
return {
|
|
222
|
-
status: true,
|
|
223
|
-
message: "Xóa thành công"
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
167
|
+
if (!apiUrl) {
|
|
168
|
+
// Khi không có apiUrl, thực hiện DELETE đến URL cụ thể với tableName
|
|
169
|
+
const res = await api.post(`${getBaseUrl()}/Admin/${tableName}/Delete`, {
|
|
170
|
+
id
|
|
171
|
+
});
|
|
172
|
+
return res.data;
|
|
173
|
+
} else {
|
|
174
|
+
// Khi có apiUrl, chuyển id thành mảng string và thực hiện DELETE
|
|
175
|
+
const ids = Array.isArray(id) ? id : [id]; // Chuyển id thành mảng nếu chưa phải là mảng
|
|
176
|
+
const res = await api.delete(`${getBaseUrl()}/${apiUrl}/${tableName}`, {
|
|
177
|
+
data: ids, // Truyền ids như là dữ liệu của body
|
|
178
|
+
headers: {
|
|
179
|
+
"Content-Type": "application/json-patch+json" // Đảm bảo Content-Type là đúng
|
|
180
|
+
}
|
|
181
|
+
});
|
|
227
182
|
return res.data;
|
|
228
|
-
} catch (error) {
|
|
229
|
-
// console.error("Error deleting data:", error);
|
|
230
|
-
throw error; // React Query mutation onError xử lý
|
|
231
183
|
}
|
|
232
184
|
};
|
|
233
|
-
|
|
234
185
|
export const deleteMultipleDataFromTable = async ({ tableName, ids }) => {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
headers: {
|
|
248
|
-
"Content-Type": "application/json-patch+json"
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// 🔴 FIX QUAN TRỌNG NHẤT CHO REACT QUERY v5
|
|
254
|
-
if (!res || res.data == null) {
|
|
255
|
-
// console.warn("DeleteMultiple API returned empty response:", {
|
|
256
|
-
// tableName,
|
|
257
|
-
// ids
|
|
258
|
-
// });
|
|
259
|
-
|
|
260
|
-
return {
|
|
261
|
-
status: true,
|
|
262
|
-
message: "Xóa nhiều bản ghi thành công"
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
|
|
186
|
+
if (!apiUrl) {
|
|
187
|
+
const res = await api.post(`${getBaseUrl()}/Admin/${tableName}/DeleteMulti`, {
|
|
188
|
+
ids
|
|
189
|
+
});
|
|
190
|
+
return res.data;
|
|
191
|
+
} else {
|
|
192
|
+
const res = await api.delete(`${getBaseUrl()}/${apiUrl}/${tableName}`, {
|
|
193
|
+
data: ids, // Truyền ids như là dữ liệu của body
|
|
194
|
+
headers: {
|
|
195
|
+
"Content-Type": "application/json-patch+json" // Đảm bảo Content-Type là đúng
|
|
196
|
+
}
|
|
197
|
+
});
|
|
266
198
|
return res.data;
|
|
267
|
-
} catch (error) {
|
|
268
|
-
// console.error("Error deleting multiple data:", error);
|
|
269
|
-
throw error; // để useMutation onError xử lý
|
|
270
199
|
}
|
|
271
200
|
};
|
|
272
|
-
|
|
273
201
|
export const saveDataToTable = async ({ tableName, data }) => {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
202
|
+
if (!apiUrl) {
|
|
203
|
+
const res = await api.post(`${getBaseUrl()}/Admin/${tableName}/SaveData`, {
|
|
204
|
+
json: JSON.stringify({ ...data })
|
|
205
|
+
});
|
|
206
|
+
return res.data;
|
|
207
|
+
} else {
|
|
208
|
+
if (!data.Id || data.Id === "0") {
|
|
209
|
+
// Khi không có ID, thực hiện POST đến apiUrl
|
|
210
|
+
const res = await api.post(`${getBaseUrl()}/${apiUrl}/${tableName}`, data);
|
|
211
|
+
return res.data;
|
|
282
212
|
} else {
|
|
283
|
-
//
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
res = await api.post(`${getBaseUrl()}/${apiUrl}/${tableName}`, data);
|
|
287
|
-
} else {
|
|
288
|
-
// UPDATE
|
|
289
|
-
res = await api.put(`${getBaseUrl()}/${apiUrl}/${tableName}/${data.Id}`, data);
|
|
290
|
-
}
|
|
213
|
+
// Khi có ID, thực hiện PUT đến apiUrl với ID trong URL
|
|
214
|
+
const res = await api.put(`${getBaseUrl()}/${apiUrl}/${tableName}/${data.Id}`, data);
|
|
215
|
+
return res.data;
|
|
291
216
|
}
|
|
292
|
-
|
|
293
|
-
// 🔴 FIX BẮT BUỘC CHO REACT QUERY v5
|
|
294
|
-
if (!res || res.data == null) {
|
|
295
|
-
// console.warn("SaveData API returned empty response:", {
|
|
296
|
-
// tableName,
|
|
297
|
-
// data
|
|
298
|
-
// });
|
|
299
|
-
|
|
300
|
-
return {
|
|
301
|
-
status: true,
|
|
302
|
-
message: "Lưu dữ liệu thành công"
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
return res.data;
|
|
307
|
-
} catch (error) {
|
|
308
|
-
// console.error("Error saving data:", error);
|
|
309
|
-
throw error; // để useMutation onError xử lý
|
|
310
217
|
}
|
|
311
218
|
};
|
|
312
|
-
|
|
313
219
|
export const changeStatusDataToTable = async ({ tableName, id, fieldName }) => {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
// MVC4
|
|
319
|
-
res = await api.post(`${getBaseUrl()}/Admin/${tableName}/ChangeStatus`, { id });
|
|
320
|
-
} else {
|
|
321
|
-
// .NET Core
|
|
322
|
-
res = await api.post(
|
|
323
|
-
`${getBaseUrl()}/${apiUrl}/${tableName}/ChangeStatus`,
|
|
324
|
-
fieldName ? { id, fieldName } : { id }
|
|
325
|
-
);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
// 🔴 FIX BẮT BUỘC CHO REACT QUERY v5
|
|
329
|
-
if (!res || res.data == null) {
|
|
330
|
-
// console.warn("ChangeStatus API returned empty response", {
|
|
331
|
-
// tableName,
|
|
332
|
-
// id,
|
|
333
|
-
// fieldName
|
|
334
|
-
// });
|
|
335
|
-
|
|
336
|
-
return {
|
|
337
|
-
status: true,
|
|
338
|
-
message: "Thay đổi trạng thái thành công"
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
|
|
220
|
+
if (!apiUrl) {
|
|
221
|
+
const res = await api.post(`${getBaseUrl()}/Admin/${tableName}/ChangeStatus`, {
|
|
222
|
+
id
|
|
223
|
+
});
|
|
342
224
|
return res.data;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
|
|
225
|
+
} else {
|
|
226
|
+
try {
|
|
227
|
+
if (fieldName) {
|
|
228
|
+
const res = await api.post(
|
|
229
|
+
`${getBaseUrl()}/${apiUrl ? `${apiUrl}/` : "Admin/"}${tableName}/ChangeStatus`,
|
|
230
|
+
{
|
|
231
|
+
id,
|
|
232
|
+
fieldName
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
headers: {
|
|
236
|
+
"Content-Type": "application/json-patch+json" // Đảm bảo Content-Type là đúng
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
);
|
|
240
|
+
return res.data;
|
|
241
|
+
} else {
|
|
242
|
+
const res = await api.post(`${getBaseUrl()}/${apiUrl ? `${apiUrl}/` : "Admin/"}${tableName}/ChangeStatus`, id, {
|
|
243
|
+
headers: {
|
|
244
|
+
"Content-Type": "application/json-patch+json" // Đảm bảo Content-Type là đúng
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
return res.data;
|
|
248
|
+
}
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.error("Error changing status:", error);
|
|
251
|
+
// Xử lý lỗi tùy thuộc vào nhu cầu của bạn, có thể ném ra hoặc trả về giá trị mặc định
|
|
252
|
+
throw error; // Hoặc return { success: false, message: error.message };
|
|
253
|
+
}
|
|
346
254
|
}
|
|
347
255
|
};
|
|
348
256
|
|
|
349
257
|
export const exportExcel = async ({ tableName, data }) => {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
258
|
+
if (!apiUrl) {
|
|
259
|
+
const res = await api.get(`${getBaseUrl()}/Admin/${tableName}/ExportData`, {
|
|
260
|
+
params: {
|
|
261
|
+
json: JSON.stringify(data)
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
return res.data;
|
|
265
|
+
} else {
|
|
266
|
+
const res = await api.get(
|
|
267
|
+
`${getBaseUrl()}/${apiUrl}/${tableName}/ExportData`,
|
|
268
|
+
{
|
|
356
269
|
params: {
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// 🔴 BẮT BUỘC: luôn return value
|
|
370
|
-
if (!res || !res.data) {
|
|
371
|
-
throw new Error("Export Excel failed: empty response");
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
return res.data; // Blob
|
|
375
|
-
} catch (error) {
|
|
376
|
-
// console.error("Error exporting excel:", error);
|
|
377
|
-
throw error;
|
|
270
|
+
...data
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
headers: {
|
|
275
|
+
"Content-Type": "application/json-patch+json" // Đảm bảo Content-Type là đúng
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
return res.data;
|
|
378
280
|
}
|
|
379
281
|
};
|
|
380
282
|
|
|
381
283
|
export const uploadFile = async (formData) => {
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
284
|
+
// 1. Lấy URL hiện tại
|
|
285
|
+
const currentUrl = window.location.href;
|
|
286
|
+
|
|
287
|
+
// 2. Append vào formData
|
|
288
|
+
formData.append("currentUrl", currentUrl);
|
|
289
|
+
|
|
290
|
+
// 3. Log tất cả key-value trong FormData để kiểm tra
|
|
291
|
+
// console.log("===== FormData Contents =====");
|
|
292
|
+
// formData.forEach((value, key) => {
|
|
293
|
+
// console.log(key, value);
|
|
294
|
+
// });
|
|
295
|
+
if (!apiUrl) {
|
|
296
|
+
const res = await api.post(`${getBaseUrl()}/Handler/fileUploader.ashx`, formData, {
|
|
297
|
+
headers: {
|
|
298
|
+
"Content-Type": "multipart/form-data"
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
return res.data;
|
|
302
|
+
} else {
|
|
303
|
+
const res = await api.post(`${getBaseUrl()}/${apiUrl}/FileUploader`, formData, {
|
|
304
|
+
headers: {
|
|
305
|
+
"Content-Type": "multipart/form-data"
|
|
306
|
+
}
|
|
387
307
|
});
|
|
388
|
-
|
|
389
|
-
// Append currentUrl 1 lần
|
|
390
|
-
fd.append("currentUrl", window.location.href);
|
|
391
|
-
|
|
392
|
-
let res;
|
|
393
|
-
|
|
394
|
-
if (!apiUrl) {
|
|
395
|
-
// MVC / ashx
|
|
396
|
-
res = await api.post(`${getBaseUrl()}/Handler/fileUploader.ashx`, fd);
|
|
397
|
-
} else {
|
|
398
|
-
// .NET Core
|
|
399
|
-
res = await api.post(`${getBaseUrl()}/${apiUrl}/FileUploader`, fd);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// 🔴 FIX BẮT BUỘC REACT QUERY v5
|
|
403
|
-
if (!res || res.data == null) {
|
|
404
|
-
// console.warn("Upload API returned empty response");
|
|
405
|
-
|
|
406
|
-
return {
|
|
407
|
-
status: true,
|
|
408
|
-
message: "Upload thành công"
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
|
|
412
308
|
return res.data;
|
|
413
|
-
} catch (error) {
|
|
414
|
-
// console.error("Error uploading file:", error);
|
|
415
|
-
throw error;
|
|
416
309
|
}
|
|
417
310
|
};
|
|
418
311
|
|
|
419
|
-
export const huongDan = async ({ data }
|
|
420
|
-
|
|
421
|
-
// Không có apiUrl → luôn return array
|
|
422
|
-
if (!apiUrl) {
|
|
423
|
-
return [];
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
const res = await api.get(`${getBaseUrl()}/${apiUrl}/HuongDanSuDung/Dropdownlist`, {
|
|
427
|
-
params: { ...data }
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
// 🔴 BẮT BUỘC: không để undefined
|
|
431
|
-
if (!res || res.data == null) {
|
|
432
|
-
// console.warn("HuongDan API returned empty response");
|
|
433
|
-
return [];
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// Đảm bảo luôn là array
|
|
437
|
-
return Array.isArray(res.data) ? res.data : [];
|
|
438
|
-
} catch (error) {
|
|
439
|
-
// console.error("Error fetching huongDan:", error);
|
|
312
|
+
export const huongDan = async ({ data }) => {
|
|
313
|
+
if (!apiUrl) {
|
|
440
314
|
return [];
|
|
315
|
+
} else {
|
|
316
|
+
const res = await api.get(
|
|
317
|
+
`${getBaseUrl()}/${apiUrl}/HuongDanSuDung/Dropdownlist`,
|
|
318
|
+
{
|
|
319
|
+
params: {
|
|
320
|
+
...data
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
headers: {
|
|
325
|
+
"Content-Type": "application/json-patch+json" // Đảm bảo Content-Type là đúng
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
);
|
|
329
|
+
return res.data;
|
|
441
330
|
}
|
|
442
331
|
};
|
|
@@ -13,7 +13,7 @@ import { useEffect, useMemo, useState } from "react";
|
|
|
13
13
|
import TablePaginationCustom from "../table/TablePagination";
|
|
14
14
|
|
|
15
15
|
import { useConfirm } from "material-ui-confirm";
|
|
16
|
-
import { useMutation, useQuery, useQueryClient } from "
|
|
16
|
+
import { useMutation, useQuery, useQueryClient } from "react-query";
|
|
17
17
|
import { toast } from "react-toastify";
|
|
18
18
|
import {
|
|
19
19
|
changeStatusDataToTable,
|
|
@@ -63,16 +63,17 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
63
63
|
const [rowsPerPage, setRowsPerPage] = useState(defaultRowsPerPage);
|
|
64
64
|
const [openDialog, setOpenDialog] = useState(false);
|
|
65
65
|
const [deleteId, setDeleteId] = useState(null);
|
|
66
|
-
const defaultSortColumn = columns.find((c) => c.defaultSort);
|
|
67
66
|
|
|
68
|
-
const [orderBy, setOrderBy] = useState(
|
|
69
|
-
const [order, setOrder] = useState(
|
|
67
|
+
const [orderBy, setOrderBy] = useState("");
|
|
68
|
+
const [order, setOrder] = useState("asc");
|
|
69
|
+
|
|
70
70
|
useEffect(() => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
if (!Array.isArray(columns) || columns.length === 0) return;
|
|
72
|
+
|
|
73
|
+
const defaultSortColumn = columns.find((c) => c.defaultSort) || columns[0];
|
|
74
|
+
|
|
75
|
+
setOrderBy(defaultSortColumn.field);
|
|
76
|
+
setOrder(defaultSortColumn.defaultOrder || "asc");
|
|
76
77
|
}, [columns]);
|
|
77
78
|
|
|
78
79
|
const handleRequestSort = (event, property) => {
|
|
@@ -81,12 +82,11 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
81
82
|
setOrderBy(property);
|
|
82
83
|
};
|
|
83
84
|
|
|
84
|
-
// 1️⃣ Xoá defaultQueryOptions khỏi useQuery
|
|
85
85
|
const { data, isLoading } = useQuery({
|
|
86
86
|
queryKey: [tableName, page, rowsPerPage, dataSearch, order, orderBy],
|
|
87
87
|
queryFn: () =>
|
|
88
88
|
getDatasFromTable({
|
|
89
|
-
tableName,
|
|
89
|
+
tableName: tableName,
|
|
90
90
|
page: page + 1,
|
|
91
91
|
pageSize: rowsPerPage,
|
|
92
92
|
data: {
|
|
@@ -97,76 +97,96 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
97
97
|
})
|
|
98
98
|
}
|
|
99
99
|
}),
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
PermissionModel: {},
|
|
104
|
-
CountTrangThai: null,
|
|
105
|
-
status: false
|
|
106
|
-
}),
|
|
107
|
-
staleTime: 60_000,
|
|
108
|
-
gcTime: 30 * 60_000, // ✅ v5 (cacheTime → gcTime)
|
|
109
|
-
refetchOnWindowFocus: true,
|
|
110
|
-
refetchInterval: 30_000,
|
|
111
|
-
onSuccess: ({ PermissionModel = {}, CountTrangThai, status }) => {
|
|
100
|
+
defaultQueryOptions,
|
|
101
|
+
// keepPreviousData: true,
|
|
102
|
+
onSuccess: ({ PermissionModel, CountTrangThai, status }) => {
|
|
112
103
|
if (dataSearch?.TrangThaiXuLy !== undefined) {
|
|
113
|
-
PermissionModel.TrangThaiXuLy = dataSearch
|
|
104
|
+
PermissionModel.TrangThaiXuLy = dataSearch?.TrangThaiXuLy;
|
|
114
105
|
}
|
|
115
|
-
|
|
116
106
|
setPermission(PermissionModel);
|
|
117
107
|
|
|
118
108
|
if (CountTrangThai) {
|
|
119
109
|
const keyCounter = `${tableName}_${userId}_TrangThaiXuLyCounter`;
|
|
120
110
|
localStorage.setItem(keyCounter, JSON.stringify(CountTrangThai));
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
});
|
|
111
|
+
// 👉 Invalidate query để Tab reload ngay
|
|
112
|
+
queryClient.invalidateQueries({ queryKey: [tableName, "CountAllTrangThaiXuly"] });
|
|
124
113
|
}
|
|
125
114
|
|
|
126
115
|
if (status) {
|
|
127
|
-
|
|
116
|
+
// console.log("LOAD LAI PermissionModel");
|
|
117
|
+
// Cuộn lên đầu trang khi tải dữ liệu thành công
|
|
118
|
+
window.scrollTo({
|
|
119
|
+
top: 0, // Vị trí pixel muốn cuộn tới
|
|
120
|
+
behavior: "smooth" // Tùy chọn cuộn mượt
|
|
121
|
+
});
|
|
128
122
|
}
|
|
129
123
|
}
|
|
130
124
|
});
|
|
131
125
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
126
|
+
const changeStatusMutation = useMutation(changeStatusDataToTable, {
|
|
127
|
+
onSuccess: ({ status = false, message = " Có lỗi xảy ra !" }) => {
|
|
128
|
+
if (URL_APPLICATION_API) {
|
|
129
|
+
toast.success(message);
|
|
130
|
+
} else {
|
|
131
|
+
toast.success("Thay đổi trạng thái thành công !");
|
|
132
|
+
}
|
|
137
133
|
queryClient.invalidateQueries({ queryKey: [tableName] });
|
|
138
134
|
queryClient.invalidateQueries({ queryKey: [tableName, "CountAllTrangThaiXuly"] });
|
|
139
135
|
},
|
|
140
136
|
onError: (error) => {
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
if (error.response && error.response.data) {
|
|
138
|
+
const message = error.response.data.message;
|
|
139
|
+
toast.error(message);
|
|
140
|
+
} else {
|
|
141
|
+
// Nếu lỗi không theo định dạng mong đợi, hiển thị thông tin lỗi chung
|
|
142
|
+
toast.error("Đã xảy ra lỗi không mong muốn.");
|
|
143
|
+
}
|
|
143
144
|
}
|
|
144
145
|
});
|
|
146
|
+
const deleteMutation = useMutation(deleteDataFromTable, {
|
|
147
|
+
onSuccess: ({ status = false, message = " Có lỗi xảy ra !" }) => {
|
|
148
|
+
if (status) {
|
|
149
|
+
if (URL_APPLICATION_API) {
|
|
150
|
+
toast.success(message);
|
|
151
|
+
} else {
|
|
152
|
+
toast.success("Xóa thành công !");
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
toast.error(" Có lỗi xảy ra !");
|
|
156
|
+
}
|
|
145
157
|
|
|
146
|
-
const deleteMutation = useMutation({
|
|
147
|
-
mutationFn: deleteDataFromTable,
|
|
148
|
-
onSuccess: ({ status = false, message = "Có lỗi xảy ra !" }) => {
|
|
149
|
-
toast[status ? "success" : "error"](status ? message : "Có lỗi xảy ra !");
|
|
150
158
|
queryClient.invalidateQueries({ queryKey: [tableName] });
|
|
151
159
|
queryClient.invalidateQueries({ queryKey: [tableName, "CountAllTrangThaiXuly"] });
|
|
152
160
|
},
|
|
153
161
|
onError: (error) => {
|
|
154
|
-
|
|
155
|
-
|
|
162
|
+
if (error.response && error.response.data) {
|
|
163
|
+
const message = error.response.data.message;
|
|
164
|
+
toast.error(message);
|
|
165
|
+
} else {
|
|
166
|
+
// Nếu lỗi không theo định dạng mong đợi, hiển thị thông tin lỗi chung
|
|
167
|
+
toast.error("Đã xảy ra lỗi không mong muốn.");
|
|
168
|
+
}
|
|
156
169
|
}
|
|
157
170
|
});
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
171
|
+
const deleteMultipleMutation = useMutation(deleteMultipleDataFromTable, {
|
|
172
|
+
onSuccess: ({ status = false, message = " Có lỗi xảy ra !" }) => {
|
|
173
|
+
if (URL_APPLICATION_API) {
|
|
174
|
+
toast.success(message);
|
|
175
|
+
} else {
|
|
176
|
+
toast.success("Xóa thành công !");
|
|
177
|
+
}
|
|
163
178
|
setSelectedItems([]);
|
|
164
179
|
queryClient.invalidateQueries({ queryKey: [tableName] });
|
|
165
180
|
queryClient.invalidateQueries({ queryKey: [tableName, "CountAllTrangThaiXuly"] });
|
|
166
181
|
},
|
|
167
182
|
onError: (error) => {
|
|
168
|
-
|
|
169
|
-
|
|
183
|
+
if (error.response && error.response.data) {
|
|
184
|
+
const message = error.response.data.message;
|
|
185
|
+
toast.error(message);
|
|
186
|
+
} else {
|
|
187
|
+
// Nếu lỗi không theo định dạng mong đợi, hiển thị thông tin lỗi chung
|
|
188
|
+
toast.error("Đã xảy ra lỗi không mong muốn.");
|
|
189
|
+
}
|
|
170
190
|
}
|
|
171
191
|
});
|
|
172
192
|
// Hàm gọi khi người dùng muốn xóa một bản ghi
|