Merge pull request #1531 from bluewave-labs/fix/be/get-monitors-by-team-id-query

Fix/be/get monitors by team id query
This commit is contained in:
Alexander Holliday authored and GitHub committed 2025-01-08 10:19:10 -08:00
commit ac839cae6c
4 files changed
+109 -43

No files matched your search

@@ -11,7 +11,6 @@ import {
updateUptimeMonitor,
pauseUptimeMonitor,
getUptimeMonitorById,
getUptimeSummaryByTeamId,
deleteUptimeMonitor,
} from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
import TextInput from "../../../Components/Inputs/TextInput";
@@ -157,7 +156,6 @@ const Configure = () => {
const action = await dispatch(updateUptimeMonitor({ authToken, monitor: monitor }));
if (action.meta.requestStatus === "fulfilled") {
createToast({ body: "Monitor updated successfully!" });
dispatch(getUptimeSummaryByTeamId(authToken));
} else {
createToast({ body: "Failed to update monitor." });
}
+1 -7
View File
@@ -14,7 +14,6 @@ import {
getUptimeSummaryByTeamId,
getUptimeMonitorsByTeamId,
} from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
import { setRowsPerPage } from "../../../Features/UI/uiSlice";
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
import { useSelector, useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
@@ -26,15 +25,13 @@ const BREADCRUMBS = [{ name: `Uptime`, path: "/uptime" }];
const UptimeMonitors = () => {
// Redux state
const { isLoading, monitorsSummary } = useSelector((state) => state.uptimeMonitors);
const authState = useSelector((state) => state.auth);
const { rowsPerPage } = useSelector((state) => state.ui.monitors);
// Local state
const [monitors, setMonitors] = useState([]);
const [sort, setSort] = useState({});
const [search, setSearch] = useState("");
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10);
const [isSearching, setIsSearching] = useState(false);
const [monitorUpdateTrigger, setMonitorUpdateTrigger] = useState(false);
@@ -46,9 +43,6 @@ const UptimeMonitors = () => {
const isAdmin = useIsAdmin();
const { isLoading, monitorsSummary } = useSelector((state) => state.uptimeMonitors);
const authState = useSelector((state) => state.auth);
const dispatch = useDispatch({});
const [monitorUpdateTrigger, setMonitorUpdateTrigger] = useState(false);
const fetchParams = useMemo(
() => ({
+106 -32
View File
@@ -12,6 +12,7 @@ import {
buildUptimeDetailsPipeline,
buildHardwareDetailsPipeline,
} from "./monitorModuleQueries.js";
import { ObjectId } from "mongodb";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@@ -570,6 +571,7 @@ const getMonitorsByTeamId = async (req, res) => {
} = req.query;
const monitorQuery = { teamId: req.params.teamId };
const monitorCount = await Monitor.countDocuments(monitorQuery);
if (type !== undefined) {
monitorQuery.type = Array.isArray(type) ? { $in: type } : type;
@@ -582,46 +584,118 @@ const getMonitorsByTeamId = async (req, res) => {
{ url: { $regex: filter, $options: "i" } },
];
}
const monitorCount = await Monitor.countDocuments(monitorQuery);
// Pagination
const skip = page && rowsPerPage ? page * rowsPerPage : 0;
// Build Sort option
const sort = field ? { [field]: order === "asc" ? 1 : -1 } : {};
const sort = { [field]: order === "asc" ? 1 : -1 };
const monitors = await Monitor.find(monitorQuery)
.skip(skip)
.limit(rowsPerPage)
.sort(sort);
// Early return if limit is set to -1, indicating we don't want any checks
if (limit === "-1") {
return { monitors, monitorCount };
const matchStage = { teamId: new ObjectId(req.params.teamId) };
if (type !== undefined) {
matchStage.type = Array.isArray(type) ? { $in: type } : type;
}
if (filter !== undefined) {
matchStage.$or = [
{ name: { $regex: filter, $options: "i" } },
{ url: { $regex: filter, $options: "i" } },
];
}
// Map each monitor to include its associated checks
const monitorsWithChecks = await Promise.all(
monitors.map(async (monitor) => {
let model = CHECK_MODEL_LOOKUP[monitor.type];
// Checks are order newest -> oldest
let checks = await model
.find({
monitorId: monitor._id,
...(status && { status }),
})
.sort({ createdAt: checkOrder === "asc" ? 1 : -1 })
.limit(limit || 0);
//Normalize checks if requested
if (normalize !== undefined) {
checks = NormalizeData(checks, 10, 100);
}
return { ...monitor.toObject(), checks };
})
);
return { monitors: monitorsWithChecks, monitorCount };
let result = await Monitor.aggregate([
{ $match: matchStage },
{ $skip: parseInt(skip) },
...(rowsPerPage ? [{ $limit: parseInt(rowsPerPage) }] : []),
{ $sort: sort },
{
$lookup: {
from: "checks",
let: { monitorId: "$_id" },
pipeline: [
{
$match: {
$expr: { $eq: ["$monitorId", "$$monitorId"] },
...(status && { status }),
},
},
{ $sort: { createdAt: checkOrder === "asc" ? 1 : -1 } },
{ $limit: parseInt(limit) || 0 },
],
as: "standardchecks",
},
},
{
$lookup: {
from: "pagespeedchecks",
let: { monitorId: "$_id" },
pipeline: [
{
$match: {
$expr: { $eq: ["$monitorId", "$$monitorId"] },
...(status && { status }),
},
},
{ $sort: { createdAt: checkOrder === "asc" ? 1 : -1 } },
{ $limit: parseInt(limit) || 0 },
],
as: "pagespeedchecks",
},
},
{
$lookup: {
from: "hardwarechecks",
let: { monitorId: "$_id" },
pipeline: [
{
$match: {
$expr: { $eq: ["$monitorId", "$$monitorId"] },
...(status && { status }),
},
},
{ $sort: { createdAt: checkOrder === "asc" ? 1 : -1 } },
{ $limit: parseInt(limit) || 0 },
],
as: "hardwarechecks",
},
},
{
$addFields: {
checks: {
$switch: {
branches: [
{
case: { $in: ["$type", ["http", "ping", "docker", "port"]] },
then: "$standardchecks",
},
{
case: { $eq: ["$type", "pagespeed"] },
then: "$pagespeedchecks",
},
{
case: { $eq: ["$type", "hardware"] },
then: "$hardwarechecks",
},
],
default: [],
},
},
},
},
{
$project: {
standardchecks: 0,
pagespeedchecks: 0,
hardwarechecks: 0,
},
},
]);
if (normalize) {
result = result.map((monitor) => {
monitor.checks = NormalizeData(monitor.checks, 10, 100);
return monitor;
});
}
return { monitors: result, monitorCount };
} catch (error) {
error.service = SERVICE_NAME;
error.method = "getMonitorsByTeamId";
+2 -2
View File
@@ -38,7 +38,7 @@ const NormalizeData = (checks, rangeMin, rangeMax) => {
Math.min(rangeMax, normalizedResponseTime)
);
return {
...check._doc,
...check,
responseTime: normalizedResponseTime,
originalResponseTime: originalResponseTime,
};
@@ -47,7 +47,7 @@ const NormalizeData = (checks, rangeMin, rangeMax) => {
return normalizedChecks;
} else {
return checks.map((check) => {
return { ...check._doc, originalResponseTime: check.responseTime };
return { ...check, originalResponseTime: check.responseTime };
});
}
};