diff --git a/Client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js b/Client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js
index 317ab1320..2e107e7e7 100644
--- a/Client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js
+++ b/Client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js
@@ -3,7 +3,7 @@ import { jwtDecode } from "jwt-decode";
import { networkService } from "../../main";
const initialState = {
isLoading: false,
- monitors: [],
+ monitorsSummary: [],
success: null,
msg: null,
};
@@ -53,14 +53,10 @@ export const getPageSpeedByTeamId = createAsyncThunk(
async (token, thunkApi) => {
const user = jwtDecode(token);
try {
- const res = await networkService.getMonitorsByTeamId(
+ const res = await networkService.getMonitorsAndSummaryByTeamId(
token,
user.teamId,
- 25,
- ["pagespeed"],
- null,
- "desc",
- false
+ ["pagespeed"]
);
return res.data;
@@ -155,7 +151,7 @@ const pageSpeedMonitorSlice = createSlice({
reducers: {
clearMonitorState: (state) => {
state.isLoading = false;
- state.monitors = [];
+ state.monitorsSummary = [];
state.success = null;
state.msg = null;
},
@@ -172,7 +168,7 @@ const pageSpeedMonitorSlice = createSlice({
.addCase(getPageSpeedByTeamId.fulfilled, (state, action) => {
state.isLoading = false;
state.success = action.payload.msg;
- state.monitors = action.payload.data;
+ state.monitorsSummary = action.payload.data;
})
.addCase(getPageSpeedByTeamId.rejected, (state, action) => {
state.isLoading = false;
diff --git a/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js b/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js
index 79789e16b..ac3ce1d6f 100644
--- a/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js
+++ b/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js
@@ -3,7 +3,7 @@ import { jwtDecode } from "jwt-decode";
import { networkService } from "../../main";
const initialState = {
isLoading: false,
- monitors: [],
+ monitorsSummary: [],
success: null,
msg: null,
};
@@ -53,14 +53,10 @@ export const getUptimeMonitorsByTeamId = createAsyncThunk(
async (token, thunkApi) => {
const user = jwtDecode(token);
try {
- const res = await networkService.getMonitorsByTeamId(
+ const res = await networkService.getMonitorsAndSummaryByTeamId(
token,
user.teamId,
- 25,
- ["http", "ping"],
- null,
- "desc",
- true
+ ["http", "ping"]
);
return res.data;
} catch (error) {
@@ -175,7 +171,7 @@ const uptimeMonitorsSlice = createSlice({
reducers: {
clearUptimeMonitorState: (state) => {
state.isLoading = false;
- state.monitors = [];
+ state.monitorsSummary = [];
state.success = null;
state.msg = null;
},
@@ -192,7 +188,7 @@ const uptimeMonitorsSlice = createSlice({
.addCase(getUptimeMonitorsByTeamId.fulfilled, (state, action) => {
state.isLoading = false;
state.success = action.payload.msg;
- state.monitors = action.payload.data;
+ state.monitorsSummary = action.payload.data;
})
.addCase(getUptimeMonitorsByTeamId.rejected, (state, action) => {
state.isLoading = false;
diff --git a/Client/src/Pages/Monitors/Home/index.jsx b/Client/src/Pages/Monitors/Home/index.jsx
index 8bff60d19..093509391 100644
--- a/Client/src/Pages/Monitors/Home/index.jsx
+++ b/Client/src/Pages/Monitors/Home/index.jsx
@@ -23,23 +23,9 @@ const Monitors = ({ isAdmin }) => {
useEffect(() => {
dispatch(getUptimeMonitorsByTeamId(authState.authToken));
}, [authState.authToken, dispatch]);
-
- const monitorStats = monitorState?.monitors?.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 }
- );
-
- let loading = monitorState.isLoading && monitorState.monitors.length === 0;
-
+ let loading =
+ monitorState?.isLoading &&
+ monitorState?.monitorsSummary?.monitors?.length === 0;
return (
{loading ? (
@@ -55,7 +41,7 @@ const Monitors = ({ isAdmin }) => {
mt={theme.spacing(5)}
>
- {monitorState.monitors?.length !== 0 && (
+ {monitorState?.monitorsSummary?.monitors?.length !== 0 && (
- {isAdmin && monitorState.monitors?.length === 0 && (
+ {isAdmin && monitorState?.monitorsSummary?.monitors?.length === 0 && (
)}
- {monitorState.monitors?.length !== 0 && (
+ {monitorState?.monitorsSummary?.monitors?.length !== 0 && (
<>
-
-
-
+
+
+
{
borderColor={theme.palette.border.light}
backgroundColor={theme.palette.background.accent}
>
- {monitorState.monitors.monitors.length}
+ {monitorState?.monitorsSummary.monitors?.monitors?.length ||
+ 0}
{/* TODO - add search bar */}
diff --git a/Client/src/Pages/PageSpeed/Details/index.jsx b/Client/src/Pages/PageSpeed/Details/index.jsx
index f4dd1f64d..4004e1715 100644
--- a/Client/src/Pages/PageSpeed/Details/index.jsx
+++ b/Client/src/Pages/PageSpeed/Details/index.jsx
@@ -217,7 +217,6 @@ const PageSpeedDetails = () => {
null,
null
);
- console.log(res.data.data);
setMonitor(res?.data?.data ?? {});
setAudits(res?.data?.data?.checks?.[0]?.audits ?? []);
} catch (error) {
diff --git a/Client/src/Pages/PageSpeed/index.jsx b/Client/src/Pages/PageSpeed/index.jsx
index 8d1273b04..ba65bf436 100644
--- a/Client/src/Pages/PageSpeed/index.jsx
+++ b/Client/src/Pages/PageSpeed/index.jsx
@@ -18,7 +18,7 @@ const PageSpeed = ({ isAdmin }) => {
const navigate = useNavigate();
const { authToken } = useSelector((state) => state.auth);
- const { monitors, isLoading } = useSelector(
+ const { monitorsSummary, isLoading } = useSelector(
(state) => state.pageSpeedMonitors
);
useEffect(() => {
@@ -27,7 +27,7 @@ const PageSpeed = ({ isAdmin }) => {
// will show skeletons only on initial load
// since monitor state is being added to redux persist, there's no reason to display skeletons on every render
- let isActuallyLoading = isLoading && monitors?.monitors.length === 0;
+ let isActuallyLoading = isLoading && monitorsSummary?.monitors?.length === 0;
return (
{
>
{isActuallyLoading ? (
- ) : monitors?.monitors?.length !== 0 ? (
+ ) : monitorsSummary?.monitors?.length !== 0 ? (
{
- {monitors?.monitors?.map((monitor) => (
-
+ {monitorsSummary?.monitors?.map((monitor) => (
+
))}
diff --git a/Client/src/Utils/NetworkService.js b/Client/src/Utils/NetworkService.js
index 4c8dd57e8..e4b7be526 100644
--- a/Client/src/Utils/NetworkService.js
+++ b/Client/src/Utils/NetworkService.js
@@ -58,9 +58,28 @@ class NetworkService {
});
}
+ async getMonitorsAndSummaryByTeamId(authToken, teamId, types) {
+ const params = new URLSearchParams();
+
+ if (types) {
+ types.forEach((type) => {
+ params.append("type", type);
+ });
+ }
+ return this.axiosInstance.get(
+ `/monitors/team/summary/${teamId}?${params.toString()}`,
+ {
+ headers: {
+ Authorization: `Bearer ${authToken}`,
+ "Content-Type": "application/json",
+ },
+ }
+ );
+ }
+
/**
* ************************************
- * Get all uptime monitors for a user
+ * Get all uptime monitors for a Team
* ************************************
*
* @async
diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js
index 091d41e2a..4571a9a65 100644
--- a/Server/controllers/monitorController.js
+++ b/Server/controllers/monitorController.js
@@ -4,6 +4,8 @@ const {
getMonitorsByTeamIdValidation,
createMonitorBodyValidation,
editMonitorBodyValidation,
+ getMonitorsAndSummaryByTeamIdParamValidation,
+ getMonitorsAndSummaryByTeamIdQueryValidation,
getMonitorsByTeamIdQueryValidation,
pauseMonitorParamValidation,
getMonitorStatsByIdParamValidation,
@@ -16,7 +18,6 @@ const {
const sslChecker = require("ssl-checker");
const SERVICE_NAME = "monitorController";
const { errorMessages, successMessages } = require("../utils/messages");
-
/**
* Returns all monitors
* @async
@@ -186,7 +187,54 @@ const getMonitorById = async (req, res, next) => {
};
/**
- * Returns all monitors belong to User with UserID
+ * Returns all monitors and a sumamry for a team with TeamID
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @returns {Promise}
+ * @throws {Error}
+ */
+
+const getMonitorsAndSummaryByTeamId = async (req, res, next) => {
+ try {
+ await getMonitorsAndSummaryByTeamIdParamValidation.validateAsync(
+ req.params
+ );
+ await getMonitorsAndSummaryByTeamIdQueryValidation.validateAsync(req.query);
+ //validation
+ } catch (error) {
+ error.status = 422;
+ error.service = SERVICE_NAME;
+ error.method === undefined &&
+ error.method === "getMonitorsAndSummaryByTeamId";
+ error.message =
+ error.details?.[0]?.message || error.message || "Validation Error";
+ next(error);
+ return;
+ }
+
+ try {
+ const { teamId } = req.params;
+ const { type } = req.query;
+ const monitorsSummary = await req.db.getMonitorsAndSummaryByTeamId(
+ teamId,
+ type
+ );
+ return res.status(200).json({
+ success: true,
+ msg: successMessages.MONITOR_GET_BY_USER_ID(teamId),
+ data: monitorsSummary,
+ });
+ } catch (error) {
+ error.service = SERVICE_NAME;
+ error.method === undefined &&
+ error.method === "getMonitorsAndSummaryByTeamId";
+ next(error);
+ }
+};
+
+/**
+ * Returns all monitors belong to team with TeamID
* @async
* @param {Express.Request} req
* @param {Express.Response} res
@@ -424,6 +472,7 @@ module.exports = {
getMonitorStatsById,
getMonitorCertificate,
getMonitorById,
+ getMonitorsAndSummaryByTeamId,
getMonitorsByTeamId,
createMonitor,
deleteMonitor,
diff --git a/Server/db/mongo/MongoDB.js b/Server/db/mongo/MongoDB.js
index 29233b73a..d6a4a243f 100644
--- a/Server/db/mongo/MongoDB.js
+++ b/Server/db/mongo/MongoDB.js
@@ -64,10 +64,9 @@ const {
const {
getAllMonitors,
- getMonitorAggregateStats,
- testMethod,
getMonitorStatsById,
getMonitorById,
+ getMonitorsAndSummaryByTeamId,
getMonitorsByTeamId,
createMonitor,
deleteMonitor,
@@ -148,6 +147,7 @@ module.exports = {
getAllMonitors,
getMonitorStatsById,
getMonitorById,
+ getMonitorsAndSummaryByTeamId,
getMonitorsByTeamId,
createMonitor,
deleteMonitor,
diff --git a/Server/db/mongo/modules/monitorModule.js b/Server/db/mongo/modules/monitorModule.js
index 0b1a38140..e77ccc696 100644
--- a/Server/db/mongo/modules/monitorModule.js
+++ b/Server/db/mongo/modules/monitorModule.js
@@ -292,6 +292,43 @@ const getMonitorById = async (monitorId) => {
}
};
+/**
+ * Get monitors and Summary by TeamID
+ * @async
+ * @param {Express.Request} req
+ * @param {Express.Response} res
+ * @returns {Promise>}
+ * @throws {Error}
+ */
+
+const getMonitorsAndSummaryByTeamId = async (teamId, type) => {
+ try {
+ const monitors = await Monitor.find({ teamId, type });
+ const monitorCounts = monitors.reduce(
+ (acc, monitor) => {
+ if (monitor.status === true) {
+ acc.up += 1;
+ }
+
+ if (monitor.status === false) {
+ acc.down += 1;
+ }
+
+ if (monitor.isActive === false) {
+ acc.paused += 1;
+ }
+ return acc;
+ },
+ { up: 0, down: 0, paused: 0 }
+ );
+ monitorCounts.total = monitors.length;
+ return { monitors, monitorCounts };
+ } catch (error) {
+ error.method = "getMonitorsAndSummaryByTeamId";
+ throw error;
+ }
+};
+
/**
* Get monitors by TeamID
* @async
@@ -464,6 +501,7 @@ module.exports = {
getAllMonitors,
getMonitorStatsById,
getMonitorById,
+ getMonitorsAndSummaryByTeamId,
getMonitorsByTeamId,
createMonitor,
deleteMonitor,
diff --git a/Server/routes/monitorRoute.js b/Server/routes/monitorRoute.js
index 7831f42f7..b29b7130a 100644
--- a/Server/routes/monitorRoute.js
+++ b/Server/routes/monitorRoute.js
@@ -7,6 +7,10 @@ router.get("/aggregate/:monitorId", monitorController.getMonitorAggregateStats);
router.get("/stats/:monitorId", monitorController.getMonitorStatsById);
router.get("/certificate/:monitorId", monitorController.getMonitorCertificate);
router.get("/:monitorId", monitorController.getMonitorById);
+router.get(
+ "/team/summary/:teamId",
+ monitorController.getMonitorsAndSummaryByTeamId
+);
router.get("/team/:teamId", monitorController.getMonitorsByTeamId);
router.post(
diff --git a/Server/validation/joi.js b/Server/validation/joi.js
index 090a49a7a..417965b95 100644
--- a/Server/validation/joi.js
+++ b/Server/validation/joi.js
@@ -161,6 +161,19 @@ const getMonitorByIdQueryValidation = joi.object({
normalize: joi.boolean(),
});
+const getMonitorsAndSummaryByTeamIdParamValidation = joi.object({
+ teamId: joi.string().required(),
+});
+
+const getMonitorsAndSummaryByTeamIdQueryValidation = joi.object({
+ type: joi
+ .alternatives()
+ .try(
+ joi.string().valid("http", "ping", "pagespeed"),
+ joi.array().items(joi.string().valid("http", "ping", "pagespeed"))
+ ),
+});
+
const getMonitorsByTeamIdValidation = joi.object({
teamId: joi.string().required(),
});
@@ -381,6 +394,8 @@ module.exports = {
createMonitorBodyValidation,
getMonitorByIdParamValidation,
getMonitorByIdQueryValidation,
+ getMonitorsAndSummaryByTeamIdParamValidation,
+ getMonitorsAndSummaryByTeamIdQueryValidation,
getMonitorsByTeamIdValidation,
getMonitorsByTeamIdQueryValidation,
getMonitorStatsByIdParamValidation,