diff --git a/client/src/Pages/Checks/Components/IncidentTable/index.jsx b/client/src/Pages/Checks/Components/IncidentTable/index.jsx
deleted file mode 100644
index bac2a00cb..000000000
--- a/client/src/Pages/Checks/Components/IncidentTable/index.jsx
+++ /dev/null
@@ -1,233 +0,0 @@
-//Components
-import Stack from "@mui/material/Stack";
-import DataTable from "@/Components/v1/Table/index.jsx";
-import Table from "@mui/material/Table";
-import TableBody from "@mui/material/TableBody";
-import TableRow from "@mui/material/TableRow";
-import TableCell from "@mui/material/TableCell";
-import TableSkeleton from "@/Components/v1/Table/skeleton.jsx";
-import Pagination from "@/Components/v1/Table/TablePagination/index.jsx";
-import { StatusLabel } from "@/Components/v1/Label/index.jsx";
-import { HttpStatusLabel } from "@/Components/v1/HttpStatusLabel/index.jsx";
-import GenericFallback from "@/Components/v1/GenericFallback/index.jsx";
-import NetworkError from "@/Components/v1/GenericFallback/NetworkError.jsx";
-
-//Utils
-import { formatDateWithTz } from "@/Utils/timeUtilsLegacy.js";
-import { useSelector } from "react-redux";
-import { useState } from "react";
-import PropTypes from "prop-types";
-import { useTranslation } from "react-i18next";
-import { useFetchChecksTeam, useFetchChecksByMonitor } from "@/Hooks/checkHooks.js";
-import { Typography, useTheme } from "@mui/material";
-import { lighten } from "@mui/material/styles";
-
-const GetTooltip = (row) => {
- const theme = useTheme();
- const phases = row?.timings?.phases;
-
- const phaseKeyFormattingMap = {
- firstByte: "first byte",
- };
- return (
-
- {`Status code: ${row?.statusCode}`}
- {`Response time: ${row?.responseTime} ms`}
- {phases && (
- <>
- {`Request timing: `}
-
-
- {Object.keys(phases)?.map((phaseKey) => (
-
-
-
- {`${phaseKeyFormattingMap[phaseKey] || phaseKey}:`}
-
-
-
- {`${phases[phaseKey]} ms`}
-
-
- ))}
-
-
- >
- )}
-
- );
-};
-
-const IncidentTable = ({
- isLoading,
- monitors,
- selectedMonitor,
- filter,
- dateRange,
- updateTrigger,
-}) => {
- //Redux state
- const uiTimezone = useSelector((state) => state.ui.timezone);
-
- //Local state
- const [page, setPage] = useState(0);
- const [rowsPerPage, setRowsPerPage] = useState(10);
- const selectedMonitorDetails = monitors?.[selectedMonitor];
- const selectedMonitorType = selectedMonitorDetails?.type;
-
- //Hooks
- const [checksMonitor, checksCountMonitor, isLoadingMonitor, networkErrorMonitor] =
- useFetchChecksByMonitor({
- monitorId: selectedMonitor === "0" ? undefined : selectedMonitor,
- type: selectedMonitorType,
- status: false,
- sortOrder: "desc",
- limit: null,
- dateRange,
- filter: filter === "resolved" ? "all" : filter,
- ack: filter === "resolved" ? true : false,
- page: page,
- rowsPerPage: rowsPerPage,
- enabled: selectedMonitor !== "0",
- updateTrigger,
- });
-
- const [checksTeam, checksCountTeam, isLoadingTeam, networkErrorTeam] =
- useFetchChecksTeam({
- status: false,
- sortOrder: "desc",
- limit: null,
- dateRange,
- filter: filter === "resolved" ? "all" : filter,
- ack: filter === "resolved" ? true : false,
- page: page,
- rowsPerPage: rowsPerPage,
- enabled: selectedMonitor === "0",
- updateTrigger,
- });
-
- const checks = selectedMonitor === "0" ? checksTeam : checksMonitor;
- const checksCount = selectedMonitor === "0" ? checksCountTeam : checksCountMonitor;
- isLoading = isLoadingTeam || isLoadingMonitor;
- const networkError = selectedMonitor === "0" ? networkErrorTeam : networkErrorMonitor;
-
- const { t } = useTranslation();
-
- //Handlers
- const handleChangePage = (_, newPage) => {
- setPage(newPage);
- };
-
- const handleChangeRowsPerPage = (event) => {
- setRowsPerPage(event.target.value);
- };
-
- const headers = [
- {
- id: "monitorName",
- content: t("incidentsTableMonitorName"),
- render: (row) => {
- return monitors?.[row.metadata?.monitorId]?.name || "N/A";
- },
- },
- {
- id: "status",
- content: t("incidentsTableStatus"),
- render: (row) => {
- const status = row.status === true ? "up" : "down";
- return (
-
- );
- },
- },
- {
- id: "dateTime",
- content: t("incidentsTableDateTime"),
- render: (row) => {
- const formattedDate = formatDateWithTz(
- row.createdAt,
- "YYYY-MM-DD HH:mm:ss A",
- uiTimezone
- );
- return formattedDate;
- },
- },
- {
- id: "statusCode",
- content: t("incidentsTableStatusCode"),
- render: (row) => ,
- },
- { id: "message", content: t("incidentsTableMessage"), render: (row) => row.message },
- ];
-
- if (isLoading) return ;
-
- if (networkError) {
- return (
-
-
-
- );
- }
-
- if (!isLoading && typeof checksCount === "undefined") {
- return {t("incidentsTableNoIncidents")};
- }
-
- return (
- <>
-
-
- >
- );
-};
-
-IncidentTable.propTypes = {
- isLoading: PropTypes.bool,
- monitors: PropTypes.object,
- selectedMonitor: PropTypes.string,
- filter: PropTypes.string,
- dateRange: PropTypes.string,
- updateTrigger: PropTypes.bool,
- setUpdateTrigger: PropTypes.func,
-};
-export default IncidentTable;
diff --git a/client/src/Pages/Checks/Components/OptionsHeader/index.jsx b/client/src/Pages/Checks/Components/OptionsHeader/index.jsx
deleted file mode 100644
index e04236a9b..000000000
--- a/client/src/Pages/Checks/Components/OptionsHeader/index.jsx
+++ /dev/null
@@ -1,139 +0,0 @@
-// Components
-import { Stack, Typography, Button, ButtonGroup } from "@mui/material";
-import Select from "@/Components/v1/Inputs/Select/index.jsx";
-import PropTypes from "prop-types";
-
-//Utils
-import { useTheme } from "@emotion/react";
-import SkeletonLayout from "./skeleton.jsx";
-import { useTranslation } from "react-i18next";
-
-const OptionsHeader = ({
- shouldRender,
- selectedMonitor = 0,
- setSelectedMonitor,
- monitors,
- filter = "all",
- setFilter,
- dateRange = "hour",
- setDateRange,
-}) => {
- const theme = useTheme();
- const { t } = useTranslation();
- const monitorNames = typeof monitors !== "undefined" ? Object.values(monitors) : [];
- const filterOptions = [
- { id: "all", name: t("incidentsOptionsHeaderFilterAll") },
- { id: "down", name: t("incidentsOptionsHeaderFilterDown") },
- { id: "resolve", name: t("incidentsOptionsHeaderFilterCannotResolve") },
- { id: "resolved", name: t("incidentsOptionsHeaderFilterResolved") },
- ];
-
- // The stacks below which are three in number have the same style so
- const stackStyles = {
- direction: "row",
- alignItems: "center",
- gap: theme.spacing(6),
- };
-
- if (!shouldRender) return ;
-
- return (
-
-
-
- {t("incidentsOptionsHeader")}
-
-
-
-
- {t("incidentsOptionsHeaderFilterBy")}
-
-
-
-
- {t("incidentsOptionsHeaderShow")}
-
-
-
-
-
-
-
-
-
- );
-};
-
-OptionsHeader.propTypes = {
- shouldRender: PropTypes.bool,
- selectedMonitor: PropTypes.string,
- setSelectedMonitor: PropTypes.func,
- monitors: PropTypes.object,
- filter: PropTypes.string,
- setFilter: PropTypes.func,
- dateRange: PropTypes.string,
- setDateRange: PropTypes.func,
-};
-
-export default OptionsHeader;
diff --git a/client/src/Pages/Checks/Components/OptionsHeader/skeleton.jsx b/client/src/Pages/Checks/Components/OptionsHeader/skeleton.jsx
deleted file mode 100644
index 8a8990dc4..000000000
--- a/client/src/Pages/Checks/Components/OptionsHeader/skeleton.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Stack, Skeleton } from "@mui/material";
-
-const SkeletonLayout = () => {
- return (
-
-
-
- );
-};
-
-export default SkeletonLayout;
diff --git a/client/src/Pages/Checks/Components/StatusBoxes/StatusBox.jsx b/client/src/Pages/Checks/Components/StatusBoxes/StatusBox.jsx
deleted file mode 100644
index d7f02ada3..000000000
--- a/client/src/Pages/Checks/Components/StatusBoxes/StatusBox.jsx
+++ /dev/null
@@ -1,129 +0,0 @@
-import PropTypes from "prop-types";
-import { useTheme } from "@emotion/react";
-import { Box, Stack, Typography } from "@mui/material";
-import Background from "@/assets/Images/background-grid.svg?react";
-import Icon from "@/Components/v1/Icon";
-
-const StatusBox = ({ title, value, status }) => {
- const theme = useTheme();
- let sharedStyles = {
- position: "absolute",
- right: 8,
- "& svg": {
- width: 20,
- height: 20,
- opacity: 0.9,
- "& path": { stroke: theme.palette.primary.contrastTextTertiary, strokeWidth: 1.7 },
- },
- };
-
- let color;
- let icon;
- if (status === "up") {
- color = theme.palette.success.lowContrast;
- icon = (
-
-
-
- );
- } else if (status === "down") {
- color = theme.palette.error.lowContrast;
- icon = (
-
-
-
- );
- } else if (status === "paused") {
- color = theme.palette.warning.lowContrast;
- icon = (
-
-
-
- );
- } else {
- color = theme.palette.accent.main;
- icon = (
-
-
-
- );
- }
-
- return (
-
-
-
-
-
-
-
- {title}
-
- {icon}
-
-
- {value}
-
-
- #
-
-
-
-
- );
-};
-
-StatusBox.propTypes = {
- title: PropTypes.string.isRequired,
- value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
- status: PropTypes.string,
-};
-
-export default StatusBox;
diff --git a/client/src/Pages/Checks/Components/StatusBoxes/index.jsx b/client/src/Pages/Checks/Components/StatusBoxes/index.jsx
deleted file mode 100644
index bb993111a..000000000
--- a/client/src/Pages/Checks/Components/StatusBoxes/index.jsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import PropTypes from "prop-types";
-import { Stack } from "@mui/material";
-import StatusBox from "./StatusBox.jsx";
-import { useTheme } from "@emotion/react";
-import { useTranslation } from "react-i18next";
-import SkeletonLayout from "./skeleton.jsx";
-
-const StatusBoxes = ({ isLoading, summary }) => {
- const theme = useTheme();
- const { t } = useTranslation();
- if (isLoading) return ;
- return (
-
-
-
-
-
-
- );
-};
-
-StatusBoxes.propTypes = {
- isLoading: PropTypes.bool,
- summary: PropTypes.object,
-};
-
-export default StatusBoxes;
diff --git a/client/src/Pages/Checks/Components/StatusBoxes/skeleton.jsx b/client/src/Pages/Checks/Components/StatusBoxes/skeleton.jsx
deleted file mode 100644
index b9aa016b7..000000000
--- a/client/src/Pages/Checks/Components/StatusBoxes/skeleton.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Skeleton, Stack } from "@mui/material";
-import { useTheme } from "@emotion/react";
-
-const SkeletonLayout = () => {
- const theme = useTheme();
- return (
-
-
-
-
-
-
- );
-};
-
-export default SkeletonLayout;
diff --git a/client/src/Pages/Checks/old.jsx b/client/src/Pages/Checks/old.jsx
deleted file mode 100644
index bcd036a58..000000000
--- a/client/src/Pages/Checks/old.jsx
+++ /dev/null
@@ -1,100 +0,0 @@
-// Components
-import { Stack } from "@mui/material";
-import Breadcrumbs from "@/Components/v1/Breadcrumbs/index.jsx";
-import GenericFallback from "@/Components/v1/GenericFallback/index.jsx";
-import IncidentTable from "./Components/IncidentTable/index.jsx";
-import OptionsHeader from "./Components/OptionsHeader/index.jsx";
-import StatusBoxes from "./Components/StatusBoxes/index.jsx";
-
-//Utils
-import { useTheme } from "@emotion/react";
-import { useFetchMonitorsByTeamId } from "@/Hooks/monitorHooks.js";
-import { useFetchChecksSummaryByTeamId } from "@/Hooks/checkHooks.js";
-import { useState, useEffect } from "react";
-import NetworkError from "@/Components/v1/GenericFallback/NetworkError.jsx";
-import { useTranslation } from "react-i18next";
-import { useParams } from "react-router-dom";
-
-//Constants
-const Checks = () => {
- // Redux state
- const { t } = useTranslation();
-
- const BREADCRUMBS = [{ name: t("checksPageTitle"), path: "/checks" }];
-
- // Local state
- const [selectedMonitor, setSelectedMonitor] = useState("0");
- const [filter, setFilter] = useState(undefined);
- const [dateRange, setDateRange] = useState("hour");
- const [monitorLookup, setMonitorLookup] = useState(undefined);
- const [updateTrigger, setUpdateTrigger] = useState(false);
-
- //Hooks
-
- //Utils
- const theme = useTheme();
- const [monitors, , isLoading, networkError] = useFetchMonitorsByTeamId({});
- const [summary, isLoadingSummary, networkErrorSummary] = useFetchChecksSummaryByTeamId({
- dateRange,
- updateTrigger,
- });
- const { monitorId } = useParams();
-
- useEffect(() => {
- if (monitorId) {
- setSelectedMonitor(monitorId);
- }
- }, [monitorId]);
-
- useEffect(() => {
- const monitorLookup = monitors?.reduce((acc, monitor) => {
- acc[monitor.id] = {
- id: monitor.id,
- name: monitor.name,
- type: monitor.type,
- };
- return acc;
- }, {});
- setMonitorLookup(monitorLookup);
- }, [monitors]);
-
- if (networkError || networkErrorSummary) {
- return (
-
-
-
- );
- }
-
- return (
-
-
-
-
-
-
-
- );
-};
-
-export default Checks;
diff --git a/server/src/repositories/checks/MongoChecksRepistory.ts b/server/src/repositories/checks/MongoChecksRepistory.ts
index 7916e2c06..e4fe01412 100644
--- a/server/src/repositories/checks/MongoChecksRepistory.ts
+++ b/server/src/repositories/checks/MongoChecksRepistory.ts
@@ -200,8 +200,28 @@ class MongoChecksRepository implements IChecksRepository {
return documents.map((doc) => this.toEntity(doc));
};
+ private toDocument = (check: Partial): CheckDocument => {
+ // Map id to _id for MongoDB storage
+ const { id, metadata, ...rest } = check;
+ return {
+ _id: id ? new mongoose.Types.ObjectId(id) : new mongoose.Types.ObjectId(),
+ metadata: metadata ? {
+ monitorId: new mongoose.Types.ObjectId(metadata.monitorId),
+ teamId: new mongoose.Types.ObjectId(metadata.teamId),
+ type: metadata.type,
+ } : {
+ monitorId: new mongoose.Types.ObjectId(),
+ teamId: new mongoose.Types.ObjectId(),
+ type: "http",
+ },
+ ...rest,
+ } as unknown as CheckDocument;
+ };
+
createChecks = async (checks: Check[]) => {
- return await CheckModel.insertMany(checks);
+ const docs = checks.map((check) => this.toDocument(check));
+ const inserted = await CheckModel.insertMany(docs);
+ return this.mapDocuments(inserted as unknown as CheckDocument[]);
};
findByMonitorId = async (