diff --git a/Client/src/Pages/PageSpeed/CreatePageSpeed/index.jsx b/Client/src/Pages/PageSpeed/CreatePageSpeed/index.jsx
index ba3a7bb4a..6823cfe21 100644
--- a/Client/src/Pages/PageSpeed/CreatePageSpeed/index.jsx
+++ b/Client/src/Pages/PageSpeed/CreatePageSpeed/index.jsx
@@ -1,42 +1,52 @@
+// React, Redux, Router
+import { useNavigate, useParams } from "react-router-dom";
+import { useEffect } from "react";
import { useState } from "react";
-import { Box, Button, ButtonGroup, Stack, Typography } from "@mui/material";
-import LoadingButton from "@mui/lab/LoadingButton";
import { useSelector, useDispatch } from "react-redux";
+
+// Utility and Network
+import { logger } from "../../../Utils/Logger";
import { monitorValidation } from "../../../Validation/validation";
-import { useNavigate } from "react-router-dom";
-import { useTheme } from "@emotion/react";
import {
createPageSpeed,
checkEndpointResolution,
} from "../../../Features/PageSpeedMonitor/pageSpeedMonitorSlice";
-import { createToast } from "../../../Utils/toastUtils";
-import { logger } from "../../../Utils/Logger";
-import { ConfigBox } from "../../Monitors/styled";
-import Radio from "../../../Components/Inputs/Radio";
+import { parseDomainName } from "../../../Utils/monitorUtils";
+
+// MUI
+import { useTheme } from "@emotion/react";
+import { Box, Stack, Typography, Button, ButtonGroup } from "@mui/material";
+import LoadingButton from "@mui/lab/LoadingButton";
+
+//Components
+import Breadcrumbs from "../../../Components/Breadcrumbs";
import TextInput from "../../../Components/Inputs/TextInput";
import { HttpAdornment } from "../../../Components/Inputs/TextInput/Adornments";
-import Select from "../../../Components/Inputs/Select";
+import { ConfigBox } from "../../Monitors/styled";
+
+import { createToast } from "../../../Utils/toastUtils";
+import Radio from "../../../Components/Inputs/Radio";
import Checkbox from "../../../Components/Inputs/Checkbox";
-import Breadcrumbs from "../../../Components/Breadcrumbs";
-import { parseDomainName } from "../../../Utils/monitorUtils";
-import "./index.css";
+import Select from "../../../Components/Inputs/Select";
const CreatePageSpeed = () => {
const MS_PER_MINUTE = 60000;
- const { user, authToken } = useSelector((state) => state.auth);
- const { isLoading } = useSelector((state) => state.pageSpeedMonitors);
- const dispatch = useDispatch();
- const navigate = useNavigate();
- const theme = useTheme();
- const idMap = {
- "monitor-url": "url",
- "monitor-name": "name",
- "monitor-checks-http": "type",
- "monitor-checks-ping": "type",
- "notify-email-default": "notification-email",
- };
+ const CRUMBS = [
+ { name: "pagespeed", path: "/pagespeed" },
+ { name: "create", path: `/pagespeed/create` },
+ ];
+ const SELECT_VALUES = [
+ { _id: 3, name: "3 minutes" },
+ { _id: 5, name: "5 minutes" },
+ { _id: 10, name: "10 minutes" },
+ { _id: 20, name: "20 minutes" },
+ { _id: 60, name: "1 hour" },
+ { _id: 1440, name: "1 day" },
+ { _id: 10080, name: "1 week" },
+ ];
+ // State
const [monitor, setMonitor] = useState({
url: "",
name: "",
@@ -44,71 +54,20 @@ const CreatePageSpeed = () => {
notifications: [],
interval: 3,
});
+
const [https, setHttps] = useState(true);
const [errors, setErrors] = useState({});
+ const { user, authToken } = useSelector((state) => state.auth);
+ const { isLoading } = useSelector((state) => state.pageSpeedMonitors);
- const handleChange = (event, name) => {
- const { value, id } = event.target;
- if (!name) name = idMap[id];
-
- if (name.includes("notification-")) {
- name = name.replace("notification-", "");
- let hasNotif = monitor.notifications.some(
- (notification) => notification.type === name
- );
- setMonitor((prev) => {
- const notifs = [...prev.notifications];
- if (hasNotif) {
- return {
- ...prev,
- notifications: notifs.filter((notif) => notif.type !== name),
- };
- } else {
- return {
- ...prev,
- notifications: [
- ...notifs,
- name === "email"
- ? { type: name, address: value }
- : // TODO - phone number
- { type: name, phone: value },
- ],
- };
- }
- });
- } else {
- setMonitor((prev) => ({
- ...prev,
- [name]: value,
- }));
-
- const { error } = monitorValidation.validate(
- { [name]: value },
- { abortEarly: false }
- );
-
- setErrors((prev) => {
- const updatedErrors = { ...prev };
- if (error) updatedErrors[name] = error.details[0].message;
- else delete updatedErrors[name];
- return updatedErrors;
- });
- }
- };
-
- const onUrlBlur = (event) => {
- const { value } = event.target;
- if (monitor.name === "") {
- setMonitor((prev) => ({
- ...prev,
- name: parseDomainName(value),
- }));
- }
- };
+ // Setup
+ const dispatch = useDispatch();
+ const navigate = useNavigate();
+ const theme = useTheme();
+ // Handlers
const handleCreateMonitor = async (event) => {
event.preventDefault();
- //obj to submit
let form = {
url: `http${https ? "s" : ""}://` + monitor.url,
name: monitor.name === "" ? monitor.url : monitor.name,
@@ -126,46 +85,98 @@ const CreatePageSpeed = () => {
newErrors[err.path[0]] = err.message;
});
setErrors(newErrors);
- createToast({ body: "Error validation data." });
- } else {
- const checkEndpointAction = await dispatch(
- checkEndpointResolution({ authToken, monitorURL: form.url })
- );
- if (checkEndpointAction.meta.requestStatus === "rejected") {
- createToast({
- body: "The endpoint you entered doesn't resolve. Check the URL again.",
- });
- setErrors({ url: "The entered URL is not reachable." });
- return;
- }
+ createToast({ body: "Please check the form for errors." });
+ return;
+ }
- form = {
- ...form,
- description: form.name,
- teamId: user.teamId,
- userId: user._id,
- notifications: monitor.notifications,
- };
- const action = await dispatch(createPageSpeed({ authToken, monitor: form }));
- if (action.meta.requestStatus === "fulfilled") {
- createToast({ body: "Monitor created successfully!" });
- navigate("/pagespeed");
- } else {
- createToast({ body: "Failed to create monitor." });
- }
+ const checkEndpointAction = await dispatch(
+ checkEndpointResolution({ authToken, monitorURL: form.url })
+ );
+
+ if (checkEndpointAction.meta.requestStatus === "rejected") {
+ createToast({
+ body: "The endpoint you entered doesn't resolve. Check the URL again.",
+ });
+ setErrors({ url: "The entered URL is not reachable." });
+ return;
+ }
+
+ form = {
+ ...form,
+ description: form.name,
+ teamId: user.teamId,
+ userId: user._id,
+ notifications: monitor.notifications,
+ };
+
+ const action = await dispatch(createPageSpeed({ authToken, monitor: form }));
+ if (action.meta.requestStatus === "fulfilled") {
+ createToast({ body: "Monitor created successfully!" });
+ navigate("/pagespeed");
+ } else {
+ createToast({ body: "Failed to create monitor." });
+ }
+ };
+
+ const handleChange = (event, formItemName) => {
+ const { value } = event.target;
+ setMonitor({
+ ...monitor,
+ [formItemName]: value,
+ });
+
+ const { error } = monitorValidation.validate(
+ { [formItemName]: value },
+ { abortEarly: false }
+ );
+
+ setErrors((prev) => ({
+ ...prev,
+ ...(error
+ ? { [formItemName]: error.details[0].message }
+ : { [formItemName]: undefined }),
+ }));
+ };
+
+ const handleNotifications = (event, type) => {
+ const { value } = event.target;
+ let notifications = [...monitor.notifications];
+ const notificationExists = notifications.some((notification) => {
+ if (notification.type === type && notification.address === value) {
+ return true;
+ }
+ return false;
+ });
+ if (notificationExists) {
+ notifications = notifications.filter((notification) => {
+ if (notification.type === type && notification.address === value) {
+ return false;
+ }
+ return true;
+ });
+ } else {
+ notifications.push({ type, address: value });
+ }
+
+ setMonitor((prev) => ({
+ ...prev,
+ notifications,
+ }));
+ };
+
+ const handleBlur = (event, formItemName) => {
+ if (formItemName === "url") {
+ const { value } = event.target;
+ if (monitor.name !== "") {
+ return;
+ }
+ setMonitor((prev) => ({
+ ...prev,
+ name: parseDomainName(value),
+ }));
}
};
- //select values
- const frequencies = [
- { _id: 3, name: "3 minutes" },
- { _id: 5, name: "5 minutes" },
- { _id: 10, name: "10 minutes" },
- { _id: 20, name: "20 minutes" },
- { _id: 60, name: "1 hour" },
- { _id: 1440, name: "1 day" },
- { _id: 10080, name: "1 week" },
- ];
return (
{
},
}}
>
-
+
{
fontWeight="inherit"
color={theme.palette.text.secondary}
>
- pagespeed monitor
+ PageSpeed monitor
@@ -224,8 +230,8 @@ const CreatePageSpeed = () => {
startAdornment={}
placeholder="google.com"
value={monitor.url}
- onChange={handleChange}
- onBlur={onUrlBlur}
+ onChange={(event) => handleChange(event, "url")}
+ onBlur={(event) => handleBlur(event, "url")}
error={errors["url"] ? true : false}
helperText={errors["url"]}
/>
@@ -236,7 +242,7 @@ const CreatePageSpeed = () => {
isOptional={true}
placeholder="Google"
value={monitor.name}
- onChange={handleChange}
+ onChange={(event) => handleChange(event, "name")}
error={errors["name"] ? true : false}
helperText={errors["name"]}
/>
@@ -253,8 +259,8 @@ const CreatePageSpeed = () => {
{
HTTPS
When there is a new incident,
- logger.warn("disabled")}
- isDisabled={true}
- />
{
(notification) => notification.type === "email"
)}
value={user?.email}
- onChange={(event) => handleChange(event)}
+ onChange={(event) => handleNotifications(event, "email")}
/>
- logger.warn("disabled")}
- isDisabled={true}
- />
- {monitor.notifications.some(
- (notification) => notification.type === "emails"
- ) ? (
-
- logger.warn("disabled")}
- />
-
- You can separate multiple emails with a comma
-
-
- ) : (
- ""
- )}
@@ -356,7 +328,7 @@ const CreatePageSpeed = () => {
label="Check frequency"
value={monitor.interval || 3}
onChange={(event) => handleChange(event, "interval")}
- items={frequencies}
+ items={SELECT_VALUES}
/>
@@ -368,7 +340,7 @@ const CreatePageSpeed = () => {
variant="contained"
color="primary"
onClick={handleCreateMonitor}
- disabled={Object.keys(errors).length !== 0 && true}
+ disabled={!Object.values(errors).every((value) => value === undefined)}
loading={isLoading}
>
Create monitor
@@ -378,5 +350,4 @@ const CreatePageSpeed = () => {
);
};
-
export default CreatePageSpeed;