diff --git a/client/src/Components/v1/FilterHeader/index.jsx b/client/src/Components/v1/FilterHeader/index.jsx deleted file mode 100644 index de2c7f0e9..000000000 --- a/client/src/Components/v1/FilterHeader/index.jsx +++ /dev/null @@ -1,100 +0,0 @@ -import { Checkbox, FormControl, ListItemText, MenuItem, Select } from "@mui/material"; -import { useTheme } from "@emotion/react"; -import PropTypes from "prop-types"; -import Icon from "../Icon"; - -/** - * A reusable filter header component that displays a dropdown menu with selectable options. - * - * @component - * @param {Object} props - The component props. - * @param {string} props.header - The header text to display when no options are selected. - * @param {Array} props.options - An array of options to display in the dropdown menu. Each option should have a `value` and `label`. - * @param {Array} [props.value] - The currently selected values. - * @param {Function} props.onChange - The callback function to handle changes in the selected values. - * @param {boolean} [props.multiple=true] - Whether multiple options can be selected. - * @returns {JSX.Element} The rendered FilterHeader component. - */ - -const FilterHeader = ({ header, options, value, onChange, multiple = true }) => { - const theme = useTheme(); - - const controlledValue = value === undefined ? [] : value; // Ensure value is always treated as an array for controlled component purposes - - return ( - - - - ); -}; - -FilterHeader.propTypes = { - header: PropTypes.string.isRequired, - options: PropTypes.arrayOf( - PropTypes.shape({ - value: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - }) - ).isRequired, - value: PropTypes.arrayOf(PropTypes.string), - onChange: PropTypes.func.isRequired, - multiple: PropTypes.bool, -}; - -export default FilterHeader; diff --git a/client/src/Components/v1/MonitorActions/index.jsx b/client/src/Components/v1/MonitorActions/index.jsx deleted file mode 100644 index f63fc23fe..000000000 --- a/client/src/Components/v1/MonitorActions/index.jsx +++ /dev/null @@ -1,119 +0,0 @@ -import * as React from "react"; -import Button from "@mui/material/Button"; -import ButtonGroup from "@mui/material/ButtonGroup"; -import Icon from "../Icon"; -import ClickAwayListener from "@mui/material/ClickAwayListener"; -import Grow from "@mui/material/Grow"; -import Paper from "@mui/material/Paper"; -import Popper from "@mui/material/Popper"; -import MenuItem from "@mui/material/MenuItem"; -import MenuList from "@mui/material/MenuList"; -import { useNavigate } from "react-router-dom"; -import { useTranslation } from "react-i18next"; -import { createToast } from "../../../Utils/toastUtils.jsx"; -import { useExportMonitors } from "../../../Hooks/monitorHooks.js"; - -const MonitorActions = ({ isLoading }) => { - const [open, setOpen] = React.useState(false); - const anchorRef = React.useRef(null); - const [selectedIndex, setSelectedIndex] = React.useState(0); - const navigate = useNavigate(); - const { t } = useTranslation(); - const [exportMonitors, isExporting] = useExportMonitors(); - - const options = [t("monitorActions.import"), t("monitorActions.export")]; - - const handleClick = async () => { - if (selectedIndex === 0) { - // Import - navigate("/uptime/bulk-import"); - } else { - // Export - const [success, error] = await exportMonitors(); - if (!success) { - createToast({ body: error || t("export.failed") }); - } - } - }; - - const handleMenuItemClick = (event, index) => { - setSelectedIndex(index); - setOpen(false); - }; - - const handleToggle = () => { - setOpen((prevOpen) => !prevOpen); - }; - - const handleClose = (event) => { - if (anchorRef.current && anchorRef.current.contains(event.target)) { - return; - } - setOpen(false); - }; - - return ( - - - - - - - {({ TransitionProps, placement }) => ( - - - - - {options.map((option, index) => ( - handleMenuItemClick(event, index)} - > - {option} - - ))} - - - - - )} - - - ); -}; - -export default MonitorActions; diff --git a/client/src/Components/v1/MonitorCountHeader/index.jsx b/client/src/Components/v1/MonitorCountHeader/index.jsx deleted file mode 100644 index eba644d26..000000000 --- a/client/src/Components/v1/MonitorCountHeader/index.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import { Stack, Typography } from "@mui/material"; -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; -import SkeletonLayout from "./skeleton.jsx"; - -const MonitorCountHeader = ({ - isLoading = false, - monitorCount, - heading = "monitors", - sx, - children, -}) => { - const theme = useTheme(); - if (isLoading) return ; - - if (monitorCount === 1) { - heading = "monitor"; - } - - return ( - - {monitorCount} {heading} - {children} - - ); -}; - -MonitorCountHeader.propTypes = { - isLoading: PropTypes.bool, - monitorCount: PropTypes.number, - heading: PropTypes.string, - children: PropTypes.node, - sx: PropTypes.object, -}; - -export default MonitorCountHeader; diff --git a/client/src/Components/v1/MonitorCountHeader/skeleton.jsx b/client/src/Components/v1/MonitorCountHeader/skeleton.jsx deleted file mode 100644 index 9b4971c32..000000000 --- a/client/src/Components/v1/MonitorCountHeader/skeleton.jsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Stack, Skeleton } from "@mui/material"; -import { useTheme } from "@emotion/react"; - -const SkeletonLayout = () => { - const theme = useTheme(); - return ( - - - - - ); -}; - -export default SkeletonLayout; diff --git a/client/src/Components/v1/MonitorCreateHeader/index.jsx b/client/src/Components/v1/MonitorCreateHeader/index.jsx index 90c12f5ec..c3a979eb9 100644 --- a/client/src/Components/v1/MonitorCreateHeader/index.jsx +++ b/client/src/Components/v1/MonitorCreateHeader/index.jsx @@ -3,7 +3,6 @@ import { useNavigate } from "react-router-dom"; import PropTypes from "prop-types"; import { useTranslation } from "react-i18next"; import { useTheme } from "@emotion/react"; -import MonitorActions from "../MonitorActions/index.jsx"; const CreateMonitorHeader = ({ isAdmin, label, isLoading = true, path, bulkPath }) => { const navigate = useNavigate(); diff --git a/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx b/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx deleted file mode 100644 index 0793e7149..000000000 --- a/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx +++ /dev/null @@ -1,158 +0,0 @@ -import Stack from "@mui/material/Stack"; -import Status from "./status.jsx"; -import Skeleton from "./skeleton.jsx"; -import Button from "@mui/material/Button"; -import { Tooltip } from "@mui/material"; -import Icon from "../Icon"; - -// Utils -import PropTypes from "prop-types"; -import { useNavigate } from "react-router-dom"; -import { useTheme } from "@mui/material/styles"; -import { usePauseMonitor } from "../../../Hooks/monitorHooks.js"; -import { useSendTestEmail } from "../../../Hooks/useSendTestEmail.js"; -import { useTranslation } from "react-i18next"; -import { useTestAllNotifications } from "../../../Hooks/useNotifications.js"; -/** - * MonitorDetailsControlHeader component displays the control header for monitor details. - * It includes status display, pause/resume button, and a configure button for admins. - * - * @component - * @param {Object} props - Component props - * @param {string} props.path - The base path for navigation - * @param {boolean} [props.isLoading=false] - Flag indicating if the data is loading - * @param {boolean} [props.isAdmin=false] - Flag indicating if the user is an admin - * @param {Object} props.monitor - The monitor object containing details - * @param {Function} props.triggerUpdate - Function to trigger an update - * @returns {JSX.Element} The rendered component - */ -const MonitorDetailsControlHeader = ({ - path, - isLoading = false, - isAdmin = false, - monitor, - triggerUpdate, -}) => { - const navigate = useNavigate(); - const theme = useTheme(); - const { t } = useTranslation(); - const [pauseMonitor, isPausing, error] = usePauseMonitor(); - - const isTestNotificationsDisabled = monitor?.notifications?.length === 0; - - const tooltipTitle = isTestNotificationsDisabled ? t("testNotificationsDisabled") : ""; - - // const [isSending, emailError, sendTestEmail] = useSendTestEmail(); - - const [testAllNotifications, isSending, errorAllNotifications] = - useTestAllNotifications(); - - if (isLoading) { - return ; - } - - return ( - - - - - - - - - - - {isAdmin && ( - - )} - {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/v1/MonitorDetailsControlHeader/skeleton.jsx b/client/src/Components/v1/MonitorDetailsControlHeader/skeleton.jsx deleted file mode 100644 index 64dc0547f..000000000 --- a/client/src/Components/v1/MonitorDetailsControlHeader/skeleton.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Stack, Skeleton } from "@mui/material"; - -const SkeletonLayout = () => { - return ( - - - - - ); -}; - -export default SkeletonLayout; diff --git a/client/src/Components/v1/MonitorDetailsControlHeader/status.jsx b/client/src/Components/v1/MonitorDetailsControlHeader/status.jsx deleted file mode 100644 index c6a3cfcfa..000000000 --- a/client/src/Components/v1/MonitorDetailsControlHeader/status.jsx +++ /dev/null @@ -1,51 +0,0 @@ -// Components -import Stack from "@mui/material/Stack"; -import PulseDot from "../Animated/PulseDot.jsx"; -import Typography from "@mui/material/Typography"; -import Dot from "../Dot/index.jsx"; -// Utils -import { formatDurationRounded } from "../../../Utils/timeUtilsLegacy.js"; -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; -import { useMonitorUtils } from "../../../Hooks/useMonitorUtils.js"; -import { formatMonitorUrl } from "../../../Utils/utils.js"; -/** - * Status component displays the status information of a monitor. - * It includes the monitor's name, URL, and check interval. - * - * @component - * @param {Object} props - Component props - * @param {Object} props.monitor - The monitor object containing details - * @param {string} props.monitor.name - The name of the monitor - * @param {string} props.monitor.url - The URL of the monitor - * @param {number} props.monitor.interval - The interval at which the monitor checks - * @returns {JSX.Element} The rendered component - */ -const Status = ({ monitor }) => { - const theme = useTheme(); - const { statusColor, determineState } = useMonitorUtils(); - - return ( - - {monitor?.name} - - - {formatMonitorUrl(monitor?.url)} - - - Checking every {formatDurationRounded(monitor?.interval)}. - - - - ); -}; - -Status.propTypes = { - monitor: PropTypes.object, -}; - -export default Status; diff --git a/client/src/Components/v1/NotificationConfig/index.jsx b/client/src/Components/v1/NotificationConfig/index.jsx deleted file mode 100644 index f1ed30ad1..000000000 --- a/client/src/Components/v1/NotificationConfig/index.jsx +++ /dev/null @@ -1,127 +0,0 @@ -// Components -import Stack from "@mui/material/Stack"; -import Typography from "@mui/material/Typography"; -import Divider from "@mui/material/Divider"; -import Icon from "../Icon"; -import Search from "../Inputs/Search/index.jsx"; - -// Utils -import { useState, useEffect } from "react"; -import { useTheme } from "@mui/material/styles"; -import PropTypes from "prop-types"; - -const NotificationConfig = ({ - notifications, - setMonitor, - setNotifications, - //FieldWrapper's props - gap, - labelMb, - labelFontWeight, - labelVariant, - labelSx = {}, - sx = {}, -}) => { - // Local state - const [notificationsSearch, setNotificationsSearch] = useState(""); - const [selectedNotifications, setSelectedNotifications] = useState([]); - - const handleSearch = (value) => { - setSelectedNotifications(value); - setMonitor((prev) => { - return { - ...prev, - notifications: value.map((notification) => notification.id), - }; - }); - }; - - // Handlers - const handleDelete = (id) => { - const updatedNotifications = selectedNotifications.filter( - (notification) => notification.id !== id - ); - - setSelectedNotifications(updatedNotifications); - setMonitor((prev) => { - return { - ...prev, - notifications: updatedNotifications.map((notification) => notification.id), - }; - }); - }; - - // Setup - const theme = useTheme(); - - useEffect(() => { - if (setNotifications) { - const toSet = setNotifications.map((notification) => { - return notifications.find((n) => n.id === notification); - }); - setSelectedNotifications(toSet); - } - }, [setNotifications, notifications]); - - return ( - - { - handleSearch(value); - }} - labelMb={labelMb} - labelVariant={labelVariant} - labelFontWeight={labelFontWeight} - labelSx={labelSx} - gap={gap} - sx={{ - ...sx, - }} - /> - - {selectedNotifications.map((notification, index) => ( - - - {notification.notificationName} - - { - handleDelete(notification.id); - }} - style={{ cursor: "pointer" }} - /> - {index < selectedNotifications.length - 1 && } - - ))} - - - ); -}; - -NotificationConfig.propTypes = { - notifications: PropTypes.array, - setMonitor: PropTypes.func, - setNotifications: PropTypes.array, -}; - -export default NotificationConfig; diff --git a/client/src/Components/v2/common/controls/HeaderMonitorControls.tsx b/client/src/Components/v2/common/controls/HeaderMonitorControls.tsx index 3fe44315a..d1a0d078d 100644 --- a/client/src/Components/v2/common/controls/HeaderMonitorControls.tsx +++ b/client/src/Components/v2/common/controls/HeaderMonitorControls.tsx @@ -159,14 +159,14 @@ export const HeaderDeleteControls = ({ )} {isAdmin && ( - )} diff --git a/client/src/Components/v2/inputs/Select.tsx b/client/src/Components/v2/inputs/Select.tsx index 8be20897d..b9675acd7 100644 --- a/client/src/Components/v2/inputs/Select.tsx +++ b/client/src/Components/v2/inputs/Select.tsx @@ -15,13 +15,7 @@ interface SelectInputProps extends Omit, "label"> { } const SelectInputInner = ( - { - fieldLabel, - required, - placeholder, - placeholderColor, - ...props - }: SelectInputProps, + { fieldLabel, required, placeholder, placeholderColor, ...props }: SelectInputProps, ref: React.ForwardedRef ) => { const theme = useTheme(); diff --git a/client/src/Hooks/monitorHooks.js b/client/src/Hooks/monitorHooks.js index 9d46e9365..006c5b76e 100644 --- a/client/src/Hooks/monitorHooks.js +++ b/client/src/Hooks/monitorHooks.js @@ -1,107 +1,8 @@ import { useEffect, useState } from "react"; import { networkService } from "../main.jsx"; import { createToast } from "../Utils/toastUtils.jsx"; -import { useTheme } from "@emotion/react"; -import { useMonitorUtils } from "./useMonitorUtils.js"; -import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; -export const useFetchMonitorsWithSummary = ({ types, monitorUpdateTrigger }) => { - const [isLoading, setIsLoading] = useState(false); - const [monitors, setMonitors] = useState(undefined); - const [monitorsSummary, setMonitorsSummary] = useState(undefined); - const [networkError, setNetworkError] = useState(false); - - useEffect(() => { - const fetchMonitors = async () => { - try { - setIsLoading(true); - const res = await networkService.getMonitorsWithSummaryByTeamId({ - types, - }); - const { monitors, summary } = res?.data?.data ?? {}; - setMonitors(monitors); - setMonitorsSummary(summary); - } catch (error) { - console.error(error); - setNetworkError(true); - createToast({ - body: error.message, - }); - } finally { - setIsLoading(false); - } - }; - fetchMonitors(); - }, [types, monitorUpdateTrigger]); - return [monitors, monitorsSummary, isLoading, networkError]; -}; - -export const useFetchMonitorsWithChecks = ({ - types, - limit, - page, - rowsPerPage, - filter, - field, - order, - monitorUpdateTrigger, -}) => { - const [isLoading, setIsLoading] = useState(false); - const [count, setCount] = useState(undefined); - const [monitors, setMonitors] = useState(undefined); - const [summary, setSummary] = useState(undefined); - const [networkError, setNetworkError] = useState(false); - - const theme = useTheme(); - const { getMonitorWithPercentage } = useMonitorUtils(); - useEffect(() => { - const fetchMonitors = async () => { - try { - setIsLoading(true); - const res = await networkService.getMonitorsWithChecksByTeamId({ - limit, - types, - page, - rowsPerPage, - filter, - field, - order, - }); - - const { count, monitors, summary } = res?.data?.data ?? {}; - const mappedMonitors = monitors.map((monitor) => - getMonitorWithPercentage(monitor, theme) - ); - setSummary(summary); - setMonitors(mappedMonitors); - setCount(count || 0); - } catch (error) { - console.error(error); - setNetworkError(true); - createToast({ - body: error.message, - }); - } finally { - setIsLoading(false); - } - }; - fetchMonitors(); - }, [ - field, - filter, - getMonitorWithPercentage, - limit, - order, - page, - rowsPerPage, - theme, - types, - monitorUpdateTrigger, - ]); - return [summary, monitors, count, isLoading, networkError]; -}; - export const useFetchMonitorsByTeamId = ({ types, filter, updateTrigger }) => { const [isLoading, setIsLoading] = useState(false); const [monitors, setMonitors] = useState(undefined); @@ -132,225 +33,17 @@ export const useFetchMonitorsByTeamId = ({ types, filter, updateTrigger }) => { return [monitors, isLoading, networkError]; }; -export const useFetchStatsByMonitorId = ({ - monitorId, - sortOrder, - limit, - dateRange, - numToDisplay, - normalize, - updateTrigger, -}) => { - const [monitor, setMonitor] = useState(undefined); - const [audits, setAudits] = useState(undefined); - const [isLoading, setIsLoading] = useState(true); - const [networkError, setNetworkError] = useState(false); - useEffect(() => { - const fetchMonitor = async () => { - try { - setIsLoading(true); - const res = await networkService.getStatsByMonitorId({ - monitorId: monitorId, - sortOrder, - limit, - dateRange, - numToDisplay, - normalize, - }); - setMonitor(res?.data?.data ?? undefined); - setAudits(res?.data?.data?.checks?.[0]?.audits ?? undefined); - } catch (error) { - setNetworkError(true); - createToast({ body: error.message }); - } finally { - setIsLoading(false); - } - }; - fetchMonitor(); - }, [monitorId, dateRange, numToDisplay, normalize, sortOrder, limit, updateTrigger]); - return [monitor, audits, isLoading, networkError]; -}; - -export const useFetchMonitorGames = ({ setGames, updateTrigger }) => { - const [isLoading, setIsLoading] = useState(true); - useEffect(() => { - const fetchGames = async () => { - try { - setIsLoading(true); - const res = await networkService.getMonitorGames(); - setGames(res.data.data); - } catch (error) { - createToast({ body: error.message }); - } finally { - setIsLoading(false); - } - }; - fetchGames(); - }, [setGames, updateTrigger]); - return [isLoading]; -}; - -export const useFetchMonitorById = ({ monitorId, setMonitor, updateTrigger }) => { - const [isLoading, setIsLoading] = useState(true); - useEffect(() => { - if (typeof monitorId === "undefined") { - setIsLoading(false); - return; - } - const fetchMonitor = async () => { - try { - setIsLoading(true); - const res = await networkService.getMonitorById({ monitorId: monitorId }); - setMonitor(res.data.data); - } catch (error) { - createToast({ body: error.message }); - } finally { - setIsLoading(false); - } - }; - fetchMonitor(); - }, [monitorId, setMonitor, updateTrigger]); - return [isLoading]; -}; - -export const useFetchHardwareMonitorById = ({ monitorId, dateRange, updateTrigger }) => { - const [isLoading, setIsLoading] = useState(true); - const [networkError, setNetworkError] = useState(false); - const [monitor, setMonitor] = useState(undefined); - - useEffect(() => { - const fetchMonitor = async () => { - try { - if (!monitorId) { - return { monitor: undefined, isLoading: false, networkError: undefined }; - } - const response = await networkService.getHardwareDetailsByMonitorId({ - monitorId: monitorId, - dateRange: dateRange, - }); - setMonitor(response.data.data); - } catch (error) { - setNetworkError(true); - } finally { - setIsLoading(false); - } - }; - fetchMonitor(); - }, [monitorId, dateRange, updateTrigger]); - return [monitor, isLoading, networkError]; -}; -export const useFetchPageSpeedMonitorById = ({ monitorId, dateRange, updateTrigger }) => { - const [isLoading, setIsLoading] = useState(true); - const [networkError, setNetworkError] = useState(false); - const [monitor, setMonitor] = useState(undefined); - const [monitorStats, setMonitorStats] = useState(undefined); - - useEffect(() => { - const fetchMonitor = async () => { - try { - if (!monitorId) { - return { monitor: undefined, isLoading: false, networkError: undefined }; - } - const response = await networkService.getPageSpeedDetailsByMonitorId({ - monitorId: monitorId, - dateRange: dateRange, - }); - setMonitor(response.data.data.monitor); - setMonitorStats(response.data.data.monitorStats); - } catch (error) { - setNetworkError(true); - } finally { - setIsLoading(false); - } - }; - fetchMonitor(); - }, [monitorId, dateRange, updateTrigger]); - return [monitor, monitorStats, isLoading, networkError]; -}; - -export const useFetchUptimeMonitorById = ({ monitorId, dateRange, trigger }) => { - const [networkError, setNetworkError] = useState(false); - const [isLoading, setIsLoading] = useState(true); - const [monitor, setMonitor] = useState(undefined); - const [monitorStats, setMonitorStats] = useState(undefined); - useEffect(() => { - const fetchMonitors = async () => { - try { - const res = await networkService.getUptimeDetailsById({ - monitorId: monitorId, - dateRange: dateRange, - normalize: true, - }); - const { monitorData, monitorStats } = res?.data?.data ?? {}; - setMonitor(monitorData); - setMonitorStats(monitorStats); - } catch (error) { - setNetworkError(true); - createToast({ body: error.message }); - } finally { - setIsLoading(false); - } - }; - fetchMonitors(); - }, [dateRange, monitorId, trigger]); - return [monitor, monitorStats, isLoading, networkError]; -}; - -export const useCreateMonitor = () => { - const [isLoading, setIsLoading] = useState(false); - const navigate = useNavigate(); - const createMonitor = async ({ monitor, redirect }) => { - try { - setIsLoading(true); - await networkService.createMonitor({ monitor }); - createToast({ body: "Monitor created successfully!" }); - if (redirect) { - navigate(redirect); - } - } catch (error) { - createToast({ body: "Failed to create monitor." }); - } finally { - setIsLoading(false); - } - }; - return [createMonitor, isLoading]; -}; - -export const useFetchGlobalSettings = () => { - const [isLoading, setIsLoading] = useState(true); - const [globalSettings, setGlobalSettings] = useState(undefined); - useEffect(() => { - const fetchGlobalSettings = async () => { - try { - const res = await networkService.getAppSettings(); - setGlobalSettings(res?.data); - } catch (error) { - console.error("Failed to fetch global settings:", error); - createToast({ body: "Failed to load global settings" }); - } finally { - setIsLoading(false); - } - }; - - fetchGlobalSettings(); - }, []); - - return [globalSettings, isLoading]; -}; - export const useDeleteMonitor = () => { const [isLoading, setIsLoading] = useState(false); - const navigate = useNavigate(); - const deleteMonitor = async ({ monitor, redirect }) => { + const { t } = useTranslation(); + const deleteMonitor = async (monitorId, successCallback = () => {}) => { try { setIsLoading(true); - await networkService.deleteMonitorById({ monitorId: monitor.id }); - createToast({ body: "Monitor deleted successfully!" }); - if (redirect) { - navigate(redirect); - } + await networkService.deleteMonitorById({ monitorId }); + successCallback(); + createToast({ body: t("monitorDeleted") }); } catch (error) { - createToast({ body: "Failed to delete monitor." }); + createToast({ body: t("failedDeleteMonitor") }); } finally { setIsLoading(false); } @@ -358,68 +51,24 @@ export const useDeleteMonitor = () => { return [deleteMonitor, isLoading]; }; -export const useUpdateMonitor = () => { - const [isLoading, setIsLoading] = useState(false); - const navigate = useNavigate(); - const updateMonitor = async ({ monitor, redirect }) => { - try { - setIsLoading(true); - const updatedFields = { - name: monitor.name, - statusWindowSize: monitor.statusWindowSize, - statusWindowThreshold: monitor.statusWindowThreshold, - description: monitor.description, - interval: monitor.interval, - notifications: monitor.notifications, - matchMethod: monitor.matchMethod, - expectedValue: monitor.expectedValue, - ignoreTlsErrors: monitor.ignoreTlsErrors, - jsonPath: monitor.jsonPath, - ...((monitor.type === "port" || monitor.type === "game") && { - port: monitor.port, - }), - ...(monitor.type == "game" && { - gameId: monitor.gameId, - }), - ...(monitor.type === "hardware" && { - thresholds: monitor.thresholds, - secret: monitor.secret, - selectedDisks: monitor.selectedDisks, - }), - }; - await networkService.updateMonitor({ - monitorId: monitor.id, - updatedFields, - }); - - createToast({ body: "Monitor updated successfully!" }); - if (redirect) { - navigate(redirect); - } - } catch (error) { - createToast({ body: "Failed to update monitor." }); - } finally { - setIsLoading(false); - } - }; - return [updateMonitor, isLoading]; -}; - export const usePauseMonitor = () => { const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(undefined); - const pauseMonitor = async ({ monitorId, triggerUpdate }) => { + const [error, setError] = useState(null); + const { t } = useTranslation(); + + const pauseMonitor = async (monitorId, successCallback = () => {}) => { try { setIsLoading(true); const res = await networkService.pauseMonitorById({ monitorId }); - createToast({ - body: res.data.data.isActive - ? "Monitor resumed successfully" - : "Monitor paused successfully", - }); - triggerUpdate(); + successCallback(); + if (res.data.data.isActive === false) { + createToast({ body: t("monitorPaused") }); + } else { + createToast({ body: t("monitorResumed") }); + } } catch (error) { - setError(error); + setError(error.message); + createToast({ body: t("failedPauseMonitor") }); } finally { setIsLoading(false); } @@ -491,7 +140,7 @@ export const useCreateBulkMonitors = () => { try { const response = await networkService.createBulkMonitors(formData); - return [true, response.data, null]; // [success, data, error] + return [true, response.data, null]; } catch (err) { const errorMessage = err?.response?.data?.msg || err.message; return [false, null, errorMessage]; @@ -503,39 +152,6 @@ export const useCreateBulkMonitors = () => { return [createBulkMonitors, isLoading]; }; -export const useExportMonitors = () => { - const [isLoading, setIsLoading] = useState(false); - const { t } = useTranslation(); - - const exportMonitors = async () => { - setIsLoading(true); - try { - const response = await networkService.exportMonitors(); - - // Create a download link - const url = window.URL.createObjectURL(response.data); - const link = document.createElement("a"); - link.href = url; - link.setAttribute("download", "monitors.csv"); - document.body.appendChild(link); - link.click(); - link.remove(); - window.URL.revokeObjectURL(url); - - createToast({ body: t("export.success") }); - return [true, null]; - } catch (err) { - const errorMessage = err?.response?.data?.msg || err.message; - createToast({ body: errorMessage || t("export.failed") }); - return [false, errorMessage]; - } finally { - setIsLoading(false); - } - }; - - return [exportMonitors, isLoading]; -}; - export const useFetchJson = () => { const [isLoading, setIsLoading] = useState(false); const fetchJson = async () => {