diff --git a/Client/src/Components/Charts/MonitorDetailsAreaChart/index.jsx b/Client/src/Components/Charts/MonitorDetailsAreaChart/index.jsx
index 567de0b68..91657f542 100644
--- a/Client/src/Components/Charts/MonitorDetailsAreaChart/index.jsx
+++ b/Client/src/Components/Charts/MonitorDetailsAreaChart/index.jsx
@@ -79,7 +79,6 @@ const MonitorDetailsAreaChart = ({ checks }) => {
MonitorDetailsAreaChart.propTypes = {
checks: PropTypes.array,
- filter: PropTypes.string,
};
CustomToolTip.propTypes = {
diff --git a/Client/src/Pages/Incidents/IncidentTable/index.jsx b/Client/src/Pages/Incidents/IncidentTable/index.jsx
new file mode 100644
index 000000000..bfcaed1e6
--- /dev/null
+++ b/Client/src/Pages/Incidents/IncidentTable/index.jsx
@@ -0,0 +1,125 @@
+import PropTypes from "prop-types";
+import {
+ TableContainer,
+ Table,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableBody,
+ TableFooter,
+ TablePagination,
+} from "@mui/material";
+
+import { useState, useEffect } from "react";
+import { useSelector } from "react-redux";
+import axiosInstance from "../../../Utils/axiosConfig";
+import { StatusLabel } from "../../../Components/Label";
+
+const IncidentTable = ({ monitorId, filter }) => {
+ const { authToken } = useSelector((state) => state.auth);
+ const [checks, setChecks] = useState([]);
+ const [checksCount, setChecksCount] = useState(0);
+ const [paginationController, setPaginationController] = useState({
+ page: 0,
+ rowsPerPage: 5,
+ });
+
+ useEffect(() => {
+ const fetchPage = async () => {
+ try {
+ if (monitorId === "0") {
+ return;
+ }
+ const res = await axiosInstance.get(
+ `/checks/${monitorId}?sortOrder=desc&filter=${filter}&page=${paginationController.page}&rowsPerPage=${paginationController.rowsPerPage}`,
+ {
+ headers: {
+ Authorization: `Bearer ${authToken}`,
+ },
+ }
+ );
+ setChecks(res.data.data.checks);
+ setChecksCount(res.data.data.checksCount);
+ } catch (error) {
+ console.log(error);
+ }
+ };
+ fetchPage();
+ }, [
+ authToken,
+ monitorId,
+ filter,
+ paginationController.page,
+ paginationController.rowsPerPage,
+ ]);
+
+ const handlePageChange = (_, newPage) => {
+ setPaginationController({
+ ...paginationController,
+ page: newPage,
+ });
+ };
+
+ const handleChangeRowsPerPage = (event) => {
+ setPaginationController({
+ ...paginationController,
+ rowsPerPage: parseInt(event.target.value, 10),
+ page: 0,
+ });
+ };
+
+ return (
+
+
+
+
+ Monitor Name
+ Status
+ Date & Time
+ Message
+
+
+
+ {checks.map((check) => {
+ const status = check.status === true ? "up" : "down";
+
+ return (
+
+
+
+
+
+ {new Date(check.createdAt).toLocaleString()}
+
+ {check.statusCode}
+
+ );
+ })}
+
+
+
+
+
+
+
+
+ );
+};
+
+IncidentTable.propTypes = {
+ monitorId: PropTypes.string.isRequired,
+ filter: PropTypes.string.isRequired,
+};
+
+export default IncidentTable;
diff --git a/Client/src/Pages/Incidents/index.jsx b/Client/src/Pages/Incidents/index.jsx
index d150b11ad..45237a0d1 100644
--- a/Client/src/Pages/Incidents/index.jsx
+++ b/Client/src/Pages/Incidents/index.jsx
@@ -9,7 +9,7 @@ import { StatusLabel } from "../../Components/Label";
import { useTheme } from "@emotion/react";
import { useNavigate } from "react-router";
import Select from "../../Components/Inputs/Select";
-
+import IncidentTable from "./IncidentTable";
import "./index.css";
/**
@@ -76,99 +76,142 @@ const Incidents = () => {
fetchMonitors();
}, [authState]);
+ useEffect(() => {}, []);
+
const handleSelect = (event) => {
setSelectedMonitor(event.target.value);
};
return (
- <>
-
- {loading ? (
-
- ) : false ? (
- <>
-
- Incident history for:
-
- {hasAnyIncidents && hasSpecificIncidents && (
-
-
- )}
-
- {hasAnyIncidents && hasSpecificIncidents ? (
- thing
- ) : (
-
- The monitor you have selected, has no recorded incidents yet.
-
- )}
- >
- ) : (
-
- }
- onClick={() => navigate(-1)}
- sx={{
- backgroundColor: theme.palette.otherColors.fillGray,
- px: theme.gap.ml,
- mb: theme.gap.ml,
- "& svg.MuiSvgIcon-root": {
- mr: theme.gap.small,
- fill: theme.palette.otherColors.slateGray,
- },
- }}
- />
-
- No incidents, yet.
-
-
- )}
+
+
+
+
+ setFilter("all")}
+ sx={{
+ backgroundColor:
+ filter === "all" && theme.palette.otherColors.fillGray,
+ }}
+ />
+ setFilter("down")}
+ sx={{
+ backgroundColor:
+ filter === "down" && theme.palette.otherColors.fillGray,
+ }}
+ />
+ setFilter("resolve")}
+ sx={{
+ backgroundColor:
+ filter === "resolve" && theme.palette.otherColors.fillGray,
+ }}
+ />
+
- >
+
+
+ // <>
+ //
+ // {loading ? (
+ //
+ // ) : false ? (
+ // <>
+ //
+ // Incident history for:
+ //
+ // {hasAnyIncidents && hasSpecificIncidents && (
+ //
+ // setFilter("all")}
+ // sx={{
+ // backgroundColor:
+ // filter === "all" && theme.palette.otherColors.fillGray,
+ // }}
+ // />
+ // setFilter("down")}
+ // sx={{
+ // backgroundColor:
+ // filter === "down" && theme.palette.otherColors.fillGray,
+ // }}
+ // />
+ // setFilter("resolve")}
+ // sx={{
+ // backgroundColor:
+ // filter === "resolve" &&
+ // theme.palette.otherColors.fillGray,
+ // }}
+ // />
+ //
+ // )}
+ //
+ // {hasAnyIncidents && hasSpecificIncidents ? (
+ // thing
+ // ) : (
+ //
+ // The monitor you have selected, has no recorded incidents yet.
+ //
+ // )}
+ // >
+ // ) : (
+ //
+ // }
+ // onClick={() => navigate(-1)}
+ // sx={{
+ // backgroundColor: theme.palette.otherColors.fillGray,
+ // px: theme.gap.ml,
+ // mb: theme.gap.ml,
+ // "& svg.MuiSvgIcon-root": {
+ // mr: theme.gap.small,
+ // fill: theme.palette.otherColors.slateGray,
+ // },
+ // }}
+ // />
+ //
+ // No incidents, yet.
+ //
+ //
+ // )}
+ //
+ // >
);
};
diff --git a/Client/src/Pages/Monitors/Details/PaginationTable/index.jsx b/Client/src/Pages/Monitors/Details/PaginationTable/index.jsx
index 5f0f8a690..71183c366 100644
--- a/Client/src/Pages/Monitors/Details/PaginationTable/index.jsx
+++ b/Client/src/Pages/Monitors/Details/PaginationTable/index.jsx
@@ -15,7 +15,7 @@ import { useSelector } from "react-redux";
import axiosInstance from "../../../../Utils/axiosConfig";
import { StatusLabel } from "../../../../Components/Label";
-const PaginationTable = ({ monitorId, filter }) => {
+const PaginationTable = ({ monitorId, dateRange }) => {
const { authToken } = useSelector((state) => state.auth);
const [checks, setChecks] = useState([]);
const [checksCount, setChecksCount] = useState(0);
@@ -28,7 +28,7 @@ const PaginationTable = ({ monitorId, filter }) => {
const fetchPage = async () => {
try {
const res = await axiosInstance.get(
- `/checks/${monitorId}?sortOrder=desc&filter=${filter}&page=${paginationController.page}&rowsPerPage=${paginationController.rowsPerPage}`,
+ `/checks/${monitorId}?sortOrder=desc&dateRange=${dateRange}&page=${paginationController.page}&rowsPerPage=${paginationController.rowsPerPage}`,
{
headers: {
Authorization: `Bearer ${authToken}`,
@@ -45,7 +45,7 @@ const PaginationTable = ({ monitorId, filter }) => {
}, [
authToken,
monitorId,
- filter,
+ dateRange,
paginationController.page,
paginationController.rowsPerPage,
]);
@@ -115,7 +115,7 @@ const PaginationTable = ({ monitorId, filter }) => {
PaginationTable.propTypes = {
monitorId: PropTypes.string.isRequired,
- filter: PropTypes.string.isRequired,
+ dateRange: PropTypes.string.isRequired,
};
export default PaginationTable;
diff --git a/Client/src/Pages/Monitors/Details/index.jsx b/Client/src/Pages/Monitors/Details/index.jsx
index 55dfd9335..4168880d5 100644
--- a/Client/src/Pages/Monitors/Details/index.jsx
+++ b/Client/src/Pages/Monitors/Details/index.jsx
@@ -113,13 +113,13 @@ const DetailsPage = () => {
const [monitor, setMonitor] = useState({});
const { monitorId } = useParams();
const { authToken } = useSelector((state) => state.auth);
- const [filter, setFilter] = useState("day");
+ const [dateRange, setDateRange] = useState("day");
const navigate = useNavigate();
const fetchMonitor = useCallback(async () => {
try {
const res = await axiosInstance.get(
- `/monitors/${monitorId}?sortOrder=asc&filter=${filter}&numToDisplay=50&normalize=true`,
+ `/monitors/${monitorId}?sortOrder=asc&filter=${dateRange}&numToDisplay=50&normalize=true`,
{
headers: {
Authorization: `Bearer ${authToken}`,
@@ -131,7 +131,7 @@ const DetailsPage = () => {
console.error("Error fetching monitor of id: " + monitorId);
navigate("/not-found");
}
- }, [authToken, monitorId, navigate, filter]);
+ }, [authToken, monitorId, navigate, dateRange]);
useEffect(() => {
fetchMonitor();
@@ -301,44 +301,43 @@ const DetailsPage = () => {
setFilter("day")}
+ onClick={() => setDateRange("day")}
sx={{
backgroundColor:
- filter === "day" && theme.palette.otherColors.fillGray,
+ dateRange === "day" &&
+ theme.palette.otherColors.fillGray,
}}
/>
setFilter("week")}
+ onClick={() => setDateRange("week")}
sx={{
backgroundColor:
- filter === "week" && theme.palette.otherColors.fillGray,
+ dateRange === "week" &&
+ theme.palette.otherColors.fillGray,
}}
/>
setFilter("month")}
+ onClick={() => setDateRange("month")}
sx={{
backgroundColor:
- filter === "month" &&
+ dateRange === "month" &&
theme.palette.otherColors.fillGray,
}}
/>
-
+
History
{/* TODO New Table */}
-
+
{/* */}
diff --git a/Server/db/mongo/modules/checkModule.js b/Server/db/mongo/modules/checkModule.js
index f2322150a..fc75ea083 100644
--- a/Server/db/mongo/modules/checkModule.js
+++ b/Server/db/mongo/modules/checkModule.js
@@ -1,11 +1,12 @@
const Check = require("../../../models/Check");
const Monitor = require("../../../models/Monitor");
const mongoose = require("mongoose");
-const filterLookup = {
+const dateRangeLookup = {
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)),
};
+
/**
* Create a check for a monitor
* @async
@@ -35,7 +36,7 @@ const getChecksCount = async (req) => {
const checksQuery = { monitorId: monitorId };
// Filter checks by "day", "week", or "month"
if (filter !== undefined) {
- checksQuery.createdAt = { $gte: filterLookup[filter] };
+ checksQuery.createdAt = { $gte: dateRangeLookup[filter] };
}
const count = await Check.countDocuments(checksQuery);
return count;
@@ -52,8 +53,8 @@ const getChecksCount = async (req) => {
const getChecks = async (req) => {
try {
const { monitorId } = req.params;
- let { sortOrder, limit, filter, page, rowsPerPage } = req.query;
-
+ let { sortOrder, limit, dateRange, filter, page, rowsPerPage } = req.query;
+ console.log(filter);
// Default limit to 0 if not provided
if (limit === undefined) limit = 0;
@@ -67,8 +68,12 @@ const getChecks = async (req) => {
// Build query
const checksQuery = { monitorId: monitorId };
// Filter checks by "day", "week", or "month"
+ if (dateRange !== undefined) {
+ checksQuery.createdAt = { $gte: dateRangeLookup[dateRange] };
+ }
+ // Fitler checks by status
if (filter !== undefined) {
- checksQuery.createdAt = { $gte: filterLookup[filter] };
+ checksQuery.status = false;
}
// Need to skip and limit here
diff --git a/Server/validation/joi.js b/Server/validation/joi.js
index f938fabd9..0109a660b 100644
--- a/Server/validation/joi.js
+++ b/Server/validation/joi.js
@@ -235,7 +235,8 @@ const getChecksParamValidation = joi.object({
const getChecksQueryValidation = joi.object({
sortOrder: joi.string().valid("asc", "desc"),
limit: joi.number(),
- filter: joi.string().valid("day", "week", "month"),
+ dateRange: joi.string().valid("day", "week", "month"),
+ filter: joi.string().valid("all", "down", "resolve"),
page: joi.number(),
rowsPerPage: joi.number(),
});