updated the grain describers to use the new enum in the pond for the moisture calculation, changed the extract moisture function to account for custom grain types, and if there is no equation set it will return the humidity, updated instances where the bin uses that function to pass in the grain settings in its inventory
This commit is contained in:
parent
bdddcfc103
commit
d6c670fb78
16 changed files with 596 additions and 140 deletions
286
src/grain/CustomGrainForm.tsx
Normal file
286
src/grain/CustomGrainForm.tsx
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
import { Box, Button, MenuItem, TextField, Typography } from "@mui/material"
|
||||
import SearchSelect, { Option } from "common/SearchSelect"
|
||||
import { cloneDeep } from "lodash"
|
||||
import { pond } from "protobuf-ts/pond"
|
||||
import { useGlobalState } from "providers"
|
||||
import { useGrainAPI } from "providers/pond/grainAPI"
|
||||
import React, { useEffect, useState } from "react"
|
||||
|
||||
interface Props {
|
||||
grainSettings?: pond.GrainSettings
|
||||
onGrainSettingsChange: (settings: pond.GrainSettings) => void
|
||||
}
|
||||
|
||||
export default function CustomGrainForm(props: Props) {
|
||||
const {grainSettings, onGrainSettingsChange} = props
|
||||
const grainAPI = useGrainAPI()
|
||||
const [{as}] = useGlobalState()
|
||||
const [name, setName] = useState("")
|
||||
const [group, setGroup] = useState("")
|
||||
const [equation, setEquation] = useState<pond.MoistureEquation>(pond.MoistureEquation.MOISTURE_EQUATION_NONE)
|
||||
const [constantA, setConstantA] = useState("0")
|
||||
const [constantB, setConstantB] = useState("0")
|
||||
const [constantC, setConstantC] = useState("0")
|
||||
const [kgPerBushel, setKgPerBushel] = useState("0")
|
||||
const [bushelsPerTonne, setBushelsPerTonne] = useState("0")
|
||||
const [newGrainSettings, setNewGrainSettings] = useState(pond.GrainSettings.create())
|
||||
const [grainMap, setGrainMap] = useState<Map<string, pond.GrainObject>>(new Map())
|
||||
const [grainOptions, setGrainOptions] = useState<Option[]>([])
|
||||
const [isNew, setIsNew] = useState(false)
|
||||
const [selectedOption, setSelectedOption] = useState<Option | null>(null)
|
||||
|
||||
useEffect(()=>{
|
||||
if(grainSettings){
|
||||
setNewGrainSettings(grainSettings)
|
||||
setName(grainSettings.name)
|
||||
setGroup(grainSettings.group)
|
||||
setEquation(grainSettings.equation)
|
||||
setConstantA(grainSettings.a.toString())
|
||||
setConstantB(grainSettings.b.toString())
|
||||
setConstantC(grainSettings.c.toString())
|
||||
setKgPerBushel(grainSettings.kgPerBushel.toString())
|
||||
setBushelsPerTonne(grainSettings.bushelsPerTonne.toString())
|
||||
}
|
||||
},[grainSettings])
|
||||
|
||||
useEffect(()=>{
|
||||
grainAPI.listGrains(0, 0, "asc", "name", undefined, undefined, undefined, as).then(resp => {
|
||||
if (resp.data.grains){
|
||||
let map: Map<string, pond.GrainObject> = new Map()
|
||||
let options: Option[] = []
|
||||
resp.data.grains.forEach(grain => {
|
||||
map.set(grain.key, grain)
|
||||
options.push({
|
||||
label: grain.name,
|
||||
value: grain.key,
|
||||
group: grain.settings?.group,
|
||||
})
|
||||
})
|
||||
setGrainOptions(options)
|
||||
setGrainMap(map)
|
||||
}
|
||||
})
|
||||
},[grainAPI])
|
||||
|
||||
const invalid = () => {
|
||||
if (name === "") return true
|
||||
if (group === "") return true
|
||||
if (isNaN(parseFloat(constantA))) return true
|
||||
if (isNaN(parseFloat(constantB))) return true
|
||||
if (isNaN(parseFloat(constantA))) return true
|
||||
if (isNaN(parseFloat(kgPerBushel))) return true
|
||||
if (isNaN(parseFloat(bushelsPerTonne))) return true
|
||||
return false
|
||||
}
|
||||
|
||||
const saveGrain = () => {
|
||||
// console.log(newGrainSettings)
|
||||
grainAPI.addGrain(newGrainSettings, as).then(resp => {
|
||||
console.log("grain added")
|
||||
}).catch(err => {
|
||||
console.log("err")
|
||||
})
|
||||
}
|
||||
|
||||
const settingsChanged = (newSettings: pond.GrainSettings) => {
|
||||
setSelectedOption(null)
|
||||
setNewGrainSettings(newSettings)
|
||||
onGrainSettingsChange(newSettings)
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Box sx={{marginBottom: 2}}>
|
||||
<SearchSelect
|
||||
label="My Grains"
|
||||
selected={selectedOption}
|
||||
changeSelection={option => {
|
||||
setIsNew(false)
|
||||
setSelectedOption(option)
|
||||
//when an option is selected set all of the state variables controlling the form entries
|
||||
let grain = grainMap.get(option?.value)
|
||||
if(grain && grain.settings){
|
||||
//set the form values
|
||||
setName(grain.name)
|
||||
setGroup(grain.settings.group)
|
||||
setEquation(grain.settings.equation)
|
||||
setConstantA(grain.settings.a.toString())
|
||||
setConstantB(grain.settings.b.toString())
|
||||
setConstantC(grain.settings.c.toString())
|
||||
setKgPerBushel(grain.settings.kgPerBushel.toString())
|
||||
setBushelsPerTonne(grain.settings.bushelsPerTonne.toString())
|
||||
//the the new grain settings object
|
||||
setNewGrainSettings(grain.settings)
|
||||
//pass that settings object back up
|
||||
settingsChanged(grain.settings)
|
||||
}
|
||||
}}
|
||||
group
|
||||
options={grainOptions}
|
||||
/>
|
||||
</Box>
|
||||
<Typography sx={{marginBottom: 1}}>Custom Grain Properties</Typography>
|
||||
<TextField
|
||||
sx={{marginBottom: 2}}
|
||||
fullWidth
|
||||
label="Name*"
|
||||
value={name}
|
||||
onChange={(e) => {
|
||||
let name = e.target.value
|
||||
setName(name)
|
||||
setIsNew(true)
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.name = name
|
||||
settingsChanged(settings)
|
||||
}}/>
|
||||
<TextField
|
||||
sx={{marginBottom: 2}}
|
||||
fullWidth
|
||||
label="Group*"
|
||||
value={group}
|
||||
onChange={(e) => {
|
||||
let group = e.target.value
|
||||
setGroup(group)
|
||||
setIsNew(true)
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.group = group
|
||||
settingsChanged(settings)
|
||||
}}/>
|
||||
<TextField
|
||||
sx={{marginBottom: 2}}
|
||||
fullWidth
|
||||
value={equation}
|
||||
helperText={"Not selecting an EMC equation to use will return the humidity instead of EMC"}
|
||||
label="EMC Equation"
|
||||
onChange={(e) => {
|
||||
let enumVal = parseFloat(e.target.value)
|
||||
setEquation(enumVal)
|
||||
setIsNew(true)
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.equation = enumVal
|
||||
settingsChanged(settings)
|
||||
}}
|
||||
select>
|
||||
<MenuItem key={pond.MoistureEquation.MOISTURE_EQUATION_NONE} value={pond.MoistureEquation.MOISTURE_EQUATION_NONE}>
|
||||
None
|
||||
</MenuItem>
|
||||
<MenuItem key={pond.MoistureEquation.MOISTURE_EQUATION_CHUNG_PFOST} value={pond.MoistureEquation.MOISTURE_EQUATION_CHUNG_PFOST}>
|
||||
Chung-Pfost
|
||||
</MenuItem>
|
||||
<MenuItem key={pond.MoistureEquation.MOISTURE_EQUATION_HENDERSON} value={pond.MoistureEquation.MOISTURE_EQUATION_HENDERSON}>
|
||||
Henderson
|
||||
</MenuItem>
|
||||
<MenuItem key={pond.MoistureEquation.MOISTURE_EQUATION_HALSEY} value={pond.MoistureEquation.MOISTURE_EQUATION_HALSEY}>
|
||||
Halsey
|
||||
</MenuItem>
|
||||
<MenuItem key={pond.MoistureEquation.MOISTURE_EQUATION_OSWIN} value={pond.MoistureEquation.MOISTURE_EQUATION_OSWIN}>
|
||||
Oswin
|
||||
</MenuItem>
|
||||
</TextField>
|
||||
<TextField
|
||||
sx={{marginBottom: 2}}
|
||||
fullWidth
|
||||
type="number"
|
||||
value={constantA}
|
||||
error={isNaN(parseFloat(constantA))}
|
||||
helperText={isNaN(parseFloat(constantA)) ? "Must be a valid number" : ""}
|
||||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setConstantA(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.a = parseFloat(val)
|
||||
settingsChanged(settings)
|
||||
}
|
||||
}}
|
||||
label="Constant A"/>
|
||||
<TextField
|
||||
sx={{marginBottom: 2}}
|
||||
fullWidth
|
||||
type="number"
|
||||
value={constantB}
|
||||
error={isNaN(parseFloat(constantB))}
|
||||
helperText={isNaN(parseFloat(constantB)) ? "Must be a valid number" : ""}
|
||||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setConstantB(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.b = parseFloat(val)
|
||||
settingsChanged(settings)
|
||||
}
|
||||
}}
|
||||
label="Constant B"/>
|
||||
<TextField
|
||||
sx={{marginBottom: 2}}
|
||||
fullWidth
|
||||
type="number"
|
||||
value={constantC}
|
||||
error={isNaN(parseFloat(constantC))}
|
||||
helperText={isNaN(parseFloat(constantC)) ? "Must be a valid number" : ""}
|
||||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setConstantC(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.c = parseFloat(val)
|
||||
settingsChanged(settings)
|
||||
}
|
||||
}}
|
||||
label="Constant C"/>
|
||||
<TextField
|
||||
sx={{marginBottom: 2}}
|
||||
fullWidth
|
||||
type="number"
|
||||
value={kgPerBushel}
|
||||
error={isNaN(parseFloat(kgPerBushel))}
|
||||
helperText={isNaN(parseFloat(kgPerBushel)) ? "Must be a valid number" : ""}
|
||||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setKgPerBushel(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.kgPerBushel = parseFloat(val)
|
||||
settingsChanged(settings)
|
||||
}
|
||||
}}
|
||||
label="kg per Bushel"/>
|
||||
<TextField
|
||||
sx={{marginBottom: 2}}
|
||||
fullWidth
|
||||
type="number"
|
||||
value={bushelsPerTonne}
|
||||
error={isNaN(parseFloat(bushelsPerTonne))}
|
||||
helperText={isNaN(parseFloat(bushelsPerTonne)) ? "Must be a valid number" : ""}
|
||||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setBushelsPerTonne(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.bushelsPerTonne = parseFloat(val)
|
||||
settingsChanged(settings)
|
||||
}
|
||||
}}
|
||||
label="Bushels per Tonne"/>
|
||||
{isNew &&
|
||||
<Box display='flex' justifyContent="flex-end">
|
||||
<Button
|
||||
variant="contained"
|
||||
disabled={invalid()}
|
||||
onClick={() => {
|
||||
saveGrain()
|
||||
setIsNew(false)
|
||||
}}
|
||||
color="primary">
|
||||
Save Custom Grain
|
||||
</Button>
|
||||
</Box>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue