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