2024-09-18 19:39:33 -04:00
|
|
|
import { Box, Button, Stack, Typography } from "@mui/material";
|
2024-10-03 09:12:59 +08:00
|
|
|
import { useSelector } from "react-redux";
|
2024-09-18 19:39:33 -04:00
|
|
|
import { useTheme } from "@emotion/react";
|
2024-10-03 09:12:59 +08:00
|
|
|
import { useEffect, useState } from "react";
|
2024-09-23 20:31:08 -04:00
|
|
|
import { ConfigBox } from "./styled";
|
|
|
|
|
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
|
|
|
|
import { LocalizationProvider } from "@mui/x-date-pickers";
|
|
|
|
|
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
2024-10-03 15:24:22 +08:00
|
|
|
import { MobileTimePicker } from "@mui/x-date-pickers/MobileTimePicker";
|
|
|
|
|
|
|
|
|
|
import dayjs from "dayjs";
|
|
|
|
|
|
2024-09-18 19:39:33 -04:00
|
|
|
import Select from "../../../Components/Inputs/Select";
|
|
|
|
|
import Field from "../../../Components/Inputs/Field";
|
2024-09-18 19:50:01 -04:00
|
|
|
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
2024-09-23 20:31:08 -04:00
|
|
|
import CalendarIcon from "../../../assets/icons/calendar.svg?react";
|
2024-09-18 19:39:33 -04:00
|
|
|
import "./index.css";
|
2024-10-03 09:12:59 +08:00
|
|
|
import Search from "../../../Components/Inputs/Search";
|
|
|
|
|
import { networkService } from "../../../main";
|
2024-09-18 21:22:22 -04:00
|
|
|
|
|
|
|
|
const repeatConfig = [
|
2024-10-03 15:24:22 +08:00
|
|
|
{ _id: 0, name: "Don't repeat", value: "none" },
|
|
|
|
|
{ _id: 1, name: "Repeat daily", value: "daily" },
|
|
|
|
|
{ _id: 2, name: "Repeat weekly", value: "weekly" },
|
2024-09-18 21:22:22 -04:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const durationConfig = [
|
|
|
|
|
{ _id: 0, name: "seconds" },
|
|
|
|
|
{ _id: 1, name: "minutes" },
|
|
|
|
|
{ _id: 2, name: "hours" },
|
|
|
|
|
{ _id: 3, name: "days" },
|
|
|
|
|
];
|
|
|
|
|
|
2024-10-03 15:24:22 +08:00
|
|
|
const getValueById = (config, id) => {
|
|
|
|
|
const item = config.find((config) => config._id === id);
|
|
|
|
|
return item ? (item.value ? item.value : item.name) : null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getIdByValue = (config, name) => {
|
|
|
|
|
const item = config.find((config) => {
|
|
|
|
|
if (config.value) return config.value === name;
|
|
|
|
|
else return config.name === name;
|
|
|
|
|
});
|
|
|
|
|
return item ? item._id : null;
|
|
|
|
|
};
|
2024-09-18 19:39:33 -04:00
|
|
|
|
|
|
|
|
const CreateMaintenance = () => {
|
|
|
|
|
const theme = useTheme();
|
2024-10-03 09:12:59 +08:00
|
|
|
const { user, authToken } = useSelector((state) => state.auth);
|
|
|
|
|
const [monitors, setMonitors] = useState([]);
|
|
|
|
|
const [search, setSearch] = useState("");
|
2024-10-03 15:24:22 +08:00
|
|
|
const [form, setForm] = useState({
|
|
|
|
|
repeat: "none",
|
|
|
|
|
startDate: dayjs().toISOString(),
|
|
|
|
|
startTime: dayjs().toISOString(),
|
|
|
|
|
duration: "",
|
|
|
|
|
durationUnit: "seconds",
|
|
|
|
|
name: "",
|
|
|
|
|
monitors: [],
|
|
|
|
|
});
|
2024-09-18 19:39:33 -04:00
|
|
|
|
2024-10-03 09:12:59 +08:00
|
|
|
useEffect(() => {
|
|
|
|
|
const fetchMonitors = async () => {
|
|
|
|
|
const response = await networkService.getMonitorsByTeamId({
|
|
|
|
|
authToken: authToken,
|
|
|
|
|
teamId: user.teamId,
|
|
|
|
|
limit: -1,
|
|
|
|
|
types: ["http", "ping", "pagespeed"],
|
|
|
|
|
});
|
|
|
|
|
setMonitors(response.data.data.monitors);
|
|
|
|
|
};
|
|
|
|
|
fetchMonitors();
|
|
|
|
|
}, [authToken, user]);
|
|
|
|
|
|
|
|
|
|
const handleSearch = (value) => {
|
|
|
|
|
setSearch(value);
|
|
|
|
|
};
|
|
|
|
|
|
2024-10-03 15:24:22 +08:00
|
|
|
const handleSelectMonitors = (monitors) => {
|
|
|
|
|
setForm({ ...form, monitors });
|
2024-10-03 09:12:59 +08:00
|
|
|
};
|
2024-10-03 15:24:22 +08:00
|
|
|
|
|
|
|
|
const handleFormChange = (key, value) => {
|
|
|
|
|
setForm({ ...form, [key]: value });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleTimeChange = (key, newTime) => {
|
|
|
|
|
setForm({ ...form, [key]: newTime });
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-18 19:50:01 -04:00
|
|
|
return (
|
|
|
|
|
<Box className="create-maintenance">
|
|
|
|
|
<Breadcrumbs
|
|
|
|
|
list={[
|
2024-10-03 09:12:59 +08:00
|
|
|
{ name: "maintenance", path: "/maintenance" },
|
2024-09-18 19:50:01 -04:00
|
|
|
{ name: "create", path: `/maintenance/create` },
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
<Stack
|
|
|
|
|
component="form"
|
|
|
|
|
noValidate
|
|
|
|
|
spellCheck="false"
|
|
|
|
|
gap={theme.spacing(12)}
|
|
|
|
|
mt={theme.spacing(6)}
|
|
|
|
|
>
|
2024-09-18 21:22:22 -04:00
|
|
|
<Box>
|
|
|
|
|
<Typography component="h1" variant="h1">
|
|
|
|
|
<Typography component="span" fontSize="inherit">
|
|
|
|
|
Create a{" "}
|
|
|
|
|
</Typography>
|
|
|
|
|
<Typography
|
|
|
|
|
component="span"
|
|
|
|
|
variant="h2"
|
|
|
|
|
fontSize="inherit"
|
|
|
|
|
fontWeight="inherit"
|
|
|
|
|
>
|
|
|
|
|
maintenance{" "}
|
|
|
|
|
</Typography>
|
|
|
|
|
<Typography component="span" fontSize="inherit">
|
|
|
|
|
window
|
|
|
|
|
</Typography>
|
2024-09-18 19:50:01 -04:00
|
|
|
</Typography>
|
2024-09-18 21:22:22 -04:00
|
|
|
<Typography component="h2" variant="body2" fontSize={14}>
|
2024-10-03 09:12:59 +08:00
|
|
|
Your pings won't be sent during this time frame
|
2024-09-18 21:22:22 -04:00
|
|
|
</Typography>
|
|
|
|
|
</Box>
|
|
|
|
|
<ConfigBox direction="row">
|
|
|
|
|
<Typography component="h2" variant="h2">
|
|
|
|
|
General Settings
|
|
|
|
|
</Typography>
|
|
|
|
|
<Box
|
2024-09-23 20:31:08 -04:00
|
|
|
px={theme.spacing(14)}
|
2024-09-18 21:22:22 -04:00
|
|
|
borderLeft={1}
|
|
|
|
|
borderLeftColor={theme.palette.border.light}
|
|
|
|
|
>
|
|
|
|
|
<Select
|
|
|
|
|
id="maintenance-repeat"
|
2024-10-03 15:24:22 +08:00
|
|
|
name="maintenance-repeat"
|
2024-09-18 21:22:22 -04:00
|
|
|
label="Maintenance Repeat"
|
2024-10-03 15:24:22 +08:00
|
|
|
value={getIdByValue(repeatConfig, form.repeat)}
|
|
|
|
|
onChange={(event) => {
|
|
|
|
|
handleFormChange(
|
|
|
|
|
"repeat",
|
|
|
|
|
getValueById(repeatConfig, event.target.value)
|
|
|
|
|
);
|
|
|
|
|
}}
|
2024-09-18 21:22:22 -04:00
|
|
|
items={repeatConfig}
|
|
|
|
|
/>
|
2024-09-23 20:31:08 -04:00
|
|
|
<Stack gap={theme.spacing(2)} mt={theme.spacing(16)}>
|
|
|
|
|
<Typography component="h3">Date</Typography>
|
|
|
|
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
|
|
|
|
<DatePicker
|
|
|
|
|
disablePast
|
|
|
|
|
disableHighlightToday
|
|
|
|
|
slots={{ openPickerIcon: CalendarIcon }}
|
|
|
|
|
slotProps={{
|
|
|
|
|
switchViewButton: { sx: { display: "none" } },
|
|
|
|
|
nextIconButton: { sx: { ml: theme.spacing(2) } },
|
|
|
|
|
field: {
|
|
|
|
|
sx: {
|
|
|
|
|
width: "fit-content",
|
|
|
|
|
"& > .MuiOutlinedInput-root": {
|
|
|
|
|
flexDirection: "row-reverse",
|
|
|
|
|
},
|
|
|
|
|
"& input": {
|
|
|
|
|
height: 34,
|
|
|
|
|
p: 0,
|
|
|
|
|
pr: theme.spacing(5),
|
|
|
|
|
},
|
|
|
|
|
"& fieldset": {
|
|
|
|
|
borderColor: theme.palette.border.dark,
|
|
|
|
|
borderRadius: theme.shape.borderRadius,
|
|
|
|
|
},
|
|
|
|
|
"&:not(:has(.Mui-disabled)):not(:has(.Mui-error)) .MuiOutlinedInput-root:not(:has(input:focus)):hover fieldset":
|
|
|
|
|
{
|
|
|
|
|
borderColor: theme.palette.border.dark,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
inputAdornment: { sx: { ml: 0, px: 3 } },
|
|
|
|
|
openPickerButton: {
|
|
|
|
|
sx: {
|
|
|
|
|
py: 0,
|
|
|
|
|
mr: 0,
|
|
|
|
|
"& path": {
|
|
|
|
|
stroke: theme.palette.other.icon,
|
|
|
|
|
strokeWidth: 1.1,
|
|
|
|
|
},
|
|
|
|
|
"&:hover": { backgroundColor: "transparent" },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
sx={{}}
|
2024-10-03 15:24:22 +08:00
|
|
|
onChange={(newDate) => {
|
|
|
|
|
handleTimeChange("startDate", newDate.toISOString());
|
|
|
|
|
}}
|
2024-09-23 20:31:08 -04:00
|
|
|
/>
|
|
|
|
|
</LocalizationProvider>
|
|
|
|
|
</Stack>
|
2024-09-18 21:22:22 -04:00
|
|
|
</Box>
|
|
|
|
|
</ConfigBox>
|
|
|
|
|
<ConfigBox>
|
|
|
|
|
<Stack direction="row">
|
|
|
|
|
<Box>
|
|
|
|
|
<Typography component="h2" variant="h2">
|
|
|
|
|
Start time
|
|
|
|
|
</Typography>
|
|
|
|
|
<Typography>
|
|
|
|
|
All dates and times are in GMT+0 time zone.
|
|
|
|
|
</Typography>
|
|
|
|
|
</Box>
|
|
|
|
|
<Stack direction="row">
|
2024-10-03 15:24:22 +08:00
|
|
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
|
|
|
|
<MobileTimePicker
|
|
|
|
|
id="maintenance-start-time"
|
|
|
|
|
value={dayjs(form.startTime)}
|
|
|
|
|
onChange={(newTime) => {
|
|
|
|
|
handleTimeChange("startTime", newTime.toISOString());
|
|
|
|
|
}}
|
|
|
|
|
slotProps={{
|
|
|
|
|
nextIconButton: { sx: { ml: theme.spacing(2) } },
|
|
|
|
|
field: {
|
|
|
|
|
sx: {
|
|
|
|
|
width: "fit-content",
|
|
|
|
|
"& > .MuiOutlinedInput-root": {
|
|
|
|
|
flexDirection: "row-reverse",
|
|
|
|
|
},
|
|
|
|
|
"& input": {
|
|
|
|
|
height: 34,
|
|
|
|
|
p: 0,
|
|
|
|
|
pl: theme.spacing(5),
|
|
|
|
|
},
|
|
|
|
|
"& fieldset": {
|
|
|
|
|
borderColor: theme.palette.border.dark,
|
|
|
|
|
borderRadius: theme.shape.borderRadius,
|
|
|
|
|
},
|
|
|
|
|
"&:not(:has(.Mui-disabled)):not(:has(.Mui-error)) .MuiOutlinedInput-root:not(:has(input:focus)):hover fieldset":
|
|
|
|
|
{
|
|
|
|
|
borderColor: theme.palette.border.dark,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</LocalizationProvider>
|
2024-09-18 21:22:22 -04:00
|
|
|
</Stack>
|
|
|
|
|
</Stack>
|
|
|
|
|
<Stack direction="row">
|
|
|
|
|
<Box>
|
|
|
|
|
<Typography component="h2" variant="h2">
|
|
|
|
|
Duration
|
|
|
|
|
</Typography>
|
|
|
|
|
</Box>
|
2024-10-03 15:24:22 +08:00
|
|
|
<Stack direction="row" spacing={theme.spacing(8)}>
|
|
|
|
|
<Field
|
|
|
|
|
type="number"
|
|
|
|
|
id="maintenance-duration"
|
|
|
|
|
value={form.duration}
|
|
|
|
|
onChange={(event) => {
|
|
|
|
|
handleFormChange("duration", event.target.value);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
2024-10-03 09:12:59 +08:00
|
|
|
<Select
|
|
|
|
|
id="maintenance-unit"
|
2024-10-03 15:24:22 +08:00
|
|
|
value={getIdByValue(durationConfig, form.durationUnit)}
|
2024-10-03 09:12:59 +08:00
|
|
|
items={durationConfig}
|
2024-10-03 15:24:22 +08:00
|
|
|
onChange={(event) => {
|
|
|
|
|
handleFormChange(
|
|
|
|
|
"durationUnit",
|
|
|
|
|
getValueById(durationConfig, event.target.value)
|
|
|
|
|
);
|
|
|
|
|
}}
|
2024-10-03 09:12:59 +08:00
|
|
|
/>
|
2024-09-18 21:22:22 -04:00
|
|
|
</Stack>
|
|
|
|
|
</Stack>
|
|
|
|
|
</ConfigBox>
|
|
|
|
|
<Box>
|
2024-09-18 19:50:01 -04:00
|
|
|
<Typography
|
2024-09-18 21:22:22 -04:00
|
|
|
component="h2"
|
2024-09-18 19:50:01 -04:00
|
|
|
variant="h2"
|
2024-09-18 21:22:22 -04:00
|
|
|
fontSize={16}
|
|
|
|
|
my={theme.spacing(6)}
|
2024-09-18 19:50:01 -04:00
|
|
|
>
|
2024-09-18 21:22:22 -04:00
|
|
|
Monitor related settings
|
2024-09-18 19:50:01 -04:00
|
|
|
</Typography>
|
2024-09-18 21:22:22 -04:00
|
|
|
<ConfigBox>
|
|
|
|
|
<Stack direction="row">
|
|
|
|
|
<Box>
|
|
|
|
|
<Typography component="h2" variant="h2">
|
|
|
|
|
Friendly name
|
|
|
|
|
</Typography>
|
|
|
|
|
</Box>
|
|
|
|
|
<Box>
|
|
|
|
|
<Field
|
|
|
|
|
id="maintenance-name"
|
2024-10-03 09:12:59 +08:00
|
|
|
placeholder="Maintenance at __ : __ for ___ minutes"
|
2024-10-03 15:24:22 +08:00
|
|
|
value={form.name}
|
|
|
|
|
onChange={(event) => {
|
|
|
|
|
handleFormChange("name", event.target.value);
|
|
|
|
|
}}
|
2024-09-18 21:22:22 -04:00
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
</Stack>
|
|
|
|
|
<Stack direction="row">
|
2024-10-03 09:12:59 +08:00
|
|
|
<Box>
|
|
|
|
|
<Typography component="h2" variant="h2">
|
|
|
|
|
Add monitors
|
|
|
|
|
</Typography>
|
|
|
|
|
</Box>
|
|
|
|
|
<Box>
|
|
|
|
|
<Search
|
2024-10-03 15:24:22 +08:00
|
|
|
multiple={true}
|
|
|
|
|
isAdorned={false}
|
2024-10-03 09:12:59 +08:00
|
|
|
options={monitors ? monitors : []}
|
|
|
|
|
filteredBy="name"
|
|
|
|
|
secondaryLabel={"type"}
|
|
|
|
|
value={search}
|
|
|
|
|
handleInputChange={handleSearch}
|
2024-10-03 15:24:22 +08:00
|
|
|
handleChange={handleSelectMonitors}
|
2024-10-03 09:12:59 +08:00
|
|
|
/>
|
|
|
|
|
</Box>
|
2024-09-18 21:22:22 -04:00
|
|
|
</Stack>
|
|
|
|
|
</ConfigBox>
|
|
|
|
|
</Box>
|
2024-09-18 19:50:01 -04:00
|
|
|
<Box ml="auto" display="inline-block">
|
|
|
|
|
<Button
|
|
|
|
|
variant="contained"
|
|
|
|
|
color="secondary"
|
|
|
|
|
onClick={() => console.log("disabled")}
|
|
|
|
|
sx={{ mr: theme.spacing(6) }}
|
|
|
|
|
>
|
|
|
|
|
Cancel
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
variant="contained"
|
|
|
|
|
color="primary"
|
2024-10-03 15:24:22 +08:00
|
|
|
onClick={() => console.log(form)}
|
2024-09-18 19:50:01 -04:00
|
|
|
disabled={false}
|
|
|
|
|
>
|
2024-09-23 20:31:08 -04:00
|
|
|
Create maintenance
|
2024-09-18 19:50:01 -04:00
|
|
|
</Button>
|
|
|
|
|
</Box>
|
|
|
|
|
</Stack>
|
|
|
|
|
</Box>
|
|
|
|
|
);
|
2024-09-18 19:39:33 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default CreateMaintenance;
|