frontend/src/objects/bulkEditForms/bulkBinSettings.tsx
2025-02-12 15:11:42 -06:00

246 lines
7.9 KiB
TypeScript

import { Button, Grid, InputAdornment, TextField } from "@material-ui/core";
import SearchSelect, { Option } from "common/SearchSelect";
import { GrainOptions } from "grain";
import { pond } from "protobuf-ts/pond";
import { useBinAPI, useSnackbar } from "providers";
import React, { useState } from "react";
import { fahrenheitToCelsius, getDistanceUnit, getTemperatureUnit } from "utils";
interface Props {
selectedBins: pond.Bin[];
refreshCallback: (reLoad: boolean) => void;
}
export default function BulkBinSettings(props: Props) {
const { selectedBins, refreshCallback } = props;
const binAPI = useBinAPI();
const { openSnack } = useSnackbar();
const gridItemWidth = 3;
// bin settings variables
const [name, setName] = useState<string | undefined>();
const [grainType, setGrainType] = useState<pond.Grain | undefined>();
const [grainOption, setGrainOption] = useState<Option | null>();
const [height, setHeight] = useState<number | undefined>();
const [diameter, setDiameter] = useState<number | undefined>();
const [customGrain, setCustomGrain] = useState<string | undefined>();
const [variant, setVariant] = useState<string | undefined>();
const [bushels, setBushels] = useState<number | undefined>();
const [capacity, setCapacity] = useState<number | undefined>();
const [highTemp, setHighTemp] = useState<number | undefined>();
const [lowTemp, setLowTemp] = useState<number | undefined>();
const convertedDistance = (enteredDistance: number) => {
if (getDistanceUnit() === pond.DistanceUnit.DISTANCE_UNIT_METERS) {
return enteredDistance * 100;
}
if (getDistanceUnit() === pond.DistanceUnit.DISTANCE_UNIT_FEET) {
return enteredDistance * 30.48;
}
return enteredDistance;
};
const convertedTemp = (enteredTemp: number) => {
let t = enteredTemp;
if (getTemperatureUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT) {
t = fahrenheitToCelsius(enteredTemp);
}
return t;
};
const updateBins = () => {
let binsToEdit: pond.BinSettings[] = [];
selectedBins.forEach(bin => {
if (bin.settings) {
if (bin.settings.inventory) {
if (grainType) bin.settings.inventory.grainType = grainType;
if (bushels) bin.settings.inventory.grainBushels = bushels;
if (customGrain) bin.settings.inventory.customTypeName = customGrain;
if (variant) bin.settings.inventory.grainSubtype = variant;
}
if (bin.settings.specs) {
if (height) bin.settings.specs.heightCm = convertedDistance(height);
if (diameter) bin.settings.specs.diameterCm = convertedDistance(diameter);
if (capacity) bin.settings.specs.bushelCapacity = capacity;
}
if (name) bin.settings.name = name;
if (highTemp) bin.settings.highTemp = convertedTemp(highTemp);
if (lowTemp) bin.settings.lowTemp = convertedTemp(lowTemp);
binsToEdit.push(bin.settings);
}
});
binAPI
.bulkBinUpdate(binsToEdit)
.then(resp => {
if (resp.data.successfull > 0) {
refreshCallback(true);
openSnack("Successfully updated " + resp.data.successfull + " bins");
}
})
.catch(err => {
openSnack("Failed to update bins");
});
};
return (
<React.Fragment>
<Grid container direction="row" spacing={2} alignContent="center" alignItems="center">
{/* first row */}
<Grid item xs={gridItemWidth}>
<TextField
fullWidth
label="Bin Name"
value={name ?? ""}
onChange={e => {
setName(e.target.value);
}}
/>
</Grid>
<Grid item xs={gridItemWidth}>
<SearchSelect
label="Grain Type"
selected={grainOption}
changeSelection={option => {
let newGrainType = option
? pond.Grain[option.value as keyof typeof pond.Grain]
: pond.Grain.GRAIN_INVALID;
setGrainType(newGrainType);
setGrainOption(option);
}}
group
options={GrainOptions()}
/>
</Grid>
<Grid item xs={gridItemWidth}>
<TextField
fullWidth
label="Grain Variant"
value={variant ?? ""}
onChange={e => {
setVariant(e.target.value);
}}
/>
</Grid>
{/* second row */}
<Grid item xs={gridItemWidth}>
<TextField
fullWidth
label="Custom Grain"
value={customGrain ?? ""}
onChange={e => {
setCustomGrain(e.target.value);
}}
/>
</Grid>
<Grid item xs={gridItemWidth}>
<TextField
fullWidth
label="Bushels"
type="number"
value={bushels ?? ""}
onChange={e => {
setBushels(parseFloat(e.target.value));
}}
/>
</Grid>
<Grid item xs={gridItemWidth}>
<TextField
fullWidth
label="Capacity"
type="number"
value={capacity ?? ""}
onChange={e => {
setCapacity(parseFloat(e.target.value));
}}
/>
</Grid>
{/* last row */}
<Grid item xs={gridItemWidth}>
<TextField
fullWidth
label="Bin Height"
type="number"
value={height ?? ""}
onChange={e => {
setHeight(parseFloat(e.target.value));
}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
{getDistanceUnit() !== pond.DistanceUnit.DISTANCE_UNIT_FEET ? "m" : "ft"}
</InputAdornment>
)
}}
/>
</Grid>
<Grid item xs={gridItemWidth}>
<TextField
fullWidth
label="Bin Diameter"
type="number"
value={diameter ?? ""}
onChange={e => {
setDiameter(parseFloat(e.target.value));
}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
{getDistanceUnit() !== pond.DistanceUnit.DISTANCE_UNIT_FEET ? "m" : "ft"}
</InputAdornment>
)
}}
/>
</Grid>
<Grid item xs={gridItemWidth}>
<TextField
fullWidth
label="High Temp Warning"
type="number"
value={highTemp ?? ""}
onChange={e => {
setHighTemp(parseFloat(e.target.value));
}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
{getTemperatureUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT
? "°F"
: "°C"}
</InputAdornment>
)
}}
/>
</Grid>
<Grid item xs={gridItemWidth}>
<TextField
fullWidth
label="Low Temp Warning"
type="number"
value={lowTemp ?? ""}
onChange={e => {
setLowTemp(parseFloat(e.target.value));
}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
{getTemperatureUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT
? "°F"
: "°C"}
</InputAdornment>
)
}}
/>
</Grid>
<Grid item xs={gridItemWidth}>
<Button
variant="contained"
color="primary"
onClick={() => {
updateBins();
}}>
Update selected Bins
</Button>
</Grid>
</Grid>
</React.Fragment>
);
}