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..d16c23733 --- /dev/null +++ b/Client/src/Pages/Incidents/IncidentTable/index.jsx @@ -0,0 +1,142 @@ +import PropTypes from "prop-types"; +import { + TableContainer, + Table, + TableHead, + TableRow, + TableCell, + TableBody, + Pagination, + PaginationItem, + Paper, +} 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 axiosInstance from "../../../Utils/axiosConfig"; +import { StatusLabel } from "../../../Components/Label"; + +const IncidentTable = ({ monitors, selectedMonitor, filter }) => { + const { authToken, user } = useSelector((state) => state.auth); + const [checks, setChecks] = useState([]); + const [checksCount, setChecksCount] = useState(0); + const [paginationController, setPaginationController] = useState({ + page: 0, + rowsPerPage: 12, + }); + + useEffect(() => { + const fetchPage = async () => { + try { + let url = `/checks/${selectedMonitor}?sortOrder=desc&filter=${filter}&page=${paginationController.page}&rowsPerPage=${paginationController.rowsPerPage}`; + + if (selectedMonitor === "0") { + url = `/checks/user/${user._id}?sortOrder=desc&filter=${filter}&page=${paginationController.page}&rowsPerPage=${paginationController.rowsPerPage}`; + } + + const res = await axiosInstance.get(url, { + headers: { + Authorization: `Bearer ${authToken}`, + }, + }); + setChecks(res.data.data.checks); + setChecksCount(res.data.data.checksCount); + } catch (error) { + console.log(error); + } + }; + fetchPage(); + }, [ + authToken, + user, + selectedMonitor, + filter, + paginationController.page, + paginationController.rowsPerPage, + ]); + + const handlePageChange = (_, newPage) => { + console.log(newPage); + setPaginationController({ + ...paginationController, + page: newPage - 1, // 0-indexed + }); + }; + + let paginationComponent = <>; + if (checksCount > paginationController.rowsPerPage) { + paginationComponent = ( + ( + + )} + /> + ); + } + + return ( + <> + + + + + Monitor Name + Status + Date & Time + Message + + + + {checks.map((check) => { + const status = check.status === true ? "up" : "down"; + + return ( + + {monitors[check.monitorId]?.name} + + + + + {new Date(check.createdAt).toLocaleString()} + + {check.statusCode} + + ); + })} + +
+
+ {paginationComponent} + + ); +}; + +IncidentTable.propTypes = { + monitors: PropTypes.object.isRequired, + selectedMonitor: PropTypes.string.isRequired, + filter: PropTypes.string.isRequired, +}; + +export default IncidentTable; diff --git a/Client/src/Pages/Incidents/index.css b/Client/src/Pages/Incidents/index.css index 1b1d2f364..1f176d470 100644 --- a/Client/src/Pages/Incidents/index.css +++ b/Client/src/Pages/Incidents/index.css @@ -14,6 +14,9 @@ height: 34px; border-color: var(--env-var-color-16); } +.incidents .MuiPagination-root { + background-color: var(--env-var-color-8); +} /* remove later */ .incidents .MuiSelect-select { diff --git a/Client/src/Pages/Incidents/index.jsx b/Client/src/Pages/Incidents/index.jsx index 4c328a364..515f8ec0c 100644 --- a/Client/src/Pages/Incidents/index.jsx +++ b/Client/src/Pages/Incidents/index.jsx @@ -1,15 +1,11 @@ import { useState, useEffect } from "react"; import { useSelector } from "react-redux"; -import { Typography, ButtonGroup, Stack, Box, Skeleton } from "@mui/material"; -import WestRoundedIcon from "@mui/icons-material/WestRounded"; +import { ButtonGroup, Stack, Skeleton, Typography } from "@mui/material"; import Button from "../../Components/Button"; import axiosInstance from "../../Utils/axiosConfig"; -import BasicTable from "../../Components/BasicTable"; -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"; /** @@ -40,8 +36,8 @@ const SkeletonLayout = () => { const Incidents = () => { const theme = useTheme(); - const navigate = useNavigate(); const authState = useSelector((state) => state.auth); + const [monitors, setMonitors] = useState({}); const [selectedMonitor, setSelectedMonitor] = useState("0"); const [loading, setLoading] = useState(false); @@ -49,21 +45,11 @@ const Incidents = () => { // TODO do something with these filters const [filter, setFilter] = useState("all"); - let data = { - cols: [ - { id: 1, name: "Status" }, - { id: 2, name: "Timestamp" }, - { id: 3, name: "Monitor" }, - { id: 4, name: "Message" }, - ], - rows: [], - }; - useEffect(() => { - const fetchIncidents = async () => { + const fetchMonitors = async () => { setLoading(true); const res = await axiosInstance.get( - `/monitors/user/${authState.user._id}?status=false`, + `/monitors/user/${authState.user._id}?status=false&limit=1`, { headers: { Authorization: `Bearer ${authState.authToken}`, @@ -82,141 +68,70 @@ const Incidents = () => { setLoading(false); }; - fetchIncidents(); + fetchMonitors(); }, [authState]); + useEffect(() => {}, []); + const handleSelect = (event) => { setSelectedMonitor(event.target.value); }; - let incidents = []; - let hasAnyIncidents = false; - let hasSpecificIncidents = false; - if (selectedMonitor === "0") { - Object.values(monitors).forEach((monitor) => { - incidents = incidents.concat(monitor.checks); - }); - if (incidents.length !== 0) hasAnyIncidents = true; - hasSpecificIncidents = hasAnyIncidents; - } else { - const monitor = monitors[selectedMonitor]; - incidents = monitor.checks; - if (incidents.length !== 0) hasSpecificIncidents = true; - hasAnyIncidents = true; - } - incidents = incidents - .sort((a, b) => { - return new Date(b.createdAt) - new Date(a.createdAt); - }) - .filter((incident) => { - if (filter === "all") return true; - else if (filter === "resolve") return incident.statusCode === 5000; - else if (filter === "down") return incident.status === false; - }) - .map((incident, idx) => { - return { - id: idx, - data: [ - { - id: idx + 0, - data: , - }, - { id: idx + 1, data: new Date(incident.createdAt).toLocaleString() }, - { id: idx + 2, data: monitors[incident.monitorId].name }, - { id: idx + 3, data: incident.statusCode }, - ], - }; - }); - data.rows = incidents; return ( - <> - - {loading ? ( - - ) : hasAnyIncidents ? ( - <> - - Incident history for: - - - No incidents, yet. - - - )} - - + +