Add select for relays
This commit is contained in:
		@@ -12,8 +12,10 @@ export interface DailyMinRuntime {
 | 
			
		||||
  catch_up_hours: number[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type RelayID = string;
 | 
			
		||||
 | 
			
		||||
export interface DeviceRelay {
 | 
			
		||||
  id: string;
 | 
			
		||||
  id: RelayID;
 | 
			
		||||
  name: string;
 | 
			
		||||
  enabled: boolean;
 | 
			
		||||
  priority: number;
 | 
			
		||||
@@ -21,8 +23,8 @@ export interface DeviceRelay {
 | 
			
		||||
  minimal_uptime: number;
 | 
			
		||||
  minimal_downtime: number;
 | 
			
		||||
  daily_runtime?: DailyMinRuntime;
 | 
			
		||||
  depends_on: DeviceRelay[];
 | 
			
		||||
  conflicts_with: DeviceRelay[];
 | 
			
		||||
  depends_on: RelayID[];
 | 
			
		||||
  conflicts_with: RelayID[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Device {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								central_frontend/src/api/RelayApi.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								central_frontend/src/api/RelayApi.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
import { APIClient } from "./ApiClient";
 | 
			
		||||
import { DeviceRelay } from "./DeviceApi";
 | 
			
		||||
 | 
			
		||||
export class RelayApi {
 | 
			
		||||
  /**
 | 
			
		||||
   * Get the full list of relays
 | 
			
		||||
   */
 | 
			
		||||
  static async GetList(): Promise<DeviceRelay[]> {
 | 
			
		||||
    return (
 | 
			
		||||
      await APIClient.exec({
 | 
			
		||||
        method: "GET",
 | 
			
		||||
        uri: "/relays/list",
 | 
			
		||||
      })
 | 
			
		||||
    ).data;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -17,8 +17,9 @@ import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
 | 
			
		||||
import { dayjsToTimeOfDay, timeOfDay } from "../utils/DateUtils";
 | 
			
		||||
import { lenValid } from "../utils/StringsUtils";
 | 
			
		||||
import { CheckboxInput } from "../widgets/forms/CheckboxInput";
 | 
			
		||||
import { TextInput } from "../widgets/forms/TextInput";
 | 
			
		||||
import { MultipleSelectInput } from "../widgets/forms/MultipleSelectInput";
 | 
			
		||||
import { SelectMultipleRelaysInput } from "../widgets/forms/SelectMultipleRelaysInput";
 | 
			
		||||
import { TextInput } from "../widgets/forms/TextInput";
 | 
			
		||||
 | 
			
		||||
export function EditDeviceRelaysDialog(p: {
 | 
			
		||||
  onClose: () => void;
 | 
			
		||||
@@ -270,6 +271,42 @@ export function EditDeviceRelaysDialog(p: {
 | 
			
		||||
            </>
 | 
			
		||||
          )}
 | 
			
		||||
        </Grid>
 | 
			
		||||
 | 
			
		||||
        <DialogFormTitle>Constraints</DialogFormTitle>
 | 
			
		||||
        <Grid container spacing={2}>
 | 
			
		||||
          <Grid item xs={6}>
 | 
			
		||||
            <SelectMultipleRelaysInput
 | 
			
		||||
              label="Required relays"
 | 
			
		||||
              exclude={[relay.id]}
 | 
			
		||||
              value={relay.depends_on}
 | 
			
		||||
              onValueChange={(v) =>
 | 
			
		||||
                setRelay((r) => {
 | 
			
		||||
                  return {
 | 
			
		||||
                    ...r,
 | 
			
		||||
                    depends_on: v,
 | 
			
		||||
                  };
 | 
			
		||||
                })
 | 
			
		||||
              }
 | 
			
		||||
              helperText="Relays that must be already up for this relay to be started"
 | 
			
		||||
            />
 | 
			
		||||
          </Grid>
 | 
			
		||||
          <Grid item xs={6}>
 | 
			
		||||
            <SelectMultipleRelaysInput
 | 
			
		||||
              label="Conflicting relays"
 | 
			
		||||
              exclude={[relay.id]}
 | 
			
		||||
              value={relay.conflicts_with}
 | 
			
		||||
              onValueChange={(v) =>
 | 
			
		||||
                setRelay((r) => {
 | 
			
		||||
                  return {
 | 
			
		||||
                    ...r,
 | 
			
		||||
                    conflicts_with: v,
 | 
			
		||||
                  };
 | 
			
		||||
                })
 | 
			
		||||
              }
 | 
			
		||||
              helperText="Relays that must be off before this relay can be started"
 | 
			
		||||
            />
 | 
			
		||||
          </Grid>
 | 
			
		||||
        </Grid>
 | 
			
		||||
      </DialogContent>
 | 
			
		||||
      <DialogActions>
 | 
			
		||||
        <Button onClick={p.onClose}>Cancel</Button>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,44 @@
 | 
			
		||||
import React from "react";
 | 
			
		||||
import { DeviceRelay, RelayID } from "../../api/DeviceApi";
 | 
			
		||||
import { RelayApi } from "../../api/RelayApi";
 | 
			
		||||
import { AsyncWidget } from "../AsyncWidget";
 | 
			
		||||
import { MultipleSelectInput } from "./MultipleSelectInput";
 | 
			
		||||
 | 
			
		||||
export function SelectMultipleRelaysInput(p: {
 | 
			
		||||
  label: string;
 | 
			
		||||
  value: RelayID[];
 | 
			
		||||
  onValueChange: (ids: RelayID[]) => void;
 | 
			
		||||
  exclude?: RelayID[];
 | 
			
		||||
  helperText?: string;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  const [list, setList] = React.useState<DeviceRelay[]>();
 | 
			
		||||
 | 
			
		||||
  const load = async () => {
 | 
			
		||||
    setList(await RelayApi.GetList());
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const values =
 | 
			
		||||
    list?.map((r) => {
 | 
			
		||||
      return {
 | 
			
		||||
        label: r.name,
 | 
			
		||||
        value: r.id,
 | 
			
		||||
      };
 | 
			
		||||
    }) ?? [];
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <AsyncWidget
 | 
			
		||||
      loadKey={1}
 | 
			
		||||
      load={load}
 | 
			
		||||
      errMsg="Failed to load the list of relays!"
 | 
			
		||||
      build={() => (
 | 
			
		||||
        <MultipleSelectInput
 | 
			
		||||
          label={p.label}
 | 
			
		||||
          onChange={p.onValueChange}
 | 
			
		||||
          selected={p.value}
 | 
			
		||||
          helperText={p.helperText}
 | 
			
		||||
          values={values}
 | 
			
		||||
        />
 | 
			
		||||
      )}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user