Display basic device information
This commit is contained in:
parent
7be81fe0e9
commit
1ce9ca3321
@ -139,6 +139,10 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
|
||||
"/web_api/devices/list_validated",
|
||||
web::get().to(devices_controller::list_validated),
|
||||
)
|
||||
.route(
|
||||
"/web_api/device/{id}",
|
||||
web::get().to(devices_controller::get_single),
|
||||
)
|
||||
.route(
|
||||
"/web_api/device/{id}/validate",
|
||||
web::post().to(devices_controller::validate_device),
|
||||
|
@ -33,6 +33,18 @@ pub struct DeviceInPath {
|
||||
id: DeviceId,
|
||||
}
|
||||
|
||||
/// Get a single device information
|
||||
pub async fn get_single(actor: WebEnergyActor, id: web::Path<DeviceInPath>) -> HttpResult {
|
||||
let Some(dev) = actor
|
||||
.send(energy_actor::GetSingleDevice(id.id.clone()))
|
||||
.await?
|
||||
else {
|
||||
return Ok(HttpResponse::NotFound().json("Requested device was not found!"));
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(dev))
|
||||
}
|
||||
|
||||
/// Validate a device
|
||||
pub async fn validate_device(actor: WebEnergyActor, id: web::Path<DeviceInPath>) -> HttpResult {
|
||||
actor
|
||||
|
@ -12,6 +12,7 @@ import { HomeRoute } from "./routes/HomeRoute";
|
||||
import { BaseAuthenticatedPage } from "./widgets/BaseAuthenticatedPage";
|
||||
import { PendingDevicesRoute } from "./routes/PendingDevicesRoute";
|
||||
import { DevicesRoute } from "./routes/DevicesRoute";
|
||||
import { DeviceRoute } from "./routes/DeviceRoute";
|
||||
|
||||
export function App() {
|
||||
if (!AuthApi.SignedIn && !ServerApi.Config.auth_disabled)
|
||||
@ -21,8 +22,9 @@ export function App() {
|
||||
createRoutesFromElements(
|
||||
<Route path="*" element={<BaseAuthenticatedPage />}>
|
||||
<Route path="" element={<HomeRoute />} />
|
||||
<Route path="devices" element={<DevicesRoute />} />
|
||||
<Route path="pending_devices" element={<PendingDevicesRoute />} />
|
||||
<Route path="devices" element={<DevicesRoute />} />
|
||||
<Route path="dev/:id" element={<DeviceRoute />} />
|
||||
<Route path="*" element={<NotFoundRoute />} />
|
||||
</Route>
|
||||
)
|
||||
|
@ -37,8 +37,8 @@ export interface Device {
|
||||
relays: DeviceRelay[];
|
||||
}
|
||||
|
||||
export function DeviceURL(d: Device, edit: boolean = false): string {
|
||||
return `/dev/${d.id}${edit ? "/edit" : ""}`;
|
||||
export function DeviceURL(d: Device): string {
|
||||
return `/dev/${encodeURIComponent(d.id)}`;
|
||||
}
|
||||
|
||||
export class DeviceApi {
|
||||
@ -76,6 +76,18 @@ export class DeviceApi {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the information about a single device
|
||||
*/
|
||||
static async GetSingle(id: string): Promise<Device> {
|
||||
return (
|
||||
await APIClient.exec({
|
||||
uri: `/device/${encodeURIComponent(id)}`,
|
||||
method: "GET",
|
||||
})
|
||||
).data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a device
|
||||
*/
|
||||
|
102
central_frontend/src/routes/DeviceRoute.tsx
Normal file
102
central_frontend/src/routes/DeviceRoute.tsx
Normal file
@ -0,0 +1,102 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Device, DeviceApi } from "../api/DeviceApi";
|
||||
import React from "react";
|
||||
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
|
||||
import {
|
||||
Card,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
|
||||
export function DeviceRoute(): React.ReactElement {
|
||||
const { id } = useParams();
|
||||
const [device, setDevice] = React.useState<Device | undefined>();
|
||||
|
||||
const loadKey = React.useRef(1);
|
||||
|
||||
const load = async () => {
|
||||
setDevice(await DeviceApi.GetSingle(id!));
|
||||
};
|
||||
|
||||
const reload = () => {
|
||||
loadKey.current += 1;
|
||||
setDevice(undefined);
|
||||
};
|
||||
|
||||
return (
|
||||
<AsyncWidget
|
||||
loadKey={loadKey.current}
|
||||
errMsg="Failed to load device information"
|
||||
load={load}
|
||||
ready={!!device}
|
||||
build={() => <DeviceRouteInner device={device!} onReload={reload} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function DeviceRouteInner(p: {
|
||||
device: Device;
|
||||
onReload: () => void;
|
||||
}): React.ReactElement {
|
||||
return (
|
||||
<SolarEnergyRouteContainer label={`Device ${p.device.name}`}>
|
||||
<GeneralDeviceInfo {...p} />
|
||||
</SolarEnergyRouteContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function GeneralDeviceInfo(p: { device: Device }): React.ReactElement {
|
||||
return (
|
||||
<TableContainer component={Paper}>
|
||||
<Typography variant="h6" style={{ padding: "6px" }}>
|
||||
General device information
|
||||
</Typography>
|
||||
<Table size="small">
|
||||
<TableBody>
|
||||
<DeviceInfoProperty label="ID" value={p.device.id} />
|
||||
<DeviceInfoProperty
|
||||
label="Reference"
|
||||
value={p.device.info.reference}
|
||||
/>
|
||||
<DeviceInfoProperty label="Version" value={p.device.info.version} />
|
||||
<DeviceInfoProperty label="Name" value={p.device.name} />
|
||||
<DeviceInfoProperty
|
||||
label="Description"
|
||||
value={p.device.description}
|
||||
/>
|
||||
<DeviceInfoProperty
|
||||
label="Enabled"
|
||||
value={p.device.enabled ? "YES" : "NO"}
|
||||
/>
|
||||
<DeviceInfoProperty
|
||||
label="Maximum number of relays"
|
||||
value={p.device.info.max_relays.toString()}
|
||||
/>
|
||||
<DeviceInfoProperty
|
||||
label="Number of configured relays"
|
||||
value={p.device.relays.length.toString()}
|
||||
/>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function DeviceInfoProperty(p: {
|
||||
icon?: React.ReactElement;
|
||||
label: string;
|
||||
value: string;
|
||||
}): React.ReactElement {
|
||||
return (
|
||||
<TableRow hover sx={{ "&:last-child td, &:last-child th": { border: 0 } }}>
|
||||
<TableCell>{p.label}</TableCell>
|
||||
<TableCell>{p.value}</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user