Update general device information

This commit is contained in:
2024-09-09 21:43:57 +02:00
parent a97614ce44
commit 36ba4efd9f
8 changed files with 109 additions and 30 deletions

View File

@ -120,6 +120,18 @@ export class DeviceApi {
).data;
}
/**
* Get the current state of a single device
*/
static async GetSingleState(id: string): Promise<DeviceState> {
return (
await APIClient.exec({
uri: `/device/${encodeURIComponent(id)}/state`,
method: "GET",
})
).data;
}
/**
* Update a device general information
*/

View File

@ -0,0 +1,15 @@
import { TableCell, TableRow } from "@mui/material";
export function DeviceInfoProperty(p: {
icon?: React.ReactElement;
label: string;
value: string;
color?: string;
}): React.ReactElement {
return (
<TableRow hover sx={{ "&:last-child td, &:last-child th": { border: 0 } }}>
<TableCell>{p.label}</TableCell>
<TableCell style={{ color: p.color }}>{p.value}</TableCell>
</TableRow>
);
}

View File

@ -1,5 +1,7 @@
import DeleteIcon from "@mui/icons-material/Delete";
import RefreshIcon from "@mui/icons-material/Refresh";
import { IconButton, Tooltip } from "@mui/material";
import Grid from "@mui/material/Grid2";
import React from "react";
import { useNavigate, useParams } from "react-router-dom";
import { Device, DeviceApi } from "../../api/DeviceApi";
@ -9,9 +11,9 @@ import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageP
import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider";
import { AsyncWidget } from "../../widgets/AsyncWidget";
import { SolarEnergyRouteContainer } from "../../widgets/SolarEnergyRouteContainer";
import { GeneralDeviceInfo } from "./GeneralDeviceInfo";
import { DeviceRelays } from "./DeviceRelays";
import Grid from "@mui/material/Grid2";
import { DeviceStateBlock } from "./DeviceStateBlock";
import { GeneralDeviceInfo } from "./GeneralDeviceInfo";
export function DeviceRoute(): React.ReactElement {
const { id } = useParams();
@ -70,15 +72,23 @@ function DeviceRouteInner(p: {
loadingMessage.hide();
}
};
return (
<SolarEnergyRouteContainer
label={`Device ${p.device.name}`}
actions={
<Tooltip title="Delete device">
<IconButton onClick={() => deleteDevice(p.device)}>
<DeleteIcon />
</IconButton>
</Tooltip>
<span>
<Tooltip title="Refresh information">
<IconButton onClick={p.onReload}>
<RefreshIcon />
</IconButton>
</Tooltip>
<Tooltip title="Delete device">
<IconButton onClick={() => deleteDevice(p.device)}>
<DeleteIcon />
</IconButton>
</Tooltip>
</span>
}
>
<Grid container spacing={2}>
@ -88,6 +98,9 @@ function DeviceRouteInner(p: {
<Grid size={{ xs: 12, md: 6 }}>
<DeviceRelays {...p} />
</Grid>
<Grid size={{ xs: 12, md: 6 }}>
<DeviceStateBlock {...p} />
</Grid>
</Grid>
</SolarEnergyRouteContainer>
);

View File

@ -0,0 +1,44 @@
import React from "react";
import { Device, DeviceApi, DeviceState } from "../../api/DeviceApi";
import { AsyncWidget } from "../../widgets/AsyncWidget";
import { DeviceRouteCard } from "./DeviceRouteCard";
import { Table, TableBody } from "@mui/material";
import { DeviceInfoProperty } from "./DeviceInfoProperty";
import { timeDiff } from "../../widgets/TimeWidget";
export function DeviceStateBlock(p: { device: Device }): React.ReactElement {
const [state, setState] = React.useState<DeviceState>();
const load = async () => {
setState(await DeviceApi.GetSingleState(p.device.id));
};
return (
<DeviceRouteCard title="Device state">
<AsyncWidget
loadKey={p.device.id}
load={load}
ready={!!state}
errMsg="Failed to load device state!"
build={() => <DeviceStateInner state={state!} />}
/>
</DeviceRouteCard>
);
}
function DeviceStateInner(p: { state: DeviceState }): React.ReactElement {
return (
<Table size="small">
<TableBody>
<DeviceInfoProperty
label="Status"
value={p.state.online ? "Online" : "Offline"}
/>
<DeviceInfoProperty
label="Last ping"
value={timeDiff(0, p.state.last_ping)}
/>
</TableBody>
</Table>
);
}

View File

@ -1,16 +1,10 @@
import EditIcon from "@mui/icons-material/Edit";
import {
IconButton,
Table,
TableBody,
TableCell,
TableRow,
Tooltip,
} from "@mui/material";
import { IconButton, Table, TableBody, Tooltip } from "@mui/material";
import React from "react";
import { Device } from "../../api/DeviceApi";
import { EditDeviceMetadataDialog } from "../../dialogs/EditDeviceMetadataDialog";
import { formatDate } from "../../widgets/TimeWidget";
import { DeviceInfoProperty } from "./DeviceInfoProperty";
import { DeviceRouteCard } from "./DeviceRouteCard";
export function GeneralDeviceInfo(p: {
@ -78,17 +72,3 @@ export function GeneralDeviceInfo(p: {
</>
);
}
function DeviceInfoProperty(p: {
icon?: React.ReactElement;
label: string;
value: string;
color?: string;
}): React.ReactElement {
return (
<TableRow hover sx={{ "&:last-child td, &:last-child th": { border: 0 } }}>
<TableCell>{p.label}</TableCell>
<TableCell style={{ color: p.color }}>{p.value}</TableCell>
</TableRow>
);
}