trithuc-mvc-react 1.6.5 → 1.6.7
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 +6 -1
- package/components/DataManagement/FilterElement.jsx +0 -1
- package/components/DataManagement/FormField.jsx +11 -4
- package/components/DataManagement/TableRowRender.jsx +13 -6
- package/components/DataManagement/TableToolbar.jsx +3 -2
- package/components/DataManagement/ViewDetailDialog.jsx +100 -0
- package/components/DataManagement/index.jsx +11 -4
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@ import TableToolbar from "./TableToolbar";
|
|
|
14
14
|
import { useDataTable, usePermission } from "./hooks";
|
|
15
15
|
|
|
16
16
|
const DataTable = () => {
|
|
17
|
-
const { tableName, selectedField, columns, dataSearch, setOpenEditorDialog, setSelectedEditItem } = useDataTable();
|
|
17
|
+
const { tableName, selectedField, columns, dataSearch, setOpenEditorDialog, setSelectedEditItem,setOpenViewDialog } = useDataTable();
|
|
18
18
|
const { setPermission, Permission } = usePermission();
|
|
19
19
|
const queryClient = useQueryClient();
|
|
20
20
|
const confirm = useConfirm();
|
|
@@ -92,6 +92,10 @@ const DataTable = () => {
|
|
|
92
92
|
setOpenEditorDialog(true);
|
|
93
93
|
setSelectedEditItem(item);
|
|
94
94
|
};
|
|
95
|
+
const handlViewDetail = (item) => {
|
|
96
|
+
setOpenViewDialog(true);
|
|
97
|
+
setSelectedEditItem(item);
|
|
98
|
+
};
|
|
95
99
|
const { rows, total } = useMemo(() => {
|
|
96
100
|
let rows = data?.data ?? [];
|
|
97
101
|
let total = data?.total ?? 0;
|
|
@@ -180,6 +184,7 @@ const DataTable = () => {
|
|
|
180
184
|
selected={isSelected(row[selectedField])}
|
|
181
185
|
onSelect={handleSelect}
|
|
182
186
|
onEdit={handlEdit}
|
|
187
|
+
onViewDetail={handlViewDetail}
|
|
183
188
|
onChangeStatus={handleChangeStatus}
|
|
184
189
|
onDelete={handleDelete}
|
|
185
190
|
/>
|
|
@@ -40,7 +40,8 @@ function FormField({
|
|
|
40
40
|
keyValueLabel,
|
|
41
41
|
childrenFields,
|
|
42
42
|
size,
|
|
43
|
-
required = false
|
|
43
|
+
required = false,
|
|
44
|
+
disabled = false
|
|
44
45
|
}) {
|
|
45
46
|
const { setValue, register } = useFormContext();
|
|
46
47
|
const getValueObject = useCallback(
|
|
@@ -71,6 +72,7 @@ function FormField({
|
|
|
71
72
|
<TextField
|
|
72
73
|
{...field}
|
|
73
74
|
multiline
|
|
75
|
+
disabled={disabled}
|
|
74
76
|
label={label + (required ? "*" : "")}
|
|
75
77
|
error={Boolean(error)}
|
|
76
78
|
helperText={error?.message}
|
|
@@ -98,6 +100,7 @@ function FormField({
|
|
|
98
100
|
helperText={error?.message}
|
|
99
101
|
fullWidth
|
|
100
102
|
placeholder={label}
|
|
103
|
+
disabled={disabled}
|
|
101
104
|
size={size}
|
|
102
105
|
/>
|
|
103
106
|
);
|
|
@@ -115,6 +118,7 @@ function FormField({
|
|
|
115
118
|
render={({ field: { onChange: onFieldChange, value }, fieldState: { error } }) => {
|
|
116
119
|
return (
|
|
117
120
|
<Autocomplete
|
|
121
|
+
disabled={disabled}
|
|
118
122
|
disablePortal
|
|
119
123
|
noOptionsText="Không có dữ liệu"
|
|
120
124
|
loading={loading}
|
|
@@ -145,7 +149,7 @@ function FormField({
|
|
|
145
149
|
render={({ field }) => (
|
|
146
150
|
<FormControl sx={{ minWidth: 160 }} fullWidth size={size}>
|
|
147
151
|
<InputLabel>{label}</InputLabel>
|
|
148
|
-
<Select {...field} label={label}>
|
|
152
|
+
<Select {...field} label={label} disabled={disabled}>
|
|
149
153
|
{[...datas].map(({ label, value }) => (
|
|
150
154
|
<MenuItem key={value} value={value}>
|
|
151
155
|
{label}
|
|
@@ -162,6 +166,7 @@ function FormField({
|
|
|
162
166
|
name={name}
|
|
163
167
|
control={control}
|
|
164
168
|
defaultValue={null}
|
|
169
|
+
disabled={disabled}
|
|
165
170
|
render={({ field }) => {
|
|
166
171
|
return (
|
|
167
172
|
<FormControl fullWidth size={size}>
|
|
@@ -182,7 +187,7 @@ function FormField({
|
|
|
182
187
|
<Controller
|
|
183
188
|
name={name}
|
|
184
189
|
control={control}
|
|
185
|
-
render={({ field }) => <FormControlLabel control={<Checkbox {...field} checked={field.value} />} label={label} />}
|
|
190
|
+
render={({ field }) => <FormControlLabel disabled={disabled} control={<Checkbox {...field} checked={field.value} />} label={label} />}
|
|
186
191
|
/>
|
|
187
192
|
|
|
188
193
|
{/* {errors.terms && (
|
|
@@ -197,6 +202,7 @@ function FormField({
|
|
|
197
202
|
<Controller
|
|
198
203
|
name={name}
|
|
199
204
|
control={control}
|
|
205
|
+
disabled={disabled}
|
|
200
206
|
defaultValue={true}
|
|
201
207
|
render={({ field }) => <FormControlLabel control={<Switch {...field} checked={field.value} />} label={label} />}
|
|
202
208
|
/>
|
|
@@ -212,6 +218,7 @@ function FormField({
|
|
|
212
218
|
}
|
|
213
219
|
return (
|
|
214
220
|
<DatePicker
|
|
221
|
+
disabled={disabled}
|
|
215
222
|
label={label + (required ? "*" : "")}
|
|
216
223
|
{...field}
|
|
217
224
|
format={DEFAULT_DATE_FORMAT}
|
|
@@ -271,7 +278,7 @@ function FormField({
|
|
|
271
278
|
render={({ field, fieldState: { error } }) => {
|
|
272
279
|
return (
|
|
273
280
|
<>
|
|
274
|
-
<UploadMultipleFile {...field} name="DinhKem" />
|
|
281
|
+
<UploadMultipleFile {...field} name="DinhKem" disabled={disabled} />
|
|
275
282
|
</>
|
|
276
283
|
);
|
|
277
284
|
}}
|
|
@@ -2,6 +2,7 @@ import { Checkbox, IconButton, Switch, TableCell, TableRow, Tooltip, Toolbar, us
|
|
|
2
2
|
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
|
|
3
3
|
import { EditOutlined } from "@mui/icons-material";
|
|
4
4
|
import { useDataTable, usePermission } from "./hooks";
|
|
5
|
+
import RemoveRedEyeOutlinedIcon from "@mui/icons-material/RemoveRedEyeOutlined";
|
|
5
6
|
|
|
6
7
|
// material
|
|
7
8
|
import { styled, useTheme } from "@mui/material/styles";
|
|
@@ -71,26 +72,32 @@ export const TableRowRender = ({ index, row, selected, onSelect, onChangeStatus,
|
|
|
71
72
|
{!disableCellThaoTac && <TableCell align="center">
|
|
72
73
|
{canEdit && (
|
|
73
74
|
<Tooltip title="Chỉnh sửa">
|
|
74
|
-
<IconButton onClick={() => onEdit(row)}>
|
|
75
|
-
<EditOutlined color="primary" />
|
|
75
|
+
<IconButton size={downXl ? "small" : "medium"} onClick={() => onEdit(row)}>
|
|
76
|
+
<EditOutlined fontSize="inherit" color="primary" />
|
|
76
77
|
</IconButton>
|
|
77
78
|
</Tooltip>
|
|
78
79
|
)}
|
|
79
|
-
|
|
80
|
+
{/* {canView && (
|
|
81
|
+
<Tooltip title="Xem chi tiết">
|
|
82
|
+
<IconButton onClick={() => onViewDetail(row)}>
|
|
83
|
+
<RemoveRedEyeOutlinedIcon color="info" />
|
|
84
|
+
</IconButton>
|
|
85
|
+
</Tooltip>
|
|
86
|
+
)} */}
|
|
80
87
|
{canDelete && (
|
|
81
88
|
<Tooltip title="Xóa">
|
|
82
|
-
<IconButton
|
|
89
|
+
<IconButton size={downXl ? "small" : "medium"}
|
|
83
90
|
onClick={() => {
|
|
84
91
|
onDelete(row[selectedField]);
|
|
85
92
|
}}
|
|
86
93
|
>
|
|
87
|
-
<DeleteOutlineIcon color="error" />
|
|
94
|
+
<DeleteOutlineIcon fontSize="inherit" color="error" />
|
|
88
95
|
</IconButton>
|
|
89
96
|
</Tooltip>
|
|
90
97
|
)}
|
|
91
98
|
{tableActionsOnTable.map(({ title, onClick, element }) => (
|
|
92
99
|
<Tooltip key={title} title={title}>
|
|
93
|
-
<IconButton
|
|
100
|
+
<IconButton size={downXl ? "small" : "medium"}
|
|
94
101
|
onClick={() => {
|
|
95
102
|
onClick(row);
|
|
96
103
|
}}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Checkbox, IconButton, Tooltip, Typography, Box } from "@mui/material";
|
|
1
|
+
import { Checkbox, IconButton, Tooltip, Typography, Box, useMediaQuery } from "@mui/material";
|
|
2
2
|
import { Delete } from "@mui/icons-material";
|
|
3
3
|
import { usePermission } from "./hooks";
|
|
4
4
|
import PropTypes from "prop-types";
|
|
@@ -10,6 +10,7 @@ const TableToolbar = ({ numSelected, onSelectAllClick, rowCount, onDeleteMultipl
|
|
|
10
10
|
const theme = useTheme();
|
|
11
11
|
const isLight = theme.palette.mode === "light";
|
|
12
12
|
const { canDeleteMulti } = usePermission();
|
|
13
|
+
const downXl = useMediaQuery(theme.breakpoints.down("xl"));
|
|
13
14
|
|
|
14
15
|
return (
|
|
15
16
|
numSelected > 0 && (
|
|
@@ -39,7 +40,7 @@ const TableToolbar = ({ numSelected, onSelectAllClick, rowCount, onDeleteMultipl
|
|
|
39
40
|
|
|
40
41
|
{canDeleteMulti && (
|
|
41
42
|
<Tooltip title="Xóa tất cả" onClick={onDeleteMultiple}>
|
|
42
|
-
<IconButton>
|
|
43
|
+
<IconButton size={downXl ? "small" : "medium"} >
|
|
43
44
|
<Delete color="primary" />
|
|
44
45
|
</IconButton>
|
|
45
46
|
</Tooltip>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import Button from "@mui/material/Button";
|
|
2
|
+
|
|
3
|
+
import Dialog from "@mui/material/Dialog";
|
|
4
|
+
import DialogActions from "@mui/material/DialogActions";
|
|
5
|
+
import DialogContent from "@mui/material/DialogContent";
|
|
6
|
+
import DialogTitle from "@mui/material/DialogTitle";
|
|
7
|
+
import IconButton from "@mui/material/IconButton";
|
|
8
|
+
import CloseIcon from "@mui/icons-material/Close";
|
|
9
|
+
|
|
10
|
+
import { useEffect, useRef, useState } from "react";
|
|
11
|
+
import PropTypes from "prop-types";
|
|
12
|
+
|
|
13
|
+
import EditorForm from "trithuc-mvc-react/components/DataManagement/EditorForm";
|
|
14
|
+
import { useDataTable, usePermission } from "trithuc-mvc-react/components/DataManagement/hooks";
|
|
15
|
+
ViewDetailDialog.propTypes = {
|
|
16
|
+
open: PropTypes.bool,
|
|
17
|
+
onClose: PropTypes.func,
|
|
18
|
+
};
|
|
19
|
+
import { Stack, Typography, List, ListItem, ListItemText, ListItemIcon, Link, Grid } from "@mui/material";
|
|
20
|
+
import TextSnippetOutlinedIcon from "@mui/icons-material/TextSnippetOutlined";
|
|
21
|
+
export const FieldView = ({ label, value }) => {
|
|
22
|
+
return (
|
|
23
|
+
<Stack direction="column">
|
|
24
|
+
<Typography variant="body2" sx={{ color: "text.secondary", }}>
|
|
25
|
+
{label}
|
|
26
|
+
</Typography>
|
|
27
|
+
<Typography variant="subtitle2">{value}</Typography>
|
|
28
|
+
</Stack>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const ListFileView = ({ files }) => {
|
|
33
|
+
let hasFile = files?.length > 0;
|
|
34
|
+
|
|
35
|
+
if (!hasFile) {
|
|
36
|
+
return <Typography variant="subtitle2">Chưa có file</Typography>;
|
|
37
|
+
}
|
|
38
|
+
return (
|
|
39
|
+
<List disablePadding sx={{ ...(hasFile && { my: 3 }) }}>
|
|
40
|
+
{files?.map(({ urlFile, tenFile, Size }) => {
|
|
41
|
+
return (
|
|
42
|
+
<ListItem
|
|
43
|
+
key={urlFile}
|
|
44
|
+
// {...varFadeInRight}
|
|
45
|
+
sx={{
|
|
46
|
+
my: 1,
|
|
47
|
+
py: 0.75,
|
|
48
|
+
px: 2,
|
|
49
|
+
borderRadius: 1,
|
|
50
|
+
border: (theme) => `solid 1px ${theme.palette.divider}`,
|
|
51
|
+
bgcolor: "background.paper"
|
|
52
|
+
}}
|
|
53
|
+
>
|
|
54
|
+
<ListItemIcon>
|
|
55
|
+
{/* <Icon icon={fileFill} width={28} height={28} /> */}
|
|
56
|
+
<TextSnippetOutlinedIcon color="info" />
|
|
57
|
+
</ListItemIcon>
|
|
58
|
+
<ListItemText
|
|
59
|
+
primary={<Link href={urlFile} >{tenFile}</Link>}
|
|
60
|
+
secondary={Size}
|
|
61
|
+
primaryTypographyProps={{ variant: "subtitle2" }}
|
|
62
|
+
secondaryTypographyProps={{ variant: "caption" }}
|
|
63
|
+
/>
|
|
64
|
+
</ListItem>
|
|
65
|
+
);
|
|
66
|
+
})}
|
|
67
|
+
</List>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
function ViewDetailDialog({ open, onClose = () => { }, fields = [] }) {
|
|
72
|
+
|
|
73
|
+
const fieldsView = fields.map(field=>({...field, disabled: true}));
|
|
74
|
+
return (
|
|
75
|
+
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth={true} scroll={'body'}>
|
|
76
|
+
<DialogTitle>
|
|
77
|
+
Xem
|
|
78
|
+
<IconButton
|
|
79
|
+
aria-label="close"
|
|
80
|
+
onClick={onClose}
|
|
81
|
+
sx={{
|
|
82
|
+
position: "absolute",
|
|
83
|
+
right: 8,
|
|
84
|
+
top: 8,
|
|
85
|
+
color: (theme) => theme.palette.grey[500]
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
<CloseIcon />
|
|
89
|
+
</IconButton>
|
|
90
|
+
</DialogTitle>
|
|
91
|
+
<DialogContent dividers={true}>
|
|
92
|
+
<EditorForm fields={fieldsView} />
|
|
93
|
+
</DialogContent>
|
|
94
|
+
<DialogActions>
|
|
95
|
+
<Button onClick={onClose}>Đóng</Button>
|
|
96
|
+
</DialogActions>
|
|
97
|
+
</Dialog>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
export default ViewDetailDialog;
|
|
@@ -9,6 +9,7 @@ import { Add, Refresh } from "@mui/icons-material";
|
|
|
9
9
|
|
|
10
10
|
import { FormProvider, useForm } from "react-hook-form";
|
|
11
11
|
import EditorDialog from "./EditorDialog";
|
|
12
|
+
import ViewDetailDialog from "./ViewDetailDialog";
|
|
12
13
|
|
|
13
14
|
import ExportExcelButton from "./ExportExcelButton";
|
|
14
15
|
import { FilterGod } from "./FilterGod";
|
|
@@ -59,6 +60,7 @@ function DataManagement({
|
|
|
59
60
|
onAddClick = () => {},
|
|
60
61
|
onEditClick = () => {},
|
|
61
62
|
tabPanel,
|
|
63
|
+
backParentNavigator,
|
|
62
64
|
slotProps = {
|
|
63
65
|
header: {
|
|
64
66
|
sx: {}
|
|
@@ -67,6 +69,7 @@ function DataManagement({
|
|
|
67
69
|
}) {
|
|
68
70
|
const [openEditorDialog, setOpenEditorDialog] = useState(false);
|
|
69
71
|
const [selectedEditItem, setSelectedEditItem] = useState(null);
|
|
72
|
+
const [openViewDialog, setOpenViewDialog] = useState(false);
|
|
70
73
|
|
|
71
74
|
const [Permission, setPermission] = useState(null);
|
|
72
75
|
|
|
@@ -113,9 +116,11 @@ function DataManagement({
|
|
|
113
116
|
disableStatus,
|
|
114
117
|
disableCellThaoTac,
|
|
115
118
|
disableAdd,
|
|
116
|
-
tableActions
|
|
119
|
+
tableActions,
|
|
120
|
+
openViewDialog,
|
|
121
|
+
setOpenViewDialog
|
|
117
122
|
};
|
|
118
|
-
}, [tableName, selectedField, columns, selectedEditItem, dataSearch, setDataSearch, validationSchema, tableActions]);
|
|
123
|
+
}, [tableName, selectedField, columns, selectedEditItem, dataSearch, setDataSearch, validationSchema, tableActions, openViewDialog, setOpenViewDialog]);
|
|
119
124
|
const permissionValues = useMemo(() => {
|
|
120
125
|
return {
|
|
121
126
|
Permission,
|
|
@@ -146,7 +151,7 @@ function DataManagement({
|
|
|
146
151
|
setValue("Search");
|
|
147
152
|
}}
|
|
148
153
|
>
|
|
149
|
-
<Refresh />
|
|
154
|
+
<Refresh fontSize="inherit" />
|
|
150
155
|
</IconButton>
|
|
151
156
|
</Tooltip>
|
|
152
157
|
|
|
@@ -156,7 +161,7 @@ function DataManagement({
|
|
|
156
161
|
<Button
|
|
157
162
|
size={elementSize}
|
|
158
163
|
variant="contained"
|
|
159
|
-
startIcon={<Add />}
|
|
164
|
+
startIcon={<Add fontSize="inherit"/>}
|
|
160
165
|
onClick={(e) => {
|
|
161
166
|
if (!disableEditor) {
|
|
162
167
|
setOpenEditorDialog(true);
|
|
@@ -175,6 +180,7 @@ function DataManagement({
|
|
|
175
180
|
<Card>
|
|
176
181
|
{tabPanel}
|
|
177
182
|
<FilterGod filters={filters} elementSize={elementSize} />
|
|
183
|
+
{backParentNavigator}
|
|
178
184
|
<DataTable />
|
|
179
185
|
</Card>
|
|
180
186
|
</FormProvider>
|
|
@@ -186,6 +192,7 @@ function DataManagement({
|
|
|
186
192
|
fields={editorFields}
|
|
187
193
|
/>
|
|
188
194
|
)}
|
|
195
|
+
<ViewDetailDialog open={openViewDialog} onClose={() => setOpenViewDialog(false)} fields={editorFields} />
|
|
189
196
|
</PermissionContext.Provider>
|
|
190
197
|
</DataTableContext.Provider>
|
|
191
198
|
</>
|