trithuc-mvc-react 1.8.7 → 1.8.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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Table, TableBody, TableCell, TableContainer, TableRow, useMediaQuery, useTheme } from "@mui/material";
|
|
1
|
+
import { Grid, Table, TableBody, TableCell, TableContainer, TableRow, Typography, useMediaQuery, useTheme } from "@mui/material";
|
|
2
2
|
import TablePaginationCustom from "../table/TablePagination";
|
|
3
3
|
import { useEffect, useMemo, useState } from "react";
|
|
4
4
|
|
|
@@ -14,223 +14,236 @@ import TableToolbar from "./TableToolbar";
|
|
|
14
14
|
import { useDataTable } from "./hooks";
|
|
15
15
|
import { usePermission } from "../../hooks";
|
|
16
16
|
const DataTable = ({ multipleActions = [] }) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const changeStatusMutation = useMutation(changeStatusDataToTable, {
|
|
53
|
-
onSuccess: () => {
|
|
54
|
-
toast.success("Thay đổi trạng thái thành công !");
|
|
55
|
-
queryClient.invalidateQueries({ queryKey: [tableName] });
|
|
56
|
-
},
|
|
57
|
-
onError: () => {
|
|
58
|
-
toast.error(" Có lỗi xảy ra !");
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
const deleteMutation = useMutation(deleteDataFromTable, {
|
|
62
|
-
onSuccess: ({ status }) => {
|
|
63
|
-
if (status) {
|
|
64
|
-
toast.success("Xóa thành công !");
|
|
65
|
-
} else {
|
|
66
|
-
toast.error(" Có lỗi xảy ra !");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
queryClient.invalidateQueries({ queryKey: [tableName] });
|
|
70
|
-
},
|
|
71
|
-
onError: () => {
|
|
72
|
-
toast.error(" Có lỗi xảy ra !");
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
const deleteMultipleMutation = useMutation(deleteMultipleDataFromTable, {
|
|
76
|
-
onSuccess: () => {
|
|
77
|
-
toast.success("Xóa thành công !");
|
|
78
|
-
setSelectedItems([]);
|
|
79
|
-
queryClient.invalidateQueries({ queryKey: [tableName] });
|
|
80
|
-
},
|
|
81
|
-
onError: () => {
|
|
82
|
-
toast.error(" Có lỗi xảy ra !");
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
const handleDelete = (id) => {
|
|
87
|
-
confirm({ description: "Bạn có chắc chắn muốn xóa bản ghi này không?", title: "Xác nhận" })
|
|
88
|
-
.then(() => {
|
|
89
|
-
deleteMutation.mutate({
|
|
90
|
-
id,
|
|
91
|
-
tableName
|
|
92
|
-
});
|
|
93
|
-
})
|
|
94
|
-
.catch(() => {});
|
|
95
|
-
};
|
|
96
|
-
const handleChangeStatus = (Id) => {
|
|
97
|
-
changeStatusMutation.mutate({
|
|
98
|
-
tableName,
|
|
99
|
-
id: Id
|
|
17
|
+
const {
|
|
18
|
+
tableName,
|
|
19
|
+
selectedField,
|
|
20
|
+
columns,
|
|
21
|
+
dataSearch,
|
|
22
|
+
setOpenEditorDialog,
|
|
23
|
+
setSelectedEditItem,
|
|
24
|
+
setOpenViewDialog,
|
|
25
|
+
onEditClick,
|
|
26
|
+
hasTabpanel
|
|
27
|
+
} = useDataTable();
|
|
28
|
+
|
|
29
|
+
const { set: setPermission } = usePermission(tableName);
|
|
30
|
+
const queryClient = useQueryClient();
|
|
31
|
+
const confirm = useConfirm();
|
|
32
|
+
const [selectedItems, setSelectedItems] = useState([]);
|
|
33
|
+
const [page, setPage] = useState(0);
|
|
34
|
+
const [rowsPerPage, setRowsPerPage] = useState(5);
|
|
35
|
+
|
|
36
|
+
const { data, isLoading } = useQuery({
|
|
37
|
+
queryKey: [tableName, page, rowsPerPage, dataSearch],
|
|
38
|
+
queryFn: () =>
|
|
39
|
+
getDatasFromTable({
|
|
40
|
+
tableName: tableName,
|
|
41
|
+
page: page + 1,
|
|
42
|
+
pageSize: rowsPerPage,
|
|
43
|
+
data: dataSearch
|
|
44
|
+
}),
|
|
45
|
+
// keepPreviousData: true,
|
|
46
|
+
onSuccess: ({ PermissionModel, status }) => {
|
|
47
|
+
if (status) {
|
|
48
|
+
// setPermission(PermissionModel);
|
|
49
|
+
// console.log("LOAD LAI PermissionModel");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
100
52
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
53
|
+
const changeStatusMutation = useMutation(changeStatusDataToTable, {
|
|
54
|
+
onSuccess: () => {
|
|
55
|
+
toast.success("Thay đổi trạng thái thành công !");
|
|
56
|
+
queryClient.invalidateQueries({ queryKey: [tableName] });
|
|
57
|
+
},
|
|
58
|
+
onError: () => {
|
|
59
|
+
toast.error(" Có lỗi xảy ra !");
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
const deleteMutation = useMutation(deleteDataFromTable, {
|
|
63
|
+
onSuccess: ({ status }) => {
|
|
64
|
+
if (status) {
|
|
65
|
+
toast.success("Xóa thành công !");
|
|
66
|
+
} else {
|
|
67
|
+
toast.error(" Có lỗi xảy ra !");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
queryClient.invalidateQueries({ queryKey: [tableName] });
|
|
71
|
+
},
|
|
72
|
+
onError: () => {
|
|
73
|
+
toast.error(" Có lỗi xảy ra !");
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
const deleteMultipleMutation = useMutation(deleteMultipleDataFromTable, {
|
|
77
|
+
onSuccess: () => {
|
|
78
|
+
toast.success("Xóa thành công !");
|
|
79
|
+
setSelectedItems([]);
|
|
80
|
+
queryClient.invalidateQueries({ queryKey: [tableName] });
|
|
81
|
+
},
|
|
82
|
+
onError: () => {
|
|
83
|
+
toast.error(" Có lỗi xảy ra !");
|
|
84
|
+
}
|
|
128
85
|
});
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
86
|
+
|
|
87
|
+
const handleDelete = (id) => {
|
|
88
|
+
confirm({ description: "Bạn có chắc chắn muốn xóa bản ghi này không?", title: "Xác nhận" })
|
|
89
|
+
.then(() => {
|
|
90
|
+
deleteMutation.mutate({
|
|
91
|
+
id,
|
|
92
|
+
tableName
|
|
93
|
+
});
|
|
94
|
+
})
|
|
95
|
+
.catch(() => {});
|
|
96
|
+
};
|
|
97
|
+
const handleChangeStatus = (Id) => {
|
|
98
|
+
changeStatusMutation.mutate({
|
|
99
|
+
tableName,
|
|
100
|
+
id: Id
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
const handlEdit = (item) => {
|
|
104
|
+
setOpenEditorDialog(true);
|
|
105
|
+
setSelectedEditItem(item);
|
|
106
|
+
onEditClick(item);
|
|
107
|
+
};
|
|
108
|
+
const handlViewDetail = (item) => {
|
|
109
|
+
setOpenViewDialog(true);
|
|
110
|
+
setSelectedEditItem(item);
|
|
111
|
+
};
|
|
112
|
+
const { rows, total } = useMemo(() => {
|
|
113
|
+
let rows = data?.data ?? [];
|
|
114
|
+
let total = data?.total ?? 0;
|
|
115
|
+
return {
|
|
116
|
+
rows: rows,
|
|
117
|
+
total
|
|
118
|
+
};
|
|
119
|
+
}, [data]);
|
|
120
|
+
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
let PermissionModel = data?.PermissionModel;
|
|
123
|
+
PermissionModel && setPermission(PermissionModel);
|
|
124
|
+
}, [data]);
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
const newSelectedItems = selectedItems.filter((selectedId) => {
|
|
127
|
+
return rows?.some((row) => row.Id == selectedId);
|
|
171
128
|
});
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
129
|
+
setSelectedItems(newSelectedItems);
|
|
130
|
+
}, [rows]);
|
|
131
|
+
const handleChangePage = (event, newPage) => {
|
|
132
|
+
setPage(newPage);
|
|
133
|
+
};
|
|
134
|
+
const isSelected = (Id) => selectedItems.indexOf(Id) !== -1;
|
|
135
|
+
|
|
136
|
+
const handleSelect = (event, Id) => {
|
|
137
|
+
const selectedIndex = selectedItems.indexOf(Id);
|
|
138
|
+
let newSelected = [];
|
|
139
|
+
|
|
140
|
+
if (selectedIndex === -1) {
|
|
141
|
+
newSelected = newSelected.concat(selectedItems, Id);
|
|
142
|
+
} else if (selectedIndex === 0) {
|
|
143
|
+
newSelected = newSelected.concat(selectedItems.slice(1));
|
|
144
|
+
} else if (selectedIndex === selectedItems.length - 1) {
|
|
145
|
+
newSelected = newSelected.concat(selectedItems.slice(0, -1));
|
|
146
|
+
} else if (selectedIndex > 0) {
|
|
147
|
+
newSelected = newSelected.concat(selectedItems.slice(0, selectedIndex), selectedItems.slice(selectedIndex + 1));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
setSelectedItems(newSelected);
|
|
151
|
+
};
|
|
152
|
+
const handleSelectAllClick = (event) => {
|
|
153
|
+
if (event.target.checked) {
|
|
154
|
+
const newSelected = rows.map((n) => n[selectedField]);
|
|
155
|
+
setSelectedItems(newSelected);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
setSelectedItems([]);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const handleChangeRowsPerPage = (event) => {
|
|
162
|
+
setRowsPerPage(parseInt(event.target.value, 10));
|
|
163
|
+
setPage(0);
|
|
164
|
+
};
|
|
165
|
+
const handleDeleteMultiple = () => {
|
|
166
|
+
confirm({ description: `Bạn có chắc chắn muốn xóa ${selectedItems?.length} bản ghi này không?`, title: "Xác nhận" })
|
|
167
|
+
.then(() => {
|
|
168
|
+
deleteMultipleMutation.mutate({
|
|
169
|
+
tableName,
|
|
170
|
+
ids: selectedItems
|
|
171
|
+
});
|
|
172
|
+
})
|
|
173
|
+
.catch(() => {});
|
|
174
|
+
};
|
|
175
|
+
const theme = useTheme();
|
|
176
|
+
const downXL = useMediaQuery(theme.breakpoints.down("xl"));
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<>
|
|
180
|
+
<TableContainer sx={{ position: "relative" }}>
|
|
181
|
+
<TableToolbar
|
|
182
|
+
onSelectAllClick={handleSelectAllClick}
|
|
183
|
+
numSelected={selectedItems?.length}
|
|
184
|
+
rowCount={rows.length}
|
|
185
|
+
onDeleteMultiple={handleDeleteMultiple}
|
|
186
|
+
selected={selectedItems}
|
|
187
|
+
multipleActions={multipleActions}
|
|
212
188
|
/>
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
189
|
+
|
|
190
|
+
<Table className="border" size={downXL ? "small" : "medium"}>
|
|
191
|
+
<TableHead
|
|
192
|
+
headLabel={columns}
|
|
193
|
+
onSelectAllClick={handleSelectAllClick}
|
|
194
|
+
numSelected={selectedItems?.length}
|
|
195
|
+
rowCount={rows.length}
|
|
196
|
+
/>
|
|
197
|
+
{isLoading ? (
|
|
198
|
+
<TableRowsLoader rowsNum={5} colsNum={columns.length + 4} />
|
|
199
|
+
) : (
|
|
200
|
+
<TableBody>
|
|
201
|
+
{[...rows].map((row, index) => (
|
|
202
|
+
<TableRowRender
|
|
203
|
+
key={row.Id}
|
|
204
|
+
index={index}
|
|
205
|
+
row={row}
|
|
206
|
+
selected={isSelected(row[selectedField])}
|
|
207
|
+
onSelect={handleSelect}
|
|
208
|
+
onEdit={handlEdit}
|
|
209
|
+
onView={handlViewDetail}
|
|
210
|
+
onChangeStatus={handleChangeStatus}
|
|
211
|
+
onDelete={handleDelete}
|
|
212
|
+
/>
|
|
213
|
+
))}
|
|
214
|
+
|
|
215
|
+
{rows?.length == 0 && (
|
|
216
|
+
<TableRow>
|
|
217
|
+
<TableCell colSpan={columns.length + 4} align="center">
|
|
218
|
+
Không có dữ liệu
|
|
219
|
+
</TableCell>
|
|
220
|
+
</TableRow>
|
|
221
|
+
)}
|
|
222
|
+
</TableBody>
|
|
223
|
+
)}
|
|
224
|
+
</Table>
|
|
225
|
+
</TableContainer>
|
|
226
|
+
|
|
227
|
+
<Grid container>
|
|
228
|
+
{!hasTabpanel && (
|
|
229
|
+
<Grid item alignSelf={"center"} sx={{ pl: 2 }}>
|
|
230
|
+
<Typography variant="body1">
|
|
231
|
+
Tổng số lượng: <span>{total}</span>
|
|
232
|
+
</Typography>
|
|
233
|
+
</Grid>
|
|
234
|
+
)}
|
|
235
|
+
|
|
236
|
+
<Grid item xs>
|
|
237
|
+
<TablePaginationCustom
|
|
238
|
+
count={total}
|
|
239
|
+
rowsPerPage={rowsPerPage}
|
|
240
|
+
page={page}
|
|
241
|
+
onPageChange={handleChangePage}
|
|
242
|
+
onRowsPerPageChange={handleChangeRowsPerPage}
|
|
243
|
+
/>
|
|
244
|
+
</Grid>
|
|
245
|
+
</Grid>
|
|
246
|
+
</>
|
|
247
|
+
);
|
|
235
248
|
};
|
|
236
249
|
export default DataTable;
|
|
@@ -16,189 +16,191 @@ import { FilterGod } from "./FilterGod";
|
|
|
16
16
|
import { usePermission } from "../../hooks";
|
|
17
17
|
|
|
18
18
|
DataManagement.propTypes = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
19
|
+
columns: PropTypes.array,
|
|
20
|
+
title: PropTypes.string,
|
|
21
|
+
tableName: PropTypes.string,
|
|
22
|
+
selectedField: PropTypes.string,
|
|
23
|
+
filters: PropTypes.arrayOf(
|
|
24
|
+
PropTypes.shape({
|
|
25
|
+
field: PropTypes.string,
|
|
26
|
+
label: PropTypes.string,
|
|
27
|
+
placeHolder: PropTypes.string,
|
|
28
|
+
type: PropTypes.oneOf(["text", "number", "date", "autocomplete", "checkbox", "radio", "switch"]),
|
|
29
|
+
onChangeAfter: PropTypes.func,
|
|
30
|
+
filters: PropTypes.array
|
|
31
|
+
})
|
|
32
|
+
),
|
|
33
|
+
editorFields: PropTypes.array,
|
|
34
|
+
validationSchema: PropTypes.object,
|
|
35
|
+
disableStatus: PropTypes.bool,
|
|
36
|
+
disableAdd: PropTypes.bool,
|
|
37
|
+
disableCellThaoTac: PropTypes.bool,
|
|
38
|
+
statusKey: PropTypes.string,
|
|
39
|
+
tableActions: PropTypes.array,
|
|
40
|
+
disableEditor: PropTypes.bool,
|
|
41
|
+
onAddClick: PropTypes.func,
|
|
42
|
+
onEditClick: PropTypes.func,
|
|
43
|
+
tabPanel: PropTypes.node
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
function DataManagement({
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
47
|
+
columns = [],
|
|
48
|
+
title,
|
|
49
|
+
tableName,
|
|
50
|
+
selectedField = "Id",
|
|
51
|
+
filters: tableFilters = [],
|
|
52
|
+
editorFields = [],
|
|
53
|
+
validationSchema = {},
|
|
54
|
+
statusKey = "Status",
|
|
55
|
+
disableStatus = false,
|
|
56
|
+
disableAdd = false,
|
|
57
|
+
disableCellThaoTac = false,
|
|
58
|
+
|
|
59
|
+
tableActions = [],
|
|
60
|
+
multipleActions = [],
|
|
61
|
+
|
|
62
|
+
disableEditor = false,
|
|
63
|
+
onAddClick = () => {},
|
|
64
|
+
onEditClick = () => {},
|
|
65
|
+
tabPanel,
|
|
66
|
+
backParentNavigator,
|
|
67
|
+
slotProps = {
|
|
68
|
+
header: {
|
|
69
|
+
sx: {}
|
|
70
|
+
}
|
|
70
71
|
}
|
|
71
|
-
}
|
|
72
72
|
}) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
73
|
+
const [openEditorDialog, setOpenEditorDialog] = useState(false);
|
|
74
|
+
const [selectedEditItem, setSelectedEditItem] = useState(null);
|
|
75
|
+
const [openViewDialog, setOpenViewDialog] = useState(false);
|
|
76
|
+
|
|
77
|
+
const { canCreate } = usePermission(tableName);
|
|
78
|
+
const { defaults, filters } = useMemo(() => {
|
|
79
|
+
const filters = tableFilters.filter(({ type }) => type !== "default");
|
|
80
|
+
const defaultFilters = tableFilters.filter(({ type }) => type === "default");
|
|
81
|
+
|
|
82
|
+
const defaults = defaultFilters.reduce((prev, { field, value }) => {
|
|
83
|
+
prev[field] = value;
|
|
84
|
+
return prev;
|
|
85
|
+
}, {});
|
|
86
|
+
return { defaults, filters };
|
|
87
|
+
}, [tableFilters]);
|
|
88
|
+
|
|
89
|
+
const theme = useTheme();
|
|
90
|
+
const upXL = useMediaQuery(theme.breakpoints.up("xl"));
|
|
91
|
+
const elementSize = useMemo(() => {
|
|
92
|
+
const elementSize = upXL ? "medium" : "small";
|
|
93
|
+
return elementSize;
|
|
94
|
+
}, [upXL]);
|
|
95
|
+
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
setDataSearch({ ...dataSearch, ...defaults });
|
|
98
|
+
}, [filters]);
|
|
99
|
+
|
|
100
|
+
const [dataSearch, setDataSearch] = useState({ ...defaults });
|
|
101
|
+
const values = useMemo(() => {
|
|
102
|
+
const hasTabpanel = !!tabPanel;
|
|
103
|
+
return {
|
|
104
|
+
tableName,
|
|
105
|
+
selectedField,
|
|
106
|
+
columns,
|
|
107
|
+
selectedEditItem,
|
|
108
|
+
setSelectedEditItem,
|
|
109
|
+
setOpenEditorDialog,
|
|
110
|
+
setOpenViewDialog,
|
|
111
|
+
dataSearch,
|
|
112
|
+
setDataSearch,
|
|
113
|
+
validationSchema,
|
|
114
|
+
statusKey,
|
|
115
|
+
disableStatus,
|
|
116
|
+
disableCellThaoTac,
|
|
117
|
+
disableAdd,
|
|
118
|
+
tableActions,
|
|
119
|
+
onEditClick,
|
|
120
|
+
hasTabpanel
|
|
121
|
+
};
|
|
122
|
+
}, [
|
|
123
|
+
tableName,
|
|
124
|
+
selectedField,
|
|
125
|
+
columns,
|
|
126
|
+
selectedEditItem,
|
|
127
|
+
dataSearch,
|
|
128
|
+
setDataSearch,
|
|
129
|
+
validationSchema,
|
|
130
|
+
tableActions,
|
|
131
|
+
openViewDialog,
|
|
132
|
+
setOpenViewDialog,
|
|
133
|
+
onEditClick,
|
|
134
|
+
]);
|
|
135
|
+
|
|
136
|
+
const methods = useForm({ defaultValues: {} });
|
|
137
|
+
const { reset, setValue } = methods;
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<>
|
|
141
|
+
<DataTableContext.Provider value={values}>
|
|
142
|
+
<FormProvider {...methods}>
|
|
143
|
+
<Stack direction="row" justifyContent={"space-between"} sx={{ mb: upXL ? 2 : 1, ...slotProps?.header?.sx }}>
|
|
144
|
+
<Typography variant="h4">{title}</Typography>
|
|
145
|
+
<Stack direction="row" spacing={1}>
|
|
146
|
+
<Tooltip title="Làm mới">
|
|
147
|
+
<IconButton
|
|
148
|
+
variant="outlined"
|
|
149
|
+
color="primary"
|
|
150
|
+
size={elementSize}
|
|
151
|
+
onClick={() => {
|
|
152
|
+
setDataSearch({ ...defaults });
|
|
153
|
+
[...filters].forEach((filter) => {
|
|
154
|
+
filter?.onChange?.();
|
|
155
|
+
});
|
|
156
|
+
reset();
|
|
157
|
+
setValue("Search");
|
|
158
|
+
}}
|
|
159
|
+
>
|
|
160
|
+
<Refresh fontSize="inherit" />
|
|
161
|
+
</IconButton>
|
|
162
|
+
</Tooltip>
|
|
163
|
+
|
|
164
|
+
<ExportExcelButton tableName={tableName} data={dataSearch} size={elementSize} />
|
|
165
|
+
{canCreate && !disableAdd && (
|
|
166
|
+
<Button
|
|
167
|
+
size={elementSize}
|
|
168
|
+
variant="contained"
|
|
169
|
+
startIcon={<Add fontSize="inherit" />}
|
|
170
|
+
onClick={(e) => {
|
|
171
|
+
if (!disableEditor) {
|
|
172
|
+
setOpenEditorDialog(true);
|
|
173
|
+
setSelectedEditItem(null);
|
|
174
|
+
}
|
|
175
|
+
onAddClick(e);
|
|
176
|
+
}}
|
|
177
|
+
>
|
|
178
|
+
Thêm
|
|
179
|
+
</Button>
|
|
180
|
+
)}
|
|
181
|
+
</Stack>
|
|
182
|
+
</Stack>
|
|
183
|
+
|
|
184
|
+
<Card>
|
|
185
|
+
{tabPanel}
|
|
186
|
+
<FilterGod filters={filters} elementSize={elementSize} />
|
|
187
|
+
{backParentNavigator}
|
|
188
|
+
|
|
189
|
+
<DataTable multipleActions={multipleActions} />
|
|
190
|
+
</Card>
|
|
191
|
+
</FormProvider>
|
|
192
|
+
|
|
193
|
+
{disableEditor || (
|
|
194
|
+
<EditorDialog
|
|
195
|
+
open={openEditorDialog}
|
|
196
|
+
onClose={() => setOpenEditorDialog(false)}
|
|
197
|
+
defaultValues={selectedEditItem}
|
|
198
|
+
fields={editorFields}
|
|
199
|
+
/>
|
|
200
|
+
)}
|
|
201
|
+
<ViewDetailDialog open={openViewDialog} onClose={() => setOpenViewDialog(false)} fields={editorFields} />
|
|
202
|
+
</DataTableContext.Provider>
|
|
203
|
+
</>
|
|
204
|
+
);
|
|
203
205
|
}
|
|
204
206
|
export default DataManagement;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TablePagination, useMediaQuery, useTheme } from "@mui/material";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
3
|
|
|
4
4
|
TablePaginationCustom.propsType = {
|
|
@@ -8,38 +8,27 @@ TablePaginationCustom.propsType = {
|
|
|
8
8
|
onPageChange: PropTypes.func,
|
|
9
9
|
onRowsPerPageChange: PropTypes.func
|
|
10
10
|
};
|
|
11
|
-
|
|
11
|
+
function defaultLabelDisplayedRows({ from, to, count }) {
|
|
12
|
+
return `${from}–${to} của ${count !== -1 ? count : `more than ${to}`}`;
|
|
13
|
+
}
|
|
12
14
|
function TablePaginationCustom({ count, rowsPerPage, page, onPageChange, onRowsPerPageChange, ...rest }) {
|
|
13
15
|
const theme = useTheme();
|
|
14
16
|
const matchsDownMD = useMediaQuery(theme.breakpoints.down("md"));
|
|
15
17
|
return (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
page={page}
|
|
31
|
-
onPageChange={onPageChange}
|
|
32
|
-
onRowsPerPageChange={onRowsPerPageChange}
|
|
33
|
-
showFirstButton={true}
|
|
34
|
-
showLastButton={true}
|
|
35
|
-
labelRowsPerPage={matchsDownMD ? "Số hàng" : "Số bản ghi trên trang:"}
|
|
36
|
-
labelDisplayedRows={function defaultLabelDisplayedRows({ from, to, count }) {
|
|
37
|
-
return `${from}–${to} của ${count !== -1 ? count : `more than ${to}`}`;
|
|
38
|
-
}}
|
|
39
|
-
/>
|
|
40
|
-
</Grid>
|
|
41
|
-
</Grid>
|
|
42
|
-
</>
|
|
18
|
+
<TablePagination
|
|
19
|
+
{...rest}
|
|
20
|
+
rowsPerPageOptions={[5, 10, 25, 100]}
|
|
21
|
+
component="div"
|
|
22
|
+
count={count}
|
|
23
|
+
rowsPerPage={rowsPerPage}
|
|
24
|
+
page={page}
|
|
25
|
+
onPageChange={onPageChange}
|
|
26
|
+
onRowsPerPageChange={onRowsPerPageChange}
|
|
27
|
+
showFirstButton={true}
|
|
28
|
+
showLastButton={true}
|
|
29
|
+
labelRowsPerPage={matchsDownMD ? "Số hàng" : "Số bản ghi trên trang:"}
|
|
30
|
+
labelDisplayedRows={defaultLabelDisplayedRows}
|
|
31
|
+
/>
|
|
43
32
|
);
|
|
44
33
|
}
|
|
45
34
|
export default TablePaginationCustom;
|