trithuc-mvc-react 3.0.0 → 3.0.2
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 +14 -0
- package/components/DataManagement/DataTableSM.jsx +15 -1
- package/components/DataManagement/ExportExcelButton.jsx +12 -13
- package/components/DataManagement/FilterGod.jsx +1 -1
- package/components/DataManagement/TableRowRender.jsx +19 -7
- package/components/DataManagement/TableRowRenderSM.jsx +105 -113
- package/components/DataManagement/index.jsx +57 -54
- package/package.json +1 -1
|
@@ -14,6 +14,14 @@ import { usePermission } from "../../hooks";
|
|
|
14
14
|
import { TableRowRender } from "./TableRowRender";
|
|
15
15
|
import TableToolbar from "./TableToolbar";
|
|
16
16
|
import { useDataTable } from "./hooks";
|
|
17
|
+
const defaultQueryOptions = {
|
|
18
|
+
keepPreviousData: true, // Giữ dữ liệu cũ trong khi tải dữ liệu mới
|
|
19
|
+
staleTime: 1000 * 60 * 1, // Thời gian dữ liệu có thể sử dụng lại trước khi gọi lại API
|
|
20
|
+
cacheTime: 1000 * 60 * 30, // Thời gian dữ liệu được lưu trong cache trước khi bị xóa
|
|
21
|
+
refetchOnWindowFocus: true, // Tự động lấy lại dữ liệu khi người dùng quay lại tab
|
|
22
|
+
refetchInterval: 1000 * 30, // Mỗi 30 giây
|
|
23
|
+
keepPreviousData: true
|
|
24
|
+
};
|
|
17
25
|
const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit, disableDelete }) => {
|
|
18
26
|
const {
|
|
19
27
|
tableName,
|
|
@@ -44,6 +52,7 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
44
52
|
pageSize: rowsPerPage,
|
|
45
53
|
data: dataSearch
|
|
46
54
|
}),
|
|
55
|
+
defaultQueryOptions,
|
|
47
56
|
// keepPreviousData: true,
|
|
48
57
|
onSuccess: ({ PermissionModel, status }) => {
|
|
49
58
|
if (dataSearch?.TrangThaiXuLy !== undefined) {
|
|
@@ -52,6 +61,11 @@ const DataTable = ({ multipleActions = [], page, setPage = () => {}, disableEdit
|
|
|
52
61
|
if (status) {
|
|
53
62
|
setPermission(PermissionModel);
|
|
54
63
|
// console.log("LOAD LAI PermissionModel");
|
|
64
|
+
// Cuộn lên đầu trang khi tải dữ liệu thành công
|
|
65
|
+
window.scrollTo({
|
|
66
|
+
top: 0, // Vị trí pixel muốn cuộn tới
|
|
67
|
+
behavior: "smooth" // Tùy chọn cuộn mượt
|
|
68
|
+
});
|
|
55
69
|
}
|
|
56
70
|
}
|
|
57
71
|
});
|
|
@@ -13,6 +13,14 @@ import { usePermission } from "../../hooks";
|
|
|
13
13
|
import { TableRowRenderSM } from "./TableRowRenderSM";
|
|
14
14
|
import TableToolbar from "./TableToolbar";
|
|
15
15
|
import { useDataTable } from "./hooks";
|
|
16
|
+
const defaultQueryOptions = {
|
|
17
|
+
keepPreviousData: true, // Giữ dữ liệu cũ trong khi tải dữ liệu mới
|
|
18
|
+
staleTime: 1000 * 60 * 1, // Thời gian dữ liệu có thể sử dụng lại trước khi gọi lại API
|
|
19
|
+
cacheTime: 1000 * 60 * 30, // Thời gian dữ liệu được lưu trong cache trước khi bị xóa
|
|
20
|
+
refetchOnWindowFocus: true, // Tự động lấy lại dữ liệu khi người dùng quay lại tab
|
|
21
|
+
refetchInterval: 1000 * 30, // Mỗi 30 giây
|
|
22
|
+
keepPreviousData: true
|
|
23
|
+
};
|
|
16
24
|
const DataTableSM = ({ multipleActions = [], page, setPage = () => {}, disableEdit, disableDelete }) => {
|
|
17
25
|
const {
|
|
18
26
|
tableName,
|
|
@@ -43,6 +51,7 @@ const DataTableSM = ({ multipleActions = [], page, setPage = () => {}, disableEd
|
|
|
43
51
|
pageSize: rowsPerPage,
|
|
44
52
|
data: dataSearch
|
|
45
53
|
}),
|
|
54
|
+
defaultQueryOptions,
|
|
46
55
|
// keepPreviousData: true,
|
|
47
56
|
onSuccess: ({ PermissionModel, status }) => {
|
|
48
57
|
if (dataSearch?.TrangThaiXuLy !== undefined) {
|
|
@@ -51,6 +60,11 @@ const DataTableSM = ({ multipleActions = [], page, setPage = () => {}, disableEd
|
|
|
51
60
|
if (status) {
|
|
52
61
|
setPermission(PermissionModel);
|
|
53
62
|
// console.log("LOAD LAI PermissionModel");
|
|
63
|
+
// Cuộn lên đầu trang khi tải dữ liệu thành công
|
|
64
|
+
window.scrollTo({
|
|
65
|
+
top: 0, // Vị trí pixel muốn cuộn tới
|
|
66
|
+
behavior: "smooth" // Tùy chọn cuộn mượt
|
|
67
|
+
});
|
|
54
68
|
}
|
|
55
69
|
}
|
|
56
70
|
});
|
|
@@ -246,7 +260,7 @@ const DataTableSM = ({ multipleActions = [], page, setPage = () => {}, disableEd
|
|
|
246
260
|
multipleActions={multipleActions}
|
|
247
261
|
/>
|
|
248
262
|
|
|
249
|
-
<Table
|
|
263
|
+
<Table size={downXL ? "small" : "medium"}>
|
|
250
264
|
{/* <TableHead
|
|
251
265
|
headLabel={columns}
|
|
252
266
|
onSelectAllClick={handleSelectAllClick}
|
|
@@ -27,23 +27,22 @@ const ExportExcelButton = ({ tableName, data, size = "small" }) => {
|
|
|
27
27
|
onClick={() => {
|
|
28
28
|
handleExportExcel(tableName, data);
|
|
29
29
|
}}
|
|
30
|
+
sx={{ ml: 0.5, mr: 0.5 }}
|
|
30
31
|
>
|
|
31
32
|
Excel
|
|
32
33
|
</Button>
|
|
33
34
|
) : (
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
</IconButton>
|
|
46
|
-
</Tooltip>
|
|
35
|
+
<Button
|
|
36
|
+
size={size}
|
|
37
|
+
variant="outlined"
|
|
38
|
+
startIcon={<Download />}
|
|
39
|
+
onClick={() => {
|
|
40
|
+
handleExportExcel(tableName, data);
|
|
41
|
+
}}
|
|
42
|
+
sx={{ ml: 0.5, mr: 0.5 }}
|
|
43
|
+
>
|
|
44
|
+
Excel
|
|
45
|
+
</Button>
|
|
47
46
|
);
|
|
48
47
|
};
|
|
49
48
|
export default ExportExcelButton;
|
|
@@ -16,7 +16,7 @@ export const FilterGod = ({ tableName, filters, elementSize = "small", setPage =
|
|
|
16
16
|
const { setDataSearch, dataSearch } = useDataTable();
|
|
17
17
|
// Lấy trạng thái từ localStorage hoặc mặc định là true
|
|
18
18
|
const [isFilterVisible, setFilterVisible] = useState(
|
|
19
|
-
() => JSON.parse(localStorage.getItem(`${tableName}-isFilterVisible`)) ??
|
|
19
|
+
() => JSON.parse(localStorage.getItem(`${tableName}-isFilterVisible`)) ?? false
|
|
20
20
|
);
|
|
21
21
|
|
|
22
22
|
// Lưu trạng thái vào localStorage mỗi khi thay đổi
|
|
@@ -68,23 +68,35 @@ export const TableRowRender = ({
|
|
|
68
68
|
({
|
|
69
69
|
field,
|
|
70
70
|
type = "text",
|
|
71
|
-
valueGetter = (row) =>
|
|
72
|
-
return row[field];
|
|
73
|
-
},
|
|
71
|
+
valueGetter = (row) => row[field], // Giá trị mặc định
|
|
74
72
|
renderCell,
|
|
75
73
|
valueFormat = (e) => e
|
|
76
74
|
}) => {
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
// Xác định `align`
|
|
76
|
+
const alignMap = {
|
|
77
|
+
image: "right",
|
|
78
|
+
number: "right",
|
|
79
|
+
date: "right",
|
|
80
|
+
datetime: "right",
|
|
81
|
+
textCenter: "center",
|
|
82
|
+
textLeft: "left",
|
|
83
|
+
textRight: "right"
|
|
84
|
+
};
|
|
85
|
+
const align = alignMap[type] || "left"; // Mặc định là "left"
|
|
86
|
+
|
|
79
87
|
return (
|
|
80
|
-
<TableCell
|
|
88
|
+
<TableCell
|
|
89
|
+
key={`${row[selectedField] || "unknown"}-${field}`} // Thêm fallback cho `key`
|
|
90
|
+
align={align}
|
|
91
|
+
>
|
|
81
92
|
{renderCell ? renderCell(row) : valueFormat(valueGetter(row))}
|
|
82
93
|
</TableCell>
|
|
83
94
|
);
|
|
84
95
|
}
|
|
85
96
|
)}
|
|
97
|
+
|
|
86
98
|
{!disableStatus && canEdit && (
|
|
87
|
-
<TableCell>
|
|
99
|
+
<TableCell align="center">
|
|
88
100
|
<Switch
|
|
89
101
|
checked={row[statusKey]}
|
|
90
102
|
onChange={() => {
|
|
@@ -47,8 +47,8 @@ export const TableRowRenderSM = ({
|
|
|
47
47
|
const downXl = useMediaQuery(theme.breakpoints.down("xl"));
|
|
48
48
|
|
|
49
49
|
return (
|
|
50
|
-
<TableRow hover key={row[selectedField]} selected={selected}>
|
|
51
|
-
<TableCell colSpan={columns.length} align="left">
|
|
50
|
+
<TableRow hover key={row[selectedField]} selected={selected} sx={{ width: "100%" }}>
|
|
51
|
+
<TableCell colSpan={columns.length} align="left" sx={{ width: "100%" }}>
|
|
52
52
|
{columns.map(({ field, label, type = "text", valueGetter = (row) => row[field], renderCell, valueFormat = (e) => e }) => {
|
|
53
53
|
const value = renderCell ? renderCell(row) : valueFormat(valueGetter(row));
|
|
54
54
|
return (
|
|
@@ -67,117 +67,109 @@ export const TableRowRenderSM = ({
|
|
|
67
67
|
inputProps={{ "aria-label": "controlled" }}
|
|
68
68
|
/>
|
|
69
69
|
)}
|
|
70
|
-
<Grid
|
|
71
|
-
{
|
|
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
|
-
</Button>
|
|
174
|
-
</Tooltip>
|
|
175
|
-
))}
|
|
176
|
-
<MoreMenu actions={tableActionsOnMoreMenu} data={row} />
|
|
177
|
-
</Box>
|
|
178
|
-
</Box>
|
|
179
|
-
</Box>
|
|
180
|
-
)}
|
|
70
|
+
<Grid container spacing={{ xs: 2, xl: 2 }} sx={{ width: "100%", pt: 2, pb: 2 }}>
|
|
71
|
+
<Grid item xs={12} sx={{ display: "flex", justifyContent: "flex-end", alignItems: "center", width: "100%" }}>
|
|
72
|
+
{!disableCellThaoTac && (
|
|
73
|
+
<>
|
|
74
|
+
{!disableEdit && canEdit && (
|
|
75
|
+
<Button
|
|
76
|
+
size="small"
|
|
77
|
+
variant="outlined"
|
|
78
|
+
color="primary"
|
|
79
|
+
onClick={() => onEdit(row)}
|
|
80
|
+
startIcon={<EditOutlined fontSize="inherit" />}
|
|
81
|
+
sx={{
|
|
82
|
+
marginLeft: 0.5,
|
|
83
|
+
marginRight: 0.5,
|
|
84
|
+
borderRadius: 14,
|
|
85
|
+
minWidth: 60,
|
|
86
|
+
padding: "2px 8px",
|
|
87
|
+
height: "20px",
|
|
88
|
+
fontSize: "0.6rem",
|
|
89
|
+
whiteSpace: "nowrap",
|
|
90
|
+
overflow: "hidden",
|
|
91
|
+
textOverflow: "ellipsis"
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
Sửa
|
|
95
|
+
</Button>
|
|
96
|
+
)}
|
|
97
|
+
{canView && !tableActions?.some(({ permissionType }) => permissionType === "view") && (
|
|
98
|
+
<Button
|
|
99
|
+
size="small"
|
|
100
|
+
variant="outlined"
|
|
101
|
+
color="info"
|
|
102
|
+
onClick={() => onView(row)}
|
|
103
|
+
startIcon={<RemoveRedEyeOutlinedIcon />}
|
|
104
|
+
sx={{
|
|
105
|
+
marginLeft: 0.5,
|
|
106
|
+
marginRight: 0.5,
|
|
107
|
+
borderRadius: 14,
|
|
108
|
+
minWidth: 60,
|
|
109
|
+
padding: "2px 8px",
|
|
110
|
+
height: "20px",
|
|
111
|
+
fontSize: "0.6rem",
|
|
112
|
+
whiteSpace: "nowrap",
|
|
113
|
+
overflow: "hidden",
|
|
114
|
+
textOverflow: "ellipsis"
|
|
115
|
+
}}
|
|
116
|
+
>
|
|
117
|
+
Xem
|
|
118
|
+
</Button>
|
|
119
|
+
)}
|
|
120
|
+
{!disableDelete && canDelete && (
|
|
121
|
+
<Button
|
|
122
|
+
size="small"
|
|
123
|
+
variant="outlined"
|
|
124
|
+
color="error"
|
|
125
|
+
onClick={() => {
|
|
126
|
+
onDelete(row[selectedField]);
|
|
127
|
+
}}
|
|
128
|
+
startIcon={<DeleteOutlineIcon fontSize="inherit" />}
|
|
129
|
+
sx={{
|
|
130
|
+
marginLeft: 0.5,
|
|
131
|
+
marginRight: 0.5,
|
|
132
|
+
borderRadius: 14,
|
|
133
|
+
minWidth: 60,
|
|
134
|
+
padding: "2px 8px",
|
|
135
|
+
height: "20px",
|
|
136
|
+
fontSize: "0.6rem",
|
|
137
|
+
whiteSpace: "nowrap",
|
|
138
|
+
overflow: "hidden",
|
|
139
|
+
textOverflow: "ellipsis"
|
|
140
|
+
}}
|
|
141
|
+
>
|
|
142
|
+
Xóa
|
|
143
|
+
</Button>
|
|
144
|
+
)}
|
|
145
|
+
{tableActionsOnTable.map(({ title, onClick, element }) => (
|
|
146
|
+
<Button
|
|
147
|
+
size="small"
|
|
148
|
+
variant="outlined"
|
|
149
|
+
onClick={() => {
|
|
150
|
+
onClick(row);
|
|
151
|
+
}}
|
|
152
|
+
startIcon={element}
|
|
153
|
+
sx={{
|
|
154
|
+
marginLeft: 0.5,
|
|
155
|
+
marginRight: 0.5,
|
|
156
|
+
borderRadius: 14,
|
|
157
|
+
minWidth: 60,
|
|
158
|
+
padding: "2px 8px",
|
|
159
|
+
height: "20px",
|
|
160
|
+
fontSize: "0.6rem",
|
|
161
|
+
whiteSpace: "nowrap",
|
|
162
|
+
overflow: "hidden",
|
|
163
|
+
textOverflow: "ellipsis"
|
|
164
|
+
}}
|
|
165
|
+
>
|
|
166
|
+
{title.toLowerCase() === "xem chi tiết" ? "Xem" : title}
|
|
167
|
+
</Button>
|
|
168
|
+
))}
|
|
169
|
+
<MoreMenu actions={tableActionsOnMoreMenu} data={row} />
|
|
170
|
+
</>
|
|
171
|
+
)}
|
|
172
|
+
</Grid>
|
|
181
173
|
</Grid>
|
|
182
174
|
</TableCell>
|
|
183
175
|
</TableRow>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Button, Card, IconButton, Stack, Tooltip, Typography, useMediaQuery, useTheme } from "@mui/material";
|
|
1
|
+
import { Button, Card, Grid, IconButton, Stack, Tooltip, Typography, useMediaQuery, useTheme } from "@mui/material";
|
|
2
2
|
|
|
3
3
|
import { useEffect, useMemo, useState } from "react";
|
|
4
4
|
|
|
@@ -189,57 +189,44 @@ function DataManagement({
|
|
|
189
189
|
<DataTableContext.Provider value={values}>
|
|
190
190
|
<FormProvider {...methods}>
|
|
191
191
|
<Stack direction="row" justifyContent={"space-between"} sx={{ mb: upXL ? 2 : 1, ...slotProps?.header?.sx }}>
|
|
192
|
-
<
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
[...filters].forEach((filter) => {
|
|
203
|
-
filter?.onChange?.();
|
|
204
|
-
});
|
|
205
|
-
reset();
|
|
206
|
-
setValue("Search");
|
|
207
|
-
}}
|
|
208
|
-
>
|
|
209
|
-
<Refresh fontSize="inherit" />
|
|
210
|
-
</IconButton>
|
|
211
|
-
</Tooltip>
|
|
212
|
-
|
|
213
|
-
{titleButtons?.map((button, index) => (
|
|
214
|
-
<div key={index}>
|
|
215
|
-
{button}
|
|
216
|
-
{/* Các phần tử khác có thể được thêm ở đây nếu cần */}
|
|
217
|
-
</div>
|
|
218
|
-
))}
|
|
219
|
-
<ExportExcelButton tableName={tableName} data={dataSearch} size={elementSize} />
|
|
220
|
-
{canCreate &&
|
|
221
|
-
!disableAdd &&
|
|
222
|
-
(!isSmallScreen ? (
|
|
223
|
-
<Button
|
|
192
|
+
<Grid container spacing={{ xs: 1, xl: 1 }}>
|
|
193
|
+
<Grid item md={9} xs={12}>
|
|
194
|
+
<Typography variant="h4">{title}</Typography>
|
|
195
|
+
</Grid>
|
|
196
|
+
<Grid item md={3} xs={12} sx={{ display: "flex", justifyContent: "flex-end", alignItems: "center" }}>
|
|
197
|
+
<HuongDanButton tableName={tableName} size={elementSize} />
|
|
198
|
+
<Tooltip title="Làm mới">
|
|
199
|
+
<IconButton
|
|
200
|
+
variant="outlined"
|
|
201
|
+
color="primary"
|
|
224
202
|
size={elementSize}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
onAddClick(e);
|
|
203
|
+
onClick={() => {
|
|
204
|
+
setDataSearch({ ...defaults });
|
|
205
|
+
[...filters].forEach((filter) => {
|
|
206
|
+
filter?.onChange?.();
|
|
207
|
+
});
|
|
208
|
+
reset();
|
|
209
|
+
setValue("Search");
|
|
233
210
|
}}
|
|
234
211
|
>
|
|
235
|
-
|
|
236
|
-
</
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
212
|
+
<Refresh fontSize="inherit" />
|
|
213
|
+
</IconButton>
|
|
214
|
+
</Tooltip>
|
|
215
|
+
|
|
216
|
+
{titleButtons?.map((button, index) => (
|
|
217
|
+
<div key={index}>
|
|
218
|
+
{button}
|
|
219
|
+
{/* Các phần tử khác có thể được thêm ở đây nếu cần */}
|
|
220
|
+
</div>
|
|
221
|
+
))}
|
|
222
|
+
<ExportExcelButton tableName={tableName} data={dataSearch} size={elementSize} />
|
|
223
|
+
{canCreate &&
|
|
224
|
+
!disableAdd &&
|
|
225
|
+
(!isSmallScreen ? (
|
|
226
|
+
<Button
|
|
242
227
|
size={elementSize}
|
|
228
|
+
variant="contained"
|
|
229
|
+
startIcon={<Add fontSize="inherit" />}
|
|
243
230
|
onClick={(e) => {
|
|
244
231
|
if (!disableEditor) {
|
|
245
232
|
setOpenEditorDialog(true);
|
|
@@ -247,13 +234,29 @@ function DataManagement({
|
|
|
247
234
|
}
|
|
248
235
|
onAddClick(e);
|
|
249
236
|
}}
|
|
250
|
-
sx={{
|
|
237
|
+
sx={{ ml: 0.5, mr: 0.5 }}
|
|
251
238
|
>
|
|
252
|
-
|
|
253
|
-
</
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
239
|
+
Thêm
|
|
240
|
+
</Button>
|
|
241
|
+
) : (
|
|
242
|
+
<Button
|
|
243
|
+
size={elementSize}
|
|
244
|
+
variant="contained"
|
|
245
|
+
startIcon={<Add fontSize="inherit" />}
|
|
246
|
+
onClick={(e) => {
|
|
247
|
+
if (!disableEditor) {
|
|
248
|
+
setOpenEditorDialog(true);
|
|
249
|
+
setSelectedEditItem(null);
|
|
250
|
+
}
|
|
251
|
+
onAddClick(e);
|
|
252
|
+
}}
|
|
253
|
+
sx={{ ml: 0.5, mr: 0.5 }}
|
|
254
|
+
>
|
|
255
|
+
Thêm
|
|
256
|
+
</Button>
|
|
257
|
+
))}
|
|
258
|
+
</Grid>
|
|
259
|
+
</Grid>
|
|
257
260
|
</Stack>
|
|
258
261
|
|
|
259
262
|
<Card>
|