298 lines
8.1 KiB
React
298 lines
8.1 KiB
React
import { useCallback, useEffect, useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { /* useDispatch, */ useSelector } from "react-redux";
|
|
import { useTheme } from "@emotion/react";
|
|
import useUtils from "../Monitors/utils";
|
|
import { jwtDecode } from "jwt-decode";
|
|
import Greeting from "../../Utils/greeting";
|
|
import GearIcon from "../../Assets/icons/settings-bold.svg?react";
|
|
import CPUChipIcon from "../../Assets/icons/cpu-chip.svg?react";
|
|
import {
|
|
Box,
|
|
Button,
|
|
IconButton,
|
|
Paper,
|
|
Stack,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableContainer,
|
|
TableHead,
|
|
TableRow,
|
|
} from "@mui/material";
|
|
import Breadcrumbs from "../../Components/Breadcrumbs";
|
|
import { StatusLabel } from "../../Components/Label";
|
|
import { Heading } from "../../Components/Heading";
|
|
import { Pagination } from "./components/TablePagination";
|
|
// import { getInfrastructureMonitorsByTeamId } from "../../Features/InfrastructureMonitors/infrastructureMonitorsSlice";
|
|
import { networkService } from "../../Utils/NetworkService.js";
|
|
import CustomGauge from "../../Components/Charts/CustomGauge/index.jsx";
|
|
|
|
const columns = [
|
|
{ label: "Host" },
|
|
{ label: "Status" },
|
|
{ label: "Frequency" },
|
|
{ label: "CPU" },
|
|
{ label: "Mem" },
|
|
{ label: "Disk" },
|
|
{ label: "Actions" },
|
|
];
|
|
|
|
const BREADCRUMBS = [{ name: `infrastructure`, path: "/infrastructure" }];
|
|
|
|
/* TODO
|
|
Create reusable table component.
|
|
It should receive as a parameter the following object:
|
|
tableData = [
|
|
columns = [
|
|
{
|
|
id: example,
|
|
label: Example Extendable,
|
|
align: "center" | "left" (default)
|
|
}
|
|
],
|
|
rows: [
|
|
{
|
|
**Number of keys will be equal to number of columns**
|
|
key1: string,
|
|
key2: number,
|
|
key3: Component
|
|
}
|
|
]
|
|
]
|
|
Apply to Monitor Table, and Account/Team.
|
|
Analyze existing BasicTable
|
|
*/
|
|
|
|
/**
|
|
* This is the Infrastructure monitoring page. This is a work in progress
|
|
*
|
|
* @param - Define params.
|
|
* @returns {JSX.Element} The infrastructure monitoring page.
|
|
*/
|
|
|
|
function Infrastructure(/* {isAdmin} */) {
|
|
const theme = useTheme();
|
|
|
|
const navigate = useNavigate();
|
|
const navigateToCreate = () => navigate("/infrastructure/create");
|
|
|
|
const [page, setPage] = useState(0);
|
|
/* TODO refactor this, so it is not aware of the MUI implementation. First argument only exists because of MUI. This should require onlu the new page. Adapting for MUI should happen inside of table pagination component */
|
|
const handleChangePage = (_, newPage) => {
|
|
setPage(newPage);
|
|
};
|
|
|
|
const [rowsPerPage, setRowsPerPage] = useState(5);
|
|
const handleChangeRowsPerPage = (event) => {
|
|
setRowsPerPage(parseInt(event.target.value));
|
|
setPage(0);
|
|
};
|
|
const [monitorState, setMonitorState] = useState({ monitors: [], total: 0 });
|
|
|
|
const { authToken } = useSelector((state) => state.auth);
|
|
const user = jwtDecode(authToken);
|
|
|
|
const fetchMonitors = useCallback(async () => {
|
|
try {
|
|
const response = await networkService.getMonitorsByTeamId({
|
|
authToken,
|
|
teamId: user.teamId,
|
|
limit: 1,
|
|
types: ["hardware"],
|
|
status: null,
|
|
checkOrder: "desc",
|
|
normalize: true,
|
|
page: page,
|
|
rowsPerPage: rowsPerPage,
|
|
});
|
|
setMonitorState({
|
|
monitors: response?.data?.data?.monitors ?? [],
|
|
total: response?.data?.data?.monitorCount ?? 0,
|
|
});
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
}, [page, rowsPerPage, authToken]);
|
|
|
|
useEffect(() => {
|
|
fetchMonitors();
|
|
}, [page, rowsPerPage]);
|
|
|
|
const { determineState } = useUtils();
|
|
const { monitors, total: totalMonitors } = monitorState;
|
|
console.log({ monitors });
|
|
console.log(monitors[0]?.checks[0]?.memory.usage_percent);
|
|
const monitorsAsRows = monitors.map((monitor) => ({
|
|
ip: monitor.name,
|
|
status: determineState(monitor),
|
|
processor: (monitor?.checks[0]?.cpu.frequency / 1000).toFixed(2) + " GHz",
|
|
cpu: monitor?.checks[0]?.cpu.usage_percent * 100,
|
|
mem: monitor?.checks[0]?.memory.usage_percent * 100,
|
|
disk: monitor?.checks[0]?.disk[0]?.usage_percent * 100,
|
|
}));
|
|
/* TODO when friendyly name i added, it shoul display frindly name + url */
|
|
/* TODO remove table scrollbar */
|
|
/* Fix search in monitors page */
|
|
/* Adding actions to the table */
|
|
/* Adding click on row action */
|
|
|
|
return (
|
|
<Stack
|
|
component="main"
|
|
style={{ width: "100%", gap: "1rem" }}
|
|
>
|
|
<Breadcrumbs list={BREADCRUMBS} />
|
|
<Stack
|
|
direction="row"
|
|
sx={{
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
gap: "1rem",
|
|
flexWrap: "wrap",
|
|
marginBottom: "3rem",
|
|
}}
|
|
>
|
|
<Box style={{ maxWidth: "65ch" }}>
|
|
<Greeting type="uptime" />
|
|
</Box>
|
|
<Button
|
|
variant="contained"
|
|
color="primary"
|
|
onClick={navigateToCreate}
|
|
sx={{ fontWeight: 500 }}
|
|
>
|
|
Create infrastructure monitor
|
|
</Button>
|
|
</Stack>
|
|
<Stack
|
|
sx={{
|
|
gap: "1rem",
|
|
}}
|
|
>
|
|
<Stack
|
|
direction="row"
|
|
sx={{
|
|
alignItems: "center",
|
|
gap: ".25rem",
|
|
flexWrap: "wrap",
|
|
}}
|
|
>
|
|
<Heading component="h2">Infrastructure monitors</Heading>
|
|
{/* TODO Correct the class current-monitors-counter, there are some unnecessary things there */}
|
|
<Box
|
|
component="span"
|
|
className="current-monitors-counter"
|
|
color={theme.palette.text.primary}
|
|
border={1}
|
|
borderColor={theme.palette.border.light}
|
|
backgroundColor={theme.palette.background.accent}
|
|
>
|
|
{totalMonitors}
|
|
</Box>
|
|
</Stack>
|
|
<TableContainer
|
|
component={Paper}
|
|
sx={{
|
|
maxHeight: "55vh",
|
|
"&::-webkit-scrollbar": {
|
|
width: ".75rem",
|
|
},
|
|
"&::-webkit-scrollbar-track": {
|
|
backgroundColor: theme.palette.secondary.light,
|
|
},
|
|
"&::-webkit-scrollbar-thumb": {
|
|
backgroundColor: theme.palette.secondary.contrastText,
|
|
outline: `1px solid ${theme.palette.secondary.contrastText}`,
|
|
},
|
|
}}
|
|
>
|
|
<Table stickyHeader>
|
|
<TableHead sx={{ backgroundColor: theme.palette.background.accent }}>
|
|
<TableRow>
|
|
{columns.map((column, index) => (
|
|
<TableCell
|
|
key={index}
|
|
align={index === 0 ? "left" : "center"}
|
|
sx={{
|
|
backgroundColor: theme.palette.background.accent,
|
|
}}
|
|
>
|
|
{column.label}
|
|
</TableCell>
|
|
))}
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{
|
|
/* ROWS */ monitorsAsRows.map((row, index) => (
|
|
<TableRow key={index}>
|
|
{/* TODO iterate over column and get column id, applying row[column.id] */}
|
|
<TableCell>{row.ip}</TableCell>
|
|
<TableCell align="center">
|
|
<StatusLabel
|
|
status={row.status}
|
|
text={row.status}
|
|
/* Use capitalize inside of Status Label */
|
|
/* Update component so we don't need to pass text and status separately*/
|
|
customStyles={{ textTransform: "capitalize" }}
|
|
/>
|
|
</TableCell>
|
|
<TableCell align="center">
|
|
<Stack
|
|
direction={"row"}
|
|
justifyContent={"center"}
|
|
alignItems={"center"}
|
|
gap=".25rem"
|
|
>
|
|
<CPUChipIcon
|
|
width={20}
|
|
height={20}
|
|
/>
|
|
{row.processor}
|
|
</Stack>
|
|
</TableCell>
|
|
<TableCell align="center">
|
|
<CustomGauge progress={row.cpu} />
|
|
</TableCell>
|
|
<TableCell align="center">
|
|
<CustomGauge progress={row.mem} />
|
|
</TableCell>
|
|
<TableCell align="center">
|
|
<CustomGauge progress={row.disk} />
|
|
</TableCell>
|
|
<TableCell align="center">
|
|
{/* Get ActionsMenu from Monitor Table and create a component */}
|
|
<IconButton
|
|
sx={{
|
|
"& svg path": {
|
|
stroke: theme.palette.other.icon,
|
|
},
|
|
}}
|
|
>
|
|
<GearIcon
|
|
width={20}
|
|
height={20}
|
|
/>
|
|
</IconButton>
|
|
</TableCell>
|
|
</TableRow>
|
|
))
|
|
}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
<Pagination
|
|
monitorCount={totalMonitors}
|
|
page={page}
|
|
rowsPerPage={rowsPerPage}
|
|
handleChangePage={handleChangePage}
|
|
handleChangeRowsPerPage={handleChangeRowsPerPage}
|
|
/>
|
|
</Stack>
|
|
</Stack>
|
|
);
|
|
}
|
|
|
|
export { Infrastructure };
|