trithuc-mvc-react 1.6.6 → 1.6.8

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.
@@ -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, onEditClick } = useDataTable();
18
18
  const { setPermission, Permission } = usePermission();
19
19
  const queryClient = useQueryClient();
20
20
  const confirm = useConfirm();
@@ -80,7 +80,7 @@ const DataTable = () => {
80
80
  tableName
81
81
  });
82
82
  })
83
- .catch(() => {});
83
+ .catch(() => { });
84
84
  };
85
85
  const handleChangeStatus = (Id) => {
86
86
  changeStatusMutation.mutate({
@@ -91,21 +91,27 @@ const DataTable = () => {
91
91
  const handlEdit = (item) => {
92
92
  setOpenEditorDialog(true);
93
93
  setSelectedEditItem(item);
94
+ onEditClick(item);
95
+
96
+ };
97
+ const handlViewDetail = (item) => {
98
+ setOpenViewDialog(true);
99
+ setSelectedEditItem(item);
94
100
  };
95
101
  const { rows, total } = useMemo(() => {
96
102
  let rows = data?.data ?? [];
97
103
  let total = data?.total ?? 0;
98
-
104
+
99
105
  return {
100
106
  rows: rows,
101
107
  total
102
108
  };
103
109
  }, [data]);
104
110
 
105
- useEffect(()=>{
111
+ useEffect(() => {
106
112
  let PermissionModel = data?.PermissionModel;
107
- PermissionModel&&setPermission(PermissionModel);
108
- },[rows])
113
+ PermissionModel && setPermission(PermissionModel);
114
+ }, [rows])
109
115
 
110
116
  const handleChangePage = (event, newPage) => {
111
117
  setPage(newPage);
@@ -147,7 +153,7 @@ const DataTable = () => {
147
153
  ids: selected
148
154
  });
149
155
  })
150
- .catch(() => {});
156
+ .catch(() => { });
151
157
  };
152
158
  const theme = useTheme();
153
159
  const downXL = useMediaQuery(theme.breakpoints.down("xl"));
@@ -180,6 +186,7 @@ const DataTable = () => {
180
186
  selected={isSelected(row[selectedField])}
181
187
  onSelect={handleSelect}
182
188
  onEdit={handlEdit}
189
+ onView={handlViewDetail}
183
190
  onChangeStatus={handleChangeStatus}
184
191
  onDelete={handleDelete}
185
192
  />
@@ -115,7 +115,8 @@ function EditorForm({ fields, submitRef }) {
115
115
  keyLabel,
116
116
  keyValue,
117
117
  keyValueLabel,
118
- required
118
+ required,
119
+ disabled=false
119
120
  }) => {
120
121
  return (
121
122
  <Grid item md={size?.md} xs={size?.xs} sm={size?.sm} key={field}>
@@ -133,6 +134,7 @@ function EditorForm({ fields, submitRef }) {
133
134
  keyValue={keyValue}
134
135
  size={elementSize}
135
136
  required={required}
137
+ disabled={disabled}
136
138
  />
137
139
  </Grid>
138
140
  );
@@ -29,7 +29,6 @@ export function FilterElement({ name, type, label, keyValue, keyLabel, childrenF
29
29
 
30
30
  switch (type) {
31
31
  case "search":
32
- console.log(size)
33
32
  return (
34
33
  <OutlinedInput
35
34
  {...rest}
@@ -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,14 +2,15 @@ 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";
8
9
  import MoreMenu from "../MoreMenu";
9
10
  import { useMemo } from "react";
10
11
 
11
- export const TableRowRender = ({ index, row, selected, onSelect, onChangeStatus, onDelete, onEdit }) => {
12
- const { selectedField, columns, statusKey, disableStatus, tableActions,disableCellThaoTac } = useDataTable();
12
+ export const TableRowRender = ({ index, row, selected, onSelect, onChangeStatus, onDelete, onEdit, onView }) => {
13
+ const { selectedField, columns, statusKey, disableStatus, tableActions, disableCellThaoTac } = useDataTable();
13
14
  const { canEdit, canDelete, canView, canAction } = usePermission();
14
15
 
15
16
  const { tableActionsOnTable, tableActionsOnMoreMenu } = useMemo(() => {
@@ -26,8 +27,8 @@ export const TableRowRender = ({ index, row, selected, onSelect, onChangeStatus,
26
27
  const tableActionsOnMoreMenu = tableActionsAfterFilter.filter(({ isOnTable = false }) => !isOnTable);
27
28
  return { tableActionsOnTable, tableActionsOnMoreMenu };
28
29
  }, [canView, canAction, tableActions]);
29
- const theme = useTheme();
30
- const downXl = useMediaQuery(theme.breakpoints.down("xl"));
30
+ const theme = useTheme();
31
+ const downXl = useMediaQuery(theme.breakpoints.down("xl"));
31
32
  return (
32
33
  <TableRow hover key={row[selectedField]} selected={selected}>
33
34
  <TableCell padding="checkbox">
@@ -72,11 +73,17 @@ export const TableRowRender = ({ index, row, selected, onSelect, onChangeStatus,
72
73
  {canEdit && (
73
74
  <Tooltip title="Chỉnh sửa">
74
75
  <IconButton size={downXl ? "small" : "medium"} onClick={() => onEdit(row)}>
75
- <EditOutlined color="primary" />
76
+ <EditOutlined fontSize="inherit" color="primary" />
77
+ </IconButton>
78
+ </Tooltip>
79
+ )}
80
+ {canView && !tableActions?.some(({ permissionType }) => permissionType == "view") && (
81
+ <Tooltip title="Xem chi tiết modal">
82
+ <IconButton onClick={() => onView(row)}>
83
+ <RemoveRedEyeOutlinedIcon color="info" />
76
84
  </IconButton>
77
85
  </Tooltip>
78
86
  )}
79
-
80
87
  {canDelete && (
81
88
  <Tooltip title="Xóa">
82
89
  <IconButton size={downXl ? "small" : "medium"}
@@ -84,7 +91,7 @@ export const TableRowRender = ({ index, row, selected, onSelect, onChangeStatus,
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
  )}
@@ -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,10 +9,11 @@ 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";
15
- import { useDataTable } from "./hooks";
16
+
16
17
 
17
18
  DataManagement.propTypes = {
18
19
  columns: PropTypes.array,
@@ -56,8 +57,8 @@ function DataManagement({
56
57
  disableCellThaoTac = false,
57
58
  tableActions = [],
58
59
  disableEditor = false,
59
- onAddClick = () => {},
60
- onEditClick = () => {},
60
+ onAddClick = () => { },
61
+ onEditClick = () => { },
61
62
  tabPanel,
62
63
  backParentNavigator,
63
64
  slotProps = {
@@ -68,6 +69,7 @@ function DataManagement({
68
69
  }) {
69
70
  const [openEditorDialog, setOpenEditorDialog] = useState(false);
70
71
  const [selectedEditItem, setSelectedEditItem] = useState(null);
72
+ const [openViewDialog, setOpenViewDialog] = useState(false);
71
73
 
72
74
  const [Permission, setPermission] = useState(null);
73
75
 
@@ -89,11 +91,7 @@ function DataManagement({
89
91
  return elementSize;
90
92
  }, [upXL]);
91
93
 
92
- useEffect(() => {
93
- if (selectedEditItem && disableEditor) {
94
- onEditClick(selectedEditItem);
95
- }
96
- }, [selectedEditItem]);
94
+
97
95
  useEffect(() => {
98
96
  setDataSearch({ ...dataSearch, ...defaults });
99
97
  }, [filters]);
@@ -107,6 +105,7 @@ function DataManagement({
107
105
  selectedEditItem,
108
106
  setSelectedEditItem,
109
107
  setOpenEditorDialog,
108
+ setOpenViewDialog,
110
109
  dataSearch,
111
110
  setDataSearch,
112
111
  validationSchema,
@@ -114,9 +113,10 @@ function DataManagement({
114
113
  disableStatus,
115
114
  disableCellThaoTac,
116
115
  disableAdd,
117
- tableActions
116
+ tableActions,
117
+ onEditClick
118
118
  };
119
- }, [tableName, selectedField, columns, selectedEditItem, dataSearch, setDataSearch, validationSchema, tableActions]);
119
+ }, [tableName, selectedField, columns, selectedEditItem, dataSearch, setDataSearch, validationSchema, tableActions, openViewDialog, setOpenViewDialog, onEditClick]);
120
120
  const permissionValues = useMemo(() => {
121
121
  return {
122
122
  Permission,
@@ -147,28 +147,28 @@ function DataManagement({
147
147
  setValue("Search");
148
148
  }}
149
149
  >
150
- <Refresh />
150
+ <Refresh fontSize="inherit" />
151
151
  </IconButton>
152
152
  </Tooltip>
153
153
 
154
154
  <ExportExcelButton tableName={tableName} data={dataSearch} size={elementSize} />
155
155
  {(!Permission || Permission.Create) && (
156
- (!disableAdd) && (
157
- <Button
158
- size={elementSize}
159
- variant="contained"
160
- startIcon={<Add />}
161
- onClick={(e) => {
162
- if (!disableEditor) {
163
- setOpenEditorDialog(true);
164
- setSelectedEditItem(null);
165
- }
166
- onAddClick(e);
167
- }}
168
- >
169
- Thêm
170
- </Button>
171
- )
156
+ (!disableAdd) && (
157
+ <Button
158
+ size={elementSize}
159
+ variant="contained"
160
+ startIcon={<Add fontSize="inherit" />}
161
+ onClick={(e) => {
162
+ if (!disableEditor) {
163
+ setOpenEditorDialog(true);
164
+ setSelectedEditItem(null);
165
+ }
166
+ onAddClick(e);
167
+ }}
168
+ >
169
+ Thêm
170
+ </Button>
171
+ )
172
172
  )}
173
173
  </Stack>
174
174
  </Stack>
@@ -188,6 +188,7 @@ function DataManagement({
188
188
  fields={editorFields}
189
189
  />
190
190
  )}
191
+ <ViewDetailDialog open={openViewDialog} onClose={() => setOpenViewDialog(false)} fields={editorFields} />
191
192
  </PermissionContext.Provider>
192
193
  </DataTableContext.Provider>
193
194
  </>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trithuc-mvc-react",
3
- "version": "1.6.6",
3
+ "version": "1.6.8",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"