Monitors -> Uptime

This commit is contained in:
Alex Holliday
2024-12-10 14:23:46 +08:00
parent ad9bda444b
commit 9c793da0f0
35 changed files with 65 additions and 146 deletions
+13 -13
View File
@@ -8,8 +8,8 @@ import NotFound from "./Pages/NotFound";
import Login from "./Pages/Auth/Login";
import Register from "./Pages/Auth/Register/Register";
import Account from "./Pages/Account";
import Monitors from "./Pages/Monitors/Home";
import CreateMonitor from "./Pages/Monitors/CreateMonitor";
import Uptime from "./Pages/Uptime/Home";
import CreateMonitor from "./Pages/Uptime/CreateUptime";
import CreateInfrastructureMonitor from "./Pages/Infrastructure/CreateMonitor";
import Incidents from "./Pages/Incidents";
import Status from "./Pages/Status";
@@ -20,10 +20,10 @@ import CheckEmail from "./Pages/Auth/CheckEmail";
import SetNewPassword from "./Pages/Auth/SetNewPassword";
import NewPasswordConfirmed from "./Pages/Auth/NewPasswordConfirmed";
import ProtectedRoute from "./Components/ProtectedRoute";
import Details from "./Pages/Monitors/Details";
import UptimeDetails from "./Pages/Uptime/Details";
import AdvancedSettings from "./Pages/AdvancedSettings";
import Maintenance from "./Pages/Maintenance";
import Configure from "./Pages/Monitors/Configure";
import Configure from "./Pages/Uptime/Configure";
import PageSpeed from "./Pages/PageSpeed";
import CreatePageSpeed from "./Pages/PageSpeed/CreatePageSpeed";
import CreateNewMaintenanceWindow from "./Pages/Maintenance/CreateMaintenance";
@@ -43,8 +43,8 @@ import { Infrastructure } from "./Pages/Infrastructure";
import InfrastructureDetails from "./Pages/Infrastructure/Details";
function App() {
const AdminCheckedRegister = withAdminCheck(Register);
const MonitorsWithAdminProp = withAdminProp(Monitors);
const MonitorDetailsWithAdminProp = withAdminProp(Details);
const UptimeWithAdminProp = withAdminProp(Uptime);
const UptimeDetailsWithAdminProp = withAdminProp(UptimeDetails);
const PageSpeedWithAdminProp = withAdminProp(PageSpeed);
const PageSpeedDetailsWithAdminProp = withAdminProp(PageSpeedDetails);
const MaintenanceWithAdminProp = withAdminProp(Maintenance);
@@ -92,22 +92,22 @@ function App() {
<Route
exact
path="/"
element={<Navigate to="/monitors" />}
element={<Navigate to="/uptime" />}
/>
<Route
path="/monitors"
element={<ProtectedRoute Component={MonitorsWithAdminProp} />}
path="/uptime"
element={<ProtectedRoute Component={UptimeWithAdminProp} />}
/>
<Route
path="/monitors/create/:monitorId?"
path="/uptime/create/:monitorId?"
element={<ProtectedRoute Component={CreateMonitor} />}
/>
<Route
path="/monitors/:monitorId/"
element={<ProtectedRoute Component={MonitorDetailsWithAdminProp} />}
path="/uptime/:monitorId/"
element={<ProtectedRoute Component={UptimeDetailsWithAdminProp} />}
/>
<Route
path="/monitors/configure/:monitorId/"
path="/uptime/configure/:monitorId/"
element={<ProtectedRoute Component={Configure} />}
/>
<Route
+3 -3
View File
@@ -47,7 +47,7 @@ import Folder from "../../assets/icons/folder.svg?react";
import "./index.css";
const menu = [
{ name: "Monitors", path: "monitors", icon: <Monitors /> },
{ name: "Uptime", path: "uptime", icon: <Monitors /> },
{ name: "Pagespeed", path: "pagespeed", icon: <PageSpeed /> },
{ name: "Infrastructure", path: "infrastructure", icon: <Integrations /> },
{ name: "Incidents", path: "incidents", icon: <Incidents /> },
@@ -262,10 +262,10 @@ function Sidebar() {
Menu
</ListSubheader>
}
sx={{
sx={{
px: theme.spacing(6),
height: "100%",
overflow: "hidden"
overflow: "hidden",
}}
>
{menu.map((item) =>
+2 -2
View File
@@ -388,7 +388,7 @@ const Login = () => {
useEffect(() => {
if (authToken) {
navigate("/monitors");
navigate("/uptime");
return;
}
networkService
@@ -454,7 +454,7 @@ const Login = () => {
} else {
const action = await dispatch(login(form));
if (action.payload.success) {
navigate("/monitors");
navigate("/uptime");
createToast({
body: "Welcome back! You're successfully logged in.",
});
+1 -1
View File
@@ -237,7 +237,7 @@ const Register = ({ isSuperAdmin }) => {
if (action.payload.success) {
const authToken = action.payload.data;
localStorage.setItem("token", authToken);
navigate("/monitors");
navigate("/uptime");
createToast({
body: "Welcome! Your account was created successfully.",
});
@@ -12,7 +12,7 @@ import { useNavigate } from "react-router-dom";
import { useTheme } from "@emotion/react";
import { createToast } from "../../../Utils/toastUtils";
import Link from "../../../Components/Link";
import { ConfigBox } from "../../Monitors/styled";
import { ConfigBox } from "../../Uptime/styled";
import TextInput from "../../../Components/Inputs/TextInput";
import Select from "../../../Components/Inputs/Select";
import Checkbox from "../../../Components/Inputs/Checkbox";
@@ -8,7 +8,7 @@ import AreaChart from "../../../Components/Charts/AreaChart";
import { useSelector } from "react-redux";
import { networkService } from "../../../main";
import PulseDot from "../../../Components/Animated/PulseDot";
import useUtils from "../../Monitors/utils";
import useUtils from "../../Uptime/utils";
import { useNavigate } from "react-router-dom";
import Empty from "./empty";
import { logger } from "../../../Utils/Logger";
@@ -109,88 +109,6 @@ const InfrastructureMenu = ({ monitor, isAdmin, updateCallback }) => {
},
}}
>
{/*
Open site action. Not necessary for infrastructure?
{actions.url !== null ? (
<MenuItem
onClick={(e) => {
closeMenu(e);
e.stopPropagation();
window.open(actions.url, "_blank", "noreferrer");
}}
>
Open site
</MenuItem>
) : (
""
)}
*/}
<MenuItem onClick={() => openDetails(monitor.id)}>Details</MenuItem>
{/*
Incidents. Necessary?
<MenuItem
onClick={(e) => {
e.stopPropagation();
navigate(`/incidents/${actions.id}`);
}}
>
Incidents
</MenuItem> */}
{/*
Configure. Necessary?
{isAdmin && (
<MenuItem
onClick={(e) => {
e.stopPropagation();
navigate(`/monitors/configure/${actions.id}`);
}}
>
Configure
</MenuItem>
)} */}
{/*
Clone. Necessary?
{isAdmin && (
<MenuItem
onClick={(e) => {
e.stopPropagation();
navigate(`/monitors/create/${actions.id}`);
}}
>
Clone
</MenuItem>
)} */}
{/*
Pause. Necessary?
const handlePause = async () => {
try {
const action = await dispatch(
pauseUptimeMonitor({ authToken, monitorId: monitor._id })
);
if (pauseUptimeMonitor.fulfilled.match(action)) {
updateCallback();
const state = action?.payload?.data.isActive === false ? "paused" : "resumed";
createToast({ body: `Monitor ${state} successfully.` });
} else {
throw new Error(action?.error?.message ?? "Failed to pause monitor.");
}
} catch (error) {
logger.error("Error pausing monitor:", monitor._id, error);
createToast({ body: "Failed to pause monitor." });
}
};
{isAdmin && (
<MenuItem
onClick={(e) => {
e.stopPropagation();
handlePause(e);
}}
>
{monitor?.isActive === true ? "Pause" : "Resume"}
</MenuItem>
)} */}
{isAdmin && <MenuItem onClick={openRemove}>Remove</MenuItem>}
</Menu>
<Dialog
+2 -2
View File
@@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { /* useDispatch, */ useSelector } from "react-redux";
import { useTheme } from "@emotion/react";
import useUtils from "../Monitors/utils";
import useUtils from "../Uptime/utils.jsx";
import { jwtDecode } from "jwt-decode";
import SkeletonLayout from "./skeleton";
import Fallback from "../../Components/Fallback";
@@ -28,7 +28,7 @@ import { Pagination } from "./components/TablePagination";
// import { getInfrastructureMonitorsByTeamId } from "../../Features/InfrastructureMonitors/infrastructureMonitorsSlice";
import { networkService } from "../../Utils/NetworkService.js";
import CustomGauge from "../../Components/Charts/CustomGauge/index.jsx";
import Host from "../Monitors/Home/host.jsx";
import Host from "../Uptime/Home/host.jsx";
import { useIsAdmin } from "../../Hooks/useIsAdmin.js";
import { InfrastructureMenu } from "./components/Menu";
@@ -13,7 +13,7 @@ import {
import { monitorValidation } from "../../../Validation/validation";
import { createToast } from "../../../Utils/toastUtils";
import { logger } from "../../../Utils/Logger";
import { ConfigBox } from "../../Monitors/styled";
import { ConfigBox } from "../../Uptime/styled";
import TextInput from "../../../Components/Inputs/TextInput";
import Select from "../../../Components/Inputs/Select";
import Checkbox from "../../../Components/Inputs/Checkbox";
@@ -23,7 +23,7 @@ import PulseDot from "../../../Components/Animated/PulseDot";
import LoadingButton from "@mui/lab/LoadingButton";
import PlayCircleOutlineRoundedIcon from "@mui/icons-material/PlayCircleOutlineRounded";
import SkeletonLayout from "./skeleton";
import useUtils from "../../Monitors/utils";
import useUtils from "../../Uptime/utils";
import "./index.css";
import Dialog from "../../../Components/Dialog";
@@ -11,7 +11,7 @@ import {
} from "../../../Features/PageSpeedMonitor/pageSpeedMonitorSlice";
import { createToast } from "../../../Utils/toastUtils";
import { logger } from "../../../Utils/Logger";
import { ConfigBox } from "../../Monitors/styled";
import { ConfigBox } from "../../Uptime/styled";
import Radio from "../../../Components/Inputs/Radio";
import TextInput from "../../../Components/Inputs/TextInput";
import { HttpAdornment } from "../../../Components/Inputs/TextInput/Adornments";
+1 -1
View File
@@ -19,7 +19,7 @@ import PulseDot from "../../../Components/Animated/PulseDot";
import PagespeedDetailsAreaChart from "./Charts/AreaChart";
import Checkbox from "../../../Components/Inputs/Checkbox";
import PieChart from "./Charts/PieChart";
import useUtils from "../../Monitors/utils";
import useUtils from "../../Uptime/utils";
import "./index.css";
const PageSpeedDetails = ({ isAdmin }) => {
+1 -1
View File
@@ -8,7 +8,7 @@ import { IconBox } from "./Details/styled";
import { Area, AreaChart, CartesianGrid, ResponsiveContainer, Tooltip } from "recharts";
import { useSelector } from "react-redux";
import { formatDateWithTz, formatDurationSplit } from "../../Utils/timeUtils";
import useUtils from "../Monitors/utils";
import useUtils from "../Uptime/utils";
import { useState } from "react";
/**
@@ -166,7 +166,7 @@ const Configure = () => {
event.preventDefault();
const action = await dispatch(deleteUptimeMonitor({ authToken, monitor }));
if (action.meta.requestStatus === "fulfilled") {
navigate("/monitors");
navigate("/uptime");
} else {
createToast({ body: "Failed to delete monitor." });
}
@@ -207,9 +207,9 @@ const Configure = () => {
<>
<Breadcrumbs
list={[
{ name: "monitors", path: "/monitors" },
{ name: "details", path: `/monitors/${monitorId}` },
{ name: "configure", path: `/monitors/configure/${monitorId}` },
{ name: "uptime", path: "/uptime" },
{ name: "details", path: `/uptime/${monitorId}` },
{ name: "configure", path: `/uptime/configure/${monitorId}` },
]}
/>
<Stack
@@ -60,8 +60,8 @@ const CreateMonitor = () => {
const theme = useTheme();
const { monitorId } = useParams();
const crumbs = [
{ name: "monitors", path: "/monitors" },
{ name: "create", path: `/monitors/create` },
{ name: "uptime", path: "/uptime" },
{ name: "create", path: `/uptime/create` },
];
// State
@@ -125,7 +125,7 @@ const CreateMonitor = () => {
const action = await dispatch(createUptimeMonitor({ authToken, monitor: form }));
if (action.meta.requestStatus === "fulfilled") {
createToast({ body: "Monitor created successfully!" });
navigate("/monitors");
navigate("/uptime");
} else {
createToast({ body: "Failed to create monitor." });
}
@@ -100,7 +100,7 @@ const DetailsPage = ({ isAdmin }) => {
}
};
fetchCertificate();
}, [authToken, monitorId, monitor]);
}, [authToken, monitorId, monitor, dateRange, uiTimezone, dateFormat]);
const splitDuration = (duration) => {
const { time, format } = formatDurationSplit(duration);
@@ -117,18 +117,17 @@ const DetailsPage = ({ isAdmin }) => {
const [hoveredUptimeData, setHoveredUptimeData] = useState(null);
const [hoveredIncidentsData, setHoveredIncidentsData] = useState(null);
const BREADCRUMBS = [
{ name: "uptime", path: "/uptime" },
{ name: "details", path: `/uptime/${monitorId}` },
];
return (
<Box className="monitor-details">
{loading ? (
<SkeletonLayout />
) : (
<>
<Breadcrumbs
list={[
{ name: "monitors", path: "/monitors" },
{ name: "details", path: `/monitors/${monitorId}` },
]}
/>
<Breadcrumbs list={BREADCRUMBS} />
<Stack
gap={theme.spacing(10)}
mt={theme.spacing(10)}
@@ -262,7 +261,7 @@ const DetailsPage = ({ isAdmin }) => {
<Button
variant="contained"
color="secondary"
onClick={() => navigate(`/monitors/configure/${monitorId}`)}
onClick={() => navigate(`/uptime/configure/${monitorId}`)}
sx={{
px: theme.spacing(5),
"& svg": {
@@ -1,7 +1,7 @@
import { useTheme } from "@emotion/react";
import { Box, Stack } from "@mui/material";
import Search from "../../../../Components/Inputs/Search";
import MemoizedMonitorTable from "../MonitorTable";
import MemoizedMonitorTable from "../UptimeTable";
import { useState } from "react";
import useDebounce from "../../../../Utils/debounce";
import PropTypes from "prop-types";
@@ -26,7 +26,7 @@ const CurrentMonitoring = ({ totalMonitors, monitors, isAdmin }) => {
alignItems="center"
mb={theme.spacing(8)}
>
<Heading component="h2">Actively monitoring</Heading>
<Heading component="h2">Uptime monitors</Heading>
<Box
className="current-monitors-counter"
@@ -268,7 +268,7 @@ const MonitorTable = ({ isAdmin, filter, setIsSearching, isSearching }) => {
},
}}
onClick={() => {
navigate(`/monitors/${monitor._id}`);
navigate(`/uptime/${monitor._id}`);
}}
>
<TableCell>
@@ -131,7 +131,7 @@ const ActionsMenu = ({ monitor, isAdmin, updateCallback }) => {
<MenuItem
onClick={(e) => {
e.stopPropagation();
navigate(`/monitors/${actions.id}`);
navigate(`/uptime/${actions.id}`);
}}
>
Details
@@ -150,7 +150,7 @@ const ActionsMenu = ({ monitor, isAdmin, updateCallback }) => {
onClick={(e) => {
e.stopPropagation();
navigate(`/monitors/configure/${actions.id}`);
navigate(`/uptime/configure/${actions.id}`);
}}
>
Configure
@@ -160,7 +160,7 @@ const ActionsMenu = ({ monitor, isAdmin, updateCallback }) => {
<MenuItem
onClick={(e) => {
e.stopPropagation();
navigate(`/monitors/create/${actions.id}`);
navigate(`/uptime/create/${actions.id}`);
}}
>
Clone
@@ -13,10 +13,12 @@ import Breadcrumbs from "../../../Components/Breadcrumbs";
import Greeting from "../../../Utils/greeting";
import { CurrentMonitoring } from "./CurrentMonitoring";
const Monitors = ({ isAdmin }) => {
const BREADCRUMBS = [{ name: `Uptime`, path: "/uptime" }];
const UptimeMonitors = ({ isAdmin }) => {
const theme = useTheme();
const navigate = useNavigate();
const monitorState = useSelector((state) => state.uptimeMonitors);
const uptimeMonitorsState = useSelector((state) => state.uptimeMonitors);
const authState = useSelector((state) => state.auth);
const dispatch = useDispatch({});
@@ -26,9 +28,9 @@ const Monitors = ({ isAdmin }) => {
//TODO bring fetching to this component, like on pageSpeed
const loading = monitorState?.isLoading;
const loading = uptimeMonitorsState?.isLoading;
const totalMonitors = monitorState?.monitorsSummary?.monitorCounts?.total;
const totalMonitors = uptimeMonitorsState?.monitorsSummary?.monitorCounts?.total;
const hasMonitors = totalMonitors > 0;
const noMonitors = !hasMonitors;
@@ -40,28 +42,28 @@ const Monitors = ({ isAdmin }) => {
gap={theme.spacing(8)}
>
<Box>
<Breadcrumbs list={[{ name: `monitors`, path: "/monitors" }]} />
<Breadcrumbs list={BREADCRUMBS} />
<Stack
direction="row"
justifyContent="space-between"
justifyContent="end"
alignItems="center"
mt={theme.spacing(5)}
gap={theme.spacing(6)}
>
<Greeting type="uptime" />
{canAddMonitor && (
<Button
variant="contained"
color="primary"
onClick={() => {
navigate("/monitors/create");
navigate("/uptime/create");
}}
sx={{ fontWeight: 500 }}
>
Create monitor
Create new
</Button>
)}
</Stack>
<Greeting type="uptime" />
</Box>
{noMonitors && <Fallback isAdmin={isAdmin} />}
{loading ? (
@@ -77,20 +79,20 @@ const Monitors = ({ isAdmin }) => {
>
<StatusBox
title="up"
value={monitorState?.monitorsSummary?.monitorCounts?.up ?? 0}
value={uptimeMonitorsState?.monitorsSummary?.monitorCounts?.up ?? 0}
/>
<StatusBox
title="down"
value={monitorState?.monitorsSummary?.monitorCounts?.down ?? 0}
value={uptimeMonitorsState?.monitorsSummary?.monitorCounts?.down ?? 0}
/>
<StatusBox
title="paused"
value={monitorState?.monitorsSummary?.monitorCounts?.paused ?? 0}
value={uptimeMonitorsState?.monitorsSummary?.monitorCounts?.paused ?? 0}
/>
</Stack>
<CurrentMonitoring
isAdmin={isAdmin}
monitors={monitorState.monitorsSummary.monitors}
monitors={uptimeMonitorsState.monitorsSummary.monitors}
totalMonitors={totalMonitors}
/>
</>
@@ -101,7 +103,7 @@ const Monitors = ({ isAdmin }) => {
);
};
Monitors.propTypes = {
UptimeMonitors.propTypes = {
isAdmin: PropTypes.bool,
};
export default Monitors;
export default UptimeMonitors;