Skip to content

Commit

Permalink
Merge pull request #1664 from bluewave-labs/fix/incidents-refactor
Browse files Browse the repository at this point in the history
fix: incidents refactor
  • Loading branch information
ajhollid authored Jan 30, 2025
2 parents 1b26726 + 02d93fd commit 481196b
Show file tree
Hide file tree
Showing 19 changed files with 523 additions and 515 deletions.
20 changes: 20 additions & 0 deletions Client/src/Components/GenericFallback/NetworkError.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Typography } from "@mui/material";
import { useTheme } from "@emotion/react";

const NetworkError = () => {
const theme = useTheme();
return (
<>
<Typography
variant="h1"
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
Network error
</Typography>
<Typography>Please check your connection</Typography>
</>
);
};

export default NetworkError;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useTheme } from "@emotion/react";
import { Box, Stack, Typography } from "@mui/material";
import { Box, Stack } from "@mui/material";
import Skeleton from "../../assets/Images/create-placeholder.svg?react";
import SkeletonDark from "../../assets/Images/create-placeholder-dark.svg?react";
import Background from "../../assets/Images/background-grid.svg?react";
Expand All @@ -11,13 +11,13 @@ import { useSelector } from "react-redux";
* @returns {JSX.Element} The rendered fallback UI.
*/

