trithuc-mvc-react 3.4.0 → 3.4.2
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.
|
@@ -16,6 +16,7 @@ import TableToolbar from "./TableToolbar";
|
|
|
16
16
|
import { useDataTable } from "./hooks";
|
|
17
17
|
import DeleteConfirmationDialog from "./DeleteConfirmationDialog";
|
|
18
18
|
import DeleteMultipleConfirmationDialog from "./DeleteMultipleConfirmationDialog";
|
|
19
|
+
import { storeGetUser } from "../../utils/storage";
|
|
19
20
|
const defaultQueryOptions = {
|
|
20
21
|
staleTime: 1000 * 60 * 1, // Thời gian dữ liệu có thể sử dụng lại trước khi gọi lại API
|
|
21
22
|
cacheTime: 1000 * 60 * 30, // Thời gian dữ liệu được lưu trong cache trước khi bị xóa
|
|
@@ -36,7 +37,8 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
36
37
|
hasTabpanel,
|
|
37
38
|
defaultRowsPerPage = 5
|
|
38
39
|
} = useDataTable();
|
|
39
|
-
|
|
40
|
+
const user = storeGetUser();
|
|
41
|
+
const userId = user?.UserId;
|
|
40
42
|
const { set: setPermission } = usePermission(tableName);
|
|
41
43
|
const queryClient = useQueryClient();
|
|
42
44
|
const confirm = useConfirm();
|
|
@@ -81,12 +83,20 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
81
83
|
}),
|
|
82
84
|
defaultQueryOptions,
|
|
83
85
|
// keepPreviousData: true,
|
|
84
|
-
onSuccess: ({ PermissionModel, status }) => {
|
|
86
|
+
onSuccess: ({ PermissionModel, CountTrangThai, status }) => {
|
|
85
87
|
if (dataSearch?.TrangThaiXuLy !== undefined) {
|
|
86
88
|
PermissionModel.TrangThaiXuLy = dataSearch?.TrangThaiXuLy;
|
|
87
89
|
}
|
|
90
|
+
setPermission(PermissionModel);
|
|
91
|
+
|
|
92
|
+
if (CountTrangThai) {
|
|
93
|
+
const keyCounter = `${tableName}_${userId}_TrangThaiXuLyCounter`;
|
|
94
|
+
localStorage.setItem(keyCounter, JSON.stringify(CountTrangThai));
|
|
95
|
+
// 👉 Invalidate query để Tab reload ngay
|
|
96
|
+
queryClient.invalidateQueries({ queryKey: [tableName, "CountAllTrangThaiXuly"] });
|
|
97
|
+
}
|
|
98
|
+
|
|
88
99
|
if (status) {
|
|
89
|
-
setPermission(PermissionModel);
|
|
90
100
|
// console.log("LOAD LAI PermissionModel");
|
|
91
101
|
// Cuộn lên đầu trang khi tải dữ liệu thành công
|
|
92
102
|
window.scrollTo({
|
|
@@ -15,6 +15,7 @@ import TableToolbar from "./TableToolbar";
|
|
|
15
15
|
import { useDataTable } from "./hooks";
|
|
16
16
|
import DeleteConfirmationDialog from "./DeleteConfirmationDialog";
|
|
17
17
|
import DeleteMultipleConfirmationDialog from "./DeleteMultipleConfirmationDialog";
|
|
18
|
+
import { storeGetUser } from "../../utils/storage";
|
|
18
19
|
const defaultQueryOptions = {
|
|
19
20
|
staleTime: 1000 * 60 * 1, // Thời gian dữ liệu có thể sử dụng lại trước khi gọi lại API
|
|
20
21
|
cacheTime: 1000 * 60 * 30, // Thời gian dữ liệu được lưu trong cache trước khi bị xóa
|
|
@@ -35,7 +36,8 @@ const DataTableSM = ({ multipleActions = [], page, setPage = () => {}, disableEd
|
|
|
35
36
|
hasTabpanel,
|
|
36
37
|
defaultRowsPerPage = 5
|
|
37
38
|
} = useDataTable();
|
|
38
|
-
|
|
39
|
+
const user = storeGetUser();
|
|
40
|
+
const userId = user?.UserId;
|
|
39
41
|
const { set: setPermission } = usePermission(tableName);
|
|
40
42
|
const queryClient = useQueryClient();
|
|
41
43
|
const confirm = useConfirm();
|
|
@@ -80,12 +82,20 @@ const DataTableSM = ({ multipleActions = [], page, setPage = () => {}, disableEd
|
|
|
80
82
|
}),
|
|
81
83
|
defaultQueryOptions,
|
|
82
84
|
// keepPreviousData: true,
|
|
83
|
-
onSuccess: ({ PermissionModel, status }) => {
|
|
85
|
+
onSuccess: ({ PermissionModel, CountTrangThai, status }) => {
|
|
84
86
|
if (dataSearch?.TrangThaiXuLy !== undefined) {
|
|
85
87
|
PermissionModel.TrangThaiXuLy = dataSearch?.TrangThaiXuLy;
|
|
86
88
|
}
|
|
89
|
+
setPermission(PermissionModel);
|
|
90
|
+
|
|
91
|
+
if (CountTrangThai) {
|
|
92
|
+
const keyCounter = `${tableName}_${userId}_TrangThaiXuLyCounter`;
|
|
93
|
+
localStorage.setItem(keyCounter, JSON.stringify(CountTrangThai));
|
|
94
|
+
// 👉 Invalidate query để Tab reload ngay
|
|
95
|
+
queryClient.invalidateQueries({ queryKey: [tableName, "CountAllTrangThaiXuly"] });
|
|
96
|
+
}
|
|
97
|
+
|
|
87
98
|
if (status) {
|
|
88
|
-
setPermission(PermissionModel);
|
|
89
99
|
// console.log("LOAD LAI PermissionModel");
|
|
90
100
|
// Cuộn lên đầu trang khi tải dữ liệu thành công
|
|
91
101
|
window.scrollTo({
|
|
@@ -120,8 +120,10 @@ function DataManagement({
|
|
|
120
120
|
const [selectedEditItem, setSelectedEditItem] = useState(null);
|
|
121
121
|
const [openViewDialog, setOpenViewDialog] = useState(false);
|
|
122
122
|
|
|
123
|
-
const { canCreate, canThongKe, canBieuDo } = usePermission(apiUrl
|
|
123
|
+
const { permission, canCreate, canExportData, canThongKe, canBieuDo } = usePermission(apiUrl || tableName);
|
|
124
124
|
|
|
125
|
+
// console.log(">>> permission from hook:", permission);
|
|
126
|
+
// console.log(">>> canCreate:", canCreate);
|
|
125
127
|
const [viewMode, setViewMode] = useState("table"); // "table" | "thongke" | "bieudo"
|
|
126
128
|
|
|
127
129
|
const { defaults, filters } = useMemo(() => {
|
|
@@ -387,7 +389,7 @@ function DataManagement({
|
|
|
387
389
|
<div key={index}>{button}</div>
|
|
388
390
|
))}
|
|
389
391
|
|
|
390
|
-
<ExportExcelButton tableName={tableName} data={dataSearch} size={elementSize} />
|
|
392
|
+
{canExportData && <ExportExcelButton tableName={tableName} data={dataSearch} size={elementSize} />}
|
|
391
393
|
|
|
392
394
|
{canCreate && !disableAdd && (
|
|
393
395
|
<Button
|
package/hooks/usePermission.js
CHANGED
|
@@ -1,101 +1,119 @@
|
|
|
1
|
-
import { useContext
|
|
1
|
+
import { useContext } from "react";
|
|
2
2
|
import { PermissionContext } from "../contexts";
|
|
3
|
+
import { storeGetUser } from "@/utils/storage";
|
|
4
|
+
|
|
5
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
3
6
|
|
|
4
7
|
const usePermission = (tableName) => {
|
|
5
8
|
if (!tableName) {
|
|
6
9
|
throw new Error("api is required");
|
|
7
10
|
}
|
|
11
|
+
|
|
8
12
|
const context = useContext(PermissionContext);
|
|
9
13
|
if (!context) {
|
|
10
14
|
throw new Error("usePermission must be used within a PermissionProvider");
|
|
11
15
|
}
|
|
16
|
+
|
|
12
17
|
const { permissionMap, setPermission } = context;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
canDelete: status.Delete ?? false,
|
|
34
|
-
canDeleteMulti: status.DeleteMulti ?? false,
|
|
35
|
-
canSave: status.Save ?? false,
|
|
36
|
-
canCreate: status.Create ?? false,
|
|
37
|
-
canAction: status.Action ?? false,
|
|
38
|
-
canView: status.View ?? false,
|
|
39
|
-
canImport: status.ImportFile ?? false,
|
|
40
|
-
canExportWord: status.ExportWord ?? false,
|
|
41
|
-
canPayment: status.Payment ?? false,
|
|
42
|
-
canThongKe: status.ThongKe ?? false,
|
|
43
|
-
canBieuDo: status.BieuDo ?? false
|
|
44
|
-
};
|
|
45
|
-
} else {
|
|
46
|
-
return {
|
|
47
|
-
canEdit: permission.Edit ?? false,
|
|
48
|
-
canDelete: permission.Delete ?? false,
|
|
49
|
-
canDeleteMulti: permission.DeleteMulti ?? false,
|
|
50
|
-
canSave: permission.Save ?? false,
|
|
51
|
-
canCreate: permission.Create ?? false,
|
|
52
|
-
canAction: permission.Action ?? false,
|
|
53
|
-
canView: permission.View ?? false,
|
|
54
|
-
canImport: permission.ImportFile ?? false,
|
|
55
|
-
canExportWord: permission.ExportWord ?? false,
|
|
56
|
-
canPayment: permission.Payment ?? false,
|
|
57
|
-
canThongKe: permission.ThongKe ?? false,
|
|
58
|
-
canBieuDo: permission.BieuDo ?? false
|
|
59
|
-
};
|
|
18
|
+
|
|
19
|
+
// --- lấy từ context trước ---
|
|
20
|
+
let permission = permissionMap[tableName];
|
|
21
|
+
// if (isDev) {
|
|
22
|
+
// console.log(`[usePermission] Context permission for ${tableName}:`, permission);
|
|
23
|
+
// }
|
|
24
|
+
|
|
25
|
+
// --- nếu chưa có thì thử lấy từ localStorage ---
|
|
26
|
+
if (!permission) {
|
|
27
|
+
const user = storeGetUser();
|
|
28
|
+
const userId = user?.UserId ?? "guest";
|
|
29
|
+
const localKey = `${tableName}_${userId}_PermissionModel`;
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const stored = localStorage.getItem(localKey);
|
|
33
|
+
if (stored) {
|
|
34
|
+
permission = JSON.parse(stored);
|
|
35
|
+
// if (isDev) {
|
|
36
|
+
// console.log(`[usePermission] Loaded from localStorage (${localKey}):`, permission);
|
|
37
|
+
// }
|
|
60
38
|
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
canEdit: false,
|
|
65
|
-
canDelete: false,
|
|
66
|
-
canDeleteMulti: false,
|
|
67
|
-
canSave: false,
|
|
68
|
-
canCreate: false,
|
|
69
|
-
canAction: false,
|
|
70
|
-
canView: false,
|
|
71
|
-
canImport: false,
|
|
72
|
-
canExportWord: false,
|
|
73
|
-
canPayment: false,
|
|
74
|
-
canThongKe: false,
|
|
75
|
-
canBieuDo: false
|
|
76
|
-
};
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.warn("Lỗi parse local permission:", err);
|
|
77
41
|
}
|
|
78
|
-
}
|
|
42
|
+
}
|
|
79
43
|
|
|
80
|
-
|
|
81
|
-
|
|
44
|
+
// mặc định tất cả quyền = false
|
|
45
|
+
let perms = {
|
|
46
|
+
canEdit: false,
|
|
47
|
+
canDelete: false,
|
|
48
|
+
canDeleteMulti: false,
|
|
49
|
+
canSave: false,
|
|
50
|
+
canCreate: false,
|
|
51
|
+
canAction: false,
|
|
52
|
+
canView: false,
|
|
53
|
+
canImport: false,
|
|
54
|
+
canExportData: false,
|
|
55
|
+
canExportWord: false,
|
|
56
|
+
canPayment: false,
|
|
57
|
+
canThongKe: false,
|
|
58
|
+
canBieuDo: false
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
if (permission) {
|
|
62
|
+
let source = permission;
|
|
63
|
+
|
|
64
|
+
// Nếu có trạng thái hợp lệ & ObjTrangThai có data thì override
|
|
65
|
+
if (
|
|
66
|
+
permission.TrangThaiXuLy !== undefined &&
|
|
67
|
+
permission.TrangThaiXuLy !== null &&
|
|
68
|
+
Array.isArray(permission.ObjTrangThai) &&
|
|
69
|
+
permission.ObjTrangThai.length > 0
|
|
70
|
+
) {
|
|
71
|
+
const status = permission.ObjTrangThai.find((t) => t.StatusId === permission.TrangThaiXuLy);
|
|
72
|
+
if (status) {
|
|
73
|
+
source = status;
|
|
74
|
+
// if (isDev) {
|
|
75
|
+
// console.log(`[usePermission] Override by status ${permission.TrangThaiXuLy}:`, source);
|
|
76
|
+
// }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Map field từ source
|
|
81
|
+
perms = {
|
|
82
|
+
canEdit: source.Edit ?? false,
|
|
83
|
+
canDelete: source.Delete ?? false,
|
|
84
|
+
canDeleteMulti: source.DeleteMulti ?? false,
|
|
85
|
+
canSave: source.Save ?? false,
|
|
86
|
+
canCreate: source.Create ?? false,
|
|
87
|
+
canAction: source.Action ?? false,
|
|
88
|
+
canView: source.View ?? false,
|
|
89
|
+
canImport: source.ImportFile ?? false,
|
|
90
|
+
canExportData: source.ExportData ?? false,
|
|
91
|
+
canExportWord: source.ExportWord ?? false,
|
|
92
|
+
canPayment: source.Payment ?? false,
|
|
93
|
+
canThongKe: source.ThongKe ?? false,
|
|
94
|
+
canBieuDo: source.BieuDo ?? false
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const set = (newPermission) => {
|
|
99
|
+
setPermission({ ...permissionMap, [tableName]: { ...newPermission } });
|
|
100
|
+
|
|
101
|
+
const user = storeGetUser();
|
|
102
|
+
const userId = user?.UserId ?? "guest";
|
|
103
|
+
const localKey = `${tableName}_${userId}_PermissionModel`;
|
|
104
|
+
|
|
105
|
+
localStorage.setItem(localKey, JSON.stringify(newPermission));
|
|
106
|
+
|
|
107
|
+
// if (isDev) {
|
|
108
|
+
// console.log(`[usePermission] Saved to localStorage (${localKey}):`, newPermission);
|
|
109
|
+
// }
|
|
82
110
|
};
|
|
83
111
|
|
|
84
112
|
return {
|
|
85
113
|
permission,
|
|
86
114
|
set,
|
|
87
|
-
|
|
88
|
-
canDelete,
|
|
89
|
-
canDeleteMulti,
|
|
90
|
-
canSave,
|
|
91
|
-
canCreate,
|
|
92
|
-
canAction,
|
|
93
|
-
canView,
|
|
94
|
-
canImport,
|
|
95
|
-
canExportWord,
|
|
96
|
-
canPayment,
|
|
97
|
-
canThongKe,
|
|
98
|
-
canBieuDo
|
|
115
|
+
...perms
|
|
99
116
|
};
|
|
100
117
|
};
|
|
118
|
+
|
|
101
119
|
export default usePermission;
|
package/package.json
CHANGED
package/utils/storage.js
CHANGED
|
@@ -289,3 +289,26 @@ export const storeGetlanguageSystemKey = (TypeKey, SystemKey, TypeLanguage) => {
|
|
|
289
289
|
?.Description || ""
|
|
290
290
|
);
|
|
291
291
|
};
|
|
292
|
+
// ---------------- Storage helpers ----------------
|
|
293
|
+
export const storeSetKey = (Key, data) => {
|
|
294
|
+
if (!data) return;
|
|
295
|
+
const encryptedData = encryptData(data);
|
|
296
|
+
localStorage.setItem(Key, encryptedData);
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
export const storeGetKey = (key) => {
|
|
300
|
+
const encryptedData = localStorage.getItem(key);
|
|
301
|
+
if (!encryptedData) return null;
|
|
302
|
+
return decryptData(encryptedData);
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// ---------------- Utility so sánh dữ liệu ----------------
|
|
306
|
+
export const isDataChanged = (oldData, newData) => {
|
|
307
|
+
if (!oldData) return true;
|
|
308
|
+
try {
|
|
309
|
+
return JSON.stringify(oldData) !== JSON.stringify(newData);
|
|
310
|
+
} catch (error) {
|
|
311
|
+
console.error("Error comparing data:", error);
|
|
312
|
+
return true; // nếu có lỗi thì coi như thay đổi
|
|
313
|
+
}
|
|
314
|
+
};
|