mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-18 23:59:41 -06:00
Create new UptimeDataTable component to hold search, table, and pagination
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { Skeleton } from "@mui/material";
|
||||
import DataTable from "../../../../../Components/Table";
|
||||
const ROWS_NUMBER = 7;
|
||||
const ROWS_ARRAY = Array.from({ length: ROWS_NUMBER }, (_, i) => i);
|
||||
|
||||
const TableSkeleton = () => {
|
||||
/* TODO Skeleton does not follow light and dark theme */
|
||||
|
||||
const headers = [
|
||||
{
|
||||
id: "name",
|
||||
|
||||
content: "Host",
|
||||
|
||||
render: () => <Skeleton />,
|
||||
},
|
||||
{
|
||||
id: "status",
|
||||
content: "Status",
|
||||
render: () => <Skeleton />,
|
||||
},
|
||||
{
|
||||
id: "responseTime",
|
||||
content: "Response Time",
|
||||
render: () => <Skeleton />,
|
||||
},
|
||||
{
|
||||
id: "type",
|
||||
content: "Type",
|
||||
render: () => <Skeleton />,
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
content: "Actions",
|
||||
render: () => <Skeleton />,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<DataTable
|
||||
headers={headers}
|
||||
data={ROWS_ARRAY}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export { TableSkeleton };
|
||||
231
Client/src/Pages/Uptime/Home/UptimeDataTable/index.jsx
Normal file
231
Client/src/Pages/Uptime/Home/UptimeDataTable/index.jsx
Normal file
@@ -0,0 +1,231 @@
|
||||
// Components
|
||||
import { Box, Stack, CircularProgress } from "@mui/material";
|
||||
import Search from "../../../../Components/Inputs/Search";
|
||||
import { Heading } from "../../../../Components/Heading";
|
||||
import DataTable from "../../../../Components/Table";
|
||||
import ArrowDownwardRoundedIcon from "@mui/icons-material/ArrowDownwardRounded";
|
||||
import ArrowUpwardRoundedIcon from "@mui/icons-material/ArrowUpwardRounded";
|
||||
import Host from "../host";
|
||||
import { StatusLabel } from "../../../../Components/Label";
|
||||
import BarChart from "../../../../Components/Charts/BarChart";
|
||||
import ActionsMenu from "../actionsMenu";
|
||||
|
||||
// Utils
|
||||
import { useTheme } from "@emotion/react";
|
||||
import useDebounce from "../../../../Utils/debounce";
|
||||
import { useState } from "react";
|
||||
import useUtils from "../../utils";
|
||||
import { memo } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const UptimeDataTable = ({
|
||||
isAdmin,
|
||||
isLoading,
|
||||
monitors,
|
||||
monitorCount,
|
||||
sort,
|
||||
setSort,
|
||||
search,
|
||||
setSearch,
|
||||
isSearching,
|
||||
setIsSearching,
|
||||
triggerUpdate,
|
||||
}) => {
|
||||
const { determineState } = useUtils();
|
||||
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
|
||||
//Utils
|
||||
const debouncedFilter = useDebounce(search, 500);
|
||||
const handleSearch = (value) => {
|
||||
setIsSearching(true);
|
||||
setSearch(value);
|
||||
};
|
||||
|
||||
const handleSort = (field) => {
|
||||
let order = "";
|
||||
if (sort.field !== field) {
|
||||
order = "desc";
|
||||
} else {
|
||||
order = sort.order === "asc" ? "desc" : "asc";
|
||||
}
|
||||
setSort({ field, order });
|
||||
};
|
||||
|
||||
const headers = [
|
||||
{
|
||||
id: "name",
|
||||
content: (
|
||||
<Box onClick={() => handleSort("name")}>
|
||||
Host
|
||||
<span
|
||||
style={{
|
||||
visibility: sort.field === "name" ? "visible" : "hidden",
|
||||
}}
|
||||
>
|
||||
{sort.order === "asc" ? (
|
||||
<ArrowUpwardRoundedIcon />
|
||||
) : (
|
||||
<ArrowDownwardRoundedIcon />
|
||||
)}
|
||||
</span>
|
||||
</Box>
|
||||
),
|
||||
render: (row) => (
|
||||
<Host
|
||||
key={row._id}
|
||||
url={row.url}
|
||||
title={row.title}
|
||||
percentageColor={row.percentageColor}
|
||||
percentage={row.percentage}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "status",
|
||||
content: (
|
||||
<Box
|
||||
width="max-content"
|
||||
onClick={() => handleSort("status")}
|
||||
>
|
||||
{" "}
|
||||
Status
|
||||
<span
|
||||
style={{
|
||||
visibility: sort.field === "status" ? "visible" : "hidden",
|
||||
}}
|
||||
>
|
||||
{sort.order === "asc" ? (
|
||||
<ArrowUpwardRoundedIcon />
|
||||
) : (
|
||||
<ArrowDownwardRoundedIcon />
|
||||
)}
|
||||
</span>
|
||||
</Box>
|
||||
),
|
||||
render: (row) => {
|
||||
const status = determineState(row.monitor);
|
||||
return (
|
||||
<StatusLabel
|
||||
status={status}
|
||||
text={status}
|
||||
customStyles={{ textTransform: "capitalize" }}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "responseTime",
|
||||
content: "Response Time",
|
||||
render: (row) => <BarChart checks={row.monitor.checks.slice().reverse()} />,
|
||||
},
|
||||
{
|
||||
id: "type",
|
||||
content: "Type",
|
||||
render: (row) => (
|
||||
<span style={{ textTransform: "uppercase" }}>{row.monitor.type}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
content: "Actions",
|
||||
render: (row) => (
|
||||
<ActionsMenu
|
||||
monitor={row.monitor}
|
||||
isAdmin={isAdmin}
|
||||
updateRowCallback={triggerUpdate}
|
||||
pauseCallback={triggerUpdate}
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Box
|
||||
flex={1}
|
||||
py={theme.spacing(8)}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
mb={theme.spacing(8)}
|
||||
>
|
||||
<Heading component="h2">Uptime monitors</Heading>
|
||||
|
||||
<Box
|
||||
className="current-monitors-counter"
|
||||
color={theme.palette.text.primary}
|
||||
border={1}
|
||||
borderColor={theme.palette.border.light}
|
||||
backgroundColor={theme.palette.background.accent}
|
||||
>
|
||||
{monitorCount}
|
||||
</Box>
|
||||
<Box
|
||||
width="25%"
|
||||
minWidth={150}
|
||||
ml="auto"
|
||||
>
|
||||
<Search
|
||||
options={monitors}
|
||||
filteredBy="name"
|
||||
inputValue={search}
|
||||
handleInputChange={handleSearch}
|
||||
/>
|
||||
</Box>
|
||||
</Stack>
|
||||
<Box position="relative">
|
||||
{isSearching && (
|
||||
<>
|
||||
<Box
|
||||
width="100%"
|
||||
height="100%"
|
||||
position="absolute"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.background.main,
|
||||
opacity: 0.8,
|
||||
zIndex: 100,
|
||||
}}
|
||||
/>
|
||||
<Box
|
||||
height="100%"
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
sx={{
|
||||
transform: "translateX(-50%)",
|
||||
zIndex: 101,
|
||||
}}
|
||||
>
|
||||
<CircularProgress
|
||||
sx={{
|
||||
color: theme.palette.other.icon,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
<DataTable
|
||||
headers={headers}
|
||||
data={monitors}
|
||||
config={{
|
||||
rowSX: {
|
||||
cursor: "pointer",
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.background.accent,
|
||||
},
|
||||
},
|
||||
onRowClick: (row) => {
|
||||
navigate(`/uptime/${row.id}`);
|
||||
},
|
||||
emptyView: "No monitors found",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const MemoizedUptimeDataTable = memo(UptimeDataTable);
|
||||
export default MemoizedUptimeDataTable;
|
||||
Reference in New Issue
Block a user