125 lines
3.4 KiB
TypeScript
125 lines
3.4 KiB
TypeScript
import NavigateBeforeIcon from "@mui/icons-material/NavigateBefore";
|
|
import NavigateNextIcon from "@mui/icons-material/NavigateNext";
|
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
|
import {
|
|
IconButton,
|
|
Paper,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableContainer,
|
|
TableHead,
|
|
TableRow,
|
|
Tooltip,
|
|
Typography,
|
|
} from "@mui/material";
|
|
import { DatePicker } from "@mui/x-date-pickers";
|
|
import dayjs from "dayjs";
|
|
import React from "react";
|
|
import { LogEntry, LogsAPI } from "../api/LogsAPI";
|
|
import { AsyncWidget } from "../widgets/AsyncWidget";
|
|
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
|
|
|
|
export function LogsRoute(): React.ReactElement {
|
|
const loadKey = React.useRef(1);
|
|
|
|
const [currDate, setCurrDate] = React.useState(dayjs());
|
|
|
|
const [logs, setLogs] = React.useState<LogEntry[] | undefined>();
|
|
|
|
const load = async () => {
|
|
const logs = await LogsAPI.GetLogs(currDate);
|
|
logs.reverse();
|
|
setLogs(logs);
|
|
};
|
|
|
|
const reload = () => {
|
|
setLogs(undefined);
|
|
loadKey.current += 1;
|
|
};
|
|
return (
|
|
<SolarEnergyRouteContainer
|
|
label="Logs"
|
|
actions={
|
|
<Tooltip title="Refresh logs">
|
|
<IconButton onClick={reload}>
|
|
<RefreshIcon />
|
|
</IconButton>
|
|
</Tooltip>
|
|
}
|
|
>
|
|
<div
|
|
style={{
|
|
width: "100%",
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
marginBottom: "10px",
|
|
}}
|
|
>
|
|
<Tooltip title="Previous day">
|
|
<IconButton onClick={() => setCurrDate(currDate.add(-1, "day"))}>
|
|
<NavigateBeforeIcon />
|
|
</IconButton>
|
|
</Tooltip>
|
|
<DatePicker
|
|
label="Shown day"
|
|
value={currDate}
|
|
onChange={(d) => setCurrDate(d === null ? currDate : d)}
|
|
/>
|
|
<Tooltip title="Next day">
|
|
<IconButton onClick={() => setCurrDate(currDate.add(1, "day"))}>
|
|
<NavigateNextIcon />
|
|
</IconButton>
|
|
</Tooltip>
|
|
</div>
|
|
<AsyncWidget
|
|
ready={!!logs}
|
|
loadKey={loadKey.current + currDate.toString()}
|
|
errMsg="Failed to load the logs!"
|
|
load={load}
|
|
build={() => <LogsView logs={logs!} />}
|
|
/>
|
|
</SolarEnergyRouteContainer>
|
|
);
|
|
}
|
|
|
|
function LogsView(p: { logs: LogEntry[] }): React.ReactElement {
|
|
if (p.logs.length == 0) {
|
|
return (
|
|
<Typography style={{ textAlign: "center" }}>
|
|
There was no log recorded on this day.
|
|
</Typography>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<TableContainer component={Paper}>
|
|
<Table sx={{ minWidth: 650 }} size="small" aria-label="a dense table">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>Device ID</TableCell>
|
|
<TableCell>Time</TableCell>
|
|
<TableCell>Severity</TableCell>
|
|
<TableCell>Message</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{p.logs.map((row, id) => (
|
|
<TableRow key={id} hover>
|
|
<TableCell component="th" scope="row">
|
|
{row.device_id ?? "Backend"}
|
|
</TableCell>
|
|
<TableCell>
|
|
{new Date(row.time * 1000).toLocaleTimeString()}
|
|
</TableCell>
|
|
<TableCell>{row.severity}</TableCell>
|
|
<TableCell>{row.message}</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
);
|
|
}
|