trithuc-mvc-react 3.3.7 → 3.3.9
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 +11 -0
- package/components/DataManagement/DataTable.jsx +31 -2
- package/components/DataManagement/DataTableSM.jsx +25 -2
- package/components/DataManagement/TableHead.jsx +33 -4
- package/components/DataManagement/TableRowRenderSM.jsx +97 -62
- package/components/DataManagement/index.jsx +17 -11
- package/package.json +1 -1
- package/utils/storage.js +9 -3
package/api/index.js
CHANGED
|
@@ -235,6 +235,17 @@ export const exportExcel = async ({ tableName, data }) => {
|
|
|
235
235
|
};
|
|
236
236
|
|
|
237
237
|
export const uploadFile = async (formData) => {
|
|
238
|
+
// 1. Lấy URL hiện tại
|
|
239
|
+
const currentUrl = window.location.href;
|
|
240
|
+
|
|
241
|
+
// 2. Append vào formData
|
|
242
|
+
formData.append("currentUrl", currentUrl);
|
|
243
|
+
|
|
244
|
+
// 3. Log tất cả key-value trong FormData để kiểm tra
|
|
245
|
+
// console.log("===== FormData Contents =====");
|
|
246
|
+
// formData.forEach((value, key) => {
|
|
247
|
+
// console.log(key, value);
|
|
248
|
+
// });
|
|
238
249
|
if (!apiUrl) {
|
|
239
250
|
const res = await api.post(`${getBaseUrl()}/Handler/fileUploader.ashx`, formData, {
|
|
240
251
|
headers: {
|
|
@@ -46,15 +46,38 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
46
46
|
const [rowsPerPage, setRowsPerPage] = useState(defaultRowsPerPage);
|
|
47
47
|
const [openDialog, setOpenDialog] = useState(false);
|
|
48
48
|
const [deleteId, setDeleteId] = useState(null);
|
|
49
|
+
const defaultSortColumn = columns.find((c) => c.defaultSort);
|
|
50
|
+
|
|
51
|
+
const [orderBy, setOrderBy] = useState(defaultSortColumn?.field || "");
|
|
52
|
+
const [order, setOrder] = useState(defaultSortColumn?.defaultOrder || "asc");
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
const defaultSortColumn = columns.find((c) => c.defaultSort);
|
|
55
|
+
if (defaultSortColumn) {
|
|
56
|
+
setOrderBy(defaultSortColumn.field);
|
|
57
|
+
setOrder(defaultSortColumn.defaultOrder || "asc");
|
|
58
|
+
}
|
|
59
|
+
}, [columns]);
|
|
60
|
+
|
|
61
|
+
const handleRequestSort = (event, property) => {
|
|
62
|
+
const isAsc = orderBy === property && order === "asc";
|
|
63
|
+
setOrder(isAsc ? "desc" : "asc");
|
|
64
|
+
setOrderBy(property);
|
|
65
|
+
};
|
|
49
66
|
|
|
50
67
|
const { data, isLoading } = useQuery({
|
|
51
|
-
queryKey: [tableName, page, rowsPerPage, dataSearch],
|
|
68
|
+
queryKey: [tableName, page, rowsPerPage, dataSearch, order, orderBy],
|
|
52
69
|
queryFn: () =>
|
|
53
70
|
getDatasFromTable({
|
|
54
71
|
tableName: tableName,
|
|
55
72
|
page: page + 1,
|
|
56
73
|
pageSize: rowsPerPage,
|
|
57
|
-
data:
|
|
74
|
+
data: {
|
|
75
|
+
...dataSearch,
|
|
76
|
+
...(orderBy && {
|
|
77
|
+
SortBy: orderBy,
|
|
78
|
+
IsDescending: order === "desc"
|
|
79
|
+
})
|
|
80
|
+
}
|
|
58
81
|
}),
|
|
59
82
|
defaultQueryOptions,
|
|
60
83
|
// keepPreviousData: true,
|
|
@@ -73,6 +96,7 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
73
96
|
}
|
|
74
97
|
}
|
|
75
98
|
});
|
|
99
|
+
|
|
76
100
|
const changeStatusMutation = useMutation(changeStatusDataToTable, {
|
|
77
101
|
onSuccess: ({ status = false, message = " Có lỗi xảy ra !" }) => {
|
|
78
102
|
if (URL_APPLICATION_API) {
|
|
@@ -253,6 +277,7 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
253
277
|
}
|
|
254
278
|
setOpenDeleteMultipleDialog(false); // Đóng Dialog sau khi chọn
|
|
255
279
|
};
|
|
280
|
+
|
|
256
281
|
const theme = useTheme();
|
|
257
282
|
const downXL = useMediaQuery(theme.breakpoints.down("xl"));
|
|
258
283
|
|
|
@@ -283,7 +308,11 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
283
308
|
onSelectAllClick={handleSelectAllClick}
|
|
284
309
|
numSelected={selectedItems?.length}
|
|
285
310
|
rowCount={rows.length}
|
|
311
|
+
order={order}
|
|
312
|
+
orderBy={orderBy}
|
|
313
|
+
onRequestSort={handleRequestSort}
|
|
286
314
|
/>
|
|
315
|
+
|
|
287
316
|
{isLoading ? (
|
|
288
317
|
<TableBody>
|
|
289
318
|
<TableRowsLoader rowsNum={15} colsNum={columns.length + 3} />
|
|
@@ -45,15 +45,38 @@ const DataTableSM = ({ multipleActions = [], page, setPage = () => {}, disableEd
|
|
|
45
45
|
const [rowsPerPage, setRowsPerPage] = useState(defaultRowsPerPage);
|
|
46
46
|
const [openDialog, setOpenDialog] = useState(false);
|
|
47
47
|
const [deleteId, setDeleteId] = useState(null);
|
|
48
|
+
const defaultSortColumn = columns.find((c) => c.defaultSort);
|
|
49
|
+
|
|
50
|
+
const [orderBy, setOrderBy] = useState(defaultSortColumn?.field || "");
|
|
51
|
+
const [order, setOrder] = useState(defaultSortColumn?.defaultOrder || "asc");
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
const defaultSortColumn = columns.find((c) => c.defaultSort);
|
|
54
|
+
if (defaultSortColumn) {
|
|
55
|
+
setOrderBy(defaultSortColumn.field);
|
|
56
|
+
setOrder(defaultSortColumn.defaultOrder || "asc");
|
|
57
|
+
}
|
|
58
|
+
}, [columns]);
|
|
59
|
+
|
|
60
|
+
const handleRequestSort = (event, property) => {
|
|
61
|
+
const isAsc = orderBy === property && order === "asc";
|
|
62
|
+
setOrder(isAsc ? "desc" : "asc");
|
|
63
|
+
setOrderBy(property);
|
|
64
|
+
};
|
|
48
65
|
|
|
49
66
|
const { data, isLoading } = useQuery({
|
|
50
|
-
queryKey: [tableName, page, rowsPerPage, dataSearch],
|
|
67
|
+
queryKey: [tableName, page, rowsPerPage, dataSearch, order, orderBy],
|
|
51
68
|
queryFn: () =>
|
|
52
69
|
getDatasFromTable({
|
|
53
70
|
tableName: tableName,
|
|
54
71
|
page: page + 1,
|
|
55
72
|
pageSize: rowsPerPage,
|
|
56
|
-
data:
|
|
73
|
+
data: {
|
|
74
|
+
...dataSearch,
|
|
75
|
+
...(orderBy && {
|
|
76
|
+
SortBy: orderBy,
|
|
77
|
+
IsDescending: order === "desc"
|
|
78
|
+
})
|
|
79
|
+
}
|
|
57
80
|
}),
|
|
58
81
|
defaultQueryOptions,
|
|
59
82
|
// keepPreviousData: true,
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
import { Checkbox, TableHead as MuiTableHead, TableCell, TableRow, useMediaQuery, useTheme } from "@mui/material";
|
|
1
|
+
import { Checkbox, TableHead as MuiTableHead, TableCell, TableRow, TableSortLabel, useMediaQuery, useTheme } from "@mui/material";
|
|
2
2
|
import { usePermission } from "../../hooks";
|
|
3
3
|
import { useDataTable } from "./hooks";
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
export function TableHead({ numSelected, rowCount, onSelectAllClick, headLabel, order, orderBy, onRequestSort }) {
|
|
5
6
|
const { disableStatus, disableCellThaoTac, tableName } = useDataTable();
|
|
6
7
|
const { canEdit } = usePermission(tableName);
|
|
7
8
|
|
|
8
9
|
const theme = useTheme();
|
|
9
10
|
const downXl = useMediaQuery(theme.breakpoints.down("xl"));
|
|
11
|
+
|
|
12
|
+
const createSortHandler = (property) => (event) => {
|
|
13
|
+
onRequestSort(event, property);
|
|
14
|
+
};
|
|
15
|
+
|
|
10
16
|
return (
|
|
11
17
|
<MuiTableHead sx={{ height: 56, visibility: numSelected > 0 ? "hidden" : "visible" }}>
|
|
12
18
|
<TableRow>
|
|
19
|
+
{/* Checkbox chọn tất cả */}
|
|
13
20
|
<TableCell padding="checkbox">
|
|
14
21
|
<Checkbox
|
|
15
22
|
indeterminate={numSelected > 0 && numSelected < rowCount}
|
|
@@ -18,13 +25,35 @@ export function TableHead({ numSelected, rowCount, onSelectAllClick, headLabel }
|
|
|
18
25
|
onChange={onSelectAllClick}
|
|
19
26
|
/>
|
|
20
27
|
</TableCell>
|
|
28
|
+
|
|
29
|
+
{/* STT không sort */}
|
|
21
30
|
<TableCell sx={{ textAlign: "center" }}>STT</TableCell>
|
|
31
|
+
|
|
32
|
+
{/* Các cột động */}
|
|
22
33
|
{headLabel.map((headCell) => (
|
|
23
|
-
<TableCell
|
|
24
|
-
{headCell.
|
|
34
|
+
<TableCell
|
|
35
|
+
key={headCell.field}
|
|
36
|
+
align={headCell.alignRight ? "right" : "left"}
|
|
37
|
+
sortDirection={orderBy === headCell.field ? order : false}
|
|
38
|
+
>
|
|
39
|
+
{headCell.sortable ? (
|
|
40
|
+
<TableSortLabel
|
|
41
|
+
active={orderBy === headCell.field}
|
|
42
|
+
direction={orderBy === headCell.field ? order : "asc"}
|
|
43
|
+
onClick={createSortHandler(headCell.field)}
|
|
44
|
+
>
|
|
45
|
+
{headCell.label}
|
|
46
|
+
</TableSortLabel>
|
|
47
|
+
) : (
|
|
48
|
+
headCell.label
|
|
49
|
+
)}
|
|
25
50
|
</TableCell>
|
|
26
51
|
))}
|
|
52
|
+
|
|
53
|
+
{/* Kích hoạt */}
|
|
27
54
|
{!disableStatus && canEdit && <TableCell sx={{ textAlign: "center" }}>Kích hoạt</TableCell>}
|
|
55
|
+
|
|
56
|
+
{/* Thao tác */}
|
|
28
57
|
{!disableCellThaoTac && <TableCell sx={{ minWidth: "136px", textAlign: "center" }}>Thao tác</TableCell>}
|
|
29
58
|
</TableRow>
|
|
30
59
|
</MuiTableHead>
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { EditOutlined } from "@mui/icons-material";
|
|
2
2
|
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
|
|
3
3
|
import RemoveRedEyeOutlinedIcon from "@mui/icons-material/RemoveRedEyeOutlined";
|
|
4
|
-
import { Box, Button, Grid, Switch, TableCell, TableRow, Toolbar, useMediaQuery } from "@mui/material";
|
|
4
|
+
import { Box, Button, Grid, Switch, TableCell, TableRow, Toolbar, Typography, useMediaQuery } from "@mui/material";
|
|
5
5
|
import { styled, useTheme } from "@mui/material/styles";
|
|
6
6
|
import { useMemo } from "react";
|
|
7
7
|
import { usePermission } from "../../hooks";
|
|
8
8
|
import MoreMenu from "../MoreMenu";
|
|
9
9
|
import { useDataTable } from "./hooks";
|
|
10
|
+
import { fontSize } from "@mui/system";
|
|
10
11
|
|
|
11
12
|
export const TableRowRenderSM = ({
|
|
12
13
|
index,
|
|
@@ -56,105 +57,139 @@ export const TableRowRenderSM = ({
|
|
|
56
57
|
overflowWrap: "break-word"
|
|
57
58
|
}}
|
|
58
59
|
>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
60
|
+
<Box
|
|
61
|
+
display="flex"
|
|
62
|
+
flexDirection="column"
|
|
63
|
+
gap={1}
|
|
64
|
+
border="1px solid"
|
|
65
|
+
borderColor="divider"
|
|
66
|
+
borderRadius={2}
|
|
67
|
+
boxShadow={1}
|
|
68
|
+
p={2}
|
|
69
|
+
bgcolor="background.paper"
|
|
70
|
+
sx={{
|
|
71
|
+
transition: "all 0.2s ease",
|
|
72
|
+
"&:hover": {
|
|
73
|
+
boxShadow: 3,
|
|
74
|
+
borderColor: "primary.light"
|
|
75
|
+
}
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
{/* Hiển thị các cột dữ liệu */}
|
|
79
|
+
<Grid container spacing={1}>
|
|
80
|
+
{columns.map(
|
|
81
|
+
({ field, label, type = "text", valueGetter = (row) => row[field], renderCell, valueFormat = (e) => e }) => {
|
|
82
|
+
const value = renderCell ? renderCell(row) : valueFormat(valueGetter(row));
|
|
83
|
+
return (
|
|
84
|
+
<Grid size={12} key={`${row[selectedField]}-${field}`}>
|
|
85
|
+
<strong>{label}: </strong> {value}
|
|
86
|
+
</Grid>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
)}
|
|
90
|
+
</Grid>
|
|
91
|
+
{/* Công tắc trạng thái */}
|
|
92
|
+
{!disableStatus && canEdit && (
|
|
93
|
+
<Box sx={{ mt: 1 }}>
|
|
94
|
+
<Switch
|
|
95
|
+
checked={row[statusKey]}
|
|
96
|
+
onChange={() => onChangeStatus(row[selectedField])}
|
|
97
|
+
inputProps={{ "aria-label": "controlled" }}
|
|
98
|
+
/>
|
|
99
|
+
</Box>
|
|
100
|
+
)}
|
|
80
101
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
102
|
+
{/* Các nút thao tác */}
|
|
103
|
+
<Box
|
|
104
|
+
mt={2}
|
|
105
|
+
pt={1}
|
|
106
|
+
display="flex"
|
|
107
|
+
gap={1}
|
|
108
|
+
flexWrap="wrap"
|
|
109
|
+
justifyContent="flex-end"
|
|
110
|
+
borderTop="1px solid"
|
|
111
|
+
borderColor="divider"
|
|
112
|
+
>
|
|
113
|
+
{!disableCellThaoTac && (
|
|
114
|
+
<>
|
|
115
|
+
{!disableEdit && canEdit && (
|
|
87
116
|
<Button
|
|
88
|
-
fullWidth
|
|
89
117
|
size="small"
|
|
90
|
-
variant="
|
|
118
|
+
variant="contained"
|
|
91
119
|
color="primary"
|
|
92
120
|
onClick={() => onEdit(row)}
|
|
93
|
-
startIcon={<EditOutlined
|
|
94
|
-
sx={
|
|
121
|
+
startIcon={<EditOutlined />}
|
|
122
|
+
sx={modernButtonStyle}
|
|
95
123
|
>
|
|
96
124
|
Cập nhật
|
|
97
125
|
</Button>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<Grid size={4}>
|
|
126
|
+
)}
|
|
127
|
+
|
|
128
|
+
{canView && !tableActions?.some(({ permissionType }) => permissionType === "view") && (
|
|
102
129
|
<Button
|
|
103
|
-
fullWidth
|
|
104
130
|
size="small"
|
|
105
131
|
variant="outlined"
|
|
106
132
|
color="info"
|
|
107
133
|
onClick={() => onView(row)}
|
|
108
134
|
startIcon={<RemoveRedEyeOutlinedIcon />}
|
|
109
|
-
sx={
|
|
135
|
+
sx={modernButtonStyle}
|
|
110
136
|
>
|
|
111
137
|
Xem
|
|
112
138
|
</Button>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
<Grid size={4}>
|
|
139
|
+
)}
|
|
140
|
+
|
|
141
|
+
{!disableDelete && canDelete && (
|
|
117
142
|
<Button
|
|
118
|
-
fullWidth
|
|
119
143
|
size="small"
|
|
120
144
|
variant="outlined"
|
|
121
145
|
color="error"
|
|
122
146
|
onClick={() => onDelete(row[selectedField])}
|
|
123
|
-
startIcon={<DeleteOutlineIcon
|
|
124
|
-
sx={
|
|
147
|
+
startIcon={<DeleteOutlineIcon />}
|
|
148
|
+
sx={modernButtonStyle}
|
|
125
149
|
>
|
|
126
150
|
Xóa
|
|
127
151
|
</Button>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
<Grid key={row.Id} size={4}>
|
|
152
|
+
)}
|
|
153
|
+
|
|
154
|
+
{tableActionsOnTable.map(
|
|
155
|
+
({ title, size, onClick, element, visible = true }, idx) =>
|
|
156
|
+
(typeof visible === "function" ? visible(row) : visible) && (
|
|
134
157
|
<Button
|
|
135
|
-
fullWidth
|
|
136
158
|
key={idx}
|
|
137
159
|
size="small"
|
|
138
160
|
variant="outlined"
|
|
139
161
|
onClick={() => onClick(row)}
|
|
140
162
|
startIcon={element}
|
|
141
|
-
sx={
|
|
142
|
-
...buttonStyle
|
|
143
|
-
}}
|
|
163
|
+
sx={modernButtonStyle}
|
|
144
164
|
>
|
|
145
165
|
{title === "xem chi tiết" ? "Xem" : title}
|
|
146
166
|
</Button>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
167
|
+
)
|
|
168
|
+
)}
|
|
169
|
+
|
|
170
|
+
<MoreMenu actions={tableActionsOnMoreMenu} data={row} />
|
|
171
|
+
</>
|
|
172
|
+
)}
|
|
173
|
+
</Box>
|
|
174
|
+
</Box>
|
|
154
175
|
</TableCell>
|
|
155
176
|
</TableRow>
|
|
156
177
|
);
|
|
157
178
|
};
|
|
179
|
+
const modernButtonStyle = {
|
|
180
|
+
fontWeight: 400,
|
|
181
|
+
fontSize: "0.7rem",
|
|
182
|
+
borderRadius: 2,
|
|
183
|
+
minWidth: 90,
|
|
184
|
+
textTransform: "none",
|
|
185
|
+
px: 1,
|
|
186
|
+
py: 0.5,
|
|
187
|
+
boxShadow: "none",
|
|
188
|
+
transition: "all 0.2s ease-in-out",
|
|
189
|
+
"&:hover": {
|
|
190
|
+
boxShadow: "0px 2px 6px rgba(0,0,0,0.1)"
|
|
191
|
+
}
|
|
192
|
+
};
|
|
158
193
|
|
|
159
194
|
// Button style dùng chung
|
|
160
195
|
const buttonStyle = {
|
|
@@ -67,7 +67,8 @@ DataManagement.propTypes = {
|
|
|
67
67
|
titleAddButton: PropTypes.string,
|
|
68
68
|
thongKe: PropTypes.object,
|
|
69
69
|
bieuDo: PropTypes.object,
|
|
70
|
-
disableHead: PropTypes.bool
|
|
70
|
+
disableHead: PropTypes.bool,
|
|
71
|
+
disableSearch: PropTypes.bool
|
|
71
72
|
};
|
|
72
73
|
const getDefaultValues = (filters = []) => {
|
|
73
74
|
const defaultValues = {};
|
|
@@ -112,7 +113,8 @@ function DataManagement({
|
|
|
112
113
|
titleAddButton = "Thêm mới",
|
|
113
114
|
thongKe,
|
|
114
115
|
bieuDo,
|
|
115
|
-
disableHead = false
|
|
116
|
+
disableHead = false,
|
|
117
|
+
disableSearch = false
|
|
116
118
|
}) {
|
|
117
119
|
const [openEditorDialog, setOpenEditorDialog] = useState(false);
|
|
118
120
|
const [selectedEditItem, setSelectedEditItem] = useState(null);
|
|
@@ -189,7 +191,8 @@ function DataManagement({
|
|
|
189
191
|
titleAddButton,
|
|
190
192
|
thongKe,
|
|
191
193
|
bieuDo,
|
|
192
|
-
disableHead
|
|
194
|
+
disableHead,
|
|
195
|
+
disableSearch
|
|
193
196
|
};
|
|
194
197
|
}, [
|
|
195
198
|
reserPage,
|
|
@@ -211,7 +214,8 @@ function DataManagement({
|
|
|
211
214
|
defaultRowsPerPage,
|
|
212
215
|
thongKe,
|
|
213
216
|
bieuDo,
|
|
214
|
-
disableHead
|
|
217
|
+
disableHead,
|
|
218
|
+
disableSearch
|
|
215
219
|
]);
|
|
216
220
|
const methods = useForm({ defaultValues: getDefaultValues(filters) });
|
|
217
221
|
const { reset, setValue } = methods;
|
|
@@ -426,13 +430,15 @@ function DataManagement({
|
|
|
426
430
|
{tabPanel}
|
|
427
431
|
{viewMode === "table" && (
|
|
428
432
|
<>
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
433
|
+
{!disableSearch && (
|
|
434
|
+
<FilterGod
|
|
435
|
+
tableName={tableName}
|
|
436
|
+
filters={filters}
|
|
437
|
+
filterButtons={filterButtons}
|
|
438
|
+
elementSize={elementSize}
|
|
439
|
+
setPage={setPage}
|
|
440
|
+
/>
|
|
441
|
+
)}
|
|
436
442
|
{backParentNavigator}
|
|
437
443
|
{!isSmallScreen ? (
|
|
438
444
|
<DataTable
|
package/package.json
CHANGED
package/utils/storage.js
CHANGED
|
@@ -142,11 +142,9 @@ export const storeSetCurrentInfor = (data) => {
|
|
|
142
142
|
const storedThamSo = storedUserInfo?.ThamSoHeThong?.find((item) => item.TenThamSo === "DEFAULT_ROWS_PER_PAGE");
|
|
143
143
|
const newThamSo = data?.ThamSoHeThong?.find((item) => item.TenThamSo === "DEFAULT_ROWS_PER_PAGE");
|
|
144
144
|
|
|
145
|
-
// Kiểm tra và cập nhật nếu thông tin mới từ API
|
|
146
145
|
if (newThamSo) {
|
|
147
146
|
const isUpdated = !storedThamSo || new Date(newThamSo.ModifiedDate) > new Date(storedThamSo?.ModifiedDate);
|
|
148
147
|
if (isUpdated) {
|
|
149
|
-
// Xóa dữ liệu `rowsPerPage` cũ từ localStorage nếu cần
|
|
150
148
|
Object.keys(localStorage).forEach((key) => {
|
|
151
149
|
if (key.endsWith("rowsPerPage")) {
|
|
152
150
|
localStorage.removeItem(key);
|
|
@@ -155,10 +153,18 @@ export const storeSetCurrentInfor = (data) => {
|
|
|
155
153
|
}
|
|
156
154
|
}
|
|
157
155
|
|
|
158
|
-
// Mã hóa dữ liệu và lưu vào localStorage
|
|
159
156
|
try {
|
|
160
157
|
const encryptedData = encryptData(data);
|
|
161
158
|
localStorage.setItem("GetCurrentInfor", encryptedData);
|
|
159
|
+
|
|
160
|
+
// 🔹 Bắn event cho từng tham số hệ thống
|
|
161
|
+
data?.ThamSoHeThong?.forEach((item) => {
|
|
162
|
+
window.dispatchEvent(
|
|
163
|
+
new CustomEvent("GetCurrentInfor-changed", {
|
|
164
|
+
detail: { key: item.TenThamSo, value: item.GiaTri }
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
});
|
|
162
168
|
} catch (error) {
|
|
163
169
|
console.error("Error encrypting or saving data to localStorage:", error);
|
|
164
170
|
}
|