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.
- package/components/DataManagement/DataTable.jsx +1 -1
- package/components/DataManagement/EditorForm.jsx +7 -7
- package/components/DataManagement/FilterGod.jsx +19 -17
- package/components/date/DateRangePicker.jsx +154 -111
- package/components/date/StaticDateRangePicker.jsx +258 -294
- package/components/date/context.js +0 -0
- package/components/date/index.jsx +64 -0
- package/package.json +1 -1
- package/styles/index.css +0 -275
- package/components/date/index.js +0 -1
|
@@ -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,
|
|
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
|
-
|
|
4
|
+
|
|
5
5
|
import { FilterElement } from "./FilterElement";
|
|
6
6
|
import { useDataTable } from "./hooks";
|
|
7
7
|
|
|
8
|
-
import AccordionDetails from
|
|
9
|
-
import ExpandMoreIcon from
|
|
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
|
-
|
|
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(
|
|
44
|
-
...
|
|
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
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
92
|
-
|
|
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
|
-
|
|
142
|
-
});
|
|
143
|
-
export default DateRangePickerMemo;
|
|
186
|
+
export default DateRangePicker;
|