From 04f75efa11fefe78f50035d3000aefddf6f60757 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 15 May 2025 10:48:32 -0700 Subject: [PATCH 01/10] add hook for monitor contolrs --- client/src/Hooks/useMonitorControls.js | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 client/src/Hooks/useMonitorControls.js diff --git a/client/src/Hooks/useMonitorControls.js b/client/src/Hooks/useMonitorControls.js new file mode 100644 index 000000000..b7d2ebe21 --- /dev/null +++ b/client/src/Hooks/useMonitorControls.js @@ -0,0 +1,30 @@ +import { useState } from "react"; +import { networkService } from "../main"; +import { createToast } from "../Utils/toastUtils"; + +const usePauseMonitor = ({ monitorId, triggerUpdate }) => { + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(undefined); + const [monitor, setMonitor] = useState(undefined); + const pauseMonitor = async () => { + try { + setIsLoading(false); + const res = await networkService.pauseMonitorById({ monitorId }); + setMonitor(res.data.data); + createToast({ + body: res.data.data.isActive + ? "Monitor resumed successfully" + : "Monitor paused successfully", + }); + triggerUpdate(); + } catch (error) { + setError(error); + } finally { + setIsLoading(false); + } + }; + + return [pauseMonitor, isLoading, error]; +}; + +export { usePauseMonitor }; From 9263f9f950f963fc72e6022d7633ce36a8ab6859 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 15 May 2025 10:48:54 -0700 Subject: [PATCH 02/10] add unified control header for all monitor details pages --- .../MonitorDetailsControlHeader/index.jsx | 80 +++++++++++++++++++ .../MonitorDetailsControlHeader/skeleton.jsx | 23 ++++++ .../MonitorDetailsControlHeader/status.jsx | 44 ++++++++++ 3 files changed, 147 insertions(+) create mode 100644 client/src/Components/MonitorDetailsControlHeader/index.jsx create mode 100644 client/src/Components/MonitorDetailsControlHeader/skeleton.jsx create mode 100644 client/src/Components/MonitorDetailsControlHeader/status.jsx diff --git a/client/src/Components/MonitorDetailsControlHeader/index.jsx b/client/src/Components/MonitorDetailsControlHeader/index.jsx new file mode 100644 index 000000000..1639799c4 --- /dev/null +++ b/client/src/Components/MonitorDetailsControlHeader/index.jsx @@ -0,0 +1,80 @@ +import Stack from "@mui/material/Stack"; +import Status from "./status"; +import Skeleton from "./skeleton"; +import Button from "@mui/material/Button"; +import SettingsOutlinedIcon from "@mui/icons-material/SettingsOutlined"; +import PauseOutlinedIcon from "@mui/icons-material/PauseOutlined"; +import PlayArrowOutlinedIcon from "@mui/icons-material/PlayArrowOutlined"; + +// Utils +import PropTypes from "prop-types"; +import { useNavigate } from "react-router-dom"; +import { useTheme } from "@mui/material/styles"; +import { usePauseMonitor } from "../../Hooks/useMonitorControls"; +import { useEffect } from "react"; +const MonitorDetailsControlHeader = ({ + path, + isLoading = false, + isAdmin = false, + monitor, + triggerUpdate, +}) => { + const navigate = useNavigate(); + const theme = useTheme(); + const [pauseMonitor, updatedMonitor, isPausing, error] = usePauseMonitor({ + monitorId: monitor?._id, + triggerUpdate, + }); + + if (isLoading) { + return ; + } + + return ( + + + + + + + {isAdmin && ( + + )} + + + ); +}; + +MonitorDetailsControlHeader.propTypes = { + path: PropTypes.string, + isLoading: PropTypes.bool, + isAdmin: PropTypes.bool, + monitor: PropTypes.object, + triggerUpdate: PropTypes.func, +}; + +export default MonitorDetailsControlHeader; diff --git a/client/src/Components/MonitorDetailsControlHeader/skeleton.jsx b/client/src/Components/MonitorDetailsControlHeader/skeleton.jsx new file mode 100644 index 000000000..64dc0547f --- /dev/null +++ b/client/src/Components/MonitorDetailsControlHeader/skeleton.jsx @@ -0,0 +1,23 @@ +import { Stack, Skeleton } from "@mui/material"; + +const SkeletonLayout = () => { + return ( + + + + + ); +}; + +export default SkeletonLayout; diff --git a/client/src/Components/MonitorDetailsControlHeader/status.jsx b/client/src/Components/MonitorDetailsControlHeader/status.jsx new file mode 100644 index 000000000..910a22210 --- /dev/null +++ b/client/src/Components/MonitorDetailsControlHeader/status.jsx @@ -0,0 +1,44 @@ +// Components +import Stack from "@mui/material/Stack"; +import PulseDot from "../../Components/Animated/PulseDot"; +import Typography from "@mui/material/Typography"; +import Dot from "../../Components/Dot"; +// Utils +import { formatDurationRounded } from "../../Utils/timeUtils"; +import PropTypes from "prop-types"; +import { useTheme } from "@emotion/react"; +import useUtils from "../../Pages/Uptime/Monitors/Hooks/useUtils"; + +const Status = ({ monitor }) => { + const theme = useTheme(); + const { statusColor, determineState } = useUtils(); + + return ( + + {monitor?.name} + + + + {monitor?.url?.replace(/^https?:\/\//, "") || "..."} + + + + Checking every {formatDurationRounded(monitor?.interval)}. + + + + ); +}; + +Status.propTypes = { + monitor: PropTypes.object, +}; + +export default Status; From 54db96a03e9c29642b7b3cebcfde011a72a11fb5 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 15 May 2025 10:49:38 -0700 Subject: [PATCH 03/10] add trigger to useFetchUptimeMonitorDetails --- client/src/Hooks/useFetchUptimeMonitorDetails.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/src/Hooks/useFetchUptimeMonitorDetails.js b/client/src/Hooks/useFetchUptimeMonitorDetails.js index c8cb81e65..3c0ac7ee6 100644 --- a/client/src/Hooks/useFetchUptimeMonitorDetails.js +++ b/client/src/Hooks/useFetchUptimeMonitorDetails.js @@ -3,13 +3,12 @@ import { networkService } from "../main"; import { useNavigate } from "react-router-dom"; import { createToast } from "../Utils/toastUtils"; -export const useFetchUptimeMonitorDetails = ({ monitorId, dateRange }) => { +export const useFetchUptimeMonitorDetails = ({ monitorId, dateRange, trigger }) => { const [networkError, setNetworkError] = useState(false); const [isLoading, setIsLoading] = useState(true); const [monitor, setMonitor] = useState(undefined); const [monitorStats, setMonitorStats] = useState(undefined); const navigate = useNavigate(); - useEffect(() => { const fetchMonitors = async () => { try { @@ -29,7 +28,7 @@ export const useFetchUptimeMonitorDetails = ({ monitorId, dateRange }) => { } }; fetchMonitors(); - }, [dateRange, monitorId, navigate]); + }, [dateRange, monitorId, navigate, trigger]); return [monitor, monitorStats, isLoading, networkError]; }; From f9fcd4ff3a037f163b342b0e42b26f23f670b178 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 15 May 2025 10:50:21 -0700 Subject: [PATCH 04/10] remove pause from uptime config page --- client/src/Pages/Uptime/Configure/index.jsx | 49 --------------------- 1 file changed, 49 deletions(-) diff --git a/client/src/Pages/Uptime/Configure/index.jsx b/client/src/Pages/Uptime/Configure/index.jsx index 5afbc4a27..d52780eea 100644 --- a/client/src/Pages/Uptime/Configure/index.jsx +++ b/client/src/Pages/Uptime/Configure/index.jsx @@ -158,23 +158,6 @@ const Configure = () => { } }; - const handlePause = async () => { - try { - const action = await dispatch(pauseUptimeMonitor({ monitorId })); - if (pauseUptimeMonitor.fulfilled.match(action)) { - const monitor = action.payload.data; - setMonitor(monitor); - const state = action?.payload?.data.isActive === false ? "paused" : "resumed"; - createToast({ body: `Monitor ${state} successfully.` }); - } else if (pauseUptimeMonitor.rejected.match(action)) { - throw new Error(action.error.message); - } - } catch (error) { - logger.error("Error pausing monitor: " + monitorId); - createToast({ body: "Failed to pause monitor" }); - } - }; - const handleSubmit = async (event) => { event.preventDefault(); const action = await dispatch(updateUptimeMonitor({ monitor: monitor })); @@ -329,38 +312,6 @@ const Configure = () => { ml: "auto", }} > -