Frontend requests log on backend

This commit is contained in:
Pierre HUBERT 2024-10-02 21:54:54 +02:00
parent 75753051f9
commit 7dfb172aeb
4 changed files with 118 additions and 1 deletions

View File

@ -10,6 +10,7 @@ import { DeviceRoute } from "./routes/DeviceRoute/DeviceRoute";
import { DevicesRoute } from "./routes/DevicesRoute"; import { DevicesRoute } from "./routes/DevicesRoute";
import { HomeRoute } from "./routes/HomeRoute"; import { HomeRoute } from "./routes/HomeRoute";
import { LoginRoute } from "./routes/LoginRoute"; import { LoginRoute } from "./routes/LoginRoute";
import { LogsRoute } from "./routes/LogsRoute";
import { NotFoundRoute } from "./routes/NotFoundRoute"; import { NotFoundRoute } from "./routes/NotFoundRoute";
import { PendingDevicesRoute } from "./routes/PendingDevicesRoute"; import { PendingDevicesRoute } from "./routes/PendingDevicesRoute";
import { RelaysListRoute } from "./routes/RelaysListRoute"; import { RelaysListRoute } from "./routes/RelaysListRoute";
@ -27,6 +28,7 @@ export function App() {
<Route path="devices" element={<DevicesRoute />} /> <Route path="devices" element={<DevicesRoute />} />
<Route path="dev/:id" element={<DeviceRoute />} /> <Route path="dev/:id" element={<DeviceRoute />} />
<Route path="relays" element={<RelaysListRoute />} /> <Route path="relays" element={<RelaysListRoute />} />
<Route path="logs" element={<LogsRoute />} />
<Route path="*" element={<NotFoundRoute />} /> <Route path="*" element={<NotFoundRoute />} />
</Route> </Route>
) )

View File

@ -0,0 +1,29 @@
import { Dayjs } from "dayjs";
import { APIClient } from "./ApiClient";
export type LogSeverity = "Debug" | "Info" | "Warn" | "Error";
export interface LogEntry {
device_id: string;
time: number;
severity: LogSeverity;
message: string;
}
export class LogsAPI {
/**
* Request the logs from the server
*
* @param date The date that contains the requested date
*/
static async GetLogs(date: Dayjs): Promise<LogEntry[]> {
const day = Math.floor(date.unix() / (3600 * 24));
const res = await APIClient.exec({
uri: `/logging/logs?day=${day}`,
method: "GET",
});
return res.data;
}
}

View File

@ -0,0 +1,75 @@
import NavigateBeforeIcon from "@mui/icons-material/NavigateBefore";
import NavigateNextIcon from "@mui/icons-material/NavigateNext";
import RefreshIcon from "@mui/icons-material/Refresh";
import { IconButton, Tooltip } 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 () => {
setLogs(await LogsAPI.GetLogs(currDate));
};
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",
}}
>
<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 {
return "TODO : show logs";
}

View File

@ -1,4 +1,10 @@
import { mdiChip, mdiElectricSwitch, mdiHome, mdiNewBox } from "@mdi/js"; import {
mdiChip,
mdiElectricSwitch,
mdiHome,
mdiNewBox,
mdiNotebookMultiple,
} from "@mdi/js";
import Icon from "@mdi/react"; import Icon from "@mdi/react";
import { import {
List, List,
@ -35,6 +41,11 @@ export function SolarEnergyNavList(): React.ReactElement {
uri="/relays" uri="/relays"
icon={<Icon path={mdiElectricSwitch} size={1} />} icon={<Icon path={mdiElectricSwitch} size={1} />}
/> />
<NavLink
label="Logging"
uri="/logs"
icon={<Icon path={mdiNotebookMultiple} size={1} />}
/>
</List> </List>
); );
} }