diff --git a/client/src/Components/ActionsMenu/index.jsx b/client/src/Components/ActionsMenu/index.jsx index 4d5ab7c01..1b590a471 100644 --- a/client/src/Components/ActionsMenu/index.jsx +++ b/client/src/Components/ActionsMenu/index.jsx @@ -1,17 +1,18 @@ +// Components +import IconButton from "@mui/material/IconButton"; +import Menu from "@mui/material/Menu"; +import MenuItem from "@mui/material/MenuItem"; +import Settings from "../../assets/icons/settings-bold.svg?react"; +import Dialog from "../../Components/Dialog"; + +// Utils import { useState } from "react"; -import { useSelector, useDispatch } from "react-redux"; import { useTheme } from "@emotion/react"; import { useNavigate } from "react-router-dom"; import { createToast } from "../../Utils/toastUtils"; -import { logger } from "../../Utils/Logger"; -import { IconButton, Menu, MenuItem } from "@mui/material"; -import { - deleteUptimeMonitor, - pauseUptimeMonitor, -} from "../../Features/UptimeMonitors/uptimeMonitorsSlice"; -import Settings from "../../assets/icons/settings-bold.svg?react"; + import PropTypes from "prop-types"; -import Dialog from "../../Components/Dialog"; +import { usePauseMonitor, useDeleteMonitor } from "../../Hooks/monitorHooks"; const ActionsMenu = ({ monitor, @@ -23,38 +24,27 @@ const ActionsMenu = ({ const [anchorEl, setAnchorEl] = useState(null); const [actions, setActions] = useState({}); const [isOpen, setIsOpen] = useState(false); - const dispatch = useDispatch(); const theme = useTheme(); - const { isLoading } = useSelector((state) => state.uptimeMonitors); + const [pauseMonitor, isPausing, error] = usePauseMonitor(); + const [deleteMonitor, isDeleting] = useDeleteMonitor(); const handleRemove = async (event) => { event.preventDefault(); event.stopPropagation(); let monitor = { _id: actions.id }; - const action = await dispatch(deleteUptimeMonitor({ monitor })); - if (action.meta.requestStatus === "fulfilled") { - setIsOpen(false); // close modal - updateRowCallback(); - createToast({ body: "Monitor deleted successfully." }); - } else { - createToast({ body: "Failed to delete monitor." }); - } + await deleteMonitor({ monitor }); + updateRowCallback(); }; const handlePause = async () => { try { setIsLoading(true); - const action = await dispatch(pauseUptimeMonitor({ monitorId: monitor._id })); - if (pauseUptimeMonitor.fulfilled.match(action)) { - const state = action?.payload?.data.isActive === false ? "resumed" : "paused"; - createToast({ body: `Monitor ${state} successfully.` }); - pauseCallback(); - } else { - throw new Error(action?.error?.message ?? "Failed to pause monitor."); - } + await pauseMonitor({ monitorId: monitor._id }); + pauseCallback(); } catch (error) { - logger.error("Error pausing monitor:", monitor._id, error); createToast({ body: "Failed to pause monitor." }); + } finally { + setIsLoading(false); } }; @@ -210,7 +200,7 @@ const ActionsMenu = ({ e.stopPropagation(); handleRemove(e); }} - isLoading={isLoading} + isLoading={isDeleting} modelTitle="modal-delete-monitor" modelDescription="delete-monitor-confirmation" /> diff --git a/client/src/Components/Dialog/index.jsx b/client/src/Components/Dialog/index.jsx index e07597df4..678eb8721 100644 --- a/client/src/Components/Dialog/index.jsx +++ b/client/src/Components/Dialog/index.jsx @@ -57,7 +57,7 @@ Dialog.propTypes = { onCancel: PropTypes.func.isRequired, confirmationButtonLabel: PropTypes.string.isRequired, onConfirm: PropTypes.func.isRequired, - isLoading: PropTypes.bool.isRequired, + isLoading: PropTypes.bool, }; export default Dialog; diff --git a/client/src/Components/Sidebar/index.jsx b/client/src/Components/Sidebar/index.jsx index f487148f5..06a140c54 100644 --- a/client/src/Components/Sidebar/index.jsx +++ b/client/src/Components/Sidebar/index.jsx @@ -49,7 +49,6 @@ import { useDispatch, useSelector } from "react-redux"; import { useTranslation } from "react-i18next"; import { clearAuthState } from "../../Features/Auth/authSlice"; import { toggleSidebar } from "../../Features/UI/uiSlice"; -import { clearUptimeMonitorState } from "../../Features/UptimeMonitors/uptimeMonitorsSlice"; const getMenu = (t) => [ { name: t("menu.uptime"), path: "uptime", icon: }, @@ -197,7 +196,6 @@ function Sidebar() { const logout = async () => { // Clear auth state dispatch(clearAuthState()); - dispatch(clearUptimeMonitorState()); navigate("/login"); }; diff --git a/client/src/Components/StatBox/index.jsx b/client/src/Components/StatBox/index.jsx index 93fa46c2b..7d093de60 100644 --- a/client/src/Components/StatBox/index.jsx +++ b/client/src/Components/StatBox/index.jsx @@ -136,8 +136,8 @@ const StatBox = ({ }; StatBox.propTypes = { - heading: PropTypes.string.isRequired, - subHeading: PropTypes.node.isRequired, + heading: PropTypes.string, + subHeading: PropTypes.node, gradient: PropTypes.bool, status: PropTypes.string, sx: PropTypes.object, diff --git a/client/src/Components/TabPanels/Account/ProfilePanel.jsx b/client/src/Components/TabPanels/Account/ProfilePanel.jsx index ad6d15b98..9b209bf3e 100644 --- a/client/src/Components/TabPanels/Account/ProfilePanel.jsx +++ b/client/src/Components/TabPanels/Account/ProfilePanel.jsx @@ -8,7 +8,6 @@ import ImageUpload from "../../Inputs/ImageUpload"; import { newOrChangedCredentials } from "../../../Validation/validation"; import { useDispatch, useSelector } from "react-redux"; import { clearAuthState, deleteUser, update } from "../../../Features/Auth/authSlice"; -import { clearUptimeMonitorState } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice"; import { createToast } from "../../../Utils/toastUtils"; import { logger } from "../../../Utils/Logger"; import { GenericDialog } from "../../Dialog/genericDialog"; @@ -162,7 +161,6 @@ const ProfilePanel = () => { const action = await dispatch(deleteUser()); if (action.payload.success) { dispatch(clearAuthState()); - dispatch(clearUptimeMonitorState()); } else { if (action.payload) { // dispatch errors diff --git a/client/src/Features/InfrastructureMonitors/infrastructureMonitorsSlice.js b/client/src/Features/InfrastructureMonitors/infrastructureMonitorsSlice.js deleted file mode 100644 index 62bdf4811..000000000 --- a/client/src/Features/InfrastructureMonitors/infrastructureMonitorsSlice.js +++ /dev/null @@ -1,389 +0,0 @@ -import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; -import { networkService } from "../../main"; -const initialState = { - isLoading: false, - monitorsSummary: [], - success: null, - msg: null, -}; - -export const createInfrastructureMonitor = createAsyncThunk( - "infrastructureMonitors/createMonitor", - async (data, thunkApi) => { - try { - const { monitor } = data; - const res = await networkService.createMonitor({ monitor: monitor }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const checkInfrastructureEndpointResolution = createAsyncThunk( - "infrastructureMonitors/CheckEndpoint", - async (data, thunkApi) => { - try { - const { monitorURL } = data; - const res = await networkService.checkEndpointResolution({ - monitorURL: monitorURL, - }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const getInfrastructureMonitorById = createAsyncThunk( - "infrastructureMonitors/getMonitorById", - async (data, thunkApi) => { - try { - const { monitorId } = data; - const res = await networkService.getMonitorById({ monitorId: monitorId }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const getInfrastructureMonitorsByTeamId = createAsyncThunk( - "infrastructureMonitors/getMonitorsByTeamId", - async (_, thunkApi) => { - const user = thunkApi.getState().auth.user; - try { - const res = await networkService.getMonitorsAndSummaryByTeamId({ - teamId: user.teamId, - types: ["hardware"], - limit: 1, - rowsPerPage: 0, - }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const updateInfrastructureMonitor = createAsyncThunk( - "infrastructureMonitors/updateMonitor", - async ({ monitorId, monitor }, thunkApi) => { - try { - const updatedFields = { - name: monitor.name, - description: monitor.description, - interval: monitor.interval, - notifications: monitor.notifications, - thresholds: monitor.thresholds, - secret: monitor.secret, - }; - const res = await networkService.updateMonitor({ - monitorId, - monitor, - updatedFields, - }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const deleteInfrastructureMonitor = createAsyncThunk( - "infrastructureMonitors/deleteMonitor", - async (data, thunkApi) => { - try { - const { monitor } = data; - const res = await networkService.deleteMonitorById({ monitorId: monitor._id }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const pauseInfrastructureMonitor = createAsyncThunk( - "infrastructureMonitors/pauseMonitor", - async (data, thunkApi) => { - try { - const { monitorId } = data; - const res = await networkService.pauseMonitorById({ monitorId: monitorId }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const deleteInfrastructureMonitorChecksByTeamId = createAsyncThunk( - "infrastructureMonitors/deleteChecksByTeamId", - async (data, thunkApi) => { - try { - const { teamId } = data; - const res = await networkService.deleteChecksByTeamId({ teamId: teamId }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const deleteAllInfrastructureMonitors = createAsyncThunk( - "infrastructureMonitors/deleteAllMonitors", - async (data, thunkApi) => { - try { - const res = await networkService.deleteAllMonitors(); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -const infrastructureMonitorsSlice = createSlice({ - name: "infrastructureMonitors", - initialState, - reducers: { - clearInfrastructureMonitorState: (state) => { - state.isLoading = false; - state.monitorsSummary = []; - state.success = null; - state.msg = null; - }, - }, - extraReducers: (builder) => { - builder - // ***************************************************** - // Monitors by teamId - // ***************************************************** - - .addCase(getInfrastructureMonitorsByTeamId.pending, (state) => { - state.isLoading = true; - }) - .addCase(getInfrastructureMonitorsByTeamId.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.msg; - state.monitorsSummary = action.payload.data; - }) - .addCase(getInfrastructureMonitorsByTeamId.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Getting infrastructure monitors failed"; - }) - - // ***************************************************** - // Create Monitor - // ***************************************************** - .addCase(createInfrastructureMonitor.pending, (state) => { - state.isLoading = true; - }) - .addCase(createInfrastructureMonitor.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(createInfrastructureMonitor.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to create infrastructure monitor"; - }) - // ***************************************************** - // Resolve Endpoint - // ***************************************************** - .addCase(checkInfrastructureEndpointResolution.pending, (state) => { - state.isLoading = true; - }) - .addCase(checkInfrastructureEndpointResolution.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(checkInfrastructureEndpointResolution.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to check endpoint resolution"; - }) - // ***************************************************** - // Get Monitor By Id - // ***************************************************** - .addCase(getInfrastructureMonitorById.pending, (state) => { - state.isLoading = true; - }) - .addCase(getInfrastructureMonitorById.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(getInfrastructureMonitorById.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to get infrastructure monitor"; - }) - // ***************************************************** - // update Monitor - // ***************************************************** - .addCase(updateInfrastructureMonitor.pending, (state) => { - state.isLoading = true; - }) - .addCase(updateInfrastructureMonitor.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(updateInfrastructureMonitor.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to update infrastructure monitor"; - }) - - // ***************************************************** - // Delete Monitor - // ***************************************************** - .addCase(deleteInfrastructureMonitor.pending, (state) => { - state.isLoading = true; - }) - .addCase(deleteInfrastructureMonitor.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(deleteInfrastructureMonitor.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to delete infrastructure monitor"; - }) - // ***************************************************** - // Delete Monitor checks by Team ID - // ***************************************************** - .addCase(deleteInfrastructureMonitorChecksByTeamId.pending, (state) => { - state.isLoading = true; - }) - .addCase(deleteInfrastructureMonitorChecksByTeamId.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(deleteInfrastructureMonitorChecksByTeamId.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to delete monitor checks"; - }) - // ***************************************************** - // Pause Monitor - // ***************************************************** - .addCase(pauseInfrastructureMonitor.pending, (state) => { - state.isLoading = true; - }) - .addCase(pauseInfrastructureMonitor.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(pauseInfrastructureMonitor.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to pause infrastructure monitor"; - }) - // ***************************************************** - // Delete all Monitors - // ***************************************************** - .addCase(deleteAllInfrastructureMonitors.pending, (state) => { - state.isLoading = true; - }) - .addCase(deleteAllInfrastructureMonitors.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(deleteAllInfrastructureMonitors.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload ? action.payload.msg : "Failed to delete all monitors"; - }); - }, -}); - -export const { setInfrastructureMonitors, clearInfrastructureMonitorState } = - infrastructureMonitorsSlice.actions; - -export default infrastructureMonitorsSlice.reducer; diff --git a/client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js b/client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js deleted file mode 100644 index 3ed2da13f..000000000 --- a/client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js +++ /dev/null @@ -1,309 +0,0 @@ -import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; -import { networkService } from "../../main"; -const initialState = { - isLoading: false, - monitorsSummary: [], - success: null, - msg: null, -}; - -export const createPageSpeed = createAsyncThunk( - "pageSpeedMonitors/createPageSpeed", - async (data, thunkApi) => { - try { - const { monitor } = data; - const res = await networkService.createMonitor({ monitor: monitor }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const checkEndpointResolution = createAsyncThunk( - "monitors/checkEndpoint", - async (data, thunkApi) => { - try { - const { monitorURL } = data; - const res = await networkService.checkEndpointResolution({ - monitorURL: monitorURL, - }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const getPagespeedMonitorById = createAsyncThunk( - "monitors/getMonitorById", - async (data, thunkApi) => { - try { - const { monitorId } = data; - const res = await networkService.getMonitorById({ monitorId: monitorId }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const getPageSpeedByTeamId = createAsyncThunk( - "pageSpeedMonitors/getPageSpeedByTeamId", - async (_, thunkApi) => { - const user = thunkApi.getState().auth.user; - try { - const res = await networkService.getMonitorsAndSummaryByTeamId({ - teamId: user.teamId, - types: ["pagespeed"], - }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const updatePageSpeed = createAsyncThunk( - "pageSpeedMonitors/updatePageSpeed", - async (data, thunkApi) => { - try { - const { monitor } = data; - const updatedFields = { - name: monitor.name, - description: monitor.description, - interval: monitor.interval, - notifications: monitor.notifications, - }; - const res = await networkService.updateMonitor({ - monitorId: monitor._id, - updatedFields: updatedFields, - }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const deletePageSpeed = createAsyncThunk( - "pageSpeedMonitors/deletePageSpeed", - async (data, thunkApi) => { - try { - const { monitor } = data; - const res = await networkService.deleteMonitorById({ monitorId: monitor._id }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); -export const pausePageSpeed = createAsyncThunk( - "pageSpeedMonitors/pausePageSpeed", - async (data, thunkApi) => { - try { - const { monitorId } = data; - const res = await networkService.pauseMonitorById({ monitorId: monitorId }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -const pageSpeedMonitorSlice = createSlice({ - name: "pageSpeedMonitor", - initialState, - reducers: { - clearMonitorState: (state) => { - state.isLoading = false; - state.monitorsSummary = []; - state.success = null; - state.msg = null; - }, - }, - extraReducers: (builder) => { - builder - // ***************************************************** - // Monitors by teamId - // ***************************************************** - - .addCase(getPageSpeedByTeamId.pending, (state) => { - state.isLoading = true; - }) - .addCase(getPageSpeedByTeamId.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.msg; - state.monitorsSummary = action.payload.data; - }) - .addCase(getPageSpeedByTeamId.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Getting page speed monitors failed"; - }) - - // ***************************************************** - .addCase(getPagespeedMonitorById.pending, (state) => { - state.isLoading = true; - }) - .addCase(getPagespeedMonitorById.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(getPagespeedMonitorById.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to get pagespeed monitor"; - }) - - // ***************************************************** - // Create Monitor - // ***************************************************** - .addCase(createPageSpeed.pending, (state) => { - state.isLoading = true; - }) - .addCase(createPageSpeed.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(createPageSpeed.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to create page speed monitor"; - }) - // ***************************************************** - // Resolve Endpoint - // ***************************************************** - .addCase(checkEndpointResolution.pending, (state) => { - state.isLoading = true; - }) - .addCase(checkEndpointResolution.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(checkEndpointResolution.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to check endpoint resolution"; - }) - // ***************************************************** - // Update Monitor - // ***************************************************** - .addCase(updatePageSpeed.pending, (state) => { - state.isLoading = true; - }) - .addCase(updatePageSpeed.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(updatePageSpeed.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to update page speed monitor"; - }) - - // ***************************************************** - // Delete Monitor - // ***************************************************** - .addCase(deletePageSpeed.pending, (state) => { - state.isLoading = true; - }) - .addCase(deletePageSpeed.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(deletePageSpeed.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to delete page speed monitor"; - }) - // ***************************************************** - // Pause Monitor - // ***************************************************** - .addCase(pausePageSpeed.pending, (state) => { - state.isLoading = true; - }) - .addCase(pausePageSpeed.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(pausePageSpeed.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to pause page speed monitor"; - }); - }, -}); - -export const { setMonitors, clearMonitorState } = pageSpeedMonitorSlice.actions; - -export default pageSpeedMonitorSlice.reducer; diff --git a/client/src/Features/Settings/settingsSlice.js b/client/src/Features/Settings/settingsSlice.js deleted file mode 100644 index d0725627a..000000000 --- a/client/src/Features/Settings/settingsSlice.js +++ /dev/null @@ -1,100 +0,0 @@ -import { networkService } from "../../main"; -import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; - -const initialState = { - isLoading: false, - apiBaseUrl: "", - logLevel: "debug", - pagespeedApiKey: "", -}; - -export const getAppSettings = createAsyncThunk( - "settings/getSettings", - async (data, thunkApi) => { - try { - const res = await networkService.getAppSettings(); - return res.data; - } catch (error) { - if (error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const updateAppSettings = createAsyncThunk( - "settings/updateSettings", - async ({ settings }, thunkApi) => { - try { - const parsedSettings = { - language: settings.language, - pagespeedApiKey: settings.pagespeedApiKey, - }; - const res = await networkService.updateAppSettings({ settings: parsedSettings }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -const handleGetSettingsFulfilled = (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - state.apiBaseUrl = action.payload.data.apiBaseUrl; - state.logLevel = action.payload.data.logLevel; - state.language = action.payload.data.language; - state.pagespeedApiKey = action.payload.data.pagespeedApiKey; -}; -const handleGetSettingsRejected = (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload ? action.payload.msg : "Failed to get settings."; -}; -const handleUpdateSettingsFulfilled = (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - state.apiBaseUrl = action.payload.data.apiBaseUrl; - state.logLevel = action.payload.data.logLevel; -}; -const handleUpdateSettingsRejected = (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload ? action.payload.msg : "Failed to update settings."; -}; - -const settingsSlice = createSlice({ - name: "settings", - initialState, - extraReducers: (builder) => { - builder - .addCase(getAppSettings.pending, (state) => { - state.isLoading = true; - }) - .addCase(getAppSettings.fulfilled, handleGetSettingsFulfilled) - .addCase(getAppSettings.rejected, handleGetSettingsRejected); - - builder - .addCase(updateAppSettings.pending, (state) => { - state.isLoading = true; - }) - .addCase(updateAppSettings.fulfilled, handleUpdateSettingsFulfilled) - .addCase(updateAppSettings.rejected, handleUpdateSettingsRejected); - }, -}); - -export default settingsSlice.reducer; diff --git a/client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js b/client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js deleted file mode 100644 index 74ad803d3..000000000 --- a/client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js +++ /dev/null @@ -1,380 +0,0 @@ -import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; -import { networkService } from "../../main"; -const initialState = { - isLoading: false, - monitorsSummary: [], - success: null, - msg: null, -}; - -export const createUptimeMonitor = createAsyncThunk( - "monitors/createMonitor", - async (data, thunkApi) => { - try { - const { monitor } = data; - const res = await networkService.createMonitor({ monitor: monitor }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const checkEndpointResolution = createAsyncThunk( - "monitors/checkEndpoint", - async (data, thunkApi) => { - try { - const { monitorURL } = data; - const res = await networkService.checkEndpointResolution({ - monitorURL: monitorURL, - }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const getUptimeMonitorById = createAsyncThunk( - "monitors/getMonitorById", - async (data, thunkApi) => { - try { - const { monitorId } = data; - const res = await networkService.getMonitorById({ monitorId: monitorId }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const updateUptimeMonitor = createAsyncThunk( - "monitors/updateMonitor", - async (data, thunkApi) => { - try { - const { monitor } = data; - const updatedFields = { - name: monitor.name, - description: monitor.description, - interval: monitor.interval, - notifications: monitor.notifications, - matchMethod: monitor.matchMethod, - expectedValue: monitor.expectedValue, - ignoreTlsErrors: monitor.ignoreTlsErrors, - jsonPath: monitor.jsonPath, - ...(monitor.type === "port" && { port: monitor.port }), - }; - const res = await networkService.updateMonitor({ - monitorId: monitor._id, - updatedFields, - }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const deleteUptimeMonitor = createAsyncThunk( - "monitors/deleteMonitor", - async (data, thunkApi) => { - try { - const { monitor } = data; - const res = await networkService.deleteMonitorById({ monitorId: monitor._id }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const pauseUptimeMonitor = createAsyncThunk( - "monitors/pauseMonitor", - async (data, thunkApi) => { - try { - const { monitorId } = data; - const res = await networkService.pauseMonitorById({ monitorId: monitorId }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const deleteMonitorChecksByTeamId = createAsyncThunk( - "monitors/deleteChecksByTeamId", - async (data, thunkApi) => { - try { - const { teamId } = data; - const res = await networkService.deleteChecksByTeamId({ teamId: teamId }); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); -export const addDemoMonitors = createAsyncThunk( - "monitors/addDemoMonitors", - async (data, thunkApi) => { - try { - const res = await networkService.addDemoMonitors(); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -export const deleteAllMonitors = createAsyncThunk( - "monitors/deleteAllMonitors", - async (data, thunkApi) => { - try { - const res = await networkService.deleteAllMonitors(); - return res.data; - } catch (error) { - if (error.response && error.response.data) { - return thunkApi.rejectWithValue(error.response.data); - } - const payload = { - status: false, - msg: error.message ? error.message : "Unknown error", - }; - return thunkApi.rejectWithValue(payload); - } - } -); - -const uptimeMonitorsSlice = createSlice({ - name: "uptimeMonitors", - initialState, - reducers: { - clearUptimeMonitorState: (state) => { - state.isLoading = false; - state.monitorsSummary = []; - state.success = null; - state.msg = null; - }, - }, - extraReducers: (builder) => { - builder - // ***************************************************** - // Create Monitor - // ***************************************************** - .addCase(createUptimeMonitor.pending, (state) => { - state.isLoading = true; - }) - .addCase(createUptimeMonitor.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(createUptimeMonitor.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to create uptime monitor"; - }) - // ***************************************************** - // Resolve Endpoint - // ***************************************************** - .addCase(checkEndpointResolution.pending, (state) => { - state.isLoading = true; - }) - .addCase(checkEndpointResolution.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(checkEndpointResolution.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to check endpoint resolution"; - }) - // ***************************************************** - // Get Monitor By Id - // ***************************************************** - .addCase(getUptimeMonitorById.pending, (state) => { - state.isLoading = true; - }) - .addCase(getUptimeMonitorById.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(getUptimeMonitorById.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload ? action.payload.msg : "Failed to get uptime monitor"; - }) - // ***************************************************** - // update Monitor - // ***************************************************** - .addCase(updateUptimeMonitor.pending, (state) => { - state.isLoading = true; - }) - .addCase(updateUptimeMonitor.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(updateUptimeMonitor.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to update uptime monitor"; - }) - - // ***************************************************** - // Delete Monitor - // ***************************************************** - .addCase(deleteUptimeMonitor.pending, (state) => { - state.isLoading = true; - }) - .addCase(deleteUptimeMonitor.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(deleteUptimeMonitor.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to delete uptime monitor"; - }) - // ***************************************************** - // Delete Monitor checks by Team ID - // ***************************************************** - .addCase(deleteMonitorChecksByTeamId.pending, (state) => { - state.isLoading = true; - }) - .addCase(deleteMonitorChecksByTeamId.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(deleteMonitorChecksByTeamId.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to delete monitor checks"; - }) - // ***************************************************** - // Pause Monitor - // ***************************************************** - .addCase(pauseUptimeMonitor.pending, (state) => { - state.isLoading = true; - }) - .addCase(pauseUptimeMonitor.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(pauseUptimeMonitor.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to pause uptime monitor"; - }) - // ***************************************************** - // Add Demo Monitors - // ***************************************************** - .addCase(addDemoMonitors.pending, (state) => { - state.isLoading = true; - }) - .addCase(addDemoMonitors.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(addDemoMonitors.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload - ? action.payload.msg - : "Failed to add demo uptime monitors"; - }) - // ***************************************************** - // Delete all Monitors - // ***************************************************** - .addCase(deleteAllMonitors.pending, (state) => { - state.isLoading = true; - }) - .addCase(deleteAllMonitors.fulfilled, (state, action) => { - state.isLoading = false; - state.success = action.payload.success; - state.msg = action.payload.msg; - }) - .addCase(deleteAllMonitors.rejected, (state, action) => { - state.isLoading = false; - state.success = false; - state.msg = action.payload ? action.payload.msg : "Failed to delete all monitors"; - }); - }, -}); - -export const { setUptimeMonitors, clearUptimeMonitorState } = uptimeMonitorsSlice.actions; - -export default uptimeMonitorsSlice.reducer; diff --git a/client/src/Hooks/monitorHooks.js b/client/src/Hooks/monitorHooks.js index 71f54de59..5072b5594 100644 --- a/client/src/Hooks/monitorHooks.js +++ b/client/src/Hooks/monitorHooks.js @@ -4,8 +4,9 @@ import { createToast } from "../Utils/toastUtils"; import { useTheme } from "@emotion/react"; import { useMonitorUtils } from "./useMonitorUtils"; import { useNavigate } from "react-router-dom"; +import { useTranslation } from "react-i18next"; -const useFetchMonitorsWithSummary = ({ teamId, types, monitorUpdateTrigger }) => { +const useFetchMonitorsWithSummary = ({ types, monitorUpdateTrigger }) => { const [isLoading, setIsLoading] = useState(false); const [monitors, setMonitors] = useState(undefined); const [monitorsSummary, setMonitorsSummary] = useState(undefined); @@ -16,7 +17,6 @@ const useFetchMonitorsWithSummary = ({ teamId, types, monitorUpdateTrigger }) => try { setIsLoading(true); const res = await networkService.getMonitorsWithSummaryByTeamId({ - teamId, types, }); const { monitors, summary } = res?.data?.data ?? {}; @@ -33,12 +33,11 @@ const useFetchMonitorsWithSummary = ({ teamId, types, monitorUpdateTrigger }) => } }; fetchMonitors(); - }, [teamId, types, monitorUpdateTrigger]); + }, [types, monitorUpdateTrigger]); return [monitors, monitorsSummary, isLoading, networkError]; }; const useFetchMonitorsWithChecks = ({ - teamId, types, limit, page, @@ -60,7 +59,6 @@ const useFetchMonitorsWithChecks = ({ try { setIsLoading(true); const res = await networkService.getMonitorsWithChecksByTeamId({ - teamId, limit, types, page, @@ -94,7 +92,6 @@ const useFetchMonitorsWithChecks = ({ order, page, rowsPerPage, - teamId, theme, types, monitorUpdateTrigger, @@ -103,7 +100,6 @@ const useFetchMonitorsWithChecks = ({ }; const useFetchMonitorsByTeamId = ({ - teamId, types, limit, page, @@ -126,7 +122,6 @@ const useFetchMonitorsByTeamId = ({ try { setIsLoading(true); const res = await networkService.getMonitorsByTeamId({ - teamId, limit, types, page, @@ -153,7 +148,6 @@ const useFetchMonitorsByTeamId = ({ }; fetchMonitors(); }, [ - teamId, types, limit, page, @@ -383,6 +377,58 @@ const usePauseMonitor = () => { return [pauseMonitor, isLoading, error]; }; +const useAddDemoMonitors = () => { + const [isLoading, setIsLoading] = useState(false); + const { t } = useTranslation(); + const addDemoMonitors = async () => { + try { + setIsLoading(true); + await networkService.addDemoMonitors(); + createToast({ body: t("settingsDemoMonitorsAdded") }); + } catch (error) { + createToast({ body: t("settingsFailedToAddDemoMonitors") }); + } finally { + setIsLoading(false); + } + }; + return [addDemoMonitors, isLoading]; +}; + +const useDeleteAllMonitors = () => { + const [isLoading, setIsLoading] = useState(false); + const { t } = useTranslation(); + const deleteAllMonitors = async () => { + try { + setIsLoading(true); + await networkService.deleteAllMonitors(); + createToast({ body: t("settingsMonitorsDeleted") }); + } catch (error) { + createToast({ body: t("settingsFailedToDeleteMonitors") }); + } finally { + setIsLoading(false); + } + }; + return [deleteAllMonitors, isLoading]; +}; + +const UseDeleteMonitorStats = () => { + const { t } = useTranslation(); + const [isLoading, setIsLoading] = useState(false); + const deleteMonitorStats = async ({ teamId }) => { + setIsLoading(true); + try { + const res = await networkService.deleteChecksByTeamId({ teamId }); + createToast({ body: t("settingsStatsCleared") }); + } catch (error) { + createToast({ body: t("settingsFailedToClearStats") }); + } finally { + setIsLoading(false); + } + }; + + return [deleteMonitorStats, isLoading]; +}; + export { useFetchMonitorsWithSummary, useFetchMonitorsWithChecks, @@ -395,4 +441,7 @@ export { useDeleteMonitor, useUpdateMonitor, usePauseMonitor, + useAddDemoMonitors, + useDeleteAllMonitors, + UseDeleteMonitorStats, }; diff --git a/client/src/Hooks/useDeleteMonitorStats.js b/client/src/Hooks/useDeleteMonitorStats.js deleted file mode 100644 index 64138929f..000000000 --- a/client/src/Hooks/useDeleteMonitorStats.js +++ /dev/null @@ -1,24 +0,0 @@ -import { useState } from "react"; -import { networkService } from "../main"; -import { createToast } from "../Utils/toastUtils"; -import { useTranslation } from "react-i18next"; - -const UseDeleteMonitorStats = () => { - const { t } = useTranslation(); - const [isLoading, setIsLoading] = useState(false); - const deleteMonitorStats = async ({ teamId }) => { - setIsLoading(true); - try { - const res = await networkService.deleteChecksByTeamId({ teamId }); - createToast({ body: t("settingsStatsCleared") }); - } catch (error) { - createToast({ body: t("settingsFailedToClearStats") }); - } finally { - setIsLoading(false); - } - }; - - return [deleteMonitorStats, isLoading]; -}; - -export { UseDeleteMonitorStats }; diff --git a/client/src/Hooks/useFetchSettings.js b/client/src/Hooks/useFetchSettings.js index f7651e789..7d3ff28fc 100644 --- a/client/src/Hooks/useFetchSettings.js +++ b/client/src/Hooks/useFetchSettings.js @@ -33,12 +33,13 @@ const useSaveSettings = () => { const saveSettings = async (settings) => { setIsLoading(true); try { - await networkService.updateAppSettings({ settings }); + const settingsResponse = await networkService.updateAppSettings({ settings }); if (settings.checkTTL) { await networkService.updateChecksTTL({ ttl: settings.checkTTL, }); } + console.log({ settingsResponse }); createToast({ body: t("settingsSuccessSaved") }); } catch (error) { createToast({ body: t("settingsFailedToSave") }); diff --git a/client/src/Pages/Auth/NewPasswordConfirmed.jsx b/client/src/Pages/Auth/NewPasswordConfirmed.jsx index db03f7de3..945a0d52d 100644 --- a/client/src/Pages/Auth/NewPasswordConfirmed.jsx +++ b/client/src/Pages/Auth/NewPasswordConfirmed.jsx @@ -3,7 +3,6 @@ import { useTheme } from "@emotion/react"; import { useNavigate } from "react-router"; import { useDispatch } from "react-redux"; import { clearAuthState } from "../../Features/Auth/authSlice"; -import { clearUptimeMonitorState } from "../../Features/UptimeMonitors/uptimeMonitorsSlice"; import Background from "../../assets/Images/background-grid.svg?react"; import ConfirmIcon from "../../assets/icons/check-outlined.svg?react"; import Logo from "../../assets/icons/checkmate-icon.svg?react"; @@ -19,7 +18,6 @@ const NewPasswordConfirmed = () => { const handleNavigate = () => { dispatch(clearAuthState()); - dispatch(clearUptimeMonitorState()); navigate("/login"); }; diff --git a/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx b/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx index 761ecaa0e..7a5db231f 100644 --- a/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx +++ b/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx @@ -15,7 +15,7 @@ import { useNavigate } from "react-router-dom"; import PropTypes from "prop-types"; import { useTranslation } from "react-i18next"; -const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete }) => { +const MonitorsTable = ({ isLoading, monitors, isAdmin, handleActionMenuDelete }) => { // Utils const theme = useTheme(); const { t } = useTranslation(); @@ -86,6 +86,7 @@ const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete monitor={row} isAdmin={isAdmin} updateCallback={handleActionMenuDelete} + isLoading={isLoading} /> ), }, @@ -120,7 +121,7 @@ const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete return ( { const [isOpen, setIsOpen] = useState(false); const [isDialogOpen, setIsDialogOpen] = useState(false); const theme = useTheme(); - const { isLoading } = useSelector((state) => state.uptimeMonitors); const openMenu = (e) => { e.stopPropagation(); @@ -117,7 +115,6 @@ const InfrastructureMenu = ({ monitor, isAdmin, updateCallback }) => { onCancel={cancelRemove} confirmationButtonLabel="Delete" onConfirm={handleRemove} - isLoading={isLoading} modelTitle="modal-delete-monitor" modelDescription="delete-monitor-confirmation" /> diff --git a/client/src/Pages/Infrastructure/Monitors/index.jsx b/client/src/Pages/Infrastructure/Monitors/index.jsx index 6d49f64a7..6b726309c 100644 --- a/client/src/Pages/Infrastructure/Monitors/index.jsx +++ b/client/src/Pages/Infrastructure/Monitors/index.jsx @@ -11,7 +11,6 @@ import Filter from "./Components/Filters"; // Utils import { useTheme } from "@emotion/react"; import { useState } from "react"; -import { useSelector } from "react-redux"; import { useIsAdmin } from "../../../Hooks/useIsAdmin"; import { useTranslation } from "react-i18next"; import { useFetchMonitorsByTeamId } from "../../../Hooks/monitorHooks"; @@ -21,7 +20,6 @@ const BREADCRUMBS = [{ name: `infrastructure`, path: "/infrastructure" }]; const InfrastructureMonitors = () => { // Redux state - const { user } = useSelector((state) => state.auth); // Local state const [page, setPage] = useState(0); @@ -56,7 +54,6 @@ const InfrastructureMonitors = () => { const field = toFilterStatus !== undefined ? "status" : undefined; const [monitors, summary, isLoading, networkError] = useFetchMonitorsByTeamId({ - teamId: user.teamId, limit: 1, types: TYPES, page, @@ -118,7 +115,7 @@ const InfrastructureMonitors = () => { /> { setIsLoading(true); try { const response = await networkService.getMonitorsByTeamId({ - teamId: user.teamId, limit: null, types: ["http", "ping", "pagespeed", "port"], }); diff --git a/client/src/Pages/PageSpeed/Monitors/index.jsx b/client/src/Pages/PageSpeed/Monitors/index.jsx index 319b0da21..65e43f2ec 100644 --- a/client/src/Pages/PageSpeed/Monitors/index.jsx +++ b/client/src/Pages/PageSpeed/Monitors/index.jsx @@ -9,7 +9,6 @@ import GenericFallback from "../../../Components/GenericFallback"; // Utils import { useTheme } from "@emotion/react"; -import { useSelector } from "react-redux"; import { useIsAdmin } from "../../../Hooks/useIsAdmin"; import { useTranslation } from "react-i18next"; import { useFetchMonitorsByTeamId } from "../../../Hooks/monitorHooks"; @@ -20,11 +19,8 @@ const PageSpeed = () => { const theme = useTheme(); const { t } = useTranslation(); const isAdmin = useIsAdmin(); - const { user } = useSelector((state) => state.auth); - const { pagespeedApiKey } = useSelector((state) => state.settings); const [monitors, monitorsSummary, isLoading, networkError] = useFetchMonitorsByTeamId({ - teamId: user.teamId, limit: 10, types: TYPES, page: null, @@ -60,7 +56,7 @@ const PageSpeed = () => { ]} link="/pagespeed/create" isAdmin={isAdmin} - showPageSpeedWarning={isAdmin && !pagespeedApiKey} + // showPageSpeedWarning={isAdmin && !pagespeedApiKey} /> ); } diff --git a/client/src/Pages/Settings/index.jsx b/client/src/Pages/Settings/index.jsx index b0e3c476b..d8bd79551 100644 --- a/client/src/Pages/Settings/index.jsx +++ b/client/src/Pages/Settings/index.jsx @@ -11,22 +11,20 @@ import SettingsEmail from "./SettingsEmail"; import Button from "@mui/material/Button"; // Utils import { settingsValidation } from "../../Validation/validation"; -import { createToast } from "../../Utils/toastUtils"; import { useState } from "react"; import { useTheme } from "@emotion/react"; import { useTranslation } from "react-i18next"; import { useSelector, useDispatch } from "react-redux"; import { setTimezone, setMode, setLanguage, setShowURL } from "../../Features/UI/uiSlice"; import SettingsStats from "./SettingsStats"; -import { - deleteMonitorChecksByTeamId, - addDemoMonitors, - deleteAllMonitors, -} from "../../Features/UptimeMonitors/uptimeMonitorsSlice"; -import { useFetchSettings, useSaveSettings } from "../../Hooks/useFetchSettings"; -import { UseDeleteMonitorStats } from "../../Hooks/useDeleteMonitorStats"; -import { useIsAdmin } from "../../Hooks/useIsAdmin"; +import { useFetchSettings, useSaveSettings } from "../../Hooks/useFetchSettings"; +import { useIsAdmin } from "../../Hooks/useIsAdmin"; +import { + useAddDemoMonitors, + useDeleteAllMonitors, + UseDeleteMonitorStats, +} from "../../Hooks/monitorHooks"; // Constants const BREADCRUMBS = [{ name: `Settings`, path: "/settings" }]; @@ -43,15 +41,17 @@ const Settings = () => { const [isSettingsLoading, settingsError] = useFetchSettings({ setSettingsData, }); + const [addDemoMonitors, isAddingDemoMonitors] = useAddDemoMonitors(); const [isSaving, saveError, saveSettings] = useSaveSettings(); + const [deleteAllMonitors, isDeletingMonitors] = useDeleteAllMonitors(); const [deleteMonitorStats, isDeletingMonitorStats] = UseDeleteMonitorStats(); // Setup const isAdmin = useIsAdmin(); const theme = useTheme(); const HEADING_SX = { mt: theme.spacing(2), mb: theme.spacing(2) }; - const { t, i18n } = useTranslation(); + const { t } = useTranslation(); const dispatch = useDispatch(); // Handlers @@ -101,30 +101,12 @@ const Settings = () => { } if (name === "demo") { - try { - const action = await dispatch(addDemoMonitors()); - if (addDemoMonitors.fulfilled.match(action)) { - createToast({ body: t("settingsDemoMonitorsAdded") }); - } else { - createToast({ body: t("settingsFailedToAddDemoMonitors") }); - } - } catch (error) { - createToast({ body: t("settingsFailedToAddDemoMonitors") }); - } + await addDemoMonitors(); return; } if (name === "deleteMonitors") { - try { - const action = await dispatch(deleteAllMonitors()); - if (deleteAllMonitors.fulfilled.match(action)) { - createToast({ body: t("settingsMonitorsDeleted") }); - } else { - createToast({ body: t("settingsFailedToDeleteMonitors") }); - } - } catch (error) { - createToast({ body: t("settingsFailedToDeleteMonitors") }); - } + await deleteAllMonitors(); return; } @@ -185,7 +167,9 @@ const Settings = () => { isAdmin={isAdmin} HEADER_SX={HEADING_SX} handleChange={handleChange} - isLoading={isSettingsLoading || isSaving || isDeletingMonitorStats} + isLoading={ + isSettingsLoading || isSaving || isDeletingMonitorStats || isAddingDemoMonitors + } /> { }} > diff --git a/client/src/Pages/Uptime/Monitors/index.jsx b/client/src/Pages/Uptime/Monitors/index.jsx index e313d7deb..030ce922c 100644 --- a/client/src/Pages/Uptime/Monitors/index.jsx +++ b/client/src/Pages/Uptime/Monitors/index.jsx @@ -64,7 +64,6 @@ CreateMonitorButton.propTypes = { const UptimeMonitors = () => { // Redux state - const { user } = useSelector((state) => state.auth); const rowsPerPage = useSelector((state) => state.ui.monitors.rowsPerPage); // Local state @@ -106,11 +105,8 @@ const UptimeMonitors = () => { setMonitorUpdateTrigger((prev) => !prev); }, []); - const teamId = user.teamId; - const [monitors, monitorsSummary, monitorsWithSummaryIsLoading, networkError] = useFetchMonitorsWithSummary({ - teamId, types: TYPES, monitorUpdateTrigger, }); @@ -140,7 +136,6 @@ const UptimeMonitors = () => { monitorsWithChecksIsLoading, monitorsWithChecksNetworkError, ] = useFetchMonitorsWithChecks({ - teamId, types: effectiveTypes, limit: 25, page: page, diff --git a/client/src/Utils/Logger.js b/client/src/Utils/Logger.js index b22cc0a22..f132ad408 100644 --- a/client/src/Utils/Logger.js +++ b/client/src/Utils/Logger.js @@ -6,8 +6,7 @@ class Logger { constructor() { let logLevel = LOG_LEVEL; this.unsubscribe = store.subscribe(() => { - const state = store.getState(); - logLevel = state.settings.logLevel || "debug"; + logLevel = "debug"; this.updateLogLevel(logLevel); }); } diff --git a/client/src/Utils/NetworkService.js b/client/src/Utils/NetworkService.js index 6c38688a7..e84596b97 100644 --- a/client/src/Utils/NetworkService.js +++ b/client/src/Utils/NetworkService.js @@ -3,7 +3,6 @@ import i18next from "i18next"; const BASE_URL = import.meta.env.VITE_APP_API_BASE_URL; const FALLBACK_BASE_URL = "http://localhost:5000/api/v1"; import { clearAuthState } from "../Features/Auth/authSlice"; -import { clearUptimeMonitorState } from "../Features/UptimeMonitors/uptimeMonitorsSlice"; class NetworkService { constructor(store, dispatch, navigate) { this.store = store; @@ -56,7 +55,6 @@ class NetworkService { if (error.response && error.response.status === 401) { dispatch(clearAuthState()); - dispatch(clearUptimeMonitorState()); navigate("/login"); } else if (error.request && !error.response) { return Promise.reject(error); @@ -137,36 +135,6 @@ class NetworkService { }); } - /** - * - * ************************************ - * Gets monitors and summary of stats by TeamID - * ************************************ - * - * @async - * @param {Object} config - The configuration object. - * @param {string} config.teamId - Team ID - * @param {Array} config.types - Array of monitor types - * @returns {Promise} The response from the axios POST request. - */ - async getMonitorsSummaryByTeamId(config) { - const params = new URLSearchParams(); - - if (config.types) { - config.types.forEach((type) => { - params.append("type", type); - }); - } - return this.axiosInstance.get( - `/monitors/team/summary/${config.teamId}?${params.toString()}`, - { - headers: { - "Content-Type": "application/json", - }, - } - ); - } - /** * ************************************ * Get all uptime monitors for a Team @@ -186,7 +154,7 @@ class NetworkService { */ async getMonitorsByTeamId(config) { - const { teamId, limit, types, page, rowsPerPage, filter, field, order } = config; + const { limit, types, page, rowsPerPage, filter, field, order } = config; const params = new URLSearchParams(); if (limit) params.append("limit", limit); @@ -201,7 +169,7 @@ class NetworkService { if (field) params.append("field", field); if (order) params.append("order", order); - return this.axiosInstance.get(`/monitors/team/${teamId}?${params.toString()}`, { + return this.axiosInstance.get(`/monitors/team?${params.toString()}`, { headers: { "Content-Type": "application/json", }, @@ -951,7 +919,7 @@ class NetworkService { // Fetch monitors with summary by TeamID // ************************************ async getMonitorsWithSummaryByTeamId(config) { - const { teamId, types } = config; + const { types } = config; const params = new URLSearchParams(); if (types) { @@ -960,21 +928,18 @@ class NetworkService { }); } - return this.axiosInstance.get( - `/monitors/summary/team/${teamId}?${params.toString()}`, - { - headers: { - "Content-Type": "application/json", - }, - } - ); + return this.axiosInstance.get(`/monitors/summary/team?${params.toString()}`, { + headers: { + "Content-Type": "application/json", + }, + }); } // ************************************ // Fetch monitors with checks by TeamID // ************************************ async getMonitorsWithChecksByTeamId(config) { - const { teamId, limit, types, page, rowsPerPage, filter, field, order } = config; + const { limit, types, page, rowsPerPage, filter, field, order } = config; const params = new URLSearchParams(); if (limit) params.append("limit", limit); @@ -989,14 +954,11 @@ class NetworkService { if (field) params.append("field", field); if (order) params.append("order", order); - return this.axiosInstance.get( - `/monitors/team/${teamId}/with-checks?${params.toString()}`, - { - headers: { - "Content-Type": "application/json", - }, - } - ); + return this.axiosInstance.get(`/monitors/team/with-checks?${params.toString()}`, { + headers: { + "Content-Type": "application/json", + }, + }); } // ************************************ diff --git a/client/src/store.js b/client/src/store.js index 92ddfad00..69aa3d50b 100644 --- a/client/src/store.js +++ b/client/src/store.js @@ -1,11 +1,7 @@ import { configureStore, combineReducers } from "@reduxjs/toolkit"; -import uptimeMonitorsReducer from "./Features/UptimeMonitors/uptimeMonitorsSlice"; -import infrastructureMonitorsReducer from "./Features/InfrastructureMonitors/infrastructureMonitorsSlice"; -import pageSpeedMonitorReducer from "./Features/PageSpeedMonitor/pageSpeedMonitorSlice"; import authReducer from "./Features/Auth/authSlice"; import uiReducer from "./Features/UI/uiSlice"; -import settingsReducer from "./Features/Settings/settingsSlice"; import storage from "redux-persist/lib/storage"; import { persistReducer, persistStore, createTransform } from "redux-persist"; @@ -23,17 +19,13 @@ const authTransform = createTransform( const persistConfig = { key: "root", storage, - whitelist: ["auth", "monitors", "pageSpeed", "ui", "settings"], + whitelist: ["auth", "ui"], transforms: [authTransform], }; const rootReducer = combineReducers({ - uptimeMonitors: uptimeMonitorsReducer, - infrastructureMonitors: infrastructureMonitorsReducer, auth: authReducer, - pageSpeedMonitors: pageSpeedMonitorReducer, ui: uiReducer, - settings: settingsReducer, }); const persistedReducer = persistReducer(persistConfig, rootReducer); diff --git a/server/db/mongo/modules/monitorModule.js b/server/db/mongo/modules/monitorModule.js index 3d9adab39..b6044f2c9 100755 --- a/server/db/mongo/modules/monitorModule.js +++ b/server/db/mongo/modules/monitorModule.js @@ -519,7 +519,8 @@ const getMonitorsByTeamId = async (req) => { order = "asc"; } // Build match stage - const matchStage = { teamId: ObjectId.createFromHexString(req.params.teamId) }; + const teamId = req.user.teamId; + const matchStage = { teamId: ObjectId.createFromHexString(teamId) }; if (type !== undefined) { matchStage.type = Array.isArray(type) ? { $in: type } : type; } @@ -560,7 +561,7 @@ const getMonitorsByTeamId = async (req) => { const getMonitorsAndSummaryByTeamId = async (req) => { try { const { type } = req.query; - const teamId = ObjectId.createFromHexString(req.params.teamId); + const teamId = ObjectId.createFromHexString(req.user.teamId); const matchStage = { teamId }; if (type !== undefined) { matchStage.type = Array.isArray(type) ? { $in: type } : type; @@ -594,7 +595,7 @@ const getMonitorsWithChecksByTeamId = async (req) => { field = "name"; order = "asc"; } - const teamId = ObjectId.createFromHexString(req.params.teamId); + const teamId = ObjectId.createFromHexString(req.user.teamId); // Build match stage const matchStage = { teamId }; if (type !== undefined) { diff --git a/server/routes/monitorRoute.js b/server/routes/monitorRoute.js index 6d1db90ad..0dabab407 100755 --- a/server/routes/monitorRoute.js +++ b/server/routes/monitorRoute.js @@ -35,17 +35,17 @@ class MonitorRoutes { fetchMonitorCertificate ); }); + this.router.get("/team", this.monitorController.getMonitorsByTeamId); + this.router.get("/:monitorId", this.monitorController.getMonitorById); - this.router.get("/team/:teamId", this.monitorController.getMonitorsByTeamId); - this.router.get( - "/summary/team/:teamId", + "/summary/team", this.monitorController.getMonitorsAndSummaryByTeamId ); this.router.get( - "/team/:teamId/with-checks", + "/team/with-checks", this.monitorController.getMonitorsWithChecksByTeamId ); diff --git a/server/validation/joi.js b/server/validation/joi.js index 271cd2d21..aba7118d1 100755 --- a/server/validation/joi.js +++ b/server/validation/joi.js @@ -126,9 +126,7 @@ const getMonitorByIdQueryValidation = joi.object({ normalize: joi.boolean(), }); -const getMonitorsByTeamIdParamValidation = joi.object({ - teamId: joi.string().required(), -}); +const getMonitorsByTeamIdParamValidation = joi.object({}); const getMonitorsByTeamIdQueryValidation = joi.object({ limit: joi.number(),