trithuc-mvc-react 3.1.3 → 3.1.4
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/components/DataManagement/DataTable.jsx +3 -3
- package/components/DataManagement/DataTableSM.jsx +3 -3
- package/components/DataManagement/EditorForm.jsx +1 -1
- package/components/DataManagement/TableRowRenderSM.jsx +63 -89
- package/components/DataManagement/index.jsx +2 -2
- package/components/form/DynamicForm.jsx +1 -1
- package/components/table/TablePagination.jsx +2 -2
- package/package.json +1 -1
- package/utils/storage.js +33 -0
|
@@ -257,7 +257,7 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
257
257
|
/>
|
|
258
258
|
{isLoading ? (
|
|
259
259
|
<TableBody>
|
|
260
|
-
<TableRowsLoader rowsNum={
|
|
260
|
+
<TableRowsLoader rowsNum={15} colsNum={columns.length + 3} />
|
|
261
261
|
</TableBody>
|
|
262
262
|
) : (
|
|
263
263
|
<TableBody>
|
|
@@ -293,14 +293,14 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
293
293
|
|
|
294
294
|
<Grid container>
|
|
295
295
|
{!hasTabpanel && (
|
|
296
|
-
<Grid
|
|
296
|
+
<Grid alignSelf={"center"} sx={{ pl: 2 }}>
|
|
297
297
|
<Typography variant="body1">
|
|
298
298
|
Tổng số lượng: <span>{total}</span>
|
|
299
299
|
</Typography>
|
|
300
300
|
</Grid>
|
|
301
301
|
)}
|
|
302
302
|
|
|
303
|
-
<Grid
|
|
303
|
+
<Grid>
|
|
304
304
|
<TablePaginationCustom
|
|
305
305
|
count={total}
|
|
306
306
|
rowsPerPage={rowsPerPage}
|
|
@@ -268,7 +268,7 @@ const DataTableSM = ({ multipleActions = [], page, setPage = () => {}, disableEd
|
|
|
268
268
|
/> */}
|
|
269
269
|
{isLoading ? (
|
|
270
270
|
<TableBody>
|
|
271
|
-
<TableRowsLoader rowsNum={
|
|
271
|
+
<TableRowsLoader rowsNum={10} colsNum={columns.length + 3} />
|
|
272
272
|
</TableBody>
|
|
273
273
|
) : (
|
|
274
274
|
<TableBody>
|
|
@@ -304,14 +304,14 @@ const DataTableSM = ({ multipleActions = [], page, setPage = () => {}, disableEd
|
|
|
304
304
|
|
|
305
305
|
<Grid container>
|
|
306
306
|
{!hasTabpanel && (
|
|
307
|
-
<Grid
|
|
307
|
+
<Grid alignSelf={"center"} sx={{ pl: 2 }}>
|
|
308
308
|
<Typography variant="body1" sx={{ fontSize: "0.7rem" }}>
|
|
309
309
|
Tổng số lượng: <span>{total}</span>
|
|
310
310
|
</Typography>
|
|
311
311
|
</Grid>
|
|
312
312
|
)}
|
|
313
313
|
|
|
314
|
-
<Grid
|
|
314
|
+
<Grid>
|
|
315
315
|
<TablePaginationCustom
|
|
316
316
|
count={total}
|
|
317
317
|
rowsPerPage={rowsPerPage}
|
|
@@ -1,7 +1,7 @@
|
|
|
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,
|
|
4
|
+
import { Box, Button, Grid, Switch, TableCell, TableRow, Toolbar, 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";
|
|
@@ -30,34 +30,33 @@ export const TableRowRenderSM = ({
|
|
|
30
30
|
const tableActionsAfterFilter = [...tableActions]
|
|
31
31
|
.filter((x) => x)
|
|
32
32
|
.filter(({ permissionType }) => {
|
|
33
|
-
if (permissionType === "view" && !canView)
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
if (permissionType === "action" && !canAction) {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
33
|
+
if (permissionType === "view" && !canView) return false;
|
|
34
|
+
if (permissionType === "action" && !canAction) return false;
|
|
39
35
|
return true;
|
|
40
36
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
tableActionsOnTable: tableActionsAfterFilter.filter(({ isOnTable = false }) => isOnTable),
|
|
40
|
+
tableActionsOnMoreMenu: tableActionsAfterFilter.filter(({ isOnTable = false }) => !isOnTable)
|
|
41
|
+
};
|
|
44
42
|
}, [canView, canAction, tableActions]);
|
|
45
43
|
|
|
46
44
|
const theme = useTheme();
|
|
47
45
|
const downXl = useMediaQuery(theme.breakpoints.down("xl"));
|
|
48
46
|
|
|
49
47
|
return (
|
|
50
|
-
<TableRow hover key={row[selectedField]} selected={selected}
|
|
48
|
+
<TableRow hover key={row[selectedField]} selected={selected}>
|
|
51
49
|
<TableCell
|
|
52
50
|
colSpan={columns.length}
|
|
53
51
|
align="left"
|
|
54
52
|
sx={{
|
|
55
|
-
maxWidth: "100%",
|
|
56
|
-
wordBreak: "break-word",
|
|
57
|
-
whiteSpace: "normal",
|
|
58
|
-
overflowWrap: "break-word"
|
|
53
|
+
maxWidth: "100%",
|
|
54
|
+
wordBreak: "break-word",
|
|
55
|
+
whiteSpace: "normal",
|
|
56
|
+
overflowWrap: "break-word"
|
|
59
57
|
}}
|
|
60
58
|
>
|
|
59
|
+
{/* Hiển thị các cột dữ liệu */}
|
|
61
60
|
{columns.map(({ field, label, type = "text", valueGetter = (row) => row[field], renderCell, valueFormat = (e) => e }) => {
|
|
62
61
|
const value = renderCell ? renderCell(row) : valueFormat(valueGetter(row));
|
|
63
62
|
return (
|
|
@@ -67,17 +66,21 @@ export const TableRowRenderSM = ({
|
|
|
67
66
|
</div>
|
|
68
67
|
);
|
|
69
68
|
})}
|
|
69
|
+
|
|
70
|
+
{/* Công tắc trạng thái */}
|
|
70
71
|
{!disableStatus && canEdit && (
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
onChangeStatus(row[selectedField])
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
<Box sx={{ mt: 1 }}>
|
|
73
|
+
<Switch
|
|
74
|
+
checked={row[statusKey]}
|
|
75
|
+
onChange={() => onChangeStatus(row[selectedField])}
|
|
76
|
+
inputProps={{ "aria-label": "controlled" }}
|
|
77
|
+
/>
|
|
78
|
+
</Box>
|
|
78
79
|
)}
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
|
|
81
|
+
{/* Các nút thao tác */}
|
|
82
|
+
<Grid container spacing={2} sx={{ width: "100%", pt: 2, pb: 2 }}>
|
|
83
|
+
<Grid size={{ xs: 12 }} sx={{ display: "flex", justifyContent: "flex-end", flexWrap: "wrap" }}>
|
|
81
84
|
{!disableCellThaoTac && (
|
|
82
85
|
<>
|
|
83
86
|
{!disableEdit && canEdit && (
|
|
@@ -87,18 +90,7 @@ export const TableRowRenderSM = ({
|
|
|
87
90
|
color="primary"
|
|
88
91
|
onClick={() => onEdit(row)}
|
|
89
92
|
startIcon={<EditOutlined fontSize="inherit" />}
|
|
90
|
-
sx={
|
|
91
|
-
marginLeft: 0.5,
|
|
92
|
-
marginRight: 0.5,
|
|
93
|
-
borderRadius: 14,
|
|
94
|
-
minWidth: 60,
|
|
95
|
-
padding: "2px 8px",
|
|
96
|
-
height: "20px",
|
|
97
|
-
fontSize: "0.6rem",
|
|
98
|
-
whiteSpace: "nowrap",
|
|
99
|
-
overflow: "hidden",
|
|
100
|
-
textOverflow: "ellipsis"
|
|
101
|
-
}}
|
|
93
|
+
sx={buttonStyle}
|
|
102
94
|
>
|
|
103
95
|
Sửa
|
|
104
96
|
</Button>
|
|
@@ -110,18 +102,7 @@ export const TableRowRenderSM = ({
|
|
|
110
102
|
color="info"
|
|
111
103
|
onClick={() => onView(row)}
|
|
112
104
|
startIcon={<RemoveRedEyeOutlinedIcon />}
|
|
113
|
-
sx={
|
|
114
|
-
marginLeft: 0.5,
|
|
115
|
-
marginRight: 0.5,
|
|
116
|
-
borderRadius: 14,
|
|
117
|
-
minWidth: 60,
|
|
118
|
-
padding: "2px 8px",
|
|
119
|
-
height: "20px",
|
|
120
|
-
fontSize: "0.6rem",
|
|
121
|
-
whiteSpace: "nowrap",
|
|
122
|
-
overflow: "hidden",
|
|
123
|
-
textOverflow: "ellipsis"
|
|
124
|
-
}}
|
|
105
|
+
sx={buttonStyle}
|
|
125
106
|
>
|
|
126
107
|
Xem
|
|
127
108
|
</Button>
|
|
@@ -131,51 +112,30 @@ export const TableRowRenderSM = ({
|
|
|
131
112
|
size="small"
|
|
132
113
|
variant="outlined"
|
|
133
114
|
color="error"
|
|
134
|
-
onClick={() =>
|
|
135
|
-
onDelete(row[selectedField]);
|
|
136
|
-
}}
|
|
115
|
+
onClick={() => onDelete(row[selectedField])}
|
|
137
116
|
startIcon={<DeleteOutlineIcon fontSize="inherit" />}
|
|
138
|
-
sx={
|
|
139
|
-
marginLeft: 0.5,
|
|
140
|
-
marginRight: 0.5,
|
|
141
|
-
borderRadius: 14,
|
|
142
|
-
minWidth: 60,
|
|
143
|
-
padding: "2px 8px",
|
|
144
|
-
height: "20px",
|
|
145
|
-
fontSize: "0.6rem",
|
|
146
|
-
whiteSpace: "nowrap",
|
|
147
|
-
overflow: "hidden",
|
|
148
|
-
textOverflow: "ellipsis"
|
|
149
|
-
}}
|
|
117
|
+
sx={buttonStyle}
|
|
150
118
|
>
|
|
151
119
|
Xóa
|
|
152
120
|
</Button>
|
|
153
121
|
)}
|
|
154
|
-
{tableActionsOnTable.map(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
overflow: "hidden",
|
|
172
|
-
textOverflow: "ellipsis"
|
|
173
|
-
}}
|
|
174
|
-
hidden={typeof visible === "function" && !visible(row)}
|
|
175
|
-
>
|
|
176
|
-
{title.toLowerCase() === "xem chi tiết" ? "Xem" : title}
|
|
177
|
-
</Button>
|
|
178
|
-
))}
|
|
122
|
+
{tableActionsOnTable.map(
|
|
123
|
+
({ title, onClick, element, visible = true }, idx) =>
|
|
124
|
+
(typeof visible === "function" ? visible(row) : visible) && (
|
|
125
|
+
<Button
|
|
126
|
+
key={idx}
|
|
127
|
+
size="small"
|
|
128
|
+
variant="outlined"
|
|
129
|
+
onClick={() => onClick(row)}
|
|
130
|
+
startIcon={element}
|
|
131
|
+
sx={{
|
|
132
|
+
...buttonStyle
|
|
133
|
+
}}
|
|
134
|
+
>
|
|
135
|
+
{title === "xem chi tiết" ? "Xem" : title}
|
|
136
|
+
</Button>
|
|
137
|
+
)
|
|
138
|
+
)}
|
|
179
139
|
<MoreMenu actions={tableActionsOnMoreMenu} data={row} />
|
|
180
140
|
</>
|
|
181
141
|
)}
|
|
@@ -186,8 +146,22 @@ export const TableRowRenderSM = ({
|
|
|
186
146
|
);
|
|
187
147
|
};
|
|
188
148
|
|
|
189
|
-
//
|
|
149
|
+
// Button style dùng chung
|
|
150
|
+
const buttonStyle = {
|
|
151
|
+
marginLeft: 0.3,
|
|
152
|
+
marginRight: 0.3,
|
|
153
|
+
marginBottom: 0.5,
|
|
154
|
+
borderRadius: 14,
|
|
155
|
+
minWidth: 50,
|
|
156
|
+
padding: "2px 8px",
|
|
157
|
+
height: "20px",
|
|
158
|
+
fontSize: "0.6rem",
|
|
159
|
+
whiteSpace: "nowrap",
|
|
160
|
+
overflow: "hidden",
|
|
161
|
+
textOverflow: "ellipsis"
|
|
162
|
+
};
|
|
190
163
|
|
|
164
|
+
// Toolbar style
|
|
191
165
|
export const RootStyle = styled(Toolbar)(({ theme }) => ({
|
|
192
166
|
display: "flex",
|
|
193
167
|
justifyContent: "space-between",
|
|
@@ -197,7 +197,7 @@ function DataManagement({
|
|
|
197
197
|
// Đo chiều rộng của titleText khi render lần đầu
|
|
198
198
|
useEffect(() => {
|
|
199
199
|
const titleElement = document.createElement("span");
|
|
200
|
-
titleElement.style.font = "normal
|
|
200
|
+
titleElement.style.font = "normal 14px Arial"; // Đảm bảo phông chữ và kích thước giống như bạn dùng trong UI
|
|
201
201
|
titleElement.style.visibility = "hidden"; // Ẩn element tạm thời
|
|
202
202
|
titleElement.textContent = titleText;
|
|
203
203
|
|
|
@@ -303,7 +303,7 @@ function DataManagement({
|
|
|
303
303
|
wordBreak: "break-word"
|
|
304
304
|
}}
|
|
305
305
|
>
|
|
306
|
-
<Typography variant="
|
|
306
|
+
<Typography variant={isSmallScreen ? "body2" : "subtitle1"}>{titleText}</Typography>
|
|
307
307
|
</Box>
|
|
308
308
|
|
|
309
309
|
{/* Khối phải */}
|
|
@@ -26,8 +26,8 @@ function TablePaginationCustom({ count, rowsPerPage, page, onPageChange, onRowsP
|
|
|
26
26
|
labelDisplayedRows={defaultLabelDisplayedRows}
|
|
27
27
|
sx={{
|
|
28
28
|
"& .MuiTablePagination-toolbar": {
|
|
29
|
-
paddingLeft: matchsDownMD ? "
|
|
30
|
-
paddingRight: matchsDownMD ? "
|
|
29
|
+
paddingLeft: matchsDownMD ? "3px" : "10px",
|
|
30
|
+
paddingRight: matchsDownMD ? "3px" : "10px",
|
|
31
31
|
fontSize: matchsDownMD ? "0.65rem" : "0.8rem" // Giảm kích thước font khi trên màn hình nhỏ
|
|
32
32
|
},
|
|
33
33
|
"& .MuiTablePagination-selectLabel, & .MuiTablePagination-displayedRows": {
|
package/package.json
CHANGED
package/utils/storage.js
CHANGED
|
@@ -61,6 +61,27 @@ export const storeUserData = (data) => {
|
|
|
61
61
|
const encryptedUserObj = encryptData(userObj);
|
|
62
62
|
localStorage.setItem("user", encryptedUserObj);
|
|
63
63
|
};
|
|
64
|
+
export const storeSubUserData = (data) => {
|
|
65
|
+
if (!data) return;
|
|
66
|
+
|
|
67
|
+
// Mã hóa và lưu token
|
|
68
|
+
const encryptedToken = encryptData(data.Token);
|
|
69
|
+
localStorage.setItem("token", encryptedToken);
|
|
70
|
+
|
|
71
|
+
// Tạo object user từ dữ liệu response
|
|
72
|
+
const userObj = {
|
|
73
|
+
userName: data?.UserName,
|
|
74
|
+
email: data?.Email,
|
|
75
|
+
FullName: data?.FullName,
|
|
76
|
+
Avatar: data?.Avatar,
|
|
77
|
+
Navigate: data?.Navigate,
|
|
78
|
+
PhoneNumber: data?.PhoneNumber
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Mã hóa và lưu user object vào localStorage
|
|
82
|
+
const encryptedUserObj = encryptData(userObj);
|
|
83
|
+
localStorage.setItem("subUser", encryptedUserObj);
|
|
84
|
+
};
|
|
64
85
|
export const storeSetCachedSidebarTops = (data) => {
|
|
65
86
|
if (!data) return;
|
|
66
87
|
// Mã hóa và lưu
|
|
@@ -123,7 +144,19 @@ export const storeGetUser = () => {
|
|
|
123
144
|
return null;
|
|
124
145
|
}
|
|
125
146
|
};
|
|
147
|
+
export const storeGetSubUser = () => {
|
|
148
|
+
const encryptedData = localStorage.getItem("subUser");
|
|
149
|
+
if (!encryptedData) return null;
|
|
150
|
+
const decryptedData = decryptData(encryptedData);
|
|
126
151
|
|
|
152
|
+
try {
|
|
153
|
+
// Chuyển đổi thành JSON nếu dữ liệu giải mã hợp lệ
|
|
154
|
+
return decryptedData;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.log("Error parsing decrypted user data:", error);
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
127
160
|
export const storeGetToken = () => {
|
|
128
161
|
const encryptedData = localStorage.getItem("token");
|
|
129
162
|
if (!encryptedData) return null;
|