const NetworkErrorFallback = () => {
const GenericFallback = ({ children }) => {
const theme = useTheme();
const mode = useSelector((state) => state.ui.mode);

return (
<Box
className="page-speed"
padding={theme.spacing(16)}
position="relative"
border={1}
borderColor={theme.palette.primary.lowContrast}
Expand Down Expand Up @@ -68,18 +68,11 @@ const NetworkErrorFallback = () => {
maxWidth={"300px"}
zIndex={1}
>
<Typography
variant="h1"
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
Network error
</Typography>
<Typography>Please check your connection</Typography>
{children}
</Stack>
</Stack>
</Box>
);
};

export default NetworkErrorFallback;
export default GenericFallback;
2 changes: 1 addition & 1 deletion Client/src/Components/Table/TablePagination/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Pagination.propTypes = {
paginationLabel: PropTypes.string, // Label for the pagination.
itemCount: PropTypes.number, // Total number of items for pagination.
page: PropTypes.number, // Current page index.
rowsPerPage: PropTypes.number.isRequired, // Number of rows displayed per page.
rowsPerPage: PropTypes.number, // Number of rows displayed per page.
handleChangePage: PropTypes.func.isRequired, // Function to handle page changes.
handleChangeRowsPerPage: PropTypes.func, // Function to handle changes in rows per page.
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Skeleton } from "@mui/material";

const UptimeDataTableSkeleton = () => {
const TableSkeleton = () => {
return (
<Skeleton
variant="rounded"
width="100%"
height="100%"
height="80%"
flex={1}
/>
);
};

export default UptimeDataTableSkeleton;
export default TableSkeleton;
126 changes: 126 additions & 0 deletions Client/src/Pages/Incidents/Components/IncidentTable/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//Components
import Table from "../../../../Components/Table";
import TableSkeleton from "../../../../Components/Table/skeleton";
import Pagination from "../../../../Components/Table/TablePagination";
import { StatusLabel } from "../../../../Components/Label";
import { HttpStatusLabel } from "../../../../Components/HttpStatusLabel";
import GenericFallback from "../../../../Components/GenericFallback";
import NetworkError from "../../../../Components/GenericFallback/NetworkError";

//Utils
import { formatDateWithTz } from "../../../../Utils/timeUtils";
import { useSelector } from "react-redux";
import { useState } from "react";
import useChecksFetch from "../../Hooks/useChecksFetch";
import PropTypes from "prop-types";

const IncidentTable = ({
shouldRender,
monitors,
selectedMonitor,
filter,
dateRange,
}) => {
//Redux state
const uiTimezone = useSelector((state) => state.ui.timezone);

//Local state
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10);
const { isLoading, networkError, checks, checksCount } = useChecksFetch({
selectedMonitor,
filter,
dateRange,
page,
rowsPerPage,
});

//Handlers
const handleChangePage = (_, newPage) => {
setPage(newPage);
};

const handleChangeRowsPerPage = (event) => {
setRowsPerPage(event.target.value);
};

const headers = [
{
id: "monitorName",
content: "Monitor Name",
render: (row) => monitors[row.monitorId]?.name ?? "N/A",
},
{
id: "status",
content: "Status",
render: (row) => {
const status = row.status === true ? "up" : "down";
return (
<StatusLabel
status={status}
text={status}
customStyles={{ textTransform: "capitalize" }}
/>
);
},
},
{
id: "dateTime",
content: "Date & Time",
render: (row) => {
const formattedDate = formatDateWithTz(
row.createdAt,
"YYYY-MM-DD HH:mm:ss A",
uiTimezone
);
return formattedDate;
},
},
{
id: "statusCode",
content: "Status Code",
render: (row) => <HttpStatusLabel status={row.statusCode} />,
},
{ id: "message", content: "Message", render: (row) => row.message },
];

if (!shouldRender || isLoading) return <TableSkeleton />;

if (networkError) {
return (
<GenericFallback>
<NetworkError />
</GenericFallback>
);
}

if (!isLoading && typeof checksCount === "undefined") {
return <GenericFallback>No incidents recorded</GenericFallback>;
}

return (
<>
<Table
headers={headers}
data={checks}
/>
<Pagination
paginationLabel="incidents"
itemCount={checksCount}
page={page}
rowsPerPage={rowsPerPage}
handleChangePage={handleChangePage}
handleChangeRowsPerPage={handleChangeRowsPerPage}
/>
</>
);
};

IncidentTable.propTypes = {
shouldRender: PropTypes.bool,
monitors: PropTypes.object,
selectedMonitor: PropTypes.string,
filter: PropTypes.string,
dateRange: PropTypes.string,
};
export default IncidentTable;
162 changes: 162 additions & 0 deletions Client/src/Pages/Incidents/Components/OptionsHeader/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// Components
import { Stack, Typography, Button, ButtonGroup } from "@mui/material";
import Select from "../../../../Components/Inputs/Select";
import PropTypes from "prop-types";

//Utils
import { useTheme } from "@emotion/react";
import SkeletonLayout from "./skeleton";

const OptionsHeader = ({
shouldRender,
selectedMonitor = 0,
setSelectedMonitor,
monitors,
filter = "all",
setFilter,
dateRange = "hour",
setDateRange,
}) => {
const theme = useTheme();
const monitorNames = typeof monitors !== "undefined" ? Object.values(monitors) : [];

if (!shouldRender) return <SkeletonLayout />;

return (
<Stack
direction="row"
justifyContent="space-between"
>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(6)}
>
<Typography
display="inline-block"
component="h1"
color={theme.palette.primary.contrastTextSecondary}
>
Incidents for
</Typography>
<Select
id="incidents-select-monitor"
placeholder="All servers"
value={selectedMonitor}
onChange={(e) => setSelectedMonitor(e.target.value)}
items={monitorNames}
sx={{
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastTextSecondary,
}}
/>
</Stack>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(6)}
>
<Typography
display="inline-block"
component="h1"
color={theme.palette.primary.contrastTextSecondary}
>
Filter by:
</Typography>
<ButtonGroup
sx={{
ml: "auto",
"& .MuiButtonBase-root, & .MuiButtonBase-root:hover": {
borderColor: theme.palette.primary.lowContrast,
},
}}
>
<Button
variant="group"
filled={(filter === "all").toString()}
onClick={() => setFilter("all")}
>
All
</Button>
<Button
variant="group"
filled={(filter === "down").toString()}
onClick={() => setFilter("down")}
>
Down
</Button>
<Button
variant="group"
filled={(filter === "resolve").toString()}
onClick={() => setFilter("resolve")}
>
Cannot resolve
</Button>
</ButtonGroup>
</Stack>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(6)}
>
<Typography
display="inline-block"
component="h1"
color={theme.palette.primary.contrastTextSecondary}
>
Show:
</Typography>
<ButtonGroup
sx={{
ml: "auto",
"& .MuiButtonBase-root, & .MuiButtonBase-root:hover": {
borderColor: theme.palette.primary.lowContrast,
},
}}
>
<Button
variant="group"
filled={(dateRange === "hour").toString()}
onClick={() => setDateRange("hour")}
>
Last hour
</Button>
<Button
variant="group"
filled={(dateRange === "day").toString()}
onClick={() => setDateRange("day")}
>
Last day
</Button>
<Button
variant="group"
filled={(dateRange === "week").toString()}
onClick={() => setDateRange("week")}
>
Last week
</Button>
<Button
variant="group"
filled={(dateRange === "all").toString()}
onClick={() => setDateRange("all")}
>
All
</Button>
</ButtonGroup>
</Stack>
</Stack>
);
};

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;
11 changes: 11 additions & 0 deletions Client/src/Pages/Incidents/Components/OptionsHeader/skeleton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Stack, Skeleton } from "@mui/material";

const SkeletonLayout = () => {
return (
<Stack>
<Skeleton height={40} />
</Stack>
);
};

export default SkeletonLayout;
Loading

0 comments on commit 481196b

Please sign in to comment.