From a004b7b450a13daebcdbd2f86ad8fb72bcf2a705 Mon Sep 17 00:00:00 2001 From: Jesulayomy Date: Wed, 23 Jul 2025 09:03:51 -0400 Subject: [PATCH] [Uptime]: Merged Configure into Create Component --- client/src/Pages/Uptime/Configure/index.css | 11 - client/src/Pages/Uptime/Configure/index.jsx | 526 -------- .../src/Pages/Uptime/Configure/skeleton.jsx | 90 -- client/src/Pages/Uptime/Create/index.jsx | 1179 ++++++++++------- 4 files changed, 702 insertions(+), 1104 deletions(-) delete mode 100644 client/src/Pages/Uptime/Configure/index.css delete mode 100644 client/src/Pages/Uptime/Configure/index.jsx delete mode 100644 client/src/Pages/Uptime/Configure/skeleton.jsx 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")} - - - - - - - - - - - - {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")} - - - - - - - - {t("uptimeCreate")} - - - - - - {t("uptimeCreateJsonPath")}  - - jmespath.org - -  {t("uptimeCreateJsonPathQuery")} - - - - )} - - - - - - - setIsOpen(false)} - confirmationButtonLabel="Delete" - onConfirm={handleRemove} - isLoading={isLoading} - /> - - ); -}; - -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")} - - - - - - - - {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 && ( + + + + + )} + + {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")} + + + + + + + + {t("uptimeCreate")} + + + + + + {t("uptimeCreateJsonPath") + " "} + + jmespath.org + + {" " + t("uptimeCreateJsonPathQuery")} + + + + )} + + + + + + + + {!isCreate && ( + setIsOpen(false)} + confirmationButtonLabel={t("delete")} + onConfirm={handleRemove} + isLoading={isLoading} + /> + )} + + ); +}; + +export default UptimeCreate;