mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-20 00:29:45 -06:00
Merge branch 'develop' into fix/colorful-revamp-extravaganza
This commit is contained in:
@@ -73,7 +73,14 @@ const TeamPanel = () => {
|
||||
useEffect(() => {
|
||||
let team = members;
|
||||
if (filter !== "all")
|
||||
team = members.filter((member) => member.role.includes(filter));
|
||||
team = members.filter((member) => {
|
||||
if (filter === "admin") {
|
||||
return (
|
||||
member.role.includes("admin") || member.role.includes("superadmin")
|
||||
);
|
||||
}
|
||||
return member.role.includes(filter);
|
||||
});
|
||||
|
||||
const data = {
|
||||
cols: [
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { networkService } from "../../main";
|
||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
import axios from "axios";
|
||||
|
||||
const initialState = {
|
||||
isLoading: false,
|
||||
@@ -57,9 +58,8 @@ export const update = createAsyncThunk(
|
||||
form.password && fd.append("password", form.password);
|
||||
form.newPassword && fd.append("newPassword", form.newPassword);
|
||||
if (form.file && form.file !== "") {
|
||||
const imageResult = await networkService.get(form.file, {
|
||||
const imageResult = await axios.get(form.file, {
|
||||
responseType: "blob",
|
||||
baseURL: "",
|
||||
});
|
||||
fd.append("profileImage", imageResult.data);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,26 @@ export const createUptimeMonitor = createAsyncThunk(
|
||||
}
|
||||
);
|
||||
|
||||
export const getUptimeMonitorById = createAsyncThunk(
|
||||
"monitors/getMonitorById",
|
||||
async (data, thunkApi) => {
|
||||
try {
|
||||
const { authToken, monitorId } = data;
|
||||
const res = await networkService.getMonitorByid(authToken, 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 getUptimeMonitorsByTeamId = createAsyncThunk(
|
||||
"montiors/getMonitorsByTeamId",
|
||||
async (token, thunkApi) => {
|
||||
@@ -109,6 +129,26 @@ export const deleteUptimeMonitor = createAsyncThunk(
|
||||
}
|
||||
);
|
||||
|
||||
export const pauseUptimeMonitor = createAsyncThunk(
|
||||
"monitors/pauseMonitor",
|
||||
async (data, thunkApi) => {
|
||||
try {
|
||||
const { authToken, monitorId } = data;
|
||||
const res = await networkService.pauseMonitorById(authToken, 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 uptimeMonitorsSlice = createSlice({
|
||||
name: "uptimeMonitors",
|
||||
initialState,
|
||||
@@ -160,7 +200,24 @@ const uptimeMonitorsSlice = createSlice({
|
||||
? action.payload.msg
|
||||
: "Failed to create uptime monitor";
|
||||
})
|
||||
|
||||
// *****************************************************
|
||||
// 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 pause uptime monitor";
|
||||
})
|
||||
// *****************************************************
|
||||
// update Monitor
|
||||
// *****************************************************
|
||||
@@ -197,6 +254,24 @@ const uptimeMonitorsSlice = createSlice({
|
||||
state.msg = action.payload
|
||||
? action.payload.msg
|
||||
: "Failed to delete uptime monitor";
|
||||
})
|
||||
// *****************************************************
|
||||
// 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";
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -146,6 +146,7 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => {
|
||||
<TableCell>Monitor Name</TableCell>
|
||||
<TableCell>Status</TableCell>
|
||||
<TableCell>Date & Time</TableCell>
|
||||
<TableCell>Status Code</TableCell>
|
||||
<TableCell>Message</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
@@ -166,7 +167,10 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => {
|
||||
<TableCell>
|
||||
{new Date(check.createdAt).toLocaleString()}
|
||||
</TableCell>
|
||||
<TableCell>{check.statusCode}</TableCell>
|
||||
<TableCell>
|
||||
{check.statusCode ? check.statusCode : "N/A"}
|
||||
</TableCell>
|
||||
<TableCell>{check.message}</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -2,13 +2,15 @@ import { useNavigate, useParams } from "react-router";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Box, Modal, Skeleton, Stack, Typography } from "@mui/material";
|
||||
import { Box, Modal, Stack, Typography } from "@mui/material";
|
||||
import { monitorValidation } from "../../../Validation/validation";
|
||||
import { createToast } from "../../../Utils/toastUtils";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import { ConfigBox } from "../styled";
|
||||
import {
|
||||
updateUptimeMonitor,
|
||||
pauseUptimeMonitor,
|
||||
getUptimeMonitorById,
|
||||
getUptimeMonitorsByTeamId,
|
||||
deleteUptimeMonitor,
|
||||
} from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
|
||||
@@ -20,7 +22,8 @@ import Checkbox from "../../../Components/Inputs/Checkbox";
|
||||
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
||||
import PulseDot from "../../../Components/Animated/PulseDot";
|
||||
import "./index.css";
|
||||
|
||||
import SkeletonLayout from "./skeleton";
|
||||
import ButtonSpinner from "../../../Components/ButtonSpinner";
|
||||
/**
|
||||
* Parses a URL string and returns a URL object.
|
||||
*
|
||||
@@ -35,54 +38,6 @@ const parseUrl = (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a skeleton layout.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const SkeletonLayout = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
<Stack gap={theme.spacing(20)} mt={theme.spacing(6)}>
|
||||
<Stack direction="row" gap={theme.spacing(4)} mt={theme.spacing(4)}>
|
||||
<Skeleton
|
||||
variant="circular"
|
||||
style={{ minWidth: 24, minHeight: 24 }}
|
||||
/>
|
||||
<Box width="80%">
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={24}
|
||||
sx={{ mb: theme.spacing(4) }}
|
||||
/>
|
||||
<Skeleton variant="rounded" width="50%" height={18} />
|
||||
</Box>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.spacing(6)}
|
||||
sx={{
|
||||
ml: "auto",
|
||||
alignSelf: "flex-end",
|
||||
}}
|
||||
>
|
||||
<Skeleton variant="rounded" width={150} height={34} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Stack direction="row" justifyContent="flex-end">
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure page displays monitor configurations and allows for editing actions.
|
||||
* @component
|
||||
@@ -93,7 +48,7 @@ const Configure = () => {
|
||||
const theme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const { user, authToken } = useSelector((state) => state.auth);
|
||||
const { monitors } = useSelector((state) => state.uptimeMonitors);
|
||||
const { isLoading } = useSelector((state) => state.uptimeMonitors);
|
||||
const [monitor, setMonitor] = useState({});
|
||||
const [errors, setErrors] = useState({});
|
||||
const { monitorId } = useParams();
|
||||
@@ -107,15 +62,25 @@ const Configure = () => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const data = monitors.find((monitor) => monitor._id === monitorId);
|
||||
if (!data) {
|
||||
logger.error("Error fetching monitor of id: " + monitorId);
|
||||
navigate("/not-found", { replace: true });
|
||||
}
|
||||
setMonitor({
|
||||
...data,
|
||||
});
|
||||
}, [monitorId, authToken, monitors, navigate]);
|
||||
const fetchMonitor = async () => {
|
||||
try {
|
||||
const action = await dispatch(
|
||||
getUptimeMonitorById({ authToken, monitorId })
|
||||
);
|
||||
|
||||
if (getUptimeMonitorById.fulfilled.match(action)) {
|
||||
const monitor = action.payload.data;
|
||||
setMonitor(monitor);
|
||||
} else if (getUptimeMonitorById.rejected.match(action)) {
|
||||
throw new Error(action.error.message);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("Error fetching monitor of id: " + monitorId);
|
||||
navigate("/not-found", { replace: true });
|
||||
}
|
||||
};
|
||||
fetchMonitor();
|
||||
}, [monitorId, authToken, navigate]);
|
||||
|
||||
const handleChange = (event, name) => {
|
||||
let { value, id } = event.target;
|
||||
@@ -171,6 +136,23 @@ const Configure = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handlePause = async () => {
|
||||
try {
|
||||
const action = await dispatch(
|
||||
pauseUptimeMonitor({ authToken, monitorId })
|
||||
);
|
||||
if (pauseUptimeMonitor.fulfilled.match(action)) {
|
||||
const monitor = action.payload.data;
|
||||
setMonitor(monitor);
|
||||
} else if (pauseUptimeMonitor.rejected.match(action)) {
|
||||
throw new Error(action.error.message);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("Error pausing monitor: " + monitorId);
|
||||
createToast({ body: "Failed to pause monitor" });
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
const action = await dispatch(
|
||||
@@ -207,11 +189,9 @@ const Configure = () => {
|
||||
const parsedUrl = parseUrl(monitor?.url);
|
||||
const protocol = parsedUrl?.protocol?.replace(":", "") || "";
|
||||
|
||||
let loading = Object.keys(monitor).length === 0;
|
||||
|
||||
return (
|
||||
<Stack className="configure-monitor" gap={theme.spacing(12)}>
|
||||
{loading ? (
|
||||
{Object.keys(monitor).length === 0 ? (
|
||||
<SkeletonLayout />
|
||||
) : (
|
||||
<>
|
||||
@@ -268,9 +248,10 @@ const Configure = () => {
|
||||
ml: "auto",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
<ButtonSpinner
|
||||
isLoading={isLoading}
|
||||
level="tertiary"
|
||||
label="Pause"
|
||||
label={monitor?.isActive ? "Pause" : "Resume"}
|
||||
animate="rotate180"
|
||||
img={<PauseCircleOutlineIcon />}
|
||||
sx={{
|
||||
@@ -282,8 +263,10 @@ const Configure = () => {
|
||||
mr: theme.spacing(2),
|
||||
},
|
||||
}}
|
||||
onClick={handlePause}
|
||||
/>
|
||||
<Button
|
||||
<ButtonSpinner
|
||||
isLoading={isLoading}
|
||||
level="error"
|
||||
label="Remove"
|
||||
sx={{
|
||||
@@ -398,7 +381,8 @@ const Configure = () => {
|
||||
</Stack>
|
||||
</ConfigBox>
|
||||
<Stack direction="row" justifyContent="flex-end" mt="auto">
|
||||
<Button
|
||||
<ButtonSpinner
|
||||
isLoading={isLoading}
|
||||
level="primary"
|
||||
label="Save"
|
||||
sx={{ px: theme.spacing(12) }}
|
||||
|
||||
52
Client/src/Pages/Monitors/Configure/skeleton.jsx
Normal file
52
Client/src/Pages/Monitors/Configure/skeleton.jsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Box, Skeleton, Stack } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
|
||||
/**
|
||||
* Renders a skeleton layout.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const SkeletonLayout = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
<Stack gap={theme.gap.xl} mt={theme.gap.medium}>
|
||||
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
|
||||
<Skeleton
|
||||
variant="circular"
|
||||
style={{ minWidth: 24, minHeight: 24 }}
|
||||
/>
|
||||
<Box width="80%">
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={24}
|
||||
sx={{ mb: theme.gap.small }}
|
||||
/>
|
||||
<Skeleton variant="rounded" width="50%" height={18} />
|
||||
</Box>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.gap.medium}
|
||||
sx={{
|
||||
ml: "auto",
|
||||
alignSelf: "flex-end",
|
||||
}}
|
||||
>
|
||||
<Skeleton variant="rounded" width={150} height={34} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Stack direction="row" justifyContent="flex-end">
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SkeletonLayout;
|
||||
@@ -101,6 +101,7 @@ const PaginationTable = ({ monitorId, dateRange }) => {
|
||||
<TableRow>
|
||||
<TableCell>Status</TableCell>
|
||||
<TableCell>Date & Time</TableCell>
|
||||
<TableCell>Status Code</TableCell>
|
||||
<TableCell>Message</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
@@ -120,7 +121,10 @@ const PaginationTable = ({ monitorId, dateRange }) => {
|
||||
<TableCell>
|
||||
{new Date(check.createdAt).toLocaleString()}
|
||||
</TableCell>
|
||||
<TableCell>{check.statusCode}</TableCell>
|
||||
<TableCell>
|
||||
{check.statusCode ? check.statusCode : "N/A"}
|
||||
</TableCell>
|
||||
<TableCell>{check.message}</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -172,6 +172,9 @@ const DetailsPage = ({ isAdmin }) => {
|
||||
|
||||
useEffect(() => {
|
||||
const fetchCertificate = async () => {
|
||||
if (monitor?.type !== "http") {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await networkService.getCertificateExpiry(
|
||||
authToken,
|
||||
@@ -183,7 +186,7 @@ const DetailsPage = ({ isAdmin }) => {
|
||||
}
|
||||
};
|
||||
fetchCertificate();
|
||||
}, [authToken, monitorId]);
|
||||
}, [authToken, monitorId, monitor]);
|
||||
|
||||
let loading = Object.keys(monitor).length === 0;
|
||||
return (
|
||||
|
||||
@@ -25,11 +25,20 @@ const Monitors = ({ isAdmin }) => {
|
||||
dispatch(getUptimeMonitorsByTeamId(authState.authToken));
|
||||
}, [authState.authToken, dispatch]);
|
||||
|
||||
const up = monitorState.monitors.reduce((acc, cur) => {
|
||||
return cur.status === true ? acc + 1 : acc;
|
||||
}, 0);
|
||||
const monitorStats = monitorState.monitors.reduce(
|
||||
(acc, monitor) => {
|
||||
if (monitor.isActive === false) {
|
||||
acc["paused"] += 1;
|
||||
} else if (monitor.status === true) {
|
||||
acc["up"] += 1;
|
||||
} else {
|
||||
acc["down"] += 1;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{ paused: 0, up: 0, down: 0 }
|
||||
);
|
||||
|
||||
const down = monitorState.monitors.length - up;
|
||||
const data = buildData(monitorState.monitors, isAdmin, navigate);
|
||||
|
||||
let loading = monitorState.isLoading && monitorState.monitors.length === 0;
|
||||
@@ -117,9 +126,9 @@ const Monitors = ({ isAdmin }) => {
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<StatusBox title="up" value={up} />
|
||||
<StatusBox title="down" value={down} />
|
||||
<StatusBox title="paused" value={0} />
|
||||
<StatusBox title="up" value={monitorStats.up} />
|
||||
<StatusBox title="down" value={monitorStats.down} />
|
||||
<StatusBox title="paused" value={monitorStats.paused} />
|
||||
</Stack>
|
||||
<Box
|
||||
flex={1}
|
||||
|
||||
@@ -17,6 +17,27 @@ class NetworkService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* ************************************
|
||||
* Create a new monitor
|
||||
* ************************************
|
||||
*
|
||||
* @async
|
||||
* @param {string} authToken - The authorization token to be used in the request header.
|
||||
* @param {string} monitorId - The monitor ID to be sent in the param.
|
||||
* @returns {Promise<AxiosResponse>} The response from the axios GET request.
|
||||
*/
|
||||
|
||||
async getMonitorByid(authToken, monitorId) {
|
||||
return this.axiosInstance.get(`/monitors/${monitorId}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* ************************************
|
||||
@@ -163,6 +184,28 @@ class NetworkService {
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* ************************************
|
||||
* Pauses a single monitor by its ID
|
||||
* ************************************
|
||||
*
|
||||
* @async
|
||||
* @param {string} authToken - The authorization token to be used in the request header.
|
||||
* @param {string} monitorId - The ID of the monitor to be paused.
|
||||
* @returns {Promise<AxiosResponse>} The response from the axios POST request.
|
||||
*/
|
||||
async pauseMonitorById(authToken, monitorId) {
|
||||
return this.axiosInstance.post(
|
||||
`/monitors/pause/${monitorId}`,
|
||||
{},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* ************************************
|
||||
@@ -226,7 +269,6 @@ class NetworkService {
|
||||
return this.axiosInstance.put(`/auth/user/${userId}`, form, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ const {
|
||||
createMonitorBodyValidation,
|
||||
editMonitorBodyValidation,
|
||||
getMonitorsByTeamIdQueryValidation,
|
||||
pauseMonitorParamValidation,
|
||||
} = require("../validation/joi");
|
||||
|
||||
const sslChecker = require("ssl-checker");
|
||||
@@ -123,7 +124,7 @@ const getMonitorById = async (req, res, next) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const monitor = await req.db.getMonitorById(req, res);
|
||||
const monitor = await req.db.getMonitorById(req.params.monitorId);
|
||||
if (!monitor) {
|
||||
const error = new Error(errorMessages.MONITOR_GET_BY_ID);
|
||||
error.status = 404;
|
||||
@@ -309,7 +310,7 @@ const editMonitor = async (req, res, next) => {
|
||||
// Get notifications from the request body
|
||||
const notifications = req.body.notifications;
|
||||
|
||||
const editedMonitor = await req.db.editMonitor(req, res);
|
||||
const editedMonitor = await req.db.editMonitor(monitorId, req.body);
|
||||
|
||||
await req.db.deleteNotificationsByMonitorId(editedMonitor._id);
|
||||
|
||||
@@ -337,6 +338,43 @@ const editMonitor = async (req, res, next) => {
|
||||
}
|
||||
};
|
||||
|
||||
const pauseMonitor = async (req, res, next) => {
|
||||
try {
|
||||
await pauseMonitorParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
}
|
||||
|
||||
try {
|
||||
const monitor = await req.db.getMonitorById(req.params.monitorId);
|
||||
if (monitor.isActive) {
|
||||
await req.jobQueue.deleteJob(monitor);
|
||||
} else {
|
||||
await req.jobQueue.addJob(monitor._id, monitor);
|
||||
}
|
||||
monitor.isActive = !monitor.isActive;
|
||||
const updatedMonitor = await req.db.editMonitor(
|
||||
req.params.monitorId,
|
||||
monitor
|
||||
);
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: updatedMonitor.isActive
|
||||
? successMessages.MONITOR_RESUME
|
||||
: successMessages.MONITOR_PAUSE,
|
||||
data: updatedMonitor,
|
||||
});
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "pauseMonitor";
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getAllMonitors,
|
||||
getMonitorStatsById,
|
||||
@@ -347,4 +385,5 @@ module.exports = {
|
||||
deleteMonitor,
|
||||
deleteAllMonitors,
|
||||
editMonitor,
|
||||
pauseMonitor,
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ const { NormalizeData } = require("../../../utils/dataUtils");
|
||||
*/
|
||||
const getAllMonitors = async (req, res) => {
|
||||
try {
|
||||
const monitors = await Monitor.find({ isActive: true });
|
||||
const monitors = await Monitor.find();
|
||||
return monitors;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
@@ -431,9 +431,7 @@ const deleteMonitorsByUserId = async (userId) => {
|
||||
* @returns {Promise<Monitor>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const editMonitor = async (req, res) => {
|
||||
const candidateId = req.params.monitorId;
|
||||
const candidateMonitor = req.body;
|
||||
const editMonitor = async (candidateId, candidateMonitor) => {
|
||||
candidateMonitor.notifications = undefined;
|
||||
|
||||
try {
|
||||
|
||||
@@ -89,7 +89,6 @@ const getUserByEmail = async (email) => {
|
||||
|
||||
const updateUser = async (req, res) => {
|
||||
const candidateUserId = req.params.userId;
|
||||
|
||||
try {
|
||||
const candidateUser = { ...req.body };
|
||||
// ******************************************
|
||||
|
||||
@@ -31,4 +31,11 @@ router.delete(
|
||||
isAllowed(["superadmin"]),
|
||||
monitorController.deleteAllMonitors
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/pause/:monitorId",
|
||||
isAllowed(["admin", "superadmin"]),
|
||||
monitorController.pauseMonitor
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -87,6 +87,8 @@ const successMessages = {
|
||||
//Job Queue
|
||||
JOB_QUEUE_DELETE_JOB: "Job removed successfully",
|
||||
JOB_QUEUE_OBLITERATE: "Queue OBLITERATED!!!",
|
||||
JOB_QUEUE_PAUSE_JOB: "Job paused successfully",
|
||||
JOB_QUEUE_RESUME_JOB: "Job resumed successfully",
|
||||
|
||||
//Maintenance Window Controller
|
||||
MAINTENANCE_WINDOW_CREATE: "Maintenance Window created successfully",
|
||||
|
||||
@@ -197,6 +197,10 @@ const editMonitorBodyValidation = joi.object({
|
||||
notifications: joi.array().items(joi.object()),
|
||||
});
|
||||
|
||||
const pauseMonitorParamValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
});
|
||||
|
||||
//****************************************
|
||||
// Alerts
|
||||
//****************************************
|
||||
@@ -350,6 +354,7 @@ module.exports = {
|
||||
getMonitorsByTeamIdValidation,
|
||||
getMonitorsByTeamIdQueryValidation,
|
||||
editMonitorBodyValidation,
|
||||
pauseMonitorParamValidation,
|
||||
editUserParamValidation,
|
||||
editUserBodyValidation,
|
||||
createAlertParamValidation,
|
||||
|
||||
Reference in New Issue
Block a user