diff --git a/central_frontend/src/api/RelayApi.ts b/central_frontend/src/api/RelayApi.ts index 7296bef..7d6a8db 100644 --- a/central_frontend/src/api/RelayApi.ts +++ b/central_frontend/src/api/RelayApi.ts @@ -39,4 +39,14 @@ export class RelayApi { jsonData: relay, }); } + + /** + * Delete a relay configuration + */ + static async Delete(relay: DeviceRelay): Promise { + await APIClient.exec({ + method: "DELETE", + uri: `/relay/${relay.id}`, + }); + } } diff --git a/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx b/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx index ca9a161..e9d6479 100644 --- a/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx +++ b/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx @@ -4,9 +4,9 @@ import { DialogActions, DialogContent, DialogTitle, - Grid, Typography, } from "@mui/material"; +import Grid from "@mui/material/Grid2"; import { TimePicker } from "@mui/x-date-pickers"; import React from "react"; import { Device, DeviceRelay } from "../api/DeviceApi"; @@ -81,7 +81,7 @@ export function EditDeviceRelaysDialog(p: { General info - + - + - + - + - + - + Daily runtime - + - + - + - + Constraints - + - + void; }): React.ReactElement { + const confirm = useConfirm(); + const loadingMessage = useLoadingMessage(); + const snackbar = useSnackbar(); + const alert = useAlert(); + const [dialogOpen, setDialogOpen] = React.useState(false); const [currRelay, setCurrRelay] = React.useState(); @@ -17,6 +35,25 @@ export function DeviceRelays(p: { setCurrRelay(undefined); }; + const deleteRelay = async (r: DeviceRelay) => { + if ( + !(await confirm("Do you really want to delete this relay configuration?")) + ) + return; + + try { + await RelayApi.Delete(r); + + p.onReload(); + snackbar("The relay configuration was successfully deleted!"); + } catch (e) { + console.error("Failed to delete relay!", e); + alert(`Failed to delete device relay configuration! ${e}`); + } finally { + loadingMessage.hide(); + } + }; + return ( <> {dialogOpen && ( @@ -43,7 +80,39 @@ export function DeviceRelays(p: { } > - TODO : relays list ({p.device.relays.length}) relays now) + {p.device.relays.length === 0 ? ( + + No relay configured yet. + + ) : ( + <> + )} + + {p.device.relays.map((r, i) => ( + + + + + + + + {i === p.device.relays.length - 1 && ( + + deleteRelay(r)}> + + + + )} + + } + > + + + ))} ); diff --git a/central_frontend/src/routes/DeviceRoute/DeviceRoute.tsx b/central_frontend/src/routes/DeviceRoute/DeviceRoute.tsx index 50e0368..3e9ca9a 100644 --- a/central_frontend/src/routes/DeviceRoute/DeviceRoute.tsx +++ b/central_frontend/src/routes/DeviceRoute/DeviceRoute.tsx @@ -1,5 +1,5 @@ import DeleteIcon from "@mui/icons-material/Delete"; -import { Grid, IconButton, Tooltip } from "@mui/material"; +import { IconButton, Tooltip } from "@mui/material"; import React from "react"; import { useNavigate, useParams } from "react-router-dom"; import { Device, DeviceApi } from "../../api/DeviceApi"; @@ -11,6 +11,7 @@ import { AsyncWidget } from "../../widgets/AsyncWidget"; import { SolarEnergyRouteContainer } from "../../widgets/SolarEnergyRouteContainer"; import { GeneralDeviceInfo } from "./GeneralDeviceInfo"; import { DeviceRelays } from "./DeviceRelays"; +import Grid from "@mui/material/Grid2"; export function DeviceRoute(): React.ReactElement { const { id } = useParams(); @@ -81,10 +82,10 @@ function DeviceRouteInner(p: { } > - + - + diff --git a/central_frontend/src/routes/LoginRoute.tsx b/central_frontend/src/routes/LoginRoute.tsx index db20f04..6e1d582 100644 --- a/central_frontend/src/routes/LoginRoute.tsx +++ b/central_frontend/src/routes/LoginRoute.tsx @@ -4,7 +4,6 @@ import Avatar from "@mui/material/Avatar"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; import CssBaseline from "@mui/material/CssBaseline"; -import Grid from "@mui/material/Grid"; import Link from "@mui/material/Link"; import Paper from "@mui/material/Paper"; import TextField from "@mui/material/TextField"; @@ -12,6 +11,7 @@ import Typography from "@mui/material/Typography"; import * as React from "react"; import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider"; import { AuthApi } from "../api/AuthApi"; +import Grid from "@mui/material/Grid2"; function Copyright(props: any) { return ( @@ -60,10 +60,7 @@ export function LoginRoute() { @@ -74,7 +71,12 @@ export function LoginRoute() { backgroundPosition: "left", }} /> - +