//Components import Breadcrumbs from "../../../Components/Breadcrumbs"; import TextInput from "../../../Components/Inputs/TextInput"; import { HttpAdornment } from "../../../Components/Inputs/TextInput/Adornments"; 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"; // Utils import { useTheme } from "@emotion/react"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { monitorValidation } from "../../../Validation/validation"; import { createToast } from "../../../Utils/toastUtils"; import { useGetNotificationsByTeamId } from "../../../Hooks/useNotifications"; 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 theme = useTheme(); const { t } = useTranslation(); const [notifications, notificationsAreLoading, error] = useGetNotificationsByTeamId(); const [createMonitor, isCreating] = useCreateMonitor(); const MS_PER_MINUTE = 60000; 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")} )} ); }; export default CreateMonitor;