155 lines
4.3 KiB
TypeScript
155 lines
4.3 KiB
TypeScript
import AddIcon from "@mui/icons-material/Add";
|
|
import DeleteIcon from "@mui/icons-material/Delete";
|
|
import EditIcon from "@mui/icons-material/Edit";
|
|
import {
|
|
IconButton,
|
|
ListItem,
|
|
ListItemText,
|
|
Tooltip,
|
|
Typography,
|
|
} from "@mui/material";
|
|
import React from "react";
|
|
import { Device, DeviceRelay } from "../../api/DeviceApi";
|
|
import { EditDeviceRelaysDialog } from "../../dialogs/EditDeviceRelaysDialog";
|
|
import { DeviceRouteCard } from "./DeviceRouteCard";
|
|
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
|
|
import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageProvider";
|
|
import { RelayApi, RelayStatus } from "../../api/RelayApi";
|
|
import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider";
|
|
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
|
import { AsyncWidget } from "../../widgets/AsyncWidget";
|
|
import { TimeWidget } from "../../widgets/TimeWidget";
|
|
import { BoolText } from "../../widgets/BoolText";
|
|
|
|
export function DeviceRelays(p: {
|
|
device: Device;
|
|
onReload: () => 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<DeviceRelay | undefined>();
|
|
|
|
const createNewRelay = () => {
|
|
setDialogOpen(true);
|
|
setCurrRelay(undefined);
|
|
};
|
|
|
|
const updateRelay = async (r: DeviceRelay) => {
|
|
setDialogOpen(true);
|
|
setCurrRelay(r);
|
|
};
|
|
|
|
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 && (
|
|
<EditDeviceRelaysDialog
|
|
device={p.device}
|
|
onClose={() => setDialogOpen(false)}
|
|
relay={currRelay}
|
|
onUpdated={() => {
|
|
setDialogOpen(false);
|
|
p.onReload();
|
|
}}
|
|
/>
|
|
)}
|
|
<DeviceRouteCard
|
|
title="Device relays"
|
|
actions={
|
|
<Tooltip title="Create new relay">
|
|
<IconButton
|
|
onClick={createNewRelay}
|
|
disabled={p.device.relays.length >= p.device.info.max_relays}
|
|
>
|
|
<AddIcon />
|
|
</IconButton>
|
|
</Tooltip>
|
|
}
|
|
>
|
|
{p.device.relays.length === 0 ? (
|
|
<Typography style={{ textAlign: "center" }}>
|
|
No relay configured yet.
|
|
</Typography>
|
|
) : (
|
|
<></>
|
|
)}
|
|
|
|
{p.device.relays.map((r, i) => (
|
|
<ListItem
|
|
alignItems="flex-start"
|
|
key={r.id}
|
|
secondaryAction={
|
|
<>
|
|
<Tooltip title="Edit the relay configuration">
|
|
<IconButton onClick={() => updateRelay(r)}>
|
|
<EditIcon />
|
|
</IconButton>
|
|
</Tooltip>
|
|
|
|
{i === p.device.relays.length - 1 && (
|
|
<Tooltip title="Delete the relay configuration">
|
|
<IconButton onClick={() => deleteRelay(r)}>
|
|
<DeleteIcon />
|
|
</IconButton>
|
|
</Tooltip>
|
|
)}
|
|
</>
|
|
}
|
|
>
|
|
<ListItemText
|
|
primary={r.name}
|
|
secondary={<RelayEntryStatus relay={r} />}
|
|
/>
|
|
</ListItem>
|
|
))}
|
|
</DeviceRouteCard>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function RelayEntryStatus(
|
|
p: Readonly<{ relay: DeviceRelay }>
|
|
): React.ReactElement {
|
|
const [state, setState] = React.useState<RelayStatus | undefined>();
|
|
|
|
const load = async () => {
|
|
setState(await RelayApi.SingleStatus(p.relay));
|
|
};
|
|
|
|
return (
|
|
<AsyncWidget
|
|
loadKey={p.relay.id}
|
|
load={load}
|
|
errMsg="Failed to load relay status!"
|
|
build={() => (
|
|
<>
|
|
<BoolText val={state!.on} positive="ON" negative="OFF" /> for{" "}
|
|
<TimeWidget diff time={state!.for} />
|
|
</>
|
|
)}
|
|
/>
|
|
);
|
|
}
|