2024-06-25 13:22:28 +03:30
|
|
|
import "./index.css";
|
|
|
|
|
import React, { useState } from "react";
|
2024-07-17 20:15:45 -04:00
|
|
|
import RadioButton from "../../../Components/RadioButton";
|
|
|
|
|
import Button from "../../../Components/Button";
|
2024-07-26 21:57:18 -04:00
|
|
|
import { Box, ButtonGroup, Stack, Typography } from "@mui/material";
|
2024-06-27 15:27:32 -07:00
|
|
|
import { useSelector, useDispatch } from "react-redux";
|
2024-07-19 18:04:58 -04:00
|
|
|
import { monitorValidation } from "../../../Validation/validation";
|
2024-07-30 11:25:14 -07:00
|
|
|
import { createUptimeMonitor } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
|
2024-06-27 15:45:05 -07:00
|
|
|
import { useNavigate } from "react-router-dom";
|
2024-06-28 20:05:08 -04:00
|
|
|
import { useTheme } from "@emotion/react";
|
2024-07-07 18:25:03 -04:00
|
|
|
import WestRoundedIcon from "@mui/icons-material/WestRounded";
|
2024-07-17 20:15:45 -04:00
|
|
|
import Field from "../../../Components/Inputs/Field";
|
2024-07-24 14:09:24 -04:00
|
|
|
import Select from "../../../Components/Inputs/Select";
|
2024-07-30 12:54:22 -07:00
|
|
|
import Checkbox from "../../../Components/Inputs/Checkbox";
|
2024-06-18 22:39:58 +03:30
|
|
|
|
2024-07-17 20:15:45 -04:00
|
|
|
const CreateMonitor = () => {
|
2024-06-27 15:27:32 -07:00
|
|
|
const MS_PER_MINUTE = 60000;
|
|
|
|
|
const { user, authToken } = useSelector((state) => state.auth);
|
|
|
|
|
const dispatch = useDispatch();
|
2024-06-27 15:45:05 -07:00
|
|
|
const navigate = useNavigate();
|
2024-06-28 20:05:08 -04:00
|
|
|
const theme = useTheme();
|
2024-06-27 15:27:32 -07:00
|
|
|
|
2024-06-27 17:26:00 -04:00
|
|
|
const [errors, setErrors] = useState({});
|
|
|
|
|
|
2024-06-27 16:29:50 -04:00
|
|
|
//General Settings Form
|
|
|
|
|
const [generalSettings, setGeneralSettings] = useState({ url: "", name: "" });
|
|
|
|
|
//Checks Form
|
2024-06-27 17:26:00 -04:00
|
|
|
const [checks, setChecks] = useState({
|
|
|
|
|
type: "",
|
|
|
|
|
// port: ""
|
2024-06-27 16:29:50 -04:00
|
|
|
});
|
2024-06-27 17:26:00 -04:00
|
|
|
//Incidents Form
|
|
|
|
|
// const [notifications, setNotifications] = useState({
|
|
|
|
|
// viaSms: false,
|
|
|
|
|
// viaEmail: false,
|
|
|
|
|
// viaOther: false,
|
|
|
|
|
// email: "",
|
|
|
|
|
// });
|
2024-06-27 16:29:50 -04:00
|
|
|
//Advanced Settings Form
|
|
|
|
|
const [advancedSettings, setAdvancedSettings] = useState({
|
2024-07-19 18:04:58 -04:00
|
|
|
interval: 1,
|
2024-06-27 17:26:00 -04:00
|
|
|
// retries: "",
|
|
|
|
|
// codes: "",
|
|
|
|
|
// redirects: "",
|
2024-06-27 16:29:50 -04:00
|
|
|
});
|
|
|
|
|
//Proxy Settings Form
|
2024-06-27 17:26:00 -04:00
|
|
|
// const [proxy, setProxy] = useState({
|
|
|
|
|
// enabled: false,
|
|
|
|
|
// protocol: "",
|
|
|
|
|
// address: "",
|
|
|
|
|
// proxy_port: "",
|
|
|
|
|
// });
|
2024-06-26 21:56:56 +03:30
|
|
|
|
2024-06-27 16:29:50 -04:00
|
|
|
const handleChange = (event, id, setState, checkbox) => {
|
|
|
|
|
const { value } = event.target;
|
|
|
|
|
setState((prev) => ({
|
|
|
|
|
...prev,
|
|
|
|
|
[id]: checkbox ? true : value,
|
|
|
|
|
}));
|
2024-06-27 17:26:00 -04:00
|
|
|
|
2024-07-19 18:04:58 -04:00
|
|
|
const validation = monitorValidation.validate(
|
2024-06-27 17:26:00 -04:00
|
|
|
{ [id]: value },
|
|
|
|
|
{ abortEarly: false }
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
setErrors((prev) => {
|
|
|
|
|
const updatedErrors = { ...prev };
|
|
|
|
|
|
|
|
|
|
if (validation.error) {
|
|
|
|
|
updatedErrors[id] = validation.error.details[0].message;
|
|
|
|
|
} else {
|
|
|
|
|
delete updatedErrors[id];
|
|
|
|
|
}
|
|
|
|
|
return updatedErrors;
|
|
|
|
|
});
|
2024-06-26 21:56:56 +03:30
|
|
|
};
|
2024-06-27 17:26:00 -04:00
|
|
|
// const handleCheck = (id, setState) => {
|
|
|
|
|
// setState((prev) => ({
|
|
|
|
|
// ...prev,
|
|
|
|
|
// [id]: !prev[id],
|
|
|
|
|
// }));
|
|
|
|
|
// };
|
2024-06-26 21:56:56 +03:30
|
|
|
|
2024-07-17 20:15:45 -04:00
|
|
|
const handleCreateMonitor = async (event) => {
|
2024-06-27 17:26:00 -04:00
|
|
|
event.preventDefault();
|
|
|
|
|
//obj to submit
|
2024-06-27 15:27:32 -07:00
|
|
|
let monitor = {
|
2024-07-18 12:11:27 -07:00
|
|
|
url:
|
2024-07-26 21:57:18 -04:00
|
|
|
//preprending protocol for url
|
|
|
|
|
checks.type === "http" || checks.type === "https"
|
|
|
|
|
? `${checks.type}://` + generalSettings.url
|
2024-07-18 12:11:27 -07:00
|
|
|
: generalSettings.url,
|
2024-07-22 13:56:28 -04:00
|
|
|
name:
|
|
|
|
|
generalSettings.name === ""
|
|
|
|
|
? generalSettings.url
|
|
|
|
|
: generalSettings.name,
|
2024-07-26 21:57:18 -04:00
|
|
|
//there is no separate monitor type for https since the operations for the two protocols are identical
|
|
|
|
|
//however the URL does need the correct prepend hence https is still being tracked but overwritten when prepping the monitor obj
|
|
|
|
|
type: checks.type === "https" ? "http" : checks.type,
|
2024-06-27 17:26:00 -04:00
|
|
|
};
|
|
|
|
|
|
2024-07-19 18:04:58 -04:00
|
|
|
const { error } = monitorValidation.validate(monitor, {
|
2024-07-18 12:11:53 -07:00
|
|
|
abortEarly: false,
|
|
|
|
|
});
|
2024-07-18 12:11:27 -07:00
|
|
|
|
2024-07-18 12:11:53 -07:00
|
|
|
if (error) {
|
|
|
|
|
const newErrors = {};
|
|
|
|
|
error.details.forEach((err) => {
|
|
|
|
|
newErrors[err.path[0]] = err.message;
|
|
|
|
|
});
|
|
|
|
|
setErrors(newErrors);
|
|
|
|
|
} else {
|
|
|
|
|
monitor = {
|
|
|
|
|
...monitor,
|
|
|
|
|
description: monitor.name,
|
|
|
|
|
userId: user._id,
|
2024-07-19 18:04:58 -04:00
|
|
|
// ...advancedSettings
|
|
|
|
|
interval: advancedSettings.interval * MS_PER_MINUTE,
|
2024-07-18 12:11:53 -07:00
|
|
|
};
|
|
|
|
|
try {
|
2024-07-30 11:25:14 -07:00
|
|
|
const action = await dispatch(
|
|
|
|
|
createUptimeMonitor({ authToken, monitor })
|
|
|
|
|
);
|
2024-07-18 12:11:53 -07:00
|
|
|
if (action.meta.requestStatus === "fulfilled") {
|
|
|
|
|
navigate("/monitors");
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
alert(error);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-27 17:26:00 -04:00
|
|
|
};
|
2024-06-27 16:44:56 -04:00
|
|
|
|
2024-06-27 17:26:00 -04:00
|
|
|
//select values
|
|
|
|
|
// const ports = ["Port 1", "Port 2", "Port 3"];
|
2024-07-24 14:09:24 -04:00
|
|
|
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" },
|
|
|
|
|
];
|
2024-06-25 13:22:28 +03:30
|
|
|
|
2024-06-18 22:39:58 +03:30
|
|
|
return (
|
2024-07-26 12:39:18 -04:00
|
|
|
<Box className="create-monitor">
|
2024-07-07 18:25:03 -04:00
|
|
|
<Button
|
|
|
|
|
level="tertiary"
|
|
|
|
|
label="Back"
|
|
|
|
|
img={<WestRoundedIcon />}
|
|
|
|
|
onClick={() => navigate("/monitors")}
|
|
|
|
|
sx={{
|
|
|
|
|
backgroundColor: "#f4f4f4",
|
|
|
|
|
mb: theme.gap.medium,
|
|
|
|
|
px: theme.gap.ml,
|
|
|
|
|
"& svg.MuiSvgIcon-root": {
|
|
|
|
|
pr: theme.gap.small,
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
/>
|
2024-07-22 13:41:37 -04:00
|
|
|
<form
|
|
|
|
|
className="create-monitor-form"
|
|
|
|
|
onSubmit={handleCreateMonitor}
|
|
|
|
|
noValidate
|
|
|
|
|
spellCheck="false"
|
|
|
|
|
>
|
|
|
|
|
<Typography component="h1">Create new monitor</Typography>
|
|
|
|
|
<Stack className="config-box">
|
|
|
|
|
<Box>
|
2024-06-28 20:05:08 -04:00
|
|
|
<Typography component="h2">General settings</Typography>
|
2024-07-22 13:41:37 -04:00
|
|
|
<Typography component="p" mt={theme.gap.small}>
|
2024-06-18 22:39:58 +03:30
|
|
|
Here you can select the URL of the host, together with the type of
|
|
|
|
|
monitor.
|
2024-06-28 20:05:08 -04:00
|
|
|
</Typography>
|
2024-07-22 13:41:37 -04:00
|
|
|
</Box>
|
2024-06-28 20:05:08 -04:00
|
|
|
<Stack gap={theme.gap.xl}>
|
2024-07-12 20:01:41 -04:00
|
|
|
<Field
|
2024-07-26 21:57:18 -04:00
|
|
|
type={
|
|
|
|
|
checks.type === "http" || checks.type === "https"
|
|
|
|
|
? "url"
|
|
|
|
|
: "text"
|
|
|
|
|
}
|
2024-07-12 20:01:41 -04:00
|
|
|
id="monitor-url"
|
|
|
|
|
label="URL to monitor"
|
2024-07-26 21:57:18 -04:00
|
|
|
https={checks.type === "https"}
|
2024-07-12 20:01:41 -04:00
|
|
|
placeholder="google.com"
|
2024-06-27 16:29:50 -04:00
|
|
|
value={generalSettings.url}
|
|
|
|
|
onChange={(event) =>
|
|
|
|
|
handleChange(event, "url", setGeneralSettings)
|
|
|
|
|
}
|
2024-06-28 20:05:08 -04:00
|
|
|
error={errors["url"]}
|
2024-06-18 22:39:58 +03:30
|
|
|
/>
|
2024-07-12 20:01:41 -04:00
|
|
|
<Field
|
2024-06-18 22:39:58 +03:30
|
|
|
type="text"
|
2024-07-12 20:01:41 -04:00
|
|
|
id="monitor-name"
|
|
|
|
|
label="Friendly name"
|
|
|
|
|
isOptional={true}
|
2024-06-18 22:39:58 +03:30
|
|
|
placeholder="Google"
|
2024-06-27 16:29:50 -04:00
|
|
|
value={generalSettings.name}
|
|
|
|
|
onChange={(event) =>
|
|
|
|
|
handleChange(event, "name", setGeneralSettings)
|
|
|
|
|
}
|
2024-06-28 20:05:08 -04:00
|
|
|
error={errors["name"]}
|
2024-06-18 22:39:58 +03:30
|
|
|
/>
|
2024-06-28 20:05:08 -04:00
|
|
|
</Stack>
|
2024-07-22 13:41:37 -04:00
|
|
|
</Stack>
|
|
|
|
|
<Stack className="config-box">
|
|
|
|
|
<Box>
|
2024-06-28 20:05:08 -04:00
|
|
|
<Typography component="h2">Checks to perform</Typography>
|
2024-07-22 13:41:37 -04:00
|
|
|
<Typography component="p" mt={theme.gap.small}>
|
2024-06-18 22:39:58 +03:30
|
|
|
You can always add or remove checks after adding your site.
|
2024-06-28 20:05:08 -04:00
|
|
|
</Typography>
|
2024-07-22 13:41:37 -04:00
|
|
|
</Box>
|
2024-06-28 20:05:08 -04:00
|
|
|
<Stack gap={theme.gap.large}>
|
2024-07-26 21:57:18 -04:00
|
|
|
<Stack gap={theme.gap.medium}>
|
|
|
|
|
<RadioButton
|
|
|
|
|
id="monitor-checks-http"
|
|
|
|
|
title="Website monitoring"
|
|
|
|
|
desc="Use HTTP(s) to monitor your website or API endpoint."
|
|
|
|
|
size="small"
|
|
|
|
|
value="http"
|
|
|
|
|
checked={checks.type === "http" || checks.type === "https"}
|
|
|
|
|
onChange={(event) => handleChange(event, "type", setChecks)}
|
|
|
|
|
/>
|
|
|
|
|
{checks.type === "http" || checks.type === "https" ? (
|
|
|
|
|
<ButtonGroup sx={{ ml: "32px" }}>
|
|
|
|
|
<Button
|
|
|
|
|
level="secondary"
|
|
|
|
|
label="HTTP"
|
|
|
|
|
onClick={() =>
|
|
|
|
|
setChecks((prev) => ({ ...prev, type: "http" }))
|
|
|
|
|
}
|
|
|
|
|
sx={{
|
|
|
|
|
backgroundColor:
|
|
|
|
|
checks.type === "http" &&
|
|
|
|
|
theme.palette.otherColors.fillGray,
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
level="secondary"
|
|
|
|
|
label="HTTPS"
|
|
|
|
|
onClick={() =>
|
|
|
|
|
setChecks((prev) => ({ ...prev, type: "https" }))
|
|
|
|
|
}
|
|
|
|
|
sx={{
|
|
|
|
|
backgroundColor:
|
|
|
|
|
checks.type === "https" &&
|
|
|
|
|
theme.palette.otherColors.fillGray,
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</ButtonGroup>
|
|
|
|
|
) : (
|
|
|
|
|
""
|
|
|
|
|
)}
|
|
|
|
|
</Stack>
|
2024-06-20 19:53:08 +03:30
|
|
|
<RadioButton
|
2024-06-27 16:29:50 -04:00
|
|
|
id="monitor-checks-ping"
|
2024-06-20 19:53:08 +03:30
|
|
|
title="Ping monitoring"
|
|
|
|
|
desc="Check whether your server is available or not."
|
2024-06-28 20:05:08 -04:00
|
|
|
size="small"
|
2024-06-25 13:22:28 +03:30
|
|
|
value="ping"
|
2024-06-27 17:26:00 -04:00
|
|
|
checked={checks.type === "ping"}
|
|
|
|
|
onChange={(event) => handleChange(event, "type", setChecks)}
|
2024-06-20 19:53:08 +03:30
|
|
|
/>
|
2024-06-27 16:44:56 -04:00
|
|
|
{/* TODO */}
|
|
|
|
|
{/* <RadioButton
|
2024-06-27 16:29:50 -04:00
|
|
|
id="monitor-checks-port"
|
2024-06-20 19:53:08 +03:30
|
|
|
title="Port monitoring"
|
|
|
|
|
desc="Monitor a specific service on your server."
|
2024-06-25 13:22:28 +03:30
|
|
|
value="port"
|
2024-06-27 17:26:00 -04:00
|
|
|
checked={checks.type === "port"}
|
|
|
|
|
onChange={(event) => handleChange(event, "type", setChecks)}
|
2024-06-20 19:53:08 +03:30
|
|
|
/>
|
2024-06-25 13:22:28 +03:30
|
|
|
<div className="monitors-dropdown-holder">
|
2024-06-27 16:29:50 -04:00
|
|
|
<Select
|
|
|
|
|
id="monitor-ports"
|
|
|
|
|
value={checks.port || "placeholder"}
|
|
|
|
|
inputProps={{ id: "monitor-ports-select" }}
|
|
|
|
|
onChange={(event) => handleChange(event, "port", setChecks)}
|
|
|
|
|
>
|
|
|
|
|
<MenuItem id="port-placeholder" value="placeholder">
|
|
|
|
|
Select a port to check
|
|
|
|
|
</MenuItem>
|
|
|
|
|
{ports.map((port, index) => (
|
|
|
|
|
<MenuItem key={`port-${index}`} value={port}>
|
|
|
|
|
{port}
|
|
|
|
|
</MenuItem>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
2024-06-27 16:44:56 -04:00
|
|
|
</div> */}
|
2024-06-28 20:05:08 -04:00
|
|
|
<Box className="error-container">
|
|
|
|
|
{errors["type"] ? (
|
|
|
|
|
<Typography component="p" className="input-error">
|
|
|
|
|
{errors["type"]}
|
|
|
|
|
</Typography>
|
|
|
|
|
) : (
|
|
|
|
|
""
|
|
|
|
|
)}
|
|
|
|
|
</Box>
|
|
|
|
|
</Stack>
|
2024-07-22 13:41:37 -04:00
|
|
|
</Stack>
|
2024-07-30 12:54:22 -07:00
|
|
|
|
|
|
|
|
<Stack className="config-box">
|
|
|
|
|
<Box>
|
|
|
|
|
<Typography component="h2">Incident notifications</Typography>
|
|
|
|
|
<Typography component="p" mt={theme.gap.small}>
|
|
|
|
|
When there is an incident, notify users
|
|
|
|
|
</Typography>
|
|
|
|
|
</Box>
|
|
|
|
|
<Stack gap={theme.gap.large}>
|
|
|
|
|
<Typography component="p" mt={theme.gap.small}>
|
2024-06-25 13:22:28 +03:30
|
|
|
When there is a new incident,
|
2024-07-30 12:54:22 -07:00
|
|
|
</Typography>
|
|
|
|
|
<Checkbox id="notify-sms" label="Notify via SMS (coming soon)" />
|
|
|
|
|
<Checkbox
|
|
|
|
|
id="notify-email-default"
|
|
|
|
|
label={`Notify via email (to ${user.email})`}
|
|
|
|
|
/>
|
|
|
|
|
<Checkbox
|
|
|
|
|
id="notify-email"
|
|
|
|
|
label="Also notify via email to the following addresses:"
|
|
|
|
|
/>
|
|
|
|
|
<Field
|
|
|
|
|
id="notify-email-list"
|
|
|
|
|
type="text"
|
|
|
|
|
label="You can separate multiple emails with a comma"
|
|
|
|
|
placeholder="name@gmail.com"
|
|
|
|
|
/>
|
|
|
|
|
</Stack>
|
|
|
|
|
</Stack>
|
|
|
|
|
|
2024-07-22 13:41:37 -04:00
|
|
|
<Stack className="config-box">
|
|
|
|
|
<Box>
|
2024-06-28 20:05:08 -04:00
|
|
|
<Typography component="h2">Advanced settings</Typography>
|
2024-07-22 13:41:37 -04:00
|
|
|
</Box>
|
2024-06-28 20:05:08 -04:00
|
|
|
<Stack gap={theme.gap.large}>
|
2024-07-24 14:09:24 -04:00
|
|
|
<Select
|
|
|
|
|
id="monitor-interval"
|
|
|
|
|
label="Check frequency"
|
|
|
|
|
value={advancedSettings.interval || 1}
|
|
|
|
|
onChange={(event) =>
|
|
|
|
|
handleChange(event, "interval", setAdvancedSettings)
|
|
|
|
|
}
|
|
|
|
|
items={frequencies}
|
|
|
|
|
/>
|
2024-06-27 16:44:56 -04:00
|
|
|
{/* TODO */}
|
|
|
|
|
{/* <FlexibileTextField
|
2024-06-27 16:29:50 -04:00
|
|
|
id="monitor-settings-retries"
|
|
|
|
|
title="Maximum retries before the service is marked as down"
|
2024-06-25 13:22:28 +03:30
|
|
|
type="number"
|
2024-06-27 16:29:50 -04:00
|
|
|
value={advancedSettings.retries}
|
|
|
|
|
onChange={(event) =>
|
|
|
|
|
handleChange(event, "retries", setAdvancedSettings)
|
|
|
|
|
}
|
2024-06-25 13:22:28 +03:30
|
|
|
/>
|
|
|
|
|
<FlexibileTextField
|
2024-06-27 16:29:50 -04:00
|
|
|
id="monitor-settings-codes"
|
|
|
|
|
title="Accepted status codes"
|
2024-06-25 13:22:28 +03:30
|
|
|
type="number"
|
2024-06-27 16:29:50 -04:00
|
|
|
value={advancedSettings.codes}
|
|
|
|
|
onChange={(event) =>
|
|
|
|
|
handleChange(event, "codes", setAdvancedSettings)
|
|
|
|
|
}
|
2024-06-25 13:22:28 +03:30
|
|
|
/>
|
|
|
|
|
<FlexibileTextField
|
2024-06-27 16:29:50 -04:00
|
|
|
id="monitor-settings-redirects"
|
|
|
|
|
title="Maximum redirects"
|
2024-06-25 13:22:28 +03:30
|
|
|
type="number"
|
2024-06-27 16:29:50 -04:00
|
|
|
value={advancedSettings.redirects}
|
|
|
|
|
onChange={(event) =>
|
|
|
|
|
handleChange(event, "redirects", setAdvancedSettings)
|
|
|
|
|
}
|
2024-06-27 16:44:56 -04:00
|
|
|
/> */}
|
2024-06-28 20:05:08 -04:00
|
|
|
</Stack>
|
2024-07-22 13:41:37 -04:00
|
|
|
</Stack>
|
|
|
|
|
{/* TODO */}
|
|
|
|
|
{/*
|
2024-06-18 22:39:58 +03:30
|
|
|
<ConfigBox
|
|
|
|
|
leftLayout={
|
|
|
|
|
<div className="config-box-desc">
|
|
|
|
|
<div className="config-box-desc-title">Proxy settings</div>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
2024-06-25 13:22:28 +03:30
|
|
|
rightLayout={
|
|
|
|
|
<div className="proxy-setting-config">
|
|
|
|
|
<CustomizableCheckBox
|
2024-06-27 16:29:50 -04:00
|
|
|
id="monitor-proxy-enable"
|
2024-06-25 13:22:28 +03:30
|
|
|
title="Enable proxy"
|
2024-06-27 16:29:50 -04:00
|
|
|
isChecked={proxy.enabled}
|
|
|
|
|
handleChange={() => handleCheck("enabled", setProxy)}
|
2024-06-25 13:22:28 +03:30
|
|
|
/>
|
2024-06-27 16:29:50 -04:00
|
|
|
<FlexibileTextField
|
|
|
|
|
id="monitor-proxy-protocol"
|
|
|
|
|
title="Proxy protocol"
|
|
|
|
|
value={proxy.protocol}
|
|
|
|
|
onChange={(event) => handleChange(event, "protocol", setProxy)}
|
|
|
|
|
/>
|
|
|
|
|
<FlexibileTextField
|
|
|
|
|
id="monitor-proxy-address"
|
|
|
|
|
title="Proxy address"
|
|
|
|
|
value={proxy.address}
|
|
|
|
|
onChange={(event) => handleChange(event, "address", setProxy)}
|
|
|
|
|
/>
|
|
|
|
|
<FlexibileTextField
|
|
|
|
|
id="monitor-proxy-port"
|
|
|
|
|
title="Proxy port"
|
|
|
|
|
value={proxy.proxy_port}
|
|
|
|
|
onChange={(event) => handleChange(event, "proxy_port", setProxy)}
|
|
|
|
|
/>
|
2024-06-25 13:22:28 +03:30
|
|
|
</div>
|
|
|
|
|
}
|
2024-06-27 16:44:56 -04:00
|
|
|
/> */}
|
2024-07-22 13:41:37 -04:00
|
|
|
<Stack direction="row" justifyContent="flex-end">
|
|
|
|
|
<Button
|
|
|
|
|
id="create-new-monitor-btn"
|
|
|
|
|
level="primary"
|
|
|
|
|
label="Create new monitor"
|
|
|
|
|
onClick={handleCreateMonitor}
|
|
|
|
|
disabled={Object.keys(errors).length !== 0 && true}
|
|
|
|
|
/>
|
|
|
|
|
</Stack>
|
|
|
|
|
</form>
|
2024-07-26 12:39:18 -04:00
|
|
|
</Box>
|
2024-06-18 22:39:58 +03:30
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2024-07-17 20:15:45 -04:00
|
|
|
export default CreateMonitor;
|