trithuc-mvc-react 3.3.8 → 3.4.0

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 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: dataSearch
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: dataSearch
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
- export function TableHead({ numSelected, rowCount, onSelectAllClick, headLabel }) {
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 key={headCell.field} align={headCell.alignRight ? "right" : "left"} sx={{ textAlign: "center" }}>
24
- {headCell.label}
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>
@@ -178,7 +178,7 @@ export const TableRowRenderSM = ({
178
178
  };
179
179
  const modernButtonStyle = {
180
180
  fontWeight: 400,
181
- fontSize: "0.7rem",
181
+ fontSize: "0.65rem",
182
182
  borderRadius: 2,
183
183
  minWidth: 90,
184
184
  textTransform: "none",
@@ -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
- <FilterGod
430
- tableName={tableName}
431
- filters={filters}
432
- filterButtons={filterButtons}
433
- elementSize={elementSize}
434
- setPage={setPage}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trithuc-mvc-react",
3
- "version": "3.3.8",
3
+ "version": "3.4.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
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
  }