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 ? apiUrl : tableName);
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
@@ -1,101 +1,119 @@
1
- import { useContext, useMemo } from "react";
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
- const permission = permissionMap[tableName];
14
- const {
15
- canEdit,
16
- canDelete,
17
- canDeleteMulti,
18
- canSave,
19
- canCreate,
20
- canAction,
21
- canView,
22
- canImport,
23
- canExportWord,
24
- canPayment,
25
- canThongKe,
26
- canBieuDo
27
- } = useMemo(() => {
28
- if (permission) {
29
- if (permission.TrangThaiXuLy !== undefined && permission.ObjTrangThai) {
30
- const status = permission.ObjTrangThai.find((t) => t.StatusId === permission.TrangThaiXuLy) || {};
31
- return {
32
- canEdit: status.Edit ?? false,
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
- } else {
62
- // Trường hợp permission không tồn tại
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
- }, [permission]);
42
+ }
79
43
 
80
- const set = (permission) => {
81
- setPermission({ ...permissionMap, [tableName]: permission });
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
- canEdit,
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trithuc-mvc-react",
3
- "version": "3.4.0",
3
+ "version": "3.4.2",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
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
+ };