Display basic device information
This commit is contained in:
		@@ -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>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user