Display relay status on relays page
This commit is contained in:
		@@ -45,6 +45,14 @@ export interface UpdatedInfo {
 | 
			
		||||
  enabled: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface DeviceState {
 | 
			
		||||
  id: string;
 | 
			
		||||
  last_ping: number;
 | 
			
		||||
  online: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type DevicesState = Map<string, DeviceState>;
 | 
			
		||||
 | 
			
		||||
export function DeviceURL(d: Device): string {
 | 
			
		||||
  return `/dev/${encodeURIComponent(d.id)}`;
 | 
			
		||||
}
 | 
			
		||||
@@ -74,6 +82,22 @@ export class DeviceApi {
 | 
			
		||||
    ).data;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get the state of devices
 | 
			
		||||
   */
 | 
			
		||||
  static async DevicesState(): Promise<DevicesState> {
 | 
			
		||||
    const devs: DeviceState[] = (
 | 
			
		||||
      await APIClient.exec({
 | 
			
		||||
        uri: "/devices/state",
 | 
			
		||||
        method: "GET",
 | 
			
		||||
      })
 | 
			
		||||
    ).data;
 | 
			
		||||
 | 
			
		||||
    const m = new Map();
 | 
			
		||||
    devs.forEach((d) => m.set(d.id, d));
 | 
			
		||||
    return m;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Validate a device
 | 
			
		||||
   */
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ import {
 | 
			
		||||
} from "@mui/material";
 | 
			
		||||
import React from "react";
 | 
			
		||||
import { Link, useNavigate } from "react-router-dom";
 | 
			
		||||
import { Device, DeviceApi, DeviceURL } from "../api/DeviceApi";
 | 
			
		||||
import { Device, DeviceApi, DevicesState, DeviceURL } from "../api/DeviceApi";
 | 
			
		||||
import { AsyncWidget } from "../widgets/AsyncWidget";
 | 
			
		||||
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
 | 
			
		||||
import { TimeWidget } from "../widgets/TimeWidget";
 | 
			
		||||
@@ -22,14 +22,17 @@ export function DevicesRoute(): React.ReactElement {
 | 
			
		||||
  const loadKey = React.useRef(1);
 | 
			
		||||
 | 
			
		||||
  const [list, setList] = React.useState<Device[] | undefined>();
 | 
			
		||||
  const [states, setStates] = React.useState<DevicesState | undefined>();
 | 
			
		||||
 | 
			
		||||
  const load = async () => {
 | 
			
		||||
    setList(await DeviceApi.ValidatedList());
 | 
			
		||||
    setStates(await DeviceApi.DevicesState());
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const reload = () => {
 | 
			
		||||
    loadKey.current += 1;
 | 
			
		||||
    setList(undefined);
 | 
			
		||||
    setStates(undefined);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
@@ -45,10 +48,16 @@ export function DevicesRoute(): React.ReactElement {
 | 
			
		||||
    >
 | 
			
		||||
      <AsyncWidget
 | 
			
		||||
        loadKey={loadKey.current}
 | 
			
		||||
        ready={!!list}
 | 
			
		||||
        ready={!!list && !!states}
 | 
			
		||||
        errMsg="Failed to load the list of validated devices!"
 | 
			
		||||
        load={load}
 | 
			
		||||
        build={() => <ValidatedDevicesList onReload={reload} list={list!} />}
 | 
			
		||||
        build={() => (
 | 
			
		||||
          <ValidatedDevicesList
 | 
			
		||||
            onReload={reload}
 | 
			
		||||
            list={list!}
 | 
			
		||||
            states={states!}
 | 
			
		||||
          />
 | 
			
		||||
        )}
 | 
			
		||||
      />
 | 
			
		||||
    </SolarEnergyRouteContainer>
 | 
			
		||||
  );
 | 
			
		||||
@@ -56,6 +65,7 @@ export function DevicesRoute(): React.ReactElement {
 | 
			
		||||
 | 
			
		||||
function ValidatedDevicesList(p: {
 | 
			
		||||
  list: Device[];
 | 
			
		||||
  states: DevicesState;
 | 
			
		||||
  onReload: () => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
@@ -75,6 +85,7 @@ function ValidatedDevicesList(p: {
 | 
			
		||||
            <TableCell>Max number of relays</TableCell>
 | 
			
		||||
            <TableCell>Created</TableCell>
 | 
			
		||||
            <TableCell>Updated</TableCell>
 | 
			
		||||
            <TableCell>Status</TableCell>
 | 
			
		||||
            <TableCell></TableCell>
 | 
			
		||||
          </TableRow>
 | 
			
		||||
        </TableHead>
 | 
			
		||||
@@ -97,6 +108,15 @@ function ValidatedDevicesList(p: {
 | 
			
		||||
              <TableCell>
 | 
			
		||||
                <TimeWidget time={dev.time_update} />
 | 
			
		||||
              </TableCell>
 | 
			
		||||
              <TableCell align="center">
 | 
			
		||||
                {p.states.get(dev.id)!.online ? (
 | 
			
		||||
                  <strong>Online</strong>
 | 
			
		||||
                ) : (
 | 
			
		||||
                  <em>Offline</em>
 | 
			
		||||
                )}
 | 
			
		||||
                <br />
 | 
			
		||||
                <TimeWidget diff time={p.states.get(dev.id)!.last_ping} />
 | 
			
		||||
              </TableCell>
 | 
			
		||||
              <TableCell>
 | 
			
		||||
                <Tooltip title="Open device page">
 | 
			
		||||
                  <Link to={DeviceURL(dev)}>
 | 
			
		||||
 
 | 
			
		||||
@@ -55,11 +55,14 @@ export function timeDiffFromNow(t: number): string {
 | 
			
		||||
  return timeDiff(t, time());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function TimeWidget(p: { time?: number }): React.ReactElement {
 | 
			
		||||
export function TimeWidget(p: {
 | 
			
		||||
  time?: number;
 | 
			
		||||
  diff?: boolean;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  if (!p.time) return <></>;
 | 
			
		||||
  return (
 | 
			
		||||
    <Tooltip title={formatDate(p.time)} arrow>
 | 
			
		||||
      <span>{timeDiffFromNow(p.time)}</span>
 | 
			
		||||
      <span>{p.diff ? timeDiff(0, p.time) : timeDiffFromNow(p.time)}</span>
 | 
			
		||||
    </Tooltip>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user