trithuc-mvc-react 3.1.8 → 3.2.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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Accordion, AccordionSummary, Box, IconButton, Slider, Typography } from "@mui/material";
|
|
1
|
+
import { Accordion, AccordionSummary, Box, Button, IconButton, Slider, Typography } from "@mui/material";
|
|
2
2
|
import { Grid } from "@mui/material";
|
|
3
3
|
import { useFormContext } from "react-hook-form";
|
|
4
4
|
import { FilterElement } from "./FilterElement";
|
|
@@ -14,7 +14,7 @@ import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
|
|
|
14
14
|
import "dayjs/locale/vi";
|
|
15
15
|
import { toast } from "react-toastify";
|
|
16
16
|
import { debounce } from "lodash";
|
|
17
|
-
export const FilterGod = ({ tableName, filters, elementSize = "small", setPage = () => {} }) => {
|
|
17
|
+
export const FilterGod = ({ tableName, filters, filterButtons, elementSize = "small", setPage = () => {} }) => {
|
|
18
18
|
const { handleSubmit } = useFormContext();
|
|
19
19
|
const onSubmit = (data) => console.log(data);
|
|
20
20
|
const { setDataSearch, dataSearch } = useDataTable();
|
|
@@ -188,6 +188,18 @@ export const FilterGod = ({ tableName, filters, elementSize = "small", setPage =
|
|
|
188
188
|
</Grid>
|
|
189
189
|
);
|
|
190
190
|
})}
|
|
191
|
+
{filterButtons.map(({ title, size, onClick, element, sx }, idx) => (
|
|
192
|
+
<Button
|
|
193
|
+
key={idx}
|
|
194
|
+
size={size}
|
|
195
|
+
variant="outlined"
|
|
196
|
+
onClick={() => onClick({ dataSearch })}
|
|
197
|
+
startIcon={element}
|
|
198
|
+
sx={{ ...sx }}
|
|
199
|
+
>
|
|
200
|
+
{title}
|
|
201
|
+
</Button>
|
|
202
|
+
))}
|
|
191
203
|
</Grid>
|
|
192
204
|
</AccordionDetails>
|
|
193
205
|
</Accordion>
|
|
@@ -79,12 +79,13 @@ export const TableRowRenderSM = ({
|
|
|
79
79
|
)}
|
|
80
80
|
|
|
81
81
|
{/* Các nút thao tác */}
|
|
82
|
-
<Grid container spacing={
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
{
|
|
82
|
+
<Grid container spacing={0.5} sx={{ width: "100%", pt: 2, pb: 2 }}>
|
|
83
|
+
{!disableCellThaoTac && (
|
|
84
|
+
<>
|
|
85
|
+
{!disableEdit && canEdit && (
|
|
86
|
+
<Grid size={4}>
|
|
87
87
|
<Button
|
|
88
|
+
fullWidth
|
|
88
89
|
size="small"
|
|
89
90
|
variant="outlined"
|
|
90
91
|
color="primary"
|
|
@@ -94,9 +95,12 @@ export const TableRowRenderSM = ({
|
|
|
94
95
|
>
|
|
95
96
|
Sửa
|
|
96
97
|
</Button>
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
</Grid>
|
|
99
|
+
)}
|
|
100
|
+
{canView && !tableActions?.some(({ permissionType }) => permissionType === "view") && (
|
|
101
|
+
<Grid size={4}>
|
|
99
102
|
<Button
|
|
103
|
+
fullWidth
|
|
100
104
|
size="small"
|
|
101
105
|
variant="outlined"
|
|
102
106
|
color="info"
|
|
@@ -106,9 +110,12 @@ export const TableRowRenderSM = ({
|
|
|
106
110
|
>
|
|
107
111
|
Xem
|
|
108
112
|
</Button>
|
|
109
|
-
|
|
110
|
-
|
|
113
|
+
</Grid>
|
|
114
|
+
)}
|
|
115
|
+
{!disableDelete && canDelete && (
|
|
116
|
+
<Grid size={4}>
|
|
111
117
|
<Button
|
|
118
|
+
fullWidth
|
|
112
119
|
size="small"
|
|
113
120
|
variant="outlined"
|
|
114
121
|
color="error"
|
|
@@ -118,11 +125,14 @@ export const TableRowRenderSM = ({
|
|
|
118
125
|
>
|
|
119
126
|
Xóa
|
|
120
127
|
</Button>
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
</Grid>
|
|
129
|
+
)}
|
|
130
|
+
{tableActionsOnTable.map(
|
|
131
|
+
({ title, size, onClick, element, visible = true }, idx) =>
|
|
132
|
+
(typeof visible === "function" ? visible(row) : visible) && (
|
|
133
|
+
<Grid size={4}>
|
|
125
134
|
<Button
|
|
135
|
+
fullWidth
|
|
126
136
|
key={idx}
|
|
127
137
|
size="small"
|
|
128
138
|
variant="outlined"
|
|
@@ -134,12 +144,12 @@ export const TableRowRenderSM = ({
|
|
|
134
144
|
>
|
|
135
145
|
{title === "xem chi tiết" ? "Xem" : title}
|
|
136
146
|
</Button>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
</Grid>
|
|
148
|
+
)
|
|
149
|
+
)}
|
|
150
|
+
<MoreMenu actions={tableActionsOnMoreMenu} data={row} />
|
|
151
|
+
</>
|
|
152
|
+
)}
|
|
143
153
|
</Grid>
|
|
144
154
|
</TableCell>
|
|
145
155
|
</TableRow>
|
|
@@ -148,13 +158,13 @@ export const TableRowRenderSM = ({
|
|
|
148
158
|
|
|
149
159
|
// Button style dùng chung
|
|
150
160
|
const buttonStyle = {
|
|
151
|
-
marginLeft: 0.3,
|
|
152
|
-
marginRight: 0.3,
|
|
153
|
-
marginBottom:
|
|
154
|
-
borderRadius:
|
|
161
|
+
// marginLeft: 0.3,
|
|
162
|
+
// marginRight: 0.3,
|
|
163
|
+
marginBottom: "10px",
|
|
164
|
+
borderRadius: "10px",
|
|
155
165
|
minWidth: 50,
|
|
156
|
-
padding: "
|
|
157
|
-
height: "
|
|
166
|
+
padding: "4px 8px",
|
|
167
|
+
height: "23px",
|
|
158
168
|
fontSize: "0.6rem",
|
|
159
169
|
whiteSpace: "nowrap",
|
|
160
170
|
overflow: "hidden",
|
|
@@ -50,7 +50,7 @@ DataManagement.propTypes = {
|
|
|
50
50
|
onChangeAfter: PropTypes.func
|
|
51
51
|
})
|
|
52
52
|
).isRequired,
|
|
53
|
-
|
|
53
|
+
filterButtons: PropTypes.array,
|
|
54
54
|
editorFields: PropTypes.array,
|
|
55
55
|
validationSchema: PropTypes.object,
|
|
56
56
|
disableStatus: PropTypes.bool,
|
|
@@ -65,7 +65,8 @@ DataManagement.propTypes = {
|
|
|
65
65
|
tabPanel: PropTypes.node,
|
|
66
66
|
titleAddButton: PropTypes.string,
|
|
67
67
|
thongKe: PropTypes.object,
|
|
68
|
-
bieuDo: PropTypes.object
|
|
68
|
+
bieuDo: PropTypes.object,
|
|
69
|
+
disableHead: PropTypes.bool
|
|
69
70
|
};
|
|
70
71
|
const getDefaultValues = (filters = []) => {
|
|
71
72
|
const defaultValues = {};
|
|
@@ -84,6 +85,7 @@ function DataManagement({
|
|
|
84
85
|
tableName,
|
|
85
86
|
selectedField = "Id",
|
|
86
87
|
filters: tableFilters = [],
|
|
88
|
+
filterButtons = [],
|
|
87
89
|
editorFields = [],
|
|
88
90
|
validationSchema = {},
|
|
89
91
|
statusKey = "Status",
|
|
@@ -108,7 +110,8 @@ function DataManagement({
|
|
|
108
110
|
defaultRowsPerPage = 5,
|
|
109
111
|
titleAddButton = "Thêm",
|
|
110
112
|
thongKe,
|
|
111
|
-
bieuDo
|
|
113
|
+
bieuDo,
|
|
114
|
+
disableHead = false
|
|
112
115
|
}) {
|
|
113
116
|
const [openEditorDialog, setOpenEditorDialog] = useState(false);
|
|
114
117
|
const [selectedEditItem, setSelectedEditItem] = useState(null);
|
|
@@ -177,7 +180,8 @@ function DataManagement({
|
|
|
177
180
|
defaultRowsPerPage,
|
|
178
181
|
titleAddButton,
|
|
179
182
|
thongKe,
|
|
180
|
-
bieuDo
|
|
183
|
+
bieuDo,
|
|
184
|
+
disableHead
|
|
181
185
|
};
|
|
182
186
|
}, [
|
|
183
187
|
reserPage,
|
|
@@ -198,7 +202,8 @@ function DataManagement({
|
|
|
198
202
|
backParentNavigator,
|
|
199
203
|
defaultRowsPerPage,
|
|
200
204
|
thongKe,
|
|
201
|
-
bieuDo
|
|
205
|
+
bieuDo,
|
|
206
|
+
disableHead
|
|
202
207
|
]);
|
|
203
208
|
const isSmallScreen = useMediaQuery(theme.breakpoints.down("sm")); // Xác định màn hình nhỏ
|
|
204
209
|
const methods = useForm({ defaultValues: getDefaultValues(filters) });
|
|
@@ -297,130 +302,138 @@ function DataManagement({
|
|
|
297
302
|
<>
|
|
298
303
|
<DataTableContext.Provider value={values}>
|
|
299
304
|
<FormProvider {...methods}>
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
mb: upXL ? 1 : 1,
|
|
304
|
-
flexWrap: "wrap",
|
|
305
|
-
alignItems: "center",
|
|
306
|
-
gap: 1,
|
|
307
|
-
...slotProps?.header?.sx
|
|
308
|
-
}}
|
|
309
|
-
>
|
|
310
|
-
{/* Khối trái */}
|
|
311
|
-
<Box
|
|
312
|
-
sx={{
|
|
313
|
-
flexGrow: 1,
|
|
314
|
-
Width: `${minWidthValue}px`,
|
|
315
|
-
textAlign: "left",
|
|
316
|
-
whiteSpace: "normal",
|
|
317
|
-
wordBreak: "break-word"
|
|
318
|
-
}}
|
|
319
|
-
>
|
|
320
|
-
<Typography variant={isSmallScreen ? "body2" : "subtitle1"}>{titleText}</Typography>
|
|
321
|
-
</Box>
|
|
322
|
-
|
|
323
|
-
{/* Khối phải */}
|
|
324
|
-
<Box
|
|
325
|
-
ref={rightBoxRef} // Tham chiếu đến phần tử này
|
|
305
|
+
{!disableHead && (
|
|
306
|
+
<Stack
|
|
307
|
+
direction="row"
|
|
326
308
|
sx={{
|
|
327
|
-
|
|
328
|
-
flexWrap: "
|
|
329
|
-
justifyContent: "flex-end",
|
|
309
|
+
mb: upXL ? 1 : 1,
|
|
310
|
+
flexWrap: "wrap",
|
|
330
311
|
alignItems: "center",
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
width: rightBoxMinWidth ? `${rightBoxMinWidth}px` : "auto" // Sử dụng chiều rộng đo được
|
|
312
|
+
gap: 1,
|
|
313
|
+
...slotProps?.header?.sx
|
|
334
314
|
}}
|
|
335
315
|
>
|
|
336
|
-
{
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
316
|
+
{/* Khối trái */}
|
|
317
|
+
<Box
|
|
318
|
+
sx={{
|
|
319
|
+
flexGrow: 1,
|
|
320
|
+
Width: `${minWidthValue}px`,
|
|
321
|
+
textAlign: "left",
|
|
322
|
+
whiteSpace: "normal",
|
|
323
|
+
wordBreak: "break-word"
|
|
324
|
+
}}
|
|
325
|
+
>
|
|
326
|
+
<Typography variant={isSmallScreen ? "body2" : "subtitle1"}>{titleText}</Typography>
|
|
327
|
+
</Box>
|
|
328
|
+
|
|
329
|
+
{/* Khối phải */}
|
|
330
|
+
<Box
|
|
331
|
+
ref={rightBoxRef} // Tham chiếu đến phần tử này
|
|
332
|
+
sx={{
|
|
333
|
+
display: "flex",
|
|
334
|
+
flexWrap: "nowrap",
|
|
335
|
+
justifyContent: "flex-end",
|
|
336
|
+
alignItems: "center",
|
|
337
|
+
flexShrink: 0,
|
|
338
|
+
// minWidth: "300px", // Đảm bảo chiều rộng tối thiểu
|
|
339
|
+
width: rightBoxMinWidth ? `${rightBoxMinWidth}px` : "auto" // Sử dụng chiều rộng đo được
|
|
340
|
+
}}
|
|
341
|
+
>
|
|
342
|
+
{(viewMode === "thongke" || viewMode === "bieudo") && (
|
|
343
|
+
<Tooltip title="Danh sách dữ liệu">
|
|
344
|
+
<IconButton size={elementSize} color="primary" onClick={() => setViewMode("table")} sx={{ ml: 0.5, mr: 0.5 }}>
|
|
345
|
+
<TableChartIcon fontSize="inherit" />
|
|
346
|
+
</IconButton>
|
|
347
|
+
</Tooltip>
|
|
348
|
+
)}
|
|
349
|
+
|
|
350
|
+
{canThongKe && (
|
|
351
|
+
<Tooltip title="Thống kê">
|
|
352
|
+
<IconButton
|
|
353
|
+
size={elementSize}
|
|
354
|
+
color={viewMode === "thongke" ? "secondary" : "primary"}
|
|
355
|
+
onClick={() => setViewMode("thongke")}
|
|
356
|
+
sx={{ ml: 0.5, mr: 0.5 }}
|
|
357
|
+
>
|
|
358
|
+
<BarChartIcon fontSize="inherit" />
|
|
359
|
+
</IconButton>
|
|
360
|
+
</Tooltip>
|
|
361
|
+
)}
|
|
362
|
+
|
|
363
|
+
{canBieuDo && (
|
|
364
|
+
<Tooltip title="Biểu đồ">
|
|
365
|
+
<IconButton
|
|
366
|
+
size={elementSize}
|
|
367
|
+
color={viewMode === "bieudo" ? "secondary" : "primary"}
|
|
368
|
+
onClick={() => setViewMode("bieudo")}
|
|
369
|
+
sx={{ ml: 0.5, mr: 0.5 }}
|
|
370
|
+
>
|
|
371
|
+
<PieChartIcon fontSize="inherit" />
|
|
372
|
+
</IconButton>
|
|
373
|
+
</Tooltip>
|
|
374
|
+
)}
|
|
343
375
|
|
|
344
|
-
|
|
345
|
-
<Tooltip title="
|
|
376
|
+
<HuongDanButton tableName={tableName} size={elementSize} />
|
|
377
|
+
<Tooltip title="Làm mới">
|
|
346
378
|
<IconButton
|
|
379
|
+
variant="outlined"
|
|
380
|
+
color="primary"
|
|
347
381
|
size={elementSize}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
382
|
+
onClick={() => {
|
|
383
|
+
setDataSearch({ ...defaults });
|
|
384
|
+
[...filters].forEach((filter) => {
|
|
385
|
+
filter?.onChange?.();
|
|
386
|
+
});
|
|
387
|
+
reset();
|
|
388
|
+
setValue("Search");
|
|
389
|
+
}}
|
|
351
390
|
>
|
|
352
|
-
<
|
|
391
|
+
<Refresh fontSize="inherit" />
|
|
353
392
|
</IconButton>
|
|
354
393
|
</Tooltip>
|
|
355
|
-
)}
|
|
356
394
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
395
|
+
{titleButtons?.map((button, index) => (
|
|
396
|
+
<div key={index}>{button}</div>
|
|
397
|
+
))}
|
|
398
|
+
|
|
399
|
+
<ExportExcelButton tableName={tableName} data={dataSearch} size={elementSize} />
|
|
400
|
+
|
|
401
|
+
{canCreate && !disableAdd && (
|
|
402
|
+
<Button
|
|
360
403
|
size={elementSize}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
404
|
+
variant="contained"
|
|
405
|
+
startIcon={<Add fontSize="inherit" />}
|
|
406
|
+
onClick={(e) => {
|
|
407
|
+
if (!disableEditor) {
|
|
408
|
+
setOpenEditorDialog(true);
|
|
409
|
+
setSelectedEditItem(null);
|
|
410
|
+
}
|
|
411
|
+
onAddClick(e);
|
|
412
|
+
}}
|
|
413
|
+
sx={{
|
|
414
|
+
ml: 0.5,
|
|
415
|
+
mr: 0.5,
|
|
416
|
+
minWidth: "73px"
|
|
417
|
+
}}
|
|
364
418
|
>
|
|
365
|
-
|
|
366
|
-
</
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
<Tooltip title="Làm mới">
|
|
372
|
-
<IconButton
|
|
373
|
-
variant="outlined"
|
|
374
|
-
color="primary"
|
|
375
|
-
size={elementSize}
|
|
376
|
-
onClick={() => {
|
|
377
|
-
setDataSearch({ ...defaults });
|
|
378
|
-
[...filters].forEach((filter) => {
|
|
379
|
-
filter?.onChange?.();
|
|
380
|
-
});
|
|
381
|
-
reset();
|
|
382
|
-
setValue("Search");
|
|
383
|
-
}}
|
|
384
|
-
>
|
|
385
|
-
<Refresh fontSize="inherit" />
|
|
386
|
-
</IconButton>
|
|
387
|
-
</Tooltip>
|
|
388
|
-
|
|
389
|
-
{titleButtons?.map((button, index) => (
|
|
390
|
-
<div key={index}>{button}</div>
|
|
391
|
-
))}
|
|
392
|
-
|
|
393
|
-
<ExportExcelButton tableName={tableName} data={dataSearch} size={elementSize} />
|
|
394
|
-
|
|
395
|
-
{canCreate && !disableAdd && (
|
|
396
|
-
<Button
|
|
397
|
-
size={elementSize}
|
|
398
|
-
variant="contained"
|
|
399
|
-
startIcon={<Add fontSize="inherit" />}
|
|
400
|
-
onClick={(e) => {
|
|
401
|
-
if (!disableEditor) {
|
|
402
|
-
setOpenEditorDialog(true);
|
|
403
|
-
setSelectedEditItem(null);
|
|
404
|
-
}
|
|
405
|
-
onAddClick(e);
|
|
406
|
-
}}
|
|
407
|
-
sx={{
|
|
408
|
-
ml: 0.5,
|
|
409
|
-
mr: 0.5,
|
|
410
|
-
minWidth: "73px"
|
|
411
|
-
}}
|
|
412
|
-
>
|
|
413
|
-
{titleAddButton}
|
|
414
|
-
</Button>
|
|
415
|
-
)}
|
|
416
|
-
</Box>
|
|
417
|
-
</Stack>
|
|
419
|
+
{titleAddButton}
|
|
420
|
+
</Button>
|
|
421
|
+
)}
|
|
422
|
+
</Box>
|
|
423
|
+
</Stack>
|
|
424
|
+
)}
|
|
418
425
|
|
|
419
426
|
<Card className="custom-card-DataManagement">
|
|
420
427
|
{tabPanel}
|
|
421
428
|
{viewMode === "table" && (
|
|
422
429
|
<>
|
|
423
|
-
<FilterGod
|
|
430
|
+
<FilterGod
|
|
431
|
+
tableName={tableName}
|
|
432
|
+
filters={filters}
|
|
433
|
+
filterButtons={filterButtons}
|
|
434
|
+
elementSize={elementSize}
|
|
435
|
+
setPage={setPage}
|
|
436
|
+
/>
|
|
424
437
|
{backParentNavigator}
|
|
425
438
|
{!isSmallScreen ? (
|
|
426
439
|
<DataTable
|