From 596d22739dc05a95996ccd5450db4f5216e9e6c7 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Mon, 29 Jul 2024 23:13:53 +0200 Subject: [PATCH] Can select catchup hours --- .../src/dialogs/EditDeviceRelaysDialog.tsx | 16 ++- .../src/widgets/forms/MultipleSelectInput.tsx | 113 ++++++++++++++++++ 2 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 central_frontend/src/widgets/forms/MultipleSelectInput.tsx diff --git a/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx b/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx index 8639925..1d3f898 100644 --- a/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx +++ b/central_frontend/src/dialogs/EditDeviceRelaysDialog.tsx @@ -18,6 +18,7 @@ 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"; export function EditDeviceRelaysDialog(p: { onClose: () => void; @@ -243,16 +244,23 @@ export function EditDeviceRelaysDialog(p: { /> - { + return { + label: `${i.toString().padStart(2, "0")}:00`, + value: i, + }; + })} + selected={relay.daily_runtime!.catch_up_hours} onChange={(d) => setRelay((r) => { return { ...r, daily_runtime: { ...r.daily_runtime!, - reset_time: d ? dayjsToTimeOfDay(d) : 0, + catch_up_hours: d, }, }; }) diff --git a/central_frontend/src/widgets/forms/MultipleSelectInput.tsx b/central_frontend/src/widgets/forms/MultipleSelectInput.tsx new file mode 100644 index 0000000..72cd80c --- /dev/null +++ b/central_frontend/src/widgets/forms/MultipleSelectInput.tsx @@ -0,0 +1,113 @@ +import { + FormControl, + InputLabel, + Select, + OutlinedInput, + Box, + Chip, + MenuItem, + Theme, + useTheme, + SelectChangeEvent, + FormHelperText, +} from "@mui/material"; +import React from "react"; + +export interface Value { + label: string; + value: E; +} + +const ITEM_HEIGHT = 48; +const ITEM_PADDING_TOP = 8; + +const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 250, + }, + }, +}; + +function getStyles(v: Value, selected: readonly E[], theme: Theme) { + return { + fontWeight: + selected.find((e) => e === v.value) === undefined + ? theme.typography.fontWeightRegular + : theme.typography.fontWeightMedium, + }; +} + +export function MultipleSelectInput(p: { + values: Value[]; + selected: E[]; + label: string; + onChange: (selected: E[]) => void; + helperText?: string; +}): React.ReactElement { + const [labelId] = React.useState(`id-multi-${Math.random()}`); + + const theme = useTheme(); + + const handleChange = (event: SelectChangeEvent) => { + const { + target: { value }, + } = event; + + const values: any[] = + typeof value === "string" ? value.split(",") : (value as any); + + const newVals = values.map( + (v) => p.values.find((e) => String(e.value) === String(v))!.value + ); + + // Values that appear multiple times are toggled + const setVal = new Set(); + for (const el of newVals) { + if (!setVal.has(el)) setVal.add(el); + else setVal.delete(el); + } + + p.onChange([...setVal]); + }; + + return ( +
+ + {p.label} + + {p.helperText && {p.helperText}} + +
+ ); +}