trithuc-mvc-react 1.6.13 → 1.6.14

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.
@@ -34,7 +34,7 @@ const DataTable = () => {
34
34
  onSuccess: ({ PermissionModel, status }) => {
35
35
  if (status) {
36
36
  // setPermission(PermissionModel);
37
- console.log("LOAD LAI PermissionModel");
37
+ // console.log("LOAD LAI PermissionModel");
38
38
  }
39
39
  }
40
40
  });
@@ -28,7 +28,7 @@ function EditorForm({ fields, submitRef }) {
28
28
  if (selectedEditItem) {
29
29
  setValue("Id", selectedEditItem.Id);
30
30
 
31
- fields.forEach(({ field, onChange, type, keyValue, keyValueLabel, defaultValue, }) => {
31
+ fields.forEach(({ field, onChange, type, keyValue, keyValueLabel, defaultValue }) => {
32
32
  if (type == "autocomplete") {
33
33
  onChange?.({
34
34
  [keyValue]: selectedEditItem[field]
@@ -44,8 +44,7 @@ function EditorForm({ fields, submitRef }) {
44
44
  if (typeof fileValue == "string") {
45
45
  fileValue = JSON.parse(fileValue);
46
46
  }
47
- }
48
- catch (e) {
47
+ } catch (e) {
49
48
  fileValue = [];
50
49
  }
51
50
  setValue(field, fileValue);
@@ -64,12 +63,10 @@ function EditorForm({ fields, submitRef }) {
64
63
  if (type === "switch" && defaultValue === undefined) {
65
64
  methods.setValue(field, true);
66
65
  } else {
67
-
68
66
  methods.setValue(field, defaultValue);
69
67
  }
70
68
  });
71
69
  }
72
-
73
70
  }, [selectedEditItem]);
74
71
 
75
72
  const saveMutation = useMutation(saveDataToTable, {
@@ -116,9 +113,12 @@ function EditorForm({ fields, submitRef }) {
116
113
  }
117
114
  });
118
115
  };
116
+ const onValid = (data) => {
117
+ console.log(data);
118
+ };
119
119
  return (
120
120
  <FormProvider {...methods}>
121
- <Box component={"form"} onSubmit={methods.handleSubmit(onSubmit)}>
121
+ <Box component={"form"} onSubmit={methods.handleSubmit(onSubmit, onValid)}>
122
122
  <Grid container spacing={2}>
123
123
  {fields.map(
124
124
  ({
@@ -129,7 +129,7 @@ function EditorForm({ fields, submitRef }) {
129
129
  childrenFields,
130
130
  datas,
131
131
  loading = false,
132
- onChange = () => { },
132
+ onChange = () => {},
133
133
  keyLabel,
134
134
  keyValue,
135
135
  keyValueLabel,
@@ -1,12 +1,14 @@
1
- import { Accordion, AccordionSummary, Box, FormControl, InputLabel, MenuItem, Select, Slider, Toolbar, Typography } from "@mui/material";
1
+ import { Accordion, AccordionSummary, Box, Slider, Typography } from "@mui/material";
2
2
  import { useFormContext } from "react-hook-form";
3
3
  import Grid from "@mui/material/Unstable_Grid2";
4
- import DateRangePicker from "../date/DateRangePicker";
4
+
5
5
  import { FilterElement } from "./FilterElement";
6
6
  import { useDataTable } from "./hooks";
7
7
 
8
- import AccordionDetails from '@mui/material/AccordionDetails';
9
- import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
8
+ import AccordionDetails from "@mui/material/AccordionDetails";
9
+ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
10
+ import { DateRangePicker } from "../date";
11
+ import { ArraySchema } from "yup";
10
12
 
11
13
  export const FilterGod = ({ filters, elementSize = "small" }) => {
12
14
  const { handleSubmit } = useFormContext();
@@ -14,15 +16,12 @@ export const FilterGod = ({ filters, elementSize = "small" }) => {
14
16
  const { setDataSearch, dataSearch } = useDataTable();
15
17
 
16
18
  return (
17
- <Box
18
- component={"form"}
19
- onSubmit={handleSubmit(onSubmit)}
20
- >
19
+ <Box component={"form"} onSubmit={handleSubmit(onSubmit)}>
21
20
  <Accordion>
22
21
  <AccordionSummary
23
22
  sx={{
24
23
  minHeight: 40,
25
- '& .MuiAccordionSummary-content': {
24
+ "& .MuiAccordionSummary-content": {
26
25
  my: 1
27
26
  }
28
27
  }}
@@ -36,15 +35,21 @@ export const FilterGod = ({ filters, elementSize = "small" }) => {
36
35
  <Grid container spacing={1}>
37
36
  {filters.map(({ field, size, ...rest }) => {
38
37
  if (rest.type === "date-range") {
38
+ let label = ["từ ngày", "tới ngày"];
39
+
40
+ if (Array.isArray(field.label)) {
41
+ label = field.label;
42
+ }
39
43
  return (
40
44
  <Grid key={field.toString()} md={size?.md} xs={size?.xs} sm={size?.sm}>
41
45
  <DateRangePicker
46
+ label={label}
42
47
  onChange={(value) => {
43
- setDataSearch(({ previousState }) => ({
44
- ...previousState,
48
+ setDataSearch({
49
+ ...dataSearch,
45
50
  [field[0]]: value[0],
46
51
  [field[1]]: value[1]
47
- }));
52
+ });
48
53
  }}
49
54
  size={elementSize}
50
55
  value={[dataSearch?.[field[0]], dataSearch?.[field[1]]]}
@@ -55,10 +60,7 @@ export const FilterGod = ({ filters, elementSize = "small" }) => {
55
60
 
56
61
  if (rest.type === "slider-range") {
57
62
  return (
58
- <Grid
59
- key={field.toString()}
60
- md={size?.md} xs={size?.xs} sm={size?.sm}
61
- >
63
+ <Grid key={field.toString()} md={size?.md} xs={size?.xs} sm={size?.sm}>
62
64
  <Slider
63
65
  onChange={(e, value) => {
64
66
  setDataSearch({
@@ -78,7 +80,7 @@ export const FilterGod = ({ filters, elementSize = "small" }) => {
78
80
  );
79
81
  }
80
82
  return (
81
- <Grid key={field} md={size?.md} xs={size?.xs} sm={size?.sm} >
83
+ <Grid key={field} md={size?.md} xs={size?.xs} sm={size?.sm}>
82
84
  <FilterElement name={field} {...rest} size={elementSize} />
83
85
  </Grid>
84
86
  );
@@ -5,139 +5,182 @@ import StaticDateRangePicker from "./StaticDateRangePicker";
5
5
  import moment from "moment";
6
6
  import { memo, useEffect, useRef, useState } from "react";
7
7
  import * as dateFns from "date-fns";
8
+ import { useTheme, useMediaQuery } from "@mui/material";
9
+ import { useDateRangeContext } from ".";
10
+ let timeoutStart = null;
11
+ let timeoutEnd = null;
12
+ let timeoutProper = null;
8
13
 
9
-
10
- const DateRangePicker = ({ onChange = () => {}, value }) => {
14
+ const DateRangePicker = ({ label = ["Từ ngày", "Đến ngày"] }) => {
11
15
  const [anchorEl, setAnchorEl] = useState(null);
16
+ const { dateRange, setDateRange, setIsFocusStart, setIsFocusEnd, isFocusStart, isFocusEnd, setIsFocusPoper, isFocusPoper } =
17
+ useDateRangeContext();
12
18
 
13
- const [dateRange, setDateRange] = useState({
14
- startDate: value?.[0],
15
- endDate: value?.[1]
16
- });
17
-
18
- const handleFocus = (event) => {
19
+ const handleFocus1 = (event) => {
20
+ if (timeoutStart) {
21
+ clearTimeout(timeoutStart);
22
+ }
23
+ setIsFocusStart(true);
24
+ setAnchorEl(containerRef.current);
25
+ };
26
+ const handleFocus2 = (event) => {
27
+ if (timeoutEnd) {
28
+ clearTimeout(timeoutEnd);
29
+ }
30
+ setIsFocusEnd(true);
31
+ setAnchorEl(containerRef.current);
32
+ };
33
+ const handleBlur1 = (event) => {
34
+ if (timeoutStart) {
35
+ clearTimeout(timeoutStart);
36
+ }
37
+ timeoutStart = setTimeout(() => {
38
+ setIsFocusStart(false);
39
+ }, 300);
40
+ // setIsFocusStart(false);
19
41
  setAnchorEl(containerRef.current);
20
42
  };
43
+ const handleBlur2 = (event) => {
44
+ if (timeoutEnd) {
45
+ clearTimeout(timeoutEnd);
46
+ }
47
+ setAnchorEl(containerRef.current);
48
+ timeoutEnd = setTimeout(() => {
49
+ setIsFocusEnd(false);
50
+ }, 300);
51
+ };
21
52
  const handleClose = () => {
22
53
  setAnchorEl(null);
23
54
  };
24
- const handleClickAway = () => {
25
- setAnchorEl(null);
55
+ const handleClickAway = (e) => {
56
+ timeoutProper = setTimeout(() => {
57
+ setIsFocusPoper(false);
58
+ }, 500);
59
+ };
60
+ const handleClickPopper = (e) => {
61
+ if (timeoutProper) {
62
+ clearTimeout(timeoutProper);
63
+ }
64
+ if (!isFocusPoper) {
65
+ setIsFocusPoper(true);
66
+ }
26
67
  };
27
68
 
28
- const open = Boolean(anchorEl);
69
+ const open = isFocusStart || isFocusEnd || isFocusPoper;
70
+
71
+ // console.log("open", open);
29
72
  const containerRef = useRef(null);
73
+ const theme = useTheme();
74
+ const downXl = useMediaQuery(theme.breakpoints.down("xl"));
75
+ const elementSize = downXl ? "small" : "medium";
30
76
 
31
77
  useEffect(() => {
32
- if (dateFns.isBefore(dateRange.startDate, dateRange.endDate) || dateFns.isSameDay(dateRange.startDate, dateRange.endDate)) {
33
- onChange([dateRange.startDate, dateRange.endDate]);
34
- }
35
- }, [dateRange]);
78
+ setAnchorEl(containerRef.current);
79
+ }, []);
80
+ // useEffect(() => {
81
+ // console.log("CHANGEEEE");
82
+ // }, [isFocusStart, isFocusEnd]);
83
+ // useEffect(() => {
84
+ // if (dateFns.isBefore(dateRange.startDate, dateRange.endDate) || dateFns.isSameDay(dateRange.startDate, dateRange.endDate)) {
85
+ // onChange([dateRange.startDate, dateRange.endDate]);
86
+ // }
87
+ // }, [dateRange]);
36
88
 
37
- useEffect(() => {
38
- if (!value) return;
39
- if (dateFns.isSameDay(dateRange.startDate, value[0]) && dateFns.isSameDay(dateRange.endDate, value[1])) {
40
- return;
41
- }
42
- setDateRange({
43
- startDate: value?.[0],
44
- endDate: value?.[1]
45
- });
46
- }, [value]);
89
+ // useEffect(() => {
90
+ // if (!value) return;
91
+ // if (dateFns.isSameDay(dateRange.startDate, value[0]) && dateFns.isSameDay(dateRange.endDate, value[1])) {
92
+ // return;
93
+ // }
94
+ // setDateRange({
95
+ // startDate: value?.[0],
96
+ // endDate: value?.[1]
97
+ // });
98
+ // }, [value]);
47
99
 
48
100
  return (
49
101
  <>
102
+ <Stack ref={containerRef} direction={"row"} alignContent={"center"} spacing={1}>
103
+ <DateField
104
+ sx={{ flex: 1 }}
105
+ format={DEFAULT_DATE_FORMAT}
106
+ onFocus={handleFocus1}
107
+ onBlur={handleBlur1}
108
+ label={label[0]}
109
+ onChange={(value) => {
110
+ setDateRange((d) => ({
111
+ ...d,
112
+ startDate: value ? value.toDate() : null
113
+ }));
114
+ }}
115
+ value={dateRange.startDate && moment(dateRange.startDate)}
116
+ size={elementSize}
117
+ maxDate={dateRange.endDate ?? moment(dateRange.endDate)}
118
+ />
119
+ <Typography variant="body1" sx={{ height: "24px", alignSelf: "center" }}>
120
+
121
+ </Typography>
122
+ <DateField
123
+ sx={{ flex: 1 }}
124
+ format={DEFAULT_DATE_FORMAT}
125
+ label={label[1]}
126
+ onFocus={handleFocus2}
127
+ onBlur={handleBlur2}
128
+ onChange={(value) => {
129
+ setDateRange((d) => ({
130
+ ...d,
131
+ endDate: value ? value.toDate() : null
132
+ }));
133
+ }}
134
+ value={dateRange.endDate && moment(dateRange.endDate)}
135
+ size={elementSize}
136
+ minDate={dateRange.startDate ?? moment(dateRange.startDate)}
137
+ />
138
+ </Stack>
50
139
  <ClickAwayListener onClickAway={handleClickAway}>
51
- <Stack ref={containerRef} direction={"row"} alignContent={"center"} spacing={1}>
52
- <DateField
53
- sx={{ flex: 1 }}
54
- format={DEFAULT_DATE_FORMAT}
55
- onFocus={handleFocus}
56
- label="Từ ngày"
57
- onChange={(value) => {
58
- setDateRange((d) => ({
59
- ...d,
60
- startDate: value.toDate()
61
- }));
62
- }}
63
- value={dateRange.startDate && moment(dateRange.startDate)}
64
- size="small"
65
- maxDate={dateRange.endDate ?? moment(dateRange.endDate)}
66
- />
67
- <Typography variant="body1" sx={{ height: "24px", alignSelf: "center" }}>
68
-
69
- </Typography>
70
- <DateField
71
- sx={{ flex: 1 }}
72
- format={DEFAULT_DATE_FORMAT}
73
- label="Tới ngày"
74
- onFocus={handleFocus}
75
- onChange={(value) => {
76
- setDateRange((d) => ({
77
- ...d,
78
- endDate: value.toDate()
79
- }));
80
-
81
- }}
82
- value={dateRange.endDate && moment(dateRange.endDate)}
83
- size="small"
84
- minDate={dateRange.startDate ?? moment(dateRange.startDate)}
85
- />
140
+ <Popper
141
+ sx={{
142
+ zIndex: 1036
143
+ }}
144
+ keepMounted
145
+ placement="bottom-start"
146
+ open={open}
147
+ anchorEl={anchorEl}
148
+ onClose={handleClose}
149
+ onClick={handleClickPopper}
86
150
 
87
- <Popper
88
- sx={{
89
- zIndex: 1036
151
+ // modifiers={[
152
+ // {
153
+ // name: "flip",
154
+ // enabled: true,
155
+ // options: {
156
+ // altBoundary: true,
157
+ // rootBoundary: "viewport",
158
+ // padding: 8
159
+ // }
160
+ // },
161
+ // {
162
+ // name: "preventOverflow",
163
+ // enabled: true,
164
+ // options: {
165
+ // altAxis: true,
166
+ // altBoundary: true,
167
+ // tether: true,
168
+ // rootBoundary: "document",
169
+ // padding: 8
170
+ // }
171
+ // }
172
+ // ]}
173
+ >
174
+ <StaticDateRangePicker
175
+ value={dateRange}
176
+ onUpdate={(value) => {
177
+ setDateRange(value);
90
178
  }}
91
- keepMounted
92
- placement="bottom-start"
93
- open={open}
94
- anchorEl={anchorEl}
95
- onClose={handleClose}
96
- disablePortal={false}
97
- modifiers={[
98
- {
99
- name: "flip",
100
- enabled: true,
101
- options: {
102
- altBoundary: true,
103
- rootBoundary: "viewport",
104
- padding: 8
105
- }
106
- },
107
- {
108
- name: "preventOverflow",
109
- enabled: true,
110
- options: {
111
- altAxis: true,
112
- altBoundary: true,
113
- tether: true,
114
- rootBoundary: "document",
115
- padding: 8
116
- }
117
- }
118
- ]}
119
- >
120
- <StaticDateRangePicker
121
- value={dateRange}
122
- onUpdate={(value) => {
123
- setDateRange(value);
124
- }}
125
- />
126
- </Popper>
127
- </Stack>
179
+ />
180
+ </Popper>
128
181
  </ClickAwayListener>
129
182
  </>
130
183
  );
131
184
  };
132
- const DateRangePickerMemo = memo(DateRangePicker, (prevProps, nextProps) => {
133
- try {
134
- if (dateFns.isSameDay(prevProps.value[0], nextProps.value[0]) && dateFns.isSameDay(prevProps.value[1], nextProps.value[1])) {
135
- return true; // props are equal
136
- }
137
- } catch (error) {
138
- console.log(error);
139
- }
140
185
 
141
- return false; // props are not equal -> update the component
142
- });
143
- export default DateRangePickerMemo;
186
+ export default DateRangePicker;