diff --git a/central_frontend/src/api/DeviceApi.ts b/central_frontend/src/api/DeviceApi.ts index 5024df9..4820405 100644 --- a/central_frontend/src/api/DeviceApi.ts +++ b/central_frontend/src/api/DeviceApi.ts @@ -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 { diff --git a/central_frontend/src/api/RelayApi.ts b/central_frontend/src/api/RelayApi.ts new file mode 100644 index 0000000..33f7546 --- /dev/null +++ b/central_frontend/src/api/RelayApi.ts @@ -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 { + return ( + await APIClient.exec({ + method: "GET", + uri: "/relays/list", + }) + ).data; + } +} diff --git a/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx b/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx index 1d3f898..c042692 100644 --- a/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx +++ b/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx @@ -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: { )} + + Constraints + + + + setRelay((r) => { + return { + ...r, + depends_on: v, + }; + }) + } + helperText="Relays that must be already up for this relay to be started" + /> + + + + setRelay((r) => { + return { + ...r, + conflicts_with: v, + }; + }) + } + helperText="Relays that must be off before this relay can be started" + /> + + diff --git a/central_frontend/src/widgets/forms/SelectMultipleRelaysInput.tsx b/central_frontend/src/widgets/forms/SelectMultipleRelaysInput.tsx new file mode 100644 index 0000000..adbcf0b --- /dev/null +++ b/central_frontend/src/widgets/forms/SelectMultipleRelaysInput.tsx @@ -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(); + + const load = async () => { + setList(await RelayApi.GetList()); + }; + + const values = + list?.map((r) => { + return { + label: r.name, + value: r.id, + }; + }) ?? []; + + return ( + ( + + )} + /> + ); +}