diff --git a/client/src/Pages/Uptime/Configure/index.css b/client/src/Pages/Uptime/Configure/index.css
deleted file mode 100644
index 3f24bd011..000000000
--- a/client/src/Pages/Uptime/Configure/index.css
+++ /dev/null
@@ -1,11 +0,0 @@
-.configure-monitor button.MuiButtonBase-root {
- height: var(--env-var-height-2);
-}
-
-.configure-monitor .MuiStack-root:has(span.MuiTypography-root.input-error) {
- position: relative;
-}
-.configure-monitor span.MuiTypography-root.input-error {
- position: absolute;
- top: 100%;
-}
diff --git a/client/src/Pages/Uptime/Configure/index.jsx b/client/src/Pages/Uptime/Configure/index.jsx
deleted file mode 100644
index 2dacc26ab..000000000
--- a/client/src/Pages/Uptime/Configure/index.jsx
+++ /dev/null
@@ -1,526 +0,0 @@
-// Components
-import Box from "@mui/material/Box";
-import Stack from "@mui/material/Stack";
-import Tooltip from "@mui/material/Tooltip";
-import Typography from "@mui/material/Typography";
-import Button from "@mui/material/Button";
-import FormControlLabel from "@mui/material/FormControlLabel";
-import Switch from "@mui/material/Switch";
-import ConfigBox from "../../../Components/ConfigBox";
-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 Dialog from "../../../Components/Dialog";
-import PulseDot from "../../../Components/Animated/PulseDot";
-import Checkbox from "../../../Components/Inputs/Checkbox";
-
-// Utils
-import { useParams } from "react-router";
-import { useTheme } from "@emotion/react";
-import { useState } from "react";
-import { monitorValidation } from "../../../Validation/validation";
-import { createToast } from "../../../Utils/toastUtils";
-import { useTranslation } from "react-i18next";
-import PauseOutlinedIcon from "@mui/icons-material/PauseOutlined";
-import PlayArrowOutlinedIcon from "@mui/icons-material/PlayArrowOutlined";
-import { useMonitorUtils } from "../../../Hooks/useMonitorUtils";
-import { useGetNotificationsByTeamId } from "../../../Hooks/useNotifications";
-import {
- useDeleteMonitor,
- useUpdateMonitor,
- usePauseMonitor,
- useFetchMonitorById,
-} from "../../../Hooks/monitorHooks";
-import NotificationsConfig from "../../../Components/NotificationConfig";
-
-/**
- * Parses a URL string and returns a URL object.
- *
- * @param {string} url - The URL string to parse.
- * @returns {URL} - The parsed URL object if valid, otherwise an empty string.
- */
-const parseUrl = (url) => {
- try {
- return new URL(url);
- } catch (error) {
- return null;
- }
-};
-
-/**
- * Configure page displays monitor configurations and allows for editing actions.
- * @component
- */
-const Configure = () => {
- const { monitorId } = useParams();
-
- // Local state
- const [form, setForm] = useState({
- ignoreTlsErrors: false,
- interval: 60000,
- matchMethod: "equal",
- expectedValue: "",
- jsonPath: "",
- notifications: [],
- port: "",
- type: "http",
- });
- const [useAdvancedMatching, setUseAdvancedMatching] = useState(false);
- const [updateTrigger, setUpdateTrigger] = useState(false);
- const [isOpen, setIsOpen] = useState(false);
- const [errors, setErrors] = useState({});
-
- const triggerUpdate = () => {
- setUpdateTrigger(!updateTrigger);
- };
-
- // Network
- const [notifications, notificationsAreLoading, notificationsError] =
- useGetNotificationsByTeamId();
- const [pauseMonitor, isPausing, pauseError] = usePauseMonitor({});
- const [deleteMonitor, isDeleting] = useDeleteMonitor();
- const [updateMonitor, isUpdating] = useUpdateMonitor();
- const [isLoading] = useFetchMonitorById({
- monitorId,
- setMonitor: setForm,
- updateTrigger,
- });
-
- const MS_PER_MINUTE = 60000;
- const theme = useTheme();
-
- const matchMethodOptions = [
- { _id: "equal", name: "Equal" },
- { _id: "include", name: "Include" },
- { _id: "regex", name: "Regex" },
- ];
-
- const frequencies = [
- { _id: 1, name: "1 minute" },
- { _id: 2, name: "2 minutes" },
- { _id: 3, name: "3 minutes" },
- { _id: 4, name: "4 minutes" },
- { _id: 5, name: "5 minutes" },
- ];
-
- const expectedValuePlaceholders = {
- regex: "^(success|ok)$",
- equal: "success",
- include: "ok",
- };
-
- // Handlers
- const handlePause = async () => {
- const res = await pauseMonitor({ monitorId: form?._id, triggerUpdate });
- if (typeof res !== "undefined") {
- triggerUpdate();
- }
- };
-
- const handleRemove = async (event) => {
- event.preventDefault();
- await deleteMonitor({ monitor: form, redirect: "/uptime" });
- };
-
- const onChange = (event) => {
- let { name, value, checked } = event.target;
-
- if (name === "ignoreTlsErrors") {
- value = checked;
- }
-
- if (name === "useAdvancedMatching") {
- setForm((prevForm) => {
- return {
- ...prevForm,
- matchMethod: "equal",
- };
- });
- setUseAdvancedMatching(!useAdvancedMatching);
- return;
- }
-
- if (name === "interval") {
- value = value * MS_PER_MINUTE;
- }
- setForm({ ...form, [name]: value });
-
- const validation = monitorValidation.validate(
- { [name]: value },
- { abortEarly: false }
- );
-
- setErrors((prev) => {
- const updatedErrors = { ...prev };
- if (validation.error) updatedErrors[name] = validation.error.details[0].message;
- else delete updatedErrors[name];
- return updatedErrors;
- });
- };
-
- const onSubmit = async (e) => {
- e.preventDefault();
-
- const toSubmit = {
- _id: form._id,
- url: form.url,
- name: form.name,
- type: form.type,
- matchMethod: form.matchMethod,
- expectedValue: form.expectedValue,
- jsonPath: form.jsonPath,
- interval: form.interval,
- teamId: form.teamId,
- userId: form.userId,
- port: form.port,
- ignoreTlsErrors: form.ignoreTlsErrors,
- };
-
- if (!useAdvancedMatching) {
- toSubmit.matchMethod = "";
- toSubmit.expectedValue = "";
- toSubmit.jsonPath = "";
- }
-
- const validation = monitorValidation.validate(toSubmit, {
- abortEarly: false,
- });
-
- if (validation.error) {
- const newErrors = {};
- validation.error.details.forEach((err) => {
- newErrors[err.path[0]] = err.message;
- });
- setErrors(newErrors);
- createToast({ body: "Please check the form for errors." });
- return;
- }
-
- toSubmit.notifications = form.notifications;
- await updateMonitor({ monitor: toSubmit, redirect: "/uptime" });
- };
-
- // Parse the URL
- const parsedUrl = parseUrl(form?.url);
- const protocol = parsedUrl?.protocol?.replace(":", "") || "";
-
- const { determineState, statusColor } = useMonitorUtils();
-
- const { t } = useTranslation();
-
- return (
-
-
-
-
-
-
- {form.name}
-
-
-
-
-
-
-
-
- {form.url?.replace(/^https?:\/\//, "") || "..."}
-
-
- {t("editing")}
-
-
-
-
- :
- }
- onClick={handlePause}
- >
- {form?.isActive ? t("pause") : t("resume")}
-
-
-
-
-
-
-
- {t("settingsGeneralSettings")}
-
- {t("distributedUptimeCreateSelectURL")}
-
-
-
- }
- id="monitor-url"
- label={t("urlMonitor")}
- placeholder="google.com"
- value={parsedUrl?.host || form?.url || ""}
- disabled={true}
- />
-
-
-
-
-
-
- {t("notificationConfig.title")}
- {t("notificationConfig.description")}
-
-
-
-
-
-
- {t("ignoreTLSError")}
-
- {t("ignoreTLSErrorDescription")}
-
-
-
- }
- label={t("tlsErrorIgnored")}
- />
-
-
-
-
-
- {t("distributedUptimeCreateAdvancedSettings")}
-
-
-
-
-
- {form.type === "http" && useAdvancedMatching && (
- <>
-
-
-
-
- {t("uptimeCreate")}
-
-
-
-
-
- {t("uptimeCreateJsonPath")}
-
- jmespath.org
-
- {t("uptimeCreateJsonPathQuery")}
-
-
- >
- )}
-
-
-
-
-
-
-
- );
-};
-
-export default Configure;
diff --git a/client/src/Pages/Uptime/Configure/skeleton.jsx b/client/src/Pages/Uptime/Configure/skeleton.jsx
deleted file mode 100644
index 9c1014ed4..000000000
--- a/client/src/Pages/Uptime/Configure/skeleton.jsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import { Box, Skeleton, Stack } from "@mui/material";
-import { useTheme } from "@emotion/react";
-
-/**
- * Renders a skeleton layout.
- *
- * @returns {JSX.Element}
- */
-const SkeletonLayout = () => {
- const theme = useTheme();
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- );
-};
-
-export default SkeletonLayout;
diff --git a/client/src/Pages/Uptime/Create/index.jsx b/client/src/Pages/Uptime/Create/index.jsx
index 761fd6346..c6caeacb1 100644
--- a/client/src/Pages/Uptime/Create/index.jsx
+++ b/client/src/Pages/Uptime/Create/index.jsx
@@ -1,4 +1,14 @@
//Components
+import {
+ Box,
+ Button,
+ ButtonGroup,
+ FormControlLabel,
+ Stack,
+ Switch,
+ Tooltip,
+ Typography,
+} from "@mui/material";
import Breadcrumbs from "../../../Components/Breadcrumbs";
import TextInput from "../../../Components/Inputs/TextInput";
import { HttpAdornment } from "../../../Components/Inputs/TextInput/Adornments";
@@ -6,494 +16,709 @@ import Radio from "../../../Components/Inputs/Radio";
import Select from "../../../Components/Inputs/Select";
import ConfigBox from "../../../Components/ConfigBox";
import NotificationsConfig from "../../../Components/NotificationConfig";
-import Button from "@mui/material/Button";
-import ButtonGroup from "@mui/material/ButtonGroup";
-import Box from "@mui/material/Box";
-import Stack from "@mui/material/Stack";
-import Typography from "@mui/material/Typography";
-import Switch from "@mui/material/Switch";
-import FormControlLabel from "@mui/material/FormControlLabel";
import Checkbox from "../../../Components/Inputs/Checkbox";
+import Dialog from "../../../Components/Dialog";
+import PulseDot from "../../../Components/Animated/PulseDot";
+import SkeletonLayout from "./skeleton";
// Utils
+import { useParams } from "react-router";
import { useTheme } from "@emotion/react";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { monitorValidation } from "../../../Validation/validation";
import { createToast } from "../../../Utils/toastUtils";
+import { useTranslation } from "react-i18next";
+import {
+ PauseOutlined as PauseOutlinedIcon,
+ PlayArrowOutlined as PlayArrowOutlinedIcon,
+} from "@mui/icons-material";
+import { useMonitorUtils } from "../../../Hooks/useMonitorUtils";
import { useGetNotificationsByTeamId } from "../../../Hooks/useNotifications";
import { useCreateMonitor, useFetchMonitorById } from "../../../Hooks/monitorHooks";
import { useParams } from "react-router-dom";
+import {
+ useDeleteMonitor,
+ useUpdateMonitor,
+ usePauseMonitor,
+ useFetchMonitorById,
+} from "../../../Hooks/monitorHooks";
+import { useCreateMonitor } from "../../../Hooks/monitorHooks";
-const CreateMonitor = () => {
- // Local state
- const [errors, setErrors] = useState({});
- const [https, setHttps] = useState(true);
- const [useAdvancedMatching, setUseAdvancedMatching] = useState(false);
- const [monitor, setMonitor] = useState({
- url: "",
- name: "",
- type: "http",
- matchMethod: "equal",
- expectedValue: "",
- jsonPath: "",
- notifications: [],
- interval: 1,
- ignoreTlsErrors: false,
- });
-
- // Setup
- const MS_PER_MINUTE = 60000;
- const theme = useTheme();
- const { t } = useTranslation();
- const [notifications, notificationsAreLoading, error] = useGetNotificationsByTeamId();
- const [createMonitor, isCreating] = useCreateMonitor();
- const { monitorId } = useParams();
-
- const formatAndSet = (monitor) => {
- monitor.interval = monitor.interval / MS_PER_MINUTE;
- setMonitor(monitor);
- };
- const [isLoading] = useFetchMonitorById({
- monitorId,
- setMonitor: formatAndSet,
- updateTrigger: true,
- });
-
- const SELECT_VALUES = [
- { _id: 1, name: "1 minute" },
- { _id: 2, name: "2 minutes" },
- { _id: 3, name: "3 minutes" },
- { _id: 4, name: "4 minutes" },
- { _id: 5, name: "5 minutes" },
- ];
-
- const matchMethodOptions = [
- { _id: "equal", name: "Equal" },
- { _id: "include", name: "Include" },
- { _id: "regex", name: "Regex" },
- ];
-
- const expectedValuePlaceholders = {
- regex: "^(success|ok)$",
- equal: "success",
- include: "ok",
- };
-
- const monitorTypeMaps = {
- http: {
- label: "URL to monitor",
- placeholder: "google.com",
- namePlaceholder: "Google",
- },
- ping: {
- label: "IP address to monitor",
- placeholder: "1.1.1.1",
- namePlaceholder: "Google",
- },
- docker: {
- label: "Container ID",
- placeholder: "abc123",
- namePlaceholder: "My Container",
- },
- port: {
- label: "URL to monitor",
- placeholder: "localhost",
- namePlaceholder: "Localhost:5173",
- },
- };
-
- const BREADCRUMBS = [
- { name: "uptime", path: "/uptime" },
- { name: "create", path: `/uptime/create` },
- ];
-
- // Handlers
-
- const onSubmit = async (event) => {
- event.preventDefault();
- const { notifications, ...rest } = monitor;
-
- let form = {
- ...rest,
- url:
- //prepending protocol for url
- monitor.type === "http"
- ? `http${https ? "s" : ""}://` + monitor.url
- : monitor.url,
- port: monitor.type === "port" ? monitor.port : undefined,
- name: monitor.name || monitor.url.substring(0, 50),
- type: monitor.type,
- interval: monitor.interval * MS_PER_MINUTE,
- };
-
- // If not using advanced matching, remove advanced settings
- if (!useAdvancedMatching) {
- form.matchMethod = undefined;
- form.expectedValue = undefined;
- form.jsonPath = undefined;
- }
-
- const { error } = monitorValidation.validate(form, {
- abortEarly: false,
- });
-
- if (error) {
- const newErrors = {};
- error.details.forEach((err) => {
- newErrors[err.path[0]] = err.message;
- });
- setErrors(newErrors);
- createToast({ body: "Please check the form for errors." });
- return;
- }
-
- form = {
- ...form,
- description: monitor.name || monitor.url,
- notifications: monitor.notifications,
- };
-
- await createMonitor({ monitor: form, redirect: "/uptime" });
- };
-
- const onChange = (event) => {
- const { name, value, checked } = event.target;
-
- let newValue = value;
- if (name === "ignoreTlsErrors") {
- newValue = checked;
- }
-
- if (name === "useAdvancedMatching") {
- setUseAdvancedMatching(checked);
- return;
- }
-
- const updatedMonitor = {
- ...monitor,
- [name]: newValue,
- };
-
- setMonitor(updatedMonitor);
-
- const { error } = monitorValidation.validate(
- { type: monitor.type, [name]: newValue },
- { abortEarly: false }
- );
-
- setErrors((prev) => ({
- ...prev,
- ...(error ? { [name]: error.details[0].message } : { [name]: undefined }),
- }));
- };
-
- return (
-
-
-
-
-
- {t("createYour")}{" "}
-
-
- {t("monitor")}
-
-
-
-
-
-
- {t("distributedUptimeCreateChecks")}
-
-
- {t("distributedUptimeCreateChecksDescription")}
-
-
-
-
-
- {monitor.type === "http" ? (
-
-
-
-
- ) : (
- ""
- )}
-
-
-
-
- {errors["type"] ? (
-
-
- {errors["type"]}
-
-
- ) : (
- ""
- )}
-
-
-
-
-
- {t("settingsGeneralSettings")}
-
-
- {t(`uptimeGeneralInstructions.${monitor.type}`)}
-
-
-
- : null
- }
- label={monitorTypeMaps[monitor.type].label || "URL to monitor"}
- https={https}
- placeholder={monitorTypeMaps[monitor.type].placeholder || ""}
- value={monitor.url}
- onChange={onChange}
- error={errors["url"] ? true : false}
- helperText={errors["url"]}
- />
-
-
-
-
-
-
- {t("notificationConfig.title")}
- {t("notificationConfig.description")}
-
-
-
-
-
-
- {t("ignoreTLSError")}
-
- {t("ignoreTLSErrorDescription")}
-
-
-
- }
- label={t("tlsErrorIgnored")}
- />
-
-
-
-
-
- {t("distributedUptimeCreateAdvancedSettings")}
-
-
-
-
-
- {monitor.type === "http" && useAdvancedMatching && (
- <>
-
-
-
-
- {t("uptimeCreate")}
-
-
-
-
-
- {t("uptimeCreateJsonPath")}
-
- jmespath.org
-
- {t("uptimeCreateJsonPathQuery")}
-
-
- >
- )}
-
-
-
-
-
-
-
- );
+/**
+ * Parses a URL string and returns a URL object.
+ *
+ * @param {string} url - The URL string to parse.
+ * @returns {URL} - The parsed URL object if valid, otherwise an empty string.
+ */
+const parseUrl = (url) => {
+ try {
+ return new URL(url);
+ } catch (error) {
+ return null;
+ }
};
-export default CreateMonitor;
+/**
+ * Create page renders monitor creation or configuration views.
+ * @component
+ */
+const UptimeCreate = () => {
+ const { monitorId } = useParams();
+ const isCreate = typeof monitorId === "undefined";
+
+ // States
+ const [monitor, setMonitor] = useState({
+ type: "http",
+ matchMethod: "equal",
+ expectedValue: "",
+ jsonPath: "",
+ notifications: [],
+ interval: 60000,
+ ignoreTlsErrors: false,
+ ...(isCreate ? { url: "", name: "" } : { port: undefined }),
+ });
+ const [errors, setErrors] = useState({});
+ const [https, setHttps] = useState(true);
+ const [isOpen, setIsOpen] = useState(false);
+ const [useAdvancedMatching, setUseAdvancedMatching] = useState(false);
+ const [updateTrigger, setUpdateTrigger] = useState(false);
+ const triggerUpdate = () => {
+ setUpdateTrigger(!updateTrigger);
+ };
+
+ // Hooks
+ const [notifications, notificationsAreLoading, notificationsError] =
+ useGetNotificationsByTeamId();
+ const { determineState, statusColor } = useMonitorUtils();
+ // Network
+ const [isLoading] = useFetchMonitorById({
+ monitorId,
+ setMonitor: formatAndSet,
+ updateTrigger: true,
+ });
+ const [createMonitor, isCreating] = useCreateMonitor();
+ const [pauseMonitor, isPausing] = usePauseMonitor({});
+ const [deleteMonitor, isDeleting] = useDeleteMonitor();
+ const [updateMonitor, isUpdating] = useUpdateMonitor();
+
+ // Setup
+ const theme = useTheme();
+ const { t } = useTranslation();
+ const formatAndSet = (monitor) => {
+ monitor.interval = monitor.interval / MS_PER_MINUTE;
+ setMonitor(monitor);
+ };
+
+ // Constants
+ const MS_PER_MINUTE = 60000;
+ const FREQUENCIES = [
+ { _id: 1, name: t("time.oneMinute") },
+ { _id: 2, name: t("time.twoMinutes") },
+ { _id: 3, name: t("time.threeMinutes") },
+ { _id: 4, name: t("time.fourMinutes") },
+ { _id: 5, name: t("time.fiveMinutes") },
+ ];
+ const CRUMBS = [
+ { name: "uptime", path: "/uptime" },
+ ...(isCreate
+ ? [{ name: "create", path: `/uptime/create` }]
+ : [
+ { name: "details", path: `/uptime/${monitorId}` },
+ { name: "configure", path: `/uptime/configure/${monitorId}` },
+ ]),
+ ];
+ const matchMethodOptions = [
+ { _id: "equal", name: t("matchMethodOptions.equal") },
+ { _id: "include", name: t("matchMethodOptions.include") },
+ { _id: "regex", name: t("matchMethodOptions.regex") },
+ ];
+ const expectedValuePlaceholders = {
+ regex: t("matchMethodOptions.regexPlaceholder"),
+ equal: t("matchMethodOptions.equalPlaceholder"),
+ include: t("matchMethodOptions.includePlaceholder"),
+ };
+ const monitorTypeMaps = {
+ http: {
+ label: t("monitorType.http.label"),
+ placeholder: t("monitorType.http.placeholder"),
+ namePlaceholder: t("monitorType.http.namePlaceholder"),
+ },
+ ping: {
+ label: t("monitorType.ping.label"),
+ placeholder: t("monitorType.ping.placeholder"),
+ namePlaceholder: t("monitorType.ping.namePlaceholder"),
+ },
+ docker: {
+ label: t("monitorType.docker.label"),
+ placeholder: t("monitorType.docker.placeholder"),
+ namePlaceholder: t("monitorType.docker.namePlaceholder"),
+ },
+ port: {
+ label: t("monitorType.port.label"),
+ placeholder: t("monitorType.port.placeholder"),
+ namePlaceholder: t("monitorType.port.namePlaceholder"),
+ },
+ };
+
+ // Handlers
+ const onSubmit = async (event) => {
+ event.preventDefault();
+ const { notifications, ...rest } = monitor;
+
+ let form = {};
+ if (isCreate) {
+ form = {
+ ...rest,
+ url:
+ monitor.type === "http"
+ ? `http${https ? "s" : ""}://` + monitor.url
+ : monitor.url,
+ port: monitor.type === "port" ? monitor.port : undefined,
+ name: monitor.name || monitor.url.substring(0, 50),
+ type: monitor.type,
+ interval: monitor.interval,
+ };
+ } else {
+ form = {
+ _id: monitor._id,
+ url: monitor.url,
+ name: monitor.name || monitor.url.substring(0, 50),
+ type: monitor.type,
+ matchMethod: monitor.matchMethod,
+ expectedValue: monitor.expectedValue,
+ jsonPath: monitor.jsonPath,
+ interval: monitor.interval,
+ teamId: monitor.teamId,
+ userId: monitor.userId,
+ port: monitor.type === "port" ? monitor.port : undefined,
+ ignoreTlsErrors: monitor.ignoreTlsErrors,
+ };
+ }
+ if (!useAdvancedMatching) {
+ form.matchMethod = isCreate ? undefined : "";
+ form.expectedValue = isCreate ? undefined : "";
+ form.jsonPath = isCreate ? undefined : "";
+ }
+
+ const { error } = monitorValidation.validate(form, {
+ abortEarly: false,
+ });
+
+ if (error) {
+ const newErrors = {};
+ error.details.forEach((err) => {
+ newErrors[err.path[0]] = err.message;
+ });
+ setErrors(newErrors);
+ createToast({ body: t("checkFormError") });
+ return;
+ }
+
+ form = {
+ ...form,
+ description: monitor.name || monitor.url,
+ notifications: monitor.notifications,
+ };
+
+ if (isCreate) {
+ await createMonitor({ monitor: form, redirect: "/uptime" });
+ } else {
+ await updateMonitor({ monitor: form, redirect: "/uptime" });
+ }
+ };
+
+ const onChange = (event) => {
+ let { name, value, checked } = event.target;
+
+ if (name === "ignoreTlsErrors") {
+ value = checked;
+ }
+
+ if (name === "useAdvancedMatching") {
+ setUseAdvancedMatching(checked);
+ return;
+ }
+
+ if (name === "interval") {
+ value = value * MS_PER_MINUTE;
+ }
+
+ setMonitor((prev) => ({ ...prev, [name]: value }));
+
+ const { error } = monitorValidation.validate(
+ { type: monitor.type, [name]: value },
+ { abortEarly: false }
+ );
+
+ setErrors((prev) => ({
+ ...prev,
+ ...(error ? { [name]: error.details[0].message } : { [name]: undefined }),
+ }));
+ };
+
+ const handlePause = async () => {
+ await pauseMonitor({ monitorId, triggerUpdate });
+ };
+
+ const handleRemove = async (event) => {
+ event.preventDefault();
+ await deleteMonitor({ monitor, redirect: "/uptime" });
+ };
+
+ const isBusy = isLoading || isCreating || isDeleting || isUpdating || isPausing;
+ const parsedUrl = parseUrl(monitor?.url);
+ const protocol = parsedUrl?.protocol?.replace(":", "") || "";
+
+ if (Object.keys(monitor).length === 0) {
+ return ;
+ }
+ useEffect(() => {
+ if (!isCreate) {
+ if (monitor.matchMethod) {
+ setUseAdvancedMatching(true);
+ } else {
+ setUseAdvancedMatching(false);
+ }
+ }
+ }, [monitor]);
+
+ return (
+
+
+
+
+
+
+
+
+ {!isCreate ? monitor.name : t("createYour") + " "}
+
+ {isCreate && (
+
+ {t("monitor")}
+
+ )}
+
+ {!isCreate && (
+
+
+
+
+
+
+
+ {monitor.url?.replace(/^https?:\/\//, "") || "..."}
+
+
+ {t("editing")}
+
+
+ )}
+
+ {!isCreate && (
+
+ :
+ }
+ onClick={handlePause}
+ >
+ {monitor?.isActive ? t("pause") : t("resume")}
+
+
+
+ )}
+
+ {isCreate && (
+
+
+
+ {t("distributedUptimeCreateChecks")}
+
+
+ {t("distributedUptimeCreateChecksDescription")}
+
+
+
+
+
+ {monitor.type === "http" ? (
+
+
+
+
+ ) : (
+ ""
+ )}
+
+
+
+
+ {errors["type"] ? (
+
+
+ {errors["type"]}
+
+
+ ) : (
+ ""
+ )}
+
+
+ )}
+
+
+
+ {t("settingsGeneralSettings")}
+
+
+ {isCreate
+ ? t(`uptimeGeneralInstructions.${monitor.type}`)
+ : t("distributedUptimeCreateSelectURL")}
+
+
+
+
+ )
+ }
+ helperText={errors["url"]}
+ onChange={onChange}
+ disabled={!isCreate}
+ />
+
+
+
+
+
+
+ {t("notificationConfig.title")}
+ {t("notificationConfig.description")}
+
+
+
+
+
+
+ {t("ignoreTLSError")}
+
+ {t("ignoreTLSErrorDescription")}
+
+
+
+ }
+ label={t("tlsErrorIgnored")}
+ />
+
+
+
+
+
+ {t("distributedUptimeCreateAdvancedSettings")}
+
+
+
+
+ {monitor.type === "http" && (
+
+ )}
+ {monitor.type === "http" && useAdvancedMatching && (
+ <>
+
+
+
+
+ {t("uptimeCreate")}
+
+
+
+
+
+ {t("uptimeCreateJsonPath") + " "}
+
+ jmespath.org
+
+ {" " + t("uptimeCreateJsonPathQuery")}
+
+
+ >
+ )}
+
+
+
+
+
+
+
+ {!isCreate && (
+
+ );
+};
+
+export default UptimeCreate;