diff --git a/Client/src/Components/HttpStatusLabel/index.jsx b/Client/src/Components/HttpStatusLabel/index.jsx index ca9f70fe8..52676ae7c 100644 --- a/Client/src/Components/HttpStatusLabel/index.jsx +++ b/Client/src/Components/HttpStatusLabel/index.jsx @@ -16,7 +16,7 @@ import { BaseLabel } from "../Label"; const DEFAULT_CODE = 9999; // Default code for unknown status const handleStatusCode = (status) => { - if (status >= 100 && status < 600) { + if (status) { return status; } return DEFAULT_CODE; diff --git a/Client/src/Components/Table/TablePagination/index.jsx b/Client/src/Components/Table/TablePagination/index.jsx index 66707494a..61e89232f 100644 --- a/Client/src/Components/Table/TablePagination/index.jsx +++ b/Client/src/Components/Table/TablePagination/index.jsx @@ -5,11 +5,11 @@ import { TablePaginationActions } from "./Actions"; import SelectorVertical from "../../../assets/icons/selector-vertical.svg?react"; Pagination.propTypes = { - monitorCount: PropTypes.number.isRequired, // Total number of items for pagination. + itemCount: PropTypes.number.isRequired, // Total number of items for pagination. page: PropTypes.number.isRequired, // Current page index. rowsPerPage: PropTypes.number.isRequired, // Number of rows displayed per page. handleChangePage: PropTypes.func.isRequired, // Function to handle page changes. - handleChangeRowsPerPage: PropTypes.func.isRequired, // Function to handle changes in rows per page. + handleChangeRowsPerPage: PropTypes.func, // Function to handle changes in rows per page. }; const ROWS_PER_PAGE_OPTIONS = [5, 10, 15, 25]; @@ -18,6 +18,7 @@ const ROWS_PER_PAGE_OPTIONS = [5, 10, 15, 25]; * Pagination component for table navigation with customized styling and behavior. * * @param {object} props - Component properties. + * @param {string} props.paginationLabel - Label for the pagination. * @param {number} props.monitorCount - Total number of monitors to paginate. * @param {number} props.page - Current page index (0-based). * @param {number} props.rowsPerPage - Number of rows to display per page. @@ -26,7 +27,8 @@ const ROWS_PER_PAGE_OPTIONS = [5, 10, 15, 25]; * @returns {JSX.Element} The Pagination component. */ function Pagination({ - monitorCount, + paginationLabel, + itemCount, page, rowsPerPage, handleChangePage, @@ -35,7 +37,7 @@ function Pagination({ const theme = useTheme(); const start = page * rowsPerPage + 1; - const end = Math.min(page * rowsPerPage + rowsPerPage, monitorCount); + const end = Math.min(page * rowsPerPage + rowsPerPage, itemCount); const range = `${start} - ${end}`; return ( @@ -51,11 +53,11 @@ function Pagination({ variant="body2" sx={{ opacity: 0.7 }} > - Showing {range} of {monitorCount} monitor(s) + Showing {range} of {itemCount} {paginationLabel} { ) : ( data.map((row) => { + const key = row.id || row._id || Math.random(); return ( config?.onRowClick(row)} > diff --git a/Client/src/Pages/Incidents/IncidentTable/index.jsx b/Client/src/Pages/Incidents/IncidentTable/index.jsx index b89246cb8..ae9a3ae2a 100644 --- a/Client/src/Pages/Incidents/IncidentTable/index.jsx +++ b/Client/src/Pages/Incidents/IncidentTable/index.jsx @@ -1,8 +1,6 @@ import PropTypes from "prop-types"; -import { Pagination, PaginationItem, Typography, Box } from "@mui/material"; +import { Typography, Box } from "@mui/material"; -import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded"; -import ArrowForwardRoundedIcon from "@mui/icons-material/ArrowForwardRounded"; import { useState, useEffect } from "react"; import { useSelector } from "react-redux"; import { networkService } from "../../../main"; @@ -16,7 +14,9 @@ import { HttpStatusLabel } from "../../../Components/HttpStatusLabel"; import { Empty } from "./Empty/Empty"; import { IncidentSkeleton } from "./Skeleton/Skeleton"; import DataTable from "../../../Components/Table"; -const IncidentTable = ({ monitors, selectedMonitor, filter }) => { +import Pagination from "../../../Components/Table/TablePagination"; + +const IncidentTable = ({ monitors, selectedMonitor, filter, dateRange }) => { const uiTimezone = useSelector((state) => state.ui.timezone); const theme = useTheme(); @@ -24,19 +24,10 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => { const mode = useSelector((state) => state.ui.mode); const [checks, setChecks] = useState([]); const [checksCount, setChecksCount] = useState(0); - const [paginationController, setPaginationController] = useState({ - page: 0, - rowsPerPage: 14, - }); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); const [isLoading, setIsLoading] = useState(false); - useEffect(() => { - setPaginationController((prevPaginationController) => ({ - ...prevPaginationController, - page: 0, - })); - }, [filter, selectedMonitor]); - useEffect(() => { const fetchPage = async () => { if (!monitors || Object.keys(monitors).length === 0) { @@ -51,10 +42,10 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => { teamId: user.teamId, sortOrder: "desc", limit: null, - dateRange: null, + dateRange, filter: filter, - page: paginationController.page, - rowsPerPage: paginationController.rowsPerPage, + page: page, + rowsPerPage: rowsPerPage, }); } else { res = await networkService.getChecksByMonitor({ @@ -62,12 +53,13 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => { monitorId: selectedMonitor, sortOrder: "desc", limit: null, - dateRange: null, + dateRange, filter: filter, - page: paginationController.page, - rowsPerPage: paginationController.rowsPerPage, + page, + rowsPerPage, }); } + setChecks(res.data.data.checks); setChecksCount(res.data.data.checksCount); } catch (error) { @@ -77,21 +69,14 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => { } }; fetchPage(); - }, [ - authToken, - user, - monitors, - selectedMonitor, - filter, - paginationController.page, - paginationController.rowsPerPage, - ]); + }, [authToken, user, monitors, selectedMonitor, filter, page, rowsPerPage, dateRange]); const handlePageChange = (_, newPage) => { - setPaginationController({ - ...paginationController, - page: newPage - 1, // 0-indexed - }); + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(event.target.value); }; const headers = [ @@ -134,28 +119,6 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => { { id: "message", content: "Message", render: (row) => row.message }, ]; - let paginationComponent = <>; - if (checksCount > paginationController.rowsPerPage) { - paginationComponent = ( - ( - - )} - sx={{ mt: "auto" }} - /> - ); - } - let sharedStyles = { border: 1, borderColor: theme.palette.primary.lowContrast, @@ -198,8 +161,14 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => { headers={headers} data={checks} /> - - {paginationComponent} + )} @@ -210,6 +179,7 @@ IncidentTable.propTypes = { monitors: PropTypes.object.isRequired, selectedMonitor: PropTypes.string.isRequired, filter: PropTypes.string.isRequired, + dateRange: PropTypes.string.isRequired, }; export default IncidentTable; diff --git a/Client/src/Pages/Incidents/index.css b/Client/src/Pages/Incidents/index.css deleted file mode 100644 index ddbb44e6d..000000000 --- a/Client/src/Pages/Incidents/index.css +++ /dev/null @@ -1,11 +0,0 @@ -.incidents h1.MuiTypography-root { - font-size: var(--env-var-font-size-large); - font-weight: 600; -} -.incidents button.MuiButtonBase-root, -.incidents p.MuiTypography-root { - font-size: var(--env-var-font-size-medium); -} -.incidents button.MuiButtonBase-root { - min-height: 34px; -} diff --git a/Client/src/Pages/Incidents/index.jsx b/Client/src/Pages/Incidents/index.jsx index 86f5afc5f..8305ec672 100644 --- a/Client/src/Pages/Incidents/index.jsx +++ b/Client/src/Pages/Incidents/index.jsx @@ -8,7 +8,6 @@ import { useTheme } from "@emotion/react"; import Select from "../../Components/Inputs/Select"; import IncidentTable from "./IncidentTable"; import SkeletonLayout from "./skeleton"; -import "./index.css"; const Incidents = () => { const theme = useTheme(); @@ -21,6 +20,7 @@ const Incidents = () => { // TODO do something with these filters const [filter, setFilter] = useState("all"); + const [dateRange, setDateRange] = useState("hour"); useEffect(() => { const fetchMonitors = async () => { @@ -77,62 +77,132 @@ const Incidents = () => { <> - - Incidents for - - + + - - - + + + + + + - Cannot Resolve - - + Show: + + + + + + + + )} diff --git a/Client/src/Pages/Infrastructure/index.jsx b/Client/src/Pages/Infrastructure/index.jsx index 08636a05e..0bf367b99 100644 --- a/Client/src/Pages/Infrastructure/index.jsx +++ b/Client/src/Pages/Infrastructure/index.jsx @@ -13,7 +13,7 @@ import { Box, Button, IconButton, Stack } from "@mui/material"; import Breadcrumbs from "../../Components/Breadcrumbs"; import { StatusLabel } from "../../Components/Label"; import { Heading } from "../../Components/Heading"; -import { Pagination } from "../../Components/Table/TablePagination/index.jsx"; +import Pagination from "../../Components/Table/TablePagination/index.jsx"; // import { getInfrastructureMonitorsByTeamId } from "../../Features/InfrastructureMonitors/infrastructureMonitorsSlice"; import { networkService } from "../../Utils/NetworkService.js"; import CustomGauge from "../../Components/Charts/CustomGauge/index.jsx"; @@ -269,7 +269,8 @@ function Infrastructure() { /> { } if (monitor.type === "http") { - const checkEndpointAction = await dispatch( - checkEndpointResolution({ authToken, monitorURL: form.url }) - ); - if (checkEndpointAction.meta.requestStatus === "rejected") { - createToast({ - body: "The endpoint you entered doesn't resolve. Check the URL again.", - }); - setErrors({ url: "The entered URL is not reachable." }); - return; - } + // const checkEndpointAction = await dispatch( + // checkEndpointResolution({ authToken, monitorURL: form.url }) + // ); + // if (checkEndpointAction.meta.requestStatus === "rejected") { + // createToast({ + // body: "The endpoint you entered doesn't resolve. Check the URL again.", + // }); + // setErrors({ url: "The entered URL is not reachable." }); + // return; + // } } form = { diff --git a/Client/src/Pages/Uptime/Home/index.jsx b/Client/src/Pages/Uptime/Home/index.jsx index df59185fb..446702ebb 100644 --- a/Client/src/Pages/Uptime/Home/index.jsx +++ b/Client/src/Pages/Uptime/Home/index.jsx @@ -5,7 +5,7 @@ import SkeletonLayout from "./skeleton"; import Fallback from "./fallback"; import StatusBox from "./StatusBox"; import UptimeDataTable from "./UptimeDataTable"; -import { Pagination } from "../../../Components/Table/TablePagination"; +import Pagination from "../../../Components/Table/TablePagination"; // Utils import { useTheme } from "@emotion/react"; @@ -225,7 +225,8 @@ const UptimeMonitors = () => { triggerUpdate={triggerUpdate} /> { + getChecksByMonitor = async (req, res, next) => { try { await getChecksParamValidation.validateAsync(req.params); await getChecksQueryValidation.validateAsync(req.query); @@ -54,19 +54,18 @@ class CheckController { } try { - const checks = await this.db.getChecks(req); - const checksCount = await this.db.getChecksCount(req); + const result = await this.db.getChecksByMonitor(req); return res.success({ msg: successMessages.CHECK_GET, - data: { checksCount, checks }, + data: result, }); } catch (error) { next(handleError(error, SERVICE_NAME, "getChecks")); } }; - getTeamChecks = async (req, res, next) => { + getChecksByTeam = async (req, res, next) => { try { await getTeamChecksParamValidation.validateAsync(req.params); await getTeamChecksQueryValidation.validateAsync(req.query); @@ -75,7 +74,7 @@ class CheckController { return; } try { - const checkData = await this.db.getTeamChecks(req); + const checkData = await this.db.getChecksByTeam(req); return res.success({ msg: successMessages.CHECK_GET, diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js index 097172854..86c0fb840 100644 --- a/Server/controllers/monitorController.js +++ b/Server/controllers/monitorController.js @@ -20,7 +20,7 @@ import { getTokenFromHeaders } from "../utils/utils.js"; import logger from "../utils/logger.js"; import { handleError, handleValidationError } from "./controllerUtils.js"; import axios from "axios"; - +import seedDb from "../db/mongo/utils/seedDb.js"; const SERVICE_NAME = "monitorController"; class MonitorController { @@ -495,6 +495,17 @@ class MonitorController { next(handleError(error, SERVICE_NAME, "getMonitorsByTeamId")); } }; + + seedDb = async (req, res, next) => { + try { + const token = getTokenFromHeaders(req.headers); + const { jwtSecret } = this.settingsService.getSettings(); + const { _id, teamId } = jwt.verify(token, jwtSecret); + await seedDb(_id, teamId); + } catch (error) { + next(handleError(error, SERVICE_NAME, "seedDb")); + } + }; } export default MonitorController; diff --git a/Server/db/models/Check.js b/Server/db/models/Check.js index 1946f2c59..158749986 100644 --- a/Server/db/models/Check.js +++ b/Server/db/models/Check.js @@ -12,6 +12,13 @@ const BaseCheckSchema = mongoose.Schema({ immutable: true, index: true, }, + + teamId: { + type: mongoose.Schema.Types.ObjectId, + ref: "Team", + immutable: true, + index: true, + }, /** * Status of the check (true for up, false for down). * @@ -69,6 +76,8 @@ const CheckSchema = mongoose.Schema({ ...BaseCheckSchema.obj }, { timestamps: tr CheckSchema.index({ createdAt: 1 }); CheckSchema.index({ monitorId: 1, createdAt: 1 }); CheckSchema.index({ monitorId: 1, createdAt: -1 }); +CheckSchema.index({ teamId: 1, createdAt: -1 }); +CheckSchema.index({ teamId: 1 }); export default mongoose.model("Check", CheckSchema); export { BaseCheckSchema }; diff --git a/Server/db/mongo/modules/checkModule.js b/Server/db/mongo/modules/checkModule.js index 0a552012d..7965e7c30 100644 --- a/Server/db/mongo/modules/checkModule.js +++ b/Server/db/mongo/modules/checkModule.js @@ -2,11 +2,15 @@ import Check from "../../models/Check.js"; import Monitor from "../../models/Monitor.js"; import User from "../../models/User.js"; import logger from "../../../utils/logger.js"; +import { ObjectId } from "mongodb"; + const SERVICE_NAME = "checkModule"; const dateRangeLookup = { + hour: new Date(new Date().setHours(new Date().getHours() - 1)), day: new Date(new Date().setDate(new Date().getDate() - 1)), week: new Date(new Date().setDate(new Date().getDate() - 7)), month: new Date(new Date().setMonth(new Date().getMonth() - 1)), + all: undefined, }; /** @@ -56,41 +60,6 @@ const createCheck = async (checkData) => { } }; -const getChecksCount = async (req) => { - const monitorId = req.params.monitorId; - const dateRange = req.query.dateRange; - const filter = req.query.filter; - // Build query - const checksQuery = { monitorId: monitorId }; - // Filter checks by "day", "week", or "month" - if (dateRange !== undefined) { - checksQuery.createdAt = { $gte: dateRangeLookup[dateRange] }; - } - - if (filter !== undefined) { - checksQuery.status = false; - switch (filter) { - case "all": - break; - case "down": - break; - case "resolve": - checksQuery.statusCode = 5000; - break; - default: - logger.warn({ - message: "invalid filter", - service: SERVICE_NAME, - method: "getChecksCount", - }); - break; - } - } - - const count = await Check.countDocuments(checksQuery); - return count; -}; - /** * Get all checks for a monitor * @async @@ -98,33 +67,31 @@ const getChecksCount = async (req) => { * @returns {Promise>} * @throws {Error} */ - -const getChecks = async (req) => { +const getChecksByMonitor = async (req) => { try { const { monitorId } = req.params; - let { sortOrder, limit, dateRange, filter, page, rowsPerPage } = req.query; - // Default limit to 0 if not provided - limit = limit === undefined ? 0 : limit; + let { sortOrder, dateRange, filter, page, rowsPerPage } = req.query; + page = parseInt(page); + rowsPerPage = parseInt(rowsPerPage); + // Match + const matchStage = { + monitorId: ObjectId.createFromHexString(monitorId), + status: false, + ...(dateRangeLookup[dateRange] && { + createdAt: { + $gte: dateRangeLookup[dateRange], + }, + }), + }; - // Default sort order is newest -> oldest - sortOrder = sortOrder === "asc" ? 1 : -1; - - // Build query - const checksQuery = { monitorId: monitorId }; - // Filter checks by "day", "week", or "month" - if (dateRange !== undefined) { - checksQuery.createdAt = { $gte: dateRangeLookup[dateRange] }; - } - // Filter checks by status if (filter !== undefined) { - checksQuery.status = false; switch (filter) { case "all": break; case "down": break; case "resolve": - checksQuery.statusCode = 5000; + matchStage.statusCode = 5000; break; default: logger.warn({ @@ -136,16 +103,33 @@ const getChecks = async (req) => { } } - // Need to skip and limit here + //Sort + sortOrder = sortOrder === "asc" ? 1 : -1; + + // Pagination let skip = 0; if (page && rowsPerPage) { skip = page * rowsPerPage; } - const checks = await Check.find(checksQuery) - .skip(skip) - .limit(rowsPerPage) - .sort({ createdAt: sortOrder }); - return checks; + + const checks = await Check.aggregate([ + { $match: matchStage }, + { $sort: { createdAt: sortOrder } }, + { + $facet: { + summary: [{ $count: "checksCount" }], + checks: [{ $skip: skip }, { $limit: rowsPerPage }], + }, + }, + { + $project: { + checksCount: { $arrayElemAt: ["$summary.checksCount", 0] }, + checks: "$checks", + }, + }, + ]); + + return checks[0]; } catch (error) { error.service = SERVICE_NAME; error.method = "getChecks"; @@ -153,64 +137,71 @@ const getChecks = async (req) => { } }; -const getTeamChecks = async (req) => { +const getChecksByTeam = async (req) => { try { + let { sortOrder, dateRange, filter, page, rowsPerPage } = req.query; + page = parseInt(page); + rowsPerPage = parseInt(rowsPerPage); const { teamId } = req.params; - let { sortOrder, limit, dateRange, filter, page, rowsPerPage } = req.query; - - // Get monitorIDs - const userMonitors = await Monitor.find({ teamId: teamId }).select("_id"); - - //Build check query - // Default limit to 0 if not provided - limit = limit === undefined ? 0 : limit; - // Default sort order is newest -> oldest - sortOrder = sortOrder === "asc" ? 1 : -1; - - const checksQuery = { monitorId: { $in: userMonitors } }; - + const matchStage = { + teamId: ObjectId.createFromHexString(teamId), + status: false, + ...(dateRangeLookup[dateRange] && { + createdAt: { + $gte: dateRangeLookup[dateRange], + }, + }), + }; + // Add filter to match stage if (filter !== undefined) { - checksQuery.status = false; switch (filter) { case "all": break; case "down": - checksQuery.status = false; break; case "resolve": - checksQuery.statusCode = 5000; + matchStage.statusCode = 5000; break; default: logger.warn({ message: "invalid filter", service: SERVICE_NAME, - method: "getTeamChecks", + method: "getChecksByTeam", }); break; } } - if (dateRange !== undefined) { - checksQuery.createdAt = { $gte: dateRangeLookup[dateRange] }; - } + sortOrder = sortOrder === "asc" ? 1 : -1; - // Skip and limit for pagination + // pagination let skip = 0; if (page && rowsPerPage) { skip = page * rowsPerPage; } - const checksCount = await Check.countDocuments(checksQuery); + const checks = await Check.aggregate([ + { $match: matchStage }, + { $sort: { createdAt: sortOrder } }, - const checks = await Check.find(checksQuery) - .skip(skip) - .limit(rowsPerPage) - .sort({ createdAt: sortOrder }) - .select(["monitorId", "status", "responseTime", "statusCode", "message"]); - return { checksCount, checks }; + { + $facet: { + summary: [{ $count: "checksCount" }], + checks: [{ $skip: skip }, { $limit: rowsPerPage }], + }, + }, + { + $project: { + checksCount: { $arrayElemAt: ["$summary.checksCount", 0] }, + checks: "$checks", + }, + }, + ]); + + return checks[0]; } catch (error) { error.service = SERVICE_NAME; - error.method = "getTeamChecks"; + error.method = "getChecksByTeam"; throw error; } }; @@ -298,9 +289,8 @@ const updateChecksTTL = async (teamId, ttl) => { export { createCheck, - getChecksCount, - getChecks, - getTeamChecks, + getChecksByMonitor, + getChecksByTeam, deleteChecks, deleteChecksByTeamId, updateChecksTTL, diff --git a/Server/db/mongo/utils/seedDb.js b/Server/db/mongo/utils/seedDb.js new file mode 100644 index 000000000..cd4abb8d5 --- /dev/null +++ b/Server/db/mongo/utils/seedDb.js @@ -0,0 +1,57 @@ +import Monitor from "../../models/Monitor.js"; +import Check from "../../models/Check.js"; + +const generateRandomUrl = () => { + const domains = ["example.com", "test.org", "demo.net", "sample.io", "mock.dev"]; + const paths = ["api", "status", "health", "ping", "check"]; + return `https://${domains[Math.floor(Math.random() * domains.length)]}/${paths[Math.floor(Math.random() * paths.length)]}`; +}; + +const generateChecks = (monitorId, teamId, count) => { + const checks = []; + const endTime = new Date(Date.now() - 10 * 60 * 1000); // 10 minutes ago + const startTime = new Date(endTime - count * 60 * 1000); // count minutes before endTime + + for (let i = 0; i < count; i++) { + const timestamp = new Date(startTime.getTime() + i * 60 * 1000); + const status = Math.random() > 0.05; // 95% chance of being up + + checks.push({ + monitorId, + teamId, + status, + responseTime: Math.floor(Math.random() * 1000), // Random response time between 0-1000ms + createdAt: timestamp, + updatedAt: timestamp, + }); + } + + return checks; +}; + +const seedDb = async (userId, teamId) => { + try { + console.log("Deleting all monitors and checks"); + await Monitor.deleteMany({}); + await Check.deleteMany({}); + console.log("Adding monitors"); + for (let i = 0; i < 300; i++) { + const monitor = await Monitor.create({ + name: `Monitor ${i}`, + url: generateRandomUrl(), + type: "http", + userId, + teamId, + interval: 60000, + active: false, + }); + console.log(`Adding monitor and checks for monitor ${i}`); + const checks = generateChecks(monitor._id, teamId, 10000); + await Check.insertMany(checks); + } + } catch (error) { + console.error(error); + } +}; + +export default seedDb; diff --git a/Server/routes/checkRoute.js b/Server/routes/checkRoute.js index 289e0bc2f..bab45e4d4 100644 --- a/Server/routes/checkRoute.js +++ b/Server/routes/checkRoute.js @@ -11,7 +11,7 @@ class CheckRoutes { } initRoutes() { - this.router.get("/:monitorId", this.checkController.getChecks); + this.router.get("/:monitorId", this.checkController.getChecksByMonitor); this.router.post( "/:monitorId", verifyOwnership(Monitor, "monitorId"), @@ -23,7 +23,7 @@ class CheckRoutes { this.checkController.deleteChecks ); - this.router.get("/team/:teamId", this.checkController.getTeamChecks); + this.router.get("/team/:teamId", this.checkController.getChecksByTeam); this.router.delete( "/team/:teamId", diff --git a/Server/routes/monitorRoute.js b/Server/routes/monitorRoute.js index 92b529417..964bbee7a 100644 --- a/Server/routes/monitorRoute.js +++ b/Server/routes/monitorRoute.js @@ -75,6 +75,8 @@ class MonitorRoutes { isAllowed(["admin", "superadmin"]), this.monitorController.addDemoMonitors ); + + this.router.post("/seed", isAllowed(["superadmin"]), this.monitorController.seedDb); } getRouter() { diff --git a/Server/service/networkService.js b/Server/service/networkService.js index 03bd6fef9..54edf39f9 100644 --- a/Server/service/networkService.js +++ b/Server/service/networkService.js @@ -131,6 +131,7 @@ class NetworkService { const httpResponse = { monitorId: job.data._id, + teamId: job.data.teamId, type: job.data.type, responseTime, payload: response?.data, diff --git a/Server/service/statusService.js b/Server/service/statusService.js index 5138b73ce..cca443e9e 100644 --- a/Server/service/statusService.js +++ b/Server/service/statusService.js @@ -83,10 +83,11 @@ class StatusService { * @returns {Object} The check object. */ buildCheck = (networkResponse) => { - const { monitorId, type, status, responseTime, code, message, payload } = + const { monitorId, teamId, type, status, responseTime, code, message, payload } = networkResponse; const check = { monitorId, + teamId, status, statusCode: code, responseTime, diff --git a/Server/validation/joi.js b/Server/validation/joi.js index d30235048..8f366a113 100644 --- a/Server/validation/joi.js +++ b/Server/validation/joi.js @@ -131,7 +131,7 @@ const getMonitorByIdQueryValidation = joi.object({ status: joi.boolean(), sortOrder: joi.string().valid("asc", "desc"), limit: joi.number(), - dateRange: joi.string().valid("day", "week", "month"), + dateRange: joi.string().valid("hour", "day", "week", "month", "all"), numToDisplay: joi.number(), normalize: joi.boolean(), }); @@ -166,7 +166,7 @@ const getMonitorStatsByIdQueryValidation = joi.object({ status: joi.string(), limit: joi.number(), sortOrder: joi.string().valid("asc", "desc"), - dateRange: joi.string().valid("day", "week", "month", "all"), + dateRange: joi.string().valid("hour", "day", "week", "month", "all"), numToDisplay: joi.number(), normalize: joi.boolean(), }); @@ -217,7 +217,7 @@ const getHardwareDetailsByIdParamValidation = joi.object({ }); const getHardwareDetailsByIdQueryValidation = joi.object({ - dateRange: joi.string().valid("day", "week", "month"), + dateRange: joi.string().valid("hour", "day", "week", "month", "all"), }); //**************************************** @@ -288,7 +288,7 @@ const getChecksParamValidation = joi.object({ const getChecksQueryValidation = joi.object({ sortOrder: joi.string().valid("asc", "desc"), limit: joi.number(), - dateRange: joi.string().valid("day", "week", "month"), + dateRange: joi.string().valid("hour", "day", "week", "month", "all"), filter: joi.string().valid("all", "down", "resolve"), page: joi.number(), rowsPerPage: joi.number(), @@ -301,7 +301,7 @@ const getTeamChecksParamValidation = joi.object({ const getTeamChecksQueryValidation = joi.object({ sortOrder: joi.string().valid("asc", "desc"), limit: joi.number(), - dateRange: joi.string().valid("day", "week", "month"), + dateRange: joi.string().valid("hour", "day", "week", "month", "all"), filter: joi.string().valid("all", "down", "resolve"), page: joi.number(), rowsPerPage: joi.number(),