changed the component used in the bin and component settings to the grain selector and split out the form into another component that handles just the form and passing up a grainSettings object from its fields
This commit is contained in:
parent
49aa08f232
commit
27590da78f
7 changed files with 225 additions and 151 deletions
|
|
@ -1,74 +1,37 @@
|
|||
import { ExpandMore } from "@mui/icons-material"
|
||||
import { Accordion, AccordionDetails, AccordionSummary, Box, Button, MenuItem, TextField, Typography } from "@mui/material"
|
||||
import SearchSelect, { Option } from "common/SearchSelect"
|
||||
import {MenuItem, TextField } from "@mui/material"
|
||||
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 {
|
||||
initialGrain?: pond.GrainSettings
|
||||
onGrainSettingsChange: (settings: pond.GrainSettings) => void
|
||||
grainSettings?: pond.GrainSettings
|
||||
onGrainSettingsChange: (settings: pond.GrainSettings, formValid: boolean) => void
|
||||
}
|
||||
|
||||
export default function CustomGrainForm(props: Props) {
|
||||
const {initialGrain, onGrainSettingsChange} = props
|
||||
const grainAPI = useGrainAPI()
|
||||
const [{as}] = useGlobalState()
|
||||
const [name, setName] = useState(initialGrain ? initialGrain.name : "")
|
||||
const [group, setGroup] = useState(initialGrain ? initialGrain.group : "")
|
||||
const [equation, setEquation] = useState<pond.MoistureEquation>(initialGrain ? initialGrain.equation : pond.MoistureEquation.MOISTURE_EQUATION_NONE)
|
||||
const [constantA, setConstantA] = useState(initialGrain ? initialGrain.a.toString() : "0")
|
||||
const [constantB, setConstantB] = useState(initialGrain ? initialGrain.b.toString() : "0")
|
||||
const [constantC, setConstantC] = useState(initialGrain ? initialGrain.c.toString() : "0")
|
||||
const [kgPerBushel, setKgPerBushel] = useState(initialGrain ? initialGrain.kgPerBushel.toString() : "0")
|
||||
const [bushelsPerTonne, setBushelsPerTonne] = useState(initialGrain ? initialGrain.bushelsPerTonne.toString() : "0")
|
||||
const [newGrainSettings, setNewGrainSettings] = useState(initialGrain ?? pond.GrainSettings.create())
|
||||
const [grainMap, setGrainMap] = useState<Map<string, pond.GrainObject>>(
|
||||
initialGrain ?
|
||||
new Map([
|
||||
["Active", pond.GrainObject.create({key: "Active", name: initialGrain.name, settings: initialGrain})]
|
||||
])
|
||||
:
|
||||
new Map())
|
||||
const [grainOptions, setGrainOptions] = useState<Option[]>(
|
||||
initialGrain ?
|
||||
[
|
||||
{
|
||||
label: initialGrain.name,
|
||||
value: "Active",
|
||||
group: "Active"
|
||||
}
|
||||
]
|
||||
:
|
||||
[]
|
||||
)
|
||||
const [isNew, setIsNew] = useState(false)
|
||||
const [selectedOption, setSelectedOption] = useState<Option | null>(initialGrain ? {
|
||||
label: initialGrain.name,
|
||||
value: "Active",
|
||||
group: "Active"
|
||||
} : null)
|
||||
const {grainSettings, onGrainSettingsChange} = props
|
||||
const [newGrainSettings, setNewGrainSettings] = useState(pond.GrainSettings.create())
|
||||
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")
|
||||
|
||||
useEffect(()=>{
|
||||
grainAPI.listGrains(0, 0, "asc", "name", undefined, undefined, undefined, as).then(resp => {
|
||||
let options: Option[] = grainOptions
|
||||
let map: Map<string, pond.GrainObject> = grainMap
|
||||
if (resp.data.grains){
|
||||
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])
|
||||
if(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])
|
||||
|
||||
const invalid = () => {
|
||||
if (name === "") return true
|
||||
|
|
@ -81,21 +44,12 @@ export default function CustomGrainForm(props: Props) {
|
|||
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) => {
|
||||
setNewGrainSettings(newSettings)
|
||||
onGrainSettingsChange(newSettings)
|
||||
onGrainSettingsChange(newSettings, !invalid())
|
||||
}
|
||||
|
||||
const newGrain = () => {
|
||||
const grainForm = () => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<TextField
|
||||
|
|
@ -106,7 +60,6 @@ export default function CustomGrainForm(props: Props) {
|
|||
onChange={(e) => {
|
||||
let name = e.target.value
|
||||
setName(name)
|
||||
setIsNew(true)
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.name = name
|
||||
settingsChanged(settings)
|
||||
|
|
@ -119,7 +72,6 @@ export default function CustomGrainForm(props: Props) {
|
|||
onChange={(e) => {
|
||||
let group = e.target.value
|
||||
setGroup(group)
|
||||
setIsNew(true)
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.group = group
|
||||
settingsChanged(settings)
|
||||
|
|
@ -133,7 +85,6 @@ export default function CustomGrainForm(props: Props) {
|
|||
onChange={(e) => {
|
||||
let enumVal = parseFloat(e.target.value)
|
||||
setEquation(enumVal)
|
||||
setIsNew(true)
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.equation = enumVal
|
||||
settingsChanged(settings)
|
||||
|
|
@ -165,7 +116,6 @@ export default function CustomGrainForm(props: Props) {
|
|||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setConstantA(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.a = parseFloat(val)
|
||||
|
|
@ -183,7 +133,6 @@ export default function CustomGrainForm(props: Props) {
|
|||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setConstantB(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.b = parseFloat(val)
|
||||
|
|
@ -201,7 +150,6 @@ export default function CustomGrainForm(props: Props) {
|
|||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setConstantC(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.c = parseFloat(val)
|
||||
|
|
@ -219,7 +167,6 @@ export default function CustomGrainForm(props: Props) {
|
|||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setKgPerBushel(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.kgPerBushel = parseFloat(val)
|
||||
|
|
@ -237,7 +184,6 @@ export default function CustomGrainForm(props: Props) {
|
|||
onChange={(e) => {
|
||||
let val = e.target.value
|
||||
setBushelsPerTonne(val)
|
||||
setIsNew(true)
|
||||
if(!isNaN(parseFloat(val))){
|
||||
let settings = cloneDeep(newGrainSettings)
|
||||
settings.bushelsPerTonne = parseFloat(val)
|
||||
|
|
@ -245,77 +191,13 @@ export default function CustomGrainForm(props: Props) {
|
|||
}
|
||||
}}
|
||||
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>
|
||||
)
|
||||
}
|
||||
|
||||
const grainAccordion = () => {
|
||||
return (
|
||||
<Accordion>
|
||||
<AccordionSummary expandIcon={<ExpandMore />}>Custom Grain Properties</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
{newGrain()}
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{grainOptions.length === 0 ?
|
||||
<Box>
|
||||
<Typography sx={{marginBottom: 1}}>Custom Grain Properties</Typography>
|
||||
{newGrain()}
|
||||
</Box>
|
||||
:
|
||||
<Box>
|
||||
<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>
|
||||
{grainAccordion()}
|
||||
</Box>
|
||||
|
||||
}
|
||||
{grainForm()}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
155
src/grain/CustomGrainSelector.tsx
Normal file
155
src/grain/CustomGrainSelector.tsx
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import { ExpandMore } from "@mui/icons-material"
|
||||
import { Accordion, AccordionDetails, AccordionSummary, Box, Button, Typography } from "@mui/material"
|
||||
import SearchSelect, { Option } from "common/SearchSelect"
|
||||
import { pond } from "protobuf-ts/pond"
|
||||
import { useGlobalState } from "providers"
|
||||
import { useGrainAPI } from "providers/pond/grainAPI"
|
||||
import React, { useEffect, useState } from "react"
|
||||
import CustomGrainForm from "./CustomGrainForm"
|
||||
|
||||
interface Props {
|
||||
initialGrain?: pond.GrainSettings
|
||||
onGrainSettingsChange: (settings: pond.GrainSettings) => void
|
||||
}
|
||||
|
||||
export default function CustomGrainSelector(props: Props) {
|
||||
const {initialGrain, onGrainSettingsChange} = props
|
||||
const grainAPI = useGrainAPI()
|
||||
const [{as}] = useGlobalState()
|
||||
const [newGrainSettings, setNewGrainSettings] = useState(initialGrain ?? pond.GrainSettings.create())
|
||||
const [formValid, setFormValid] = useState(true)
|
||||
const [grainMap, setGrainMap] = useState<Map<string, pond.GrainObject>>(
|
||||
initialGrain ?
|
||||
new Map([
|
||||
["Active", pond.GrainObject.create({key: "Active", name: initialGrain.name, settings: initialGrain})]
|
||||
])
|
||||
:
|
||||
new Map())
|
||||
const [grainOptions, setGrainOptions] = useState<Option[]>(
|
||||
initialGrain ?
|
||||
[
|
||||
{
|
||||
label: initialGrain.name,
|
||||
value: "Active",
|
||||
group: "Active"
|
||||
}
|
||||
]
|
||||
:
|
||||
[]
|
||||
)
|
||||
const [isNew, setIsNew] = useState(false)
|
||||
const [selectedOption, setSelectedOption] = useState<Option | null>(initialGrain ? {
|
||||
label: initialGrain.name,
|
||||
value: "Active",
|
||||
group: "Active"
|
||||
} : null)
|
||||
|
||||
useEffect(()=>{
|
||||
grainAPI.listGrains(0, 0, "asc", "name", undefined, undefined, undefined, as).then(resp => {
|
||||
let options: Option[] = grainOptions
|
||||
let map: Map<string, pond.GrainObject> = grainMap
|
||||
if (resp.data.grains){
|
||||
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 saveGrain = () => {
|
||||
// console.log(newGrainSettings)
|
||||
grainAPI.addGrain(newGrainSettings, as).then(resp => {
|
||||
console.log("grain added")
|
||||
}).catch(err => {
|
||||
console.log("err")
|
||||
})
|
||||
}
|
||||
|
||||
const settingsChanged = (newSettings: pond.GrainSettings, formValid: boolean) => {
|
||||
setNewGrainSettings(newSettings)
|
||||
setIsNew(true)
|
||||
setFormValid(formValid)
|
||||
onGrainSettingsChange(newSettings)
|
||||
}
|
||||
|
||||
const grainAccordion = () => {
|
||||
return (
|
||||
<Accordion>
|
||||
<AccordionSummary expandIcon={<ExpandMore />}>Custom Grain Properties</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<CustomGrainForm grainSettings={newGrainSettings} onGrainSettingsChange={settingsChanged}/>
|
||||
{isNew &&
|
||||
<Box display='flex' justifyContent="flex-end">
|
||||
<Button
|
||||
variant="contained"
|
||||
disabled={!formValid}
|
||||
onClick={() => {
|
||||
setIsNew(false)
|
||||
saveGrain()
|
||||
}}
|
||||
color="primary">
|
||||
Save Custom Grain
|
||||
</Button>
|
||||
</Box>
|
||||
}
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{grainOptions.length === 0 ?
|
||||
<Box>
|
||||
<Typography sx={{marginBottom: 1}}>Custom Grain Properties</Typography>
|
||||
<CustomGrainForm grainSettings={newGrainSettings} onGrainSettingsChange={settingsChanged}/>
|
||||
{isNew &&
|
||||
<Box display='flex' justifyContent="flex-end">
|
||||
<Button
|
||||
variant="contained"
|
||||
disabled={!formValid}
|
||||
onClick={() => {
|
||||
setIsNew(false)
|
||||
}}
|
||||
color="primary">
|
||||
Save Custom Grain
|
||||
</Button>
|
||||
</Box>
|
||||
}
|
||||
</Box>
|
||||
:
|
||||
<Box>
|
||||
<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){
|
||||
//the the new grain settings object
|
||||
setNewGrainSettings(grain.settings)
|
||||
//pass that settings object back up
|
||||
settingsChanged(grain.settings, true)
|
||||
}
|
||||
}}
|
||||
group
|
||||
options={grainOptions}
|
||||
/>
|
||||
</Box>
|
||||
{grainAccordion()}
|
||||
</Box>
|
||||
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue