From 91a2a72bf2be06df7a0510991678a5a336f9544c Mon Sep 17 00:00:00 2001 From: Daniel Cojocea Date: Wed, 18 Sep 2024 19:39:33 -0400 Subject: [PATCH 01/44] Purged outdated code --- Client/src/App.jsx | 4 +- .../index.css | 0 .../Maintenance/CreateMaintenance/index.jsx | 22 ++ .../CreateMaintenanceWindow/index.jsx | 298 ------------------ .../Pages/Monitors/CreateMonitor/index.css | 34 -- 5 files changed, 24 insertions(+), 334 deletions(-) rename Client/src/Pages/Maintenance/{CreateMaintenanceWindow => CreateMaintenance}/index.css (100%) create mode 100644 Client/src/Pages/Maintenance/CreateMaintenance/index.jsx delete mode 100644 Client/src/Pages/Maintenance/CreateMaintenanceWindow/index.jsx diff --git a/Client/src/App.jsx b/Client/src/App.jsx index d6fca146f..3cc9e5bd6 100644 --- a/Client/src/App.jsx +++ b/Client/src/App.jsx @@ -25,7 +25,7 @@ import withAdminProp from "./HOC/withAdminProp"; import Configure from "./Pages/Monitors/Configure"; import PageSpeed from "./Pages/PageSpeed"; import CreatePageSpeed from "./Pages/PageSpeed/CreatePageSpeed"; -import CreateNewMaintenanceWindow from "./Pages/Maintenance/CreateMaintenanceWindow"; +import CreateMaintenance from "./Pages/Maintenance/CreateMaintenance"; import PageSpeedDetails from "./Pages/PageSpeed/Details"; import PageSpeedConfigure from "./Pages/PageSpeed/Configure"; import { ThemeProvider } from "@emotion/react"; @@ -89,7 +89,7 @@ function App() { /> } + element={} /> { + const theme = useTheme(); + + return ; +}; + +export default CreateMaintenance; diff --git a/Client/src/Pages/Maintenance/CreateMaintenanceWindow/index.jsx b/Client/src/Pages/Maintenance/CreateMaintenanceWindow/index.jsx deleted file mode 100644 index 43102ac21..000000000 --- a/Client/src/Pages/Maintenance/CreateMaintenanceWindow/index.jsx +++ /dev/null @@ -1,298 +0,0 @@ -import { Box, Button, Stack, Typography } from "@mui/material"; -import "./index.css"; -import { useState } from "react"; -import Back from "../../../assets/icons/left-arrow-long.svg?react"; -import Select from "../../../Components/Inputs/Select"; -import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; -import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; -import dayjs from "dayjs"; -import { DatePicker } from "@mui/x-date-pickers/DatePicker"; -import { MobileTimePicker } from "@mui/x-date-pickers/MobileTimePicker"; -import Field from "../../../Components/Inputs/Field"; -import { maintenanceWindowValidation } from "../../../Validation/validation"; -import { logger } from "../../../Utils/Logger"; -import { createToast } from "../../../Utils/toastUtils"; -import { useTheme } from "@emotion/react"; - -const directory = { - title: "Create a maintenance window", - description: "Your pings won’t be sent in this time frame.", -}; - -const repeatOptions = [ - { _id: 1, name: "Don't repeat" }, - { _id: 2, name: "Repeat daily" }, - { _id: 3, name: "Repeat weekly" }, -]; - -const configOptionTitle = (title, description) => { - return ( - - - {title} - - {description && ( - - {description} - - )} - - ); -}; - -const durationOptions = [ - { _id: "minutes", name: "minutes" }, - { _id: "hours", name: "hours" }, - { _id: "days", name: "days" }, -]; - -const CreateNewMaintenanceWindow = () => { - const theme = useTheme(); - - const [values, setValues] = useState({ - repeat: 1, - date: dayjs(), - startTime: dayjs(), - duration: "60", - unit: "minutes", - displayName: "", - AddMonitors: "", - }); - const [errors, setErrors] = useState({}); - - const handleChange = (event, name) => { - const { value } = event.target; - setValues((prev) => ({ - ...prev, - [name]: value, - })); - }; - - const handleSubmit = async () => { - const data = { - repeat: values.repeat, - date: values.date.format("YYYY-MM-DD"), - startTime: values.startTime.format("HH:mm"), - duration: values.duration, - unit: values.unit, - displayName: values.displayName, - addMonitors: values.AddMonitors, - }; - - const { error } = maintenanceWindowValidation.validate(data, { - abortEarly: false, - }); - logger.log("error: ", error); - if (!error || error.details.length === 0) { - setErrors({}); - } else { - const newErrors = {}; - error.details.forEach((err) => { - newErrors[err.path[0]] = err.message; - }); - setErrors(newErrors); - createToast({ - body: - error.details && error.details.length > 0 - ? error.details[0].message - : "Error validating data", - }); - logger.error("Validation errors:", error.details); - } - - logger.log("Submitting data: ", data); - }; - - const configOptions = [ - { - title: "Repeat", - component: ( - handleChange(e, "unit")} - id="duration-unit" - items={durationOptions} - value={values.unit} - /> - - ), - }, - { - title: "Display name", - component: ( - handleChange(e, "displayName")} - error={errors.displayName} - /> - ), - }, - { - title: "Add monitors", - component: ( - - handleChange(e, "AddMonitors")} - error={errors.addMonitors} - /> - - Add all monitors to this maintenance window - - - ), - }, - ]; - - return ( -
- - - - - {directory.title} - - - - {directory.description} - - - - {configOptions.map((item, index) => ( - - {item.title && configOptionTitle(item.title, item.description)} - {item.component && item.component} - - ))} - - - - - - -
- ); -}; - -export default CreateNewMaintenanceWindow; diff --git a/Client/src/Pages/Monitors/CreateMonitor/index.css b/Client/src/Pages/Monitors/CreateMonitor/index.css index c38345be7..e69de29bb 100644 --- a/Client/src/Pages/Monitors/CreateMonitor/index.css +++ b/Client/src/Pages/Monitors/CreateMonitor/index.css @@ -1,34 +0,0 @@ -.create-monitor p.MuiTypography-root, -.create-monitor button.MuiButtonBase-root { - font-size: var(--env-var-font-size-medium); -} -.create-monitor h6.MuiTypography-root, -.create-monitor .MuiBox-root .field + p.MuiTypography-root { - font-size: var(--env-var-font-size-small-plus); - opacity: 0.8; -} -.create-monitor button.MuiButtonBase-root { - height: 34px; -} - -.create-monitor .error-container { - position: relative; -} -.create-monitor .error-container p.MuiTypography-root.input-error { - opacity: 0.8; - position: absolute; - top: 0; -} -.create-monitor .MuiStack-root:has(span.MuiTypography-root.input-error) { - position: relative; -} -.create-monitor span.MuiTypography-root.input-error { - position: absolute; - top: 100%; -} - -.create-monitor .MuiStack-root .MuiButtonGroup-root button { - font-size: var(--env-var-font-size-small); - height: 28px; - padding: 8px; -} From ee30f44062d00a0a13043077f19ee7286a54c3c6 Mon Sep 17 00:00:00 2001 From: Daniel Cojocea Date: Wed, 18 Sep 2024 19:50:01 -0400 Subject: [PATCH 02/44] Added basic layout --- .../Maintenance/CreateMaintenance/index.css | 72 +------------------ .../Maintenance/CreateMaintenance/index.jsx | 70 +++++++++++++++--- Client/src/Pages/Maintenance/index.css | 36 ---------- 3 files changed, 63 insertions(+), 115 deletions(-) diff --git a/Client/src/Pages/Maintenance/CreateMaintenance/index.css b/Client/src/Pages/Maintenance/CreateMaintenance/index.css index 4ee17db72..bf8514740 100644 --- a/Client/src/Pages/Maintenance/CreateMaintenance/index.css +++ b/Client/src/Pages/Maintenance/CreateMaintenance/index.css @@ -1,71 +1,3 @@ -.maintenance-options .MuiStack-root .MuiStack-root.select-wrapper, -.maintenance-options .MuiStack-root .field { - width: 60%; - max-width: 380px; -} - -.date-picker .MuiOutlinedInput-root, -.time-picker .MuiOutlinedInput-root { - height: 34px; - font-size: var(--env-var-font-size-medium); -} - -.date-picker .MuiOutlinedInput-root { - width: 140px; -} - -.time-picker .MuiOutlinedInput-root { - width: 90px; -} - -.maintenance-options .MuiInputAdornment-outlined .MuiIconButton-root svg { - width: 20px; -} - -.duration-config .field-text .MuiTextField-root, -.maintenance-options .duration-config .field { - width: 70px; - min-width: 70px; - max-width: 70px; -} - -.duration-config > .MuiStack-root.select-wrapper { - width: 100px; -} - -.duration-config - > .MuiStack-root.select-wrapper - > .MuiInputBase-root:has(> .MuiSelect-select) { - width: 100px; - min-width: 100px; -} - -.duration-config > .select-wrapper .select-component > .MuiSelect-select { - text-transform: none; -} - -.maintenance-options .add-monitors-fields .field.field-text { - width: 100%; -} - -.MuiPopover-paper.MuiMenu-paper.select-dropdown - .MuiMenu-list - .MuiButtonBase-root { - text-transform: none; -} - -.date-picker - .MuiOutlinedInput-root - .MuiInputAdornment-outlined - .MuiIconButton-root { - outline: none; - - &:hover { - background-color: transparent; - } -} - -.create-maintenance-window .MuiStack-root .MuiStack-root > button { - width: 110px; - height: 34px; +.create-maintenance button { + height: 35px; } diff --git a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx index 3c51c420e..c4aa697f6 100644 --- a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx +++ b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx @@ -1,22 +1,74 @@ import { Box, Button, Stack, Typography } from "@mui/material"; import { useTheme } from "@emotion/react"; import { useState } from "react"; -import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; -import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; -import { DatePicker } from "@mui/x-date-pickers/DatePicker"; -import { MobileTimePicker } from "@mui/x-date-pickers/MobileTimePicker"; -import { maintenanceWindowValidation } from "../../../Validation/validation"; -import { logger } from "../../../Utils/Logger"; -import { createToast } from "../../../Utils/toastUtils"; import Select from "../../../Components/Inputs/Select"; -import dayjs from "dayjs"; import Field from "../../../Components/Inputs/Field"; +import Breadcrumbs from "../../../Components/Breadcrumbs"; import "./index.css"; const CreateMaintenance = () => { const theme = useTheme(); - return ; + return ( + + + + + + Create a{" "} + + + maintenance{" "} + + + window + + + + + + + + + + ); }; export default CreateMaintenance; diff --git a/Client/src/Pages/Maintenance/index.css b/Client/src/Pages/Maintenance/index.css index 46ba8b0fa..e69de29bb 100644 --- a/Client/src/Pages/Maintenance/index.css +++ b/Client/src/Pages/Maintenance/index.css @@ -1,36 +0,0 @@ -.maintenance-checklist-main { - max-width: 350px; - min-height: 390px; - margin: auto; - padding: 5px; -} - -.maintenance-image { - width: 280px; - height: 150px; - background-color: whitesmoke; - border-radius: 10px; -} - -.maintenance-title { - color: var(--secondary-color-light); - font-size: 16px; - font-weight: bold; - margin-top: 40px; - margin-bottom: 30px; -} - -.checklist-item { - font-size: 13px; - color: var(--secondary-color-light); - display: flex; - margin-bottom: 10px; -} - -.checklist-item-text { - margin-left: 10px; -} - -.maintenance-checklist-main .maintenance-checklist-button { - margin-top: 30px; -} From 577bc9447daa407453fc8db6a70b7e055091d9f2 Mon Sep 17 00:00:00 2001 From: Daniel Cojocea Date: Wed, 18 Sep 2024 21:22:22 -0400 Subject: [PATCH 03/44] Added fields --- .../Maintenance/CreateMaintenance/index.jsx | 135 +++++++++++++++--- .../Maintenance/CreateMaintenance/styled.jsx | 20 +++ 2 files changed, 134 insertions(+), 21 deletions(-) create mode 100644 Client/src/Pages/Maintenance/CreateMaintenance/styled.jsx diff --git a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx index c4aa697f6..724643f59 100644 --- a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx +++ b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx @@ -5,6 +5,25 @@ import Select from "../../../Components/Inputs/Select"; import Field from "../../../Components/Inputs/Field"; import Breadcrumbs from "../../../Components/Breadcrumbs"; import "./index.css"; +import { ConfigBox } from "./styled"; + +const repeatConfig = [ + { _id: 0, name: "Don't repeat" }, + { _id: 1, name: "Repeat daily" }, + { _id: 2, name: "Repeat weekly" }, +]; + +const durationConfig = [ + { _id: 0, name: "seconds" }, + { _id: 1, name: "minutes" }, + { _id: 2, name: "hours" }, + { _id: 3, name: "days" }, +]; + +const periodConfig = [ + { _id: 0, name: "AM" }, + { _id: 1, name: "PM" }, +]; const CreateMaintenance = () => { const theme = useTheme(); @@ -24,30 +43,104 @@ const CreateMaintenance = () => { gap={theme.spacing(12)} mt={theme.spacing(6)} > - - - Create a{" "} + + + + Create a{" "} + + + maintenance{" "} + + + window + - + Your pings won't be sent during this time frame + + + + + General Settings + + - maintenance{" "} + + + + + + + Duration + + + + + + { const theme = useTheme(); const itemStyles = { @@ -77,6 +79,7 @@ const Select = ({ value={value} onChange={onChange} displayEmpty + name={name} inputProps={{ id: id }} IconComponent={KeyboardArrowDownIcon} MenuProps={{ disableScrollLock: true }} @@ -127,6 +130,7 @@ const Select = ({ Select.propTypes = { id: PropTypes.string.isRequired, + name: PropTypes.string, label: PropTypes.string, placeholder: PropTypes.string, isHidden: PropTypes.bool, diff --git a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx index a5e728cca..b7417377e 100644 --- a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx +++ b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx @@ -6,6 +6,10 @@ 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"; +import { MobileTimePicker } from "@mui/x-date-pickers/MobileTimePicker"; + +import dayjs from "dayjs"; + import Select from "../../../Components/Inputs/Select"; import Field from "../../../Components/Inputs/Field"; import Breadcrumbs from "../../../Components/Breadcrumbs"; @@ -15,9 +19,9 @@ import Search from "../../../Components/Inputs/Search"; import { networkService } from "../../../main"; const repeatConfig = [ - { _id: 0, name: "Don't repeat" }, - { _id: 1, name: "Repeat daily" }, - { _id: 2, name: "Repeat weekly" }, + { _id: 0, name: "Don't repeat", value: "none" }, + { _id: 1, name: "Repeat daily", value: "daily" }, + { _id: 2, name: "Repeat weekly", value: "weekly" }, ]; const durationConfig = [ @@ -27,17 +31,33 @@ const durationConfig = [ { _id: 3, name: "days" }, ]; -const periodConfig = [ - { _id: 0, name: "AM" }, - { _id: 1, name: "PM" }, -]; +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; +}; const CreateMaintenance = () => { const theme = useTheme(); const { user, authToken } = useSelector((state) => state.auth); const [monitors, setMonitors] = useState([]); const [search, setSearch] = useState(""); - const [selectedMonitor, setSelectedMonitor] = useState(null); + const [form, setForm] = useState({ + repeat: "none", + startDate: dayjs().toISOString(), + startTime: dayjs().toISOString(), + duration: "", + durationUnit: "seconds", + name: "", + monitors: [], + }); useEffect(() => { const fetchMonitors = async () => { @@ -56,9 +76,18 @@ const CreateMaintenance = () => { setSearch(value); }; - const handleSelectMonitor = (monitor) => { - setSelectedMonitor(monitor); + const handleSelectMonitors = (monitors) => { + setForm({ ...form, monitors }); }; + + const handleFormChange = (key, value) => { + setForm({ ...form, [key]: value }); + }; + + const handleTimeChange = (key, newTime) => { + setForm({ ...form, [key]: newTime }); + }; + return ( { > {}} - /> + + { + 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, + }, + }, + }, + }} + /> + @@ -186,12 +251,25 @@ const CreateMaintenance = () => { Duration - + + { + handleFormChange("duration", event.target.value); + }} + /> { Date { }} sx={{}} onChange={(newDate) => { - handleTimeChange("startDate", newDate.toISOString()); + handleTimeChange("startDate", newDate); }} + error={errors["startDate"]} /> @@ -212,10 +300,10 @@ const CreateMaintenance = () => { { - handleTimeChange("startTime", newTime.toISOString()); + handleTimeChange("startTime", newTime); }} slotProps={{ nextIconButton: { sx: { ml: theme.spacing(2) } }, @@ -241,6 +329,7 @@ const CreateMaintenance = () => { }, }, }} + error={errors["startTime"]} /> @@ -254,14 +343,15 @@ const CreateMaintenance = () => { { handleFormChange("duration", event.target.value); }} + error={errors["duration"]} />