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.
@@ -257,7 +257,7 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
257
257
  />
258
258
  {isLoading ? (
259
259
  <TableBody>
260
- <TableRowsLoader rowsNum={5} colsNum={columns.length + 4} />
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 item alignSelf={"center"} sx={{ pl: 2 }}>
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 item xs>
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={5} colsNum={columns.length + 4} />
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 item alignSelf={"center"} sx={{ pl: 2 }}>
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 item xs>
314
+ <Grid>
315
315
  <TablePaginationCustom
316
316
  count={total}
317
317
  rowsPerPage={rowsPerPage}
@@ -185,7 +185,7 @@ function EditorForm({ fields, submitRef }) {
185
185
  ...rest
186
186
  }) => {
187
187
  return (
188
- <Grid md={size?.md} xs={size?.xs} sm={size?.sm} key={field}>
188
+ <Grid size={{ ...size }} key={field}>
189
189
  <FormField
190
190
  type={type}
191
191
  label={label}
@@ -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, Tooltip, useMediaQuery } from "@mui/material";
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
- return false;
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
- const tableActionsOnTable = tableActionsAfterFilter.filter(({ isOnTable = false }) => isOnTable);
42
- const tableActionsOnMoreMenu = tableActionsAfterFilter.filter(({ isOnTable = false }) => !isOnTable);
43
- return { tableActionsOnTable, tableActionsOnMoreMenu };
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} sx={{ width: "100%" }}>
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%", // Giới hạn tối đa theo container
56
- wordBreak: "break-word", // Xuống dòng khi vượt quá
57
- whiteSpace: "normal", // Cho phép xuống dòng
58
- overflowWrap: "break-word" // Hỗ trợ xuống dòng trong các trình duyệt cũ
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
- <Switch
72
- checked={row[statusKey]}
73
- onChange={() => {
74
- onChangeStatus(row[selectedField]);
75
- }}
76
- inputProps={{ "aria-label": "controlled" }}
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
- <Grid container spacing={{ xs: 2, xl: 2 }} sx={{ width: "100%", pt: 2, pb: 2 }}>
80
- <Grid item xs={12} sx={{ display: "flex", justifyContent: "flex-end", alignItems: "center", width: "100%" }}>
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(({ title, onClick, element, visible = true }) => (
155
- <Button
156
- size="small"
157
- variant="outlined"
158
- onClick={() => {
159
- onClick(row);
160
- }}
161
- startIcon={element}
162
- sx={{
163
- marginLeft: 0.5,
164
- marginRight: 0.5,
165
- borderRadius: 14,
166
- minWidth: 60,
167
- padding: "2px 8px",
168
- height: "20px",
169
- fontSize: "0.6rem",
170
- whiteSpace: "nowrap",
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 16px Arial"; // Đảm bảo phông chữ và kích thước giống như bạn dùng trong UI
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="h4">{titleText}</Typography>
306
+ <Typography variant={isSmallScreen ? "body2" : "subtitle1"}>{titleText}</Typography>
307
307
  </Box>
308
308
 
309
309
  {/* Khối phải */}
@@ -63,7 +63,7 @@ function DynamicForm({ fields, elementSize = "medium", submitRef, validationSche
63
63
  };
64
64
  }
65
65
  return (
66
- <Grid {...sizes} key={field}>
66
+ <Grid size={{ ...sizes }} key={field}>
67
67
  <FormField
68
68
  type={type}
69
69
  label={label}
@@ -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 ? "5px" : "14px",
30
- paddingRight: matchsDownMD ? "5px" : "14px",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trithuc-mvc-react",
3
- "version": "3.1.3",
3
+ "version": "3.1.4",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
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;