Can select catchup hours

This commit is contained in:
Pierre HUBERT 2024-07-29 23:13:53 +02:00
parent 8a65687970
commit 596d22739d
2 changed files with 125 additions and 4 deletions

View File

@ -18,6 +18,7 @@ import { dayjsToTimeOfDay, timeOfDay } from "../utils/DateUtils";
import { lenValid } from "../utils/StringsUtils"; import { lenValid } from "../utils/StringsUtils";
import { CheckboxInput } from "../widgets/forms/CheckboxInput"; import { CheckboxInput } from "../widgets/forms/CheckboxInput";
import { TextInput } from "../widgets/forms/TextInput"; import { TextInput } from "../widgets/forms/TextInput";
import { MultipleSelectInput } from "../widgets/forms/MultipleSelectInput";
export function EditDeviceRelaysDialog(p: { export function EditDeviceRelaysDialog(p: {
onClose: () => void; onClose: () => void;
@ -243,16 +244,23 @@ export function EditDeviceRelaysDialog(p: {
/> />
</Grid> </Grid>
<Grid item xs={6}> <Grid item xs={6}>
<TimePicker <MultipleSelectInput
label="Catch up hours" label="Catchup hours"
value={timeOfDay(relay.daily_runtime!.reset_time)} helperText="The hours during which the relay should be turned on to reach expected runtime"
values={Array.apply(null, Array(24)).map((_y, i) => {
return {
label: `${i.toString().padStart(2, "0")}:00`,
value: i,
};
})}
selected={relay.daily_runtime!.catch_up_hours}
onChange={(d) => onChange={(d) =>
setRelay((r) => { setRelay((r) => {
return { return {
...r, ...r,
daily_runtime: { daily_runtime: {
...r.daily_runtime!, ...r.daily_runtime!,
reset_time: d ? dayjsToTimeOfDay(d) : 0, catch_up_hours: d,
}, },
}; };
}) })

View File

@ -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<E> {
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<E>(v: Value<E>, selected: readonly E[], theme: Theme) {
return {
fontWeight:
selected.find((e) => e === v.value) === undefined
? theme.typography.fontWeightRegular
: theme.typography.fontWeightMedium,
};
}
export function MultipleSelectInput<E>(p: {
values: Value<E>[];
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<E>) => {
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<E>();
for (const el of newVals) {
if (!setVal.has(el)) setVal.add(el);
else setVal.delete(el);
}
p.onChange([...setVal]);
};
return (
<div>
<FormControl fullWidth>
<InputLabel id={labelId}>{p.label}</InputLabel>
<Select
multiple
labelId={labelId}
id="bad"
label={p.label}
value={p.selected as any}
onChange={handleChange}
input={<OutlinedInput id="select-multiple-chip" label="Chip" />}
renderValue={(selected) => (
<Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
{(selected as Array<E>).map((value) => (
<Chip
key={String(value)}
label={p.values.find((e) => e.value === value)!.label}
/>
))}
</Box>
)}
MenuProps={MenuProps}
>
{p.values.map((v) => (
<MenuItem
key={v.label + String(v)}
value={String(v.value)}
style={getStyles(v, p.selected, theme)}
>
{v.label}
</MenuItem>
))}
</Select>
{p.helperText && <FormHelperText>{p.helperText}</FormHelperText>}
</FormControl>
</div>
);
}