set up the bones for the humidity mode
This commit is contained in:
parent
208a657528
commit
aa346a6a5a
3 changed files with 415 additions and 11 deletions
|
|
@ -194,6 +194,7 @@ export default function BinModeController(props: Props) {
|
||||||
//setNumSteps(DryingStepCount)
|
//setNumSteps(DryingStepCount)
|
||||||
return <DryingMode
|
return <DryingMode
|
||||||
grain={bin.settings.inventory?.grainType}
|
grain={bin.settings.inventory?.grainType}
|
||||||
|
customGrain={bin.settings.inventory?.customGrain ?? undefined}
|
||||||
devices={devices}
|
devices={devices}
|
||||||
binPrefs={binPrefs}
|
binPrefs={binPrefs}
|
||||||
deviceComponents={deviceComponents}
|
deviceComponents={deviceComponents}
|
||||||
|
|
@ -204,7 +205,18 @@ export default function BinModeController(props: Props) {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
case pond.BinMode.BIN_MODE_HYDRATING:
|
case pond.BinMode.BIN_MODE_HYDRATING:
|
||||||
return <HydratingMode />
|
return <HydratingMode
|
||||||
|
grain={bin.settings.inventory?.grainType}
|
||||||
|
customGrain={bin.settings.inventory?.customGrain ?? undefined}
|
||||||
|
devices={devices}
|
||||||
|
binPrefs={binPrefs}
|
||||||
|
deviceComponents={deviceComponents}
|
||||||
|
cancel={closeDialog}
|
||||||
|
confirm={(deviceData) => {
|
||||||
|
buildStages(deviceData)
|
||||||
|
setShowProgress(true)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
case pond.BinMode.BIN_MODE_COOLDOWN:
|
case pond.BinMode.BIN_MODE_COOLDOWN:
|
||||||
return <CooldownMode />
|
return <CooldownMode />
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { ArrowBack, ArrowForward } from "@mui/icons-material";
|
import { Box, Theme, Stepper, Step, StepLabel, Typography, RadioGroup, Radio, FormControlLabel, Button, Autocomplete, TextField, DialogTitle, DialogContent, DialogActions, CircularProgress } from "@mui/material";
|
||||||
import { Box, Theme, Stepper, Step, StepLabel, Typography, RadioGroup, Radio, FormControlLabel, Grid2, Button, Autocomplete, TextField, DialogTitle, DialogContent, DialogActions, CircularProgress } from "@mui/material";
|
|
||||||
import { makeStyles } from "@mui/styles";
|
import { makeStyles } from "@mui/styles";
|
||||||
import ConditioningSelector from "bin/conditioning/conditioningSelector";
|
import ConditioningSelector from "bin/conditioning/conditioningSelector";
|
||||||
import { Component, Device, Interaction } from "models";
|
import { Component, Device, Interaction } from "models";
|
||||||
|
|
@ -7,7 +6,7 @@ import { Ambient } from "models/Ambient";
|
||||||
import { Controller } from "models/Controller";
|
import { Controller } from "models/Controller";
|
||||||
import { Plenum } from "models/Plenum";
|
import { Plenum } from "models/Plenum";
|
||||||
import { pond, quack } from "protobuf-ts/pond";
|
import { pond, quack } from "protobuf-ts/pond";
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { ComponentSet } from "bin/conditioning/pickComponentSet"
|
import { ComponentSet } from "bin/conditioning/pickComponentSet"
|
||||||
import { componentIDToString, sameComponentID } from "pbHelpers/Component";
|
import { componentIDToString, sameComponentID } from "pbHelpers/Component";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
|
@ -15,7 +14,6 @@ import { lowerCase } from "lodash";
|
||||||
import { GetGrainExtensionMap } from "grain";
|
import { GetGrainExtensionMap } from "grain";
|
||||||
import { describeMeasurement } from "pbHelpers/MeasurementDescriber";
|
import { describeMeasurement } from "pbHelpers/MeasurementDescriber";
|
||||||
import { useGlobalState, useInteractionsAPI } from "providers";
|
import { useGlobalState, useInteractionsAPI } from "providers";
|
||||||
import BinConditioningInteraction from "bin/BinConditioningInteraction";
|
|
||||||
import ConditionDisplay from "./conditionDisplay";
|
import ConditionDisplay from "./conditionDisplay";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { DeviceChangeData } from "./BinModeController";
|
import { DeviceChangeData } from "./BinModeController";
|
||||||
|
|
@ -46,6 +44,7 @@ interface Props {
|
||||||
deviceComponents: Map<number, Component[]>
|
deviceComponents: Map<number, Component[]>
|
||||||
binPrefs?: Map<string, pond.BinComponentPreferences>
|
binPrefs?: Map<string, pond.BinComponentPreferences>
|
||||||
grain?: pond.Grain
|
grain?: pond.Grain
|
||||||
|
customGrain?: pond.GrainSettings
|
||||||
cancel: () => void
|
cancel: () => void
|
||||||
confirm: (deviceData: DeviceChangeData[]) => void
|
confirm: (deviceData: DeviceChangeData[]) => void
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +53,7 @@ const steps = [{label: "Style"}, {label: "Device"}, {label: "Interaction"}]
|
||||||
|
|
||||||
//this is our simple drying mode the way it currently works, just building the dialog to be a little more trnasparent and customizable as to what the interaction is doing
|
//this is our simple drying mode the way it currently works, just building the dialog to be a little more trnasparent and customizable as to what the interaction is doing
|
||||||
export default function DryingMode(props: Props){
|
export default function DryingMode(props: Props){
|
||||||
const {devices, deviceComponents, binPrefs, grain, cancel, confirm} = props
|
const {devices, deviceComponents, binPrefs, grain, customGrain, cancel, confirm} = props
|
||||||
const grainExtensionMap = GetGrainExtensionMap();
|
const grainExtensionMap = GetGrainExtensionMap();
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const [{user}] = useGlobalState()
|
const [{user}] = useGlobalState()
|
||||||
|
|
@ -478,6 +477,8 @@ export default function DryingMode(props: Props){
|
||||||
if(sink && source){
|
if(sink && source){
|
||||||
return (
|
return (
|
||||||
<ConditionDisplay
|
<ConditionDisplay
|
||||||
|
grain={grain}
|
||||||
|
customGrain={customGrain}
|
||||||
key={index}
|
key={index}
|
||||||
interaction={temp}
|
interaction={temp}
|
||||||
sink={sink}
|
sink={sink}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,400 @@
|
||||||
import { Box } from "@mui/material";
|
import { Box, Theme, Stepper, Step, StepLabel, Typography, RadioGroup, Radio, FormControlLabel, Button, Autocomplete, TextField, DialogTitle, DialogContent, DialogActions, CircularProgress } from "@mui/material";
|
||||||
|
import { makeStyles } from "@mui/styles";
|
||||||
|
import ConditioningSelector from "bin/conditioning/conditioningSelector";
|
||||||
|
import { Component, Device, Interaction } from "models";
|
||||||
|
import { Ambient } from "models/Ambient";
|
||||||
|
import { Controller } from "models/Controller";
|
||||||
|
import { Plenum } from "models/Plenum";
|
||||||
|
import { pond, quack } from "protobuf-ts/pond";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { ComponentSet } from "bin/conditioning/pickComponentSet"
|
||||||
|
import { componentIDToString, sameComponentID } from "pbHelpers/Component";
|
||||||
|
import moment from "moment";
|
||||||
|
import { lowerCase } from "lodash";
|
||||||
|
import { GetGrainExtensionMap } from "grain";
|
||||||
|
import { describeMeasurement } from "pbHelpers/MeasurementDescriber";
|
||||||
|
import { useGlobalState, useInteractionsAPI } from "providers";
|
||||||
|
import ConditionDisplay from "./conditionDisplay";
|
||||||
|
import React from "react";
|
||||||
|
import { DeviceChangeData } from "./BinModeController";
|
||||||
|
import { GrainCable } from "models/GrainCable";
|
||||||
|
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme: Theme) => {
|
||||||
|
return ({
|
||||||
|
stepper: {
|
||||||
|
padding: theme.spacing(0.5)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
interface Step {
|
||||||
|
label: string;
|
||||||
|
completed?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Option {
|
||||||
|
label: string;
|
||||||
|
device: Device;
|
||||||
|
icon?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
devices: Device[]
|
||||||
|
deviceComponents: Map<number, Component[]>
|
||||||
|
binPrefs?: Map<string, pond.BinComponentPreferences>
|
||||||
|
grain?: pond.Grain
|
||||||
|
customGrain?: pond.GrainSettings
|
||||||
|
cancel: () => void
|
||||||
|
confirm: (deviceData: DeviceChangeData[]) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const steps = [{label: "Style"}, {label: "Device"}, {label: "Interaction"}]
|
||||||
|
|
||||||
|
//this is our simple drying mode the way it currently works, just building the dialog to be a little more trnasparent and customizable as to what the interaction is doing
|
||||||
|
export default function DryingMode(props: Props){
|
||||||
|
const {devices, deviceComponents, binPrefs, grain, customGrain, cancel, confirm} = props
|
||||||
|
const grainExtensionMap = GetGrainExtensionMap();
|
||||||
|
const classes = useStyles()
|
||||||
|
const [{user}] = useGlobalState()
|
||||||
|
const interactionAPI = useInteractionsAPI()
|
||||||
|
const [options, setOptions] = useState<Option[]>([])
|
||||||
|
const [deviceOption, setDeviceOption] = useState<Option>()
|
||||||
|
const [selectedDevice, setSelectedDevice] = useState<Device | undefined>()
|
||||||
|
const [plenums, setPlenums] = useState<Plenum[]>([])
|
||||||
|
const [ambients, setAmbients] = useState<Ambient[]>([])
|
||||||
|
const [fans, setFans] = useState<Controller[]>([])
|
||||||
|
const [cables, setCables] = useState<GrainCable[]>([])
|
||||||
|
const [currentStep, setCurrentStep] = useState(0)
|
||||||
|
const [interactionLoading,setInteractionsLoading] = useState(false)
|
||||||
|
|
||||||
|
// possibly all 4 of these will need to be passed up, at least the conflicting, toAdd, and sets will
|
||||||
|
const [componentSets, setComponentSets] = useState<ComponentSet[]>([])
|
||||||
|
const [existingInteractions, setExistingInteractions] = useState<Interaction[]>([])
|
||||||
|
const [conflictingInteractions, setConflictingInteractions] = useState<Interaction[]>([])
|
||||||
|
const [interactionsToAdd, setInteractionsToAdd] = useState<pond.MultiInteractionSettings>()
|
||||||
|
|
||||||
|
|
||||||
|
const [sourceMap, setSourceMap] = useState<Map<string, Component>>(new Map());
|
||||||
|
const [sinkMap, setSinkMap] = useState<Map<string, Component>>(new Map());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//sort the components according to the bin preferences
|
||||||
|
useEffect(()=>{
|
||||||
|
if (!selectedDevice) return;
|
||||||
|
if (!deviceComponents.get(selectedDevice.id())) return;
|
||||||
|
var plenums: Plenum[] = [];
|
||||||
|
var ambients: Ambient[] = [];
|
||||||
|
var grainCables: GrainCable[] = [];
|
||||||
|
var fans: Controller[] = [];
|
||||||
|
var sinkMap: Map<string, Component> = new Map()
|
||||||
|
var sourceMap: Map<string, Component> = new Map()
|
||||||
|
|
||||||
|
deviceComponents.get(selectedDevice.id())!.forEach(comp => {
|
||||||
|
let pref = binPrefs?.get(comp.key());
|
||||||
|
if (pref) {
|
||||||
|
if (pref.type) {
|
||||||
|
if (pref.type === pond.BinComponent.BIN_COMPONENT_PLENUM){
|
||||||
|
plenums.push(Plenum.create(comp));
|
||||||
|
sourceMap.set(comp.locationString(), comp)
|
||||||
|
}
|
||||||
|
if (pref.type === pond.BinComponent.BIN_COMPONENT_AMBIENT){
|
||||||
|
ambients.push(Ambient.create(comp));
|
||||||
|
sourceMap.set(comp.locationString(), comp)
|
||||||
|
}
|
||||||
|
if (pref.type === pond.BinComponent.BIN_COMPONENT_GRAIN_CABLE){
|
||||||
|
grainCables.push(GrainCable.create(comp));
|
||||||
|
sourceMap.set(comp.locationString(), comp)
|
||||||
|
}
|
||||||
|
if (pref.type === pond.BinComponent.BIN_COMPONENT_FAN) {
|
||||||
|
let fan = Controller.create(comp)
|
||||||
|
fan.settings.defaultOutputState = quack.OutputMode.OUTPUT_MODE_OFF;
|
||||||
|
fans.push(fan);
|
||||||
|
sinkMap.set(comp.locationString(), comp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setPlenums(plenums);
|
||||||
|
setAmbients(ambients);
|
||||||
|
setFans(fans);
|
||||||
|
setSourceMap(sourceMap)
|
||||||
|
setSinkMap(sinkMap)
|
||||||
|
setCables(grainCables)
|
||||||
|
//also load the interactions for the selected device so that we can find any conflicting ones
|
||||||
|
setInteractionsLoading(true)
|
||||||
|
interactionAPI.listInteractionsByDevice(selectedDevice.id()).then(resp => {
|
||||||
|
setExistingInteractions(resp)
|
||||||
|
}).finally(() => {
|
||||||
|
setInteractionsLoading(false)
|
||||||
|
})
|
||||||
|
}, [deviceComponents, selectedDevice, binPrefs]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let o: Option[] = [];
|
||||||
|
devices.forEach(device => {
|
||||||
|
let newOption: Option = {device: device, label: device.name()}
|
||||||
|
if(deviceOption === undefined) {
|
||||||
|
setDeviceOption(newOption)
|
||||||
|
setSelectedDevice(device)
|
||||||
|
}
|
||||||
|
o.push(newOption);
|
||||||
|
});
|
||||||
|
setOptions(o);
|
||||||
|
}, [devices, setOptions]);
|
||||||
|
|
||||||
|
const buildFanInteraction = (
|
||||||
|
sensor: Plenum | Ambient,
|
||||||
|
fan: Controller,
|
||||||
|
tempComparison: "greater" | "less",
|
||||||
|
humidityComparison: "greater" | "less",
|
||||||
|
) => {
|
||||||
|
let interaction = pond.InteractionSettings.create({
|
||||||
|
source: sensor.location(),
|
||||||
|
sink: fan.location(),
|
||||||
|
schedule: pond.InteractionSchedule.create({
|
||||||
|
timeOfDayStart: "00:00",
|
||||||
|
timeOfDayEnd: "24:00",
|
||||||
|
timezone: moment.tz.guess(),
|
||||||
|
weekdays: moment.weekdays().map(d => lowerCase(d))
|
||||||
|
}),
|
||||||
|
notifications: pond.InteractionNotifications.create({
|
||||||
|
reports: true
|
||||||
|
}),
|
||||||
|
result: pond.InteractionResult.create({
|
||||||
|
type: quack.InteractionResultType.INTERACTION_RESULT_TYPE_TOGGLE,
|
||||||
|
value: 1
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let tempDefault = 25;
|
||||||
|
let humidityDefault = 60;
|
||||||
|
|
||||||
|
|
||||||
|
let conditions = [];
|
||||||
|
let fanConditionOne = pond.InteractionCondition.create({
|
||||||
|
measurementType: quack.MeasurementType.MEASUREMENT_TYPE_PERCENT,
|
||||||
|
comparison:
|
||||||
|
humidityComparison === "greater"
|
||||||
|
? quack.RelationalOperator.RELATIONAL_OPERATOR_GREATER_THAN
|
||||||
|
: quack.RelationalOperator.RELATIONAL_OPERATOR_LESS_THAN,
|
||||||
|
value: describeMeasurement(
|
||||||
|
quack.MeasurementType.MEASUREMENT_TYPE_PERCENT,
|
||||||
|
sensor.settings.type,
|
||||||
|
sensor.settings.subtype,
|
||||||
|
undefined,
|
||||||
|
user
|
||||||
|
).toStored(humidityDefault)
|
||||||
|
});
|
||||||
|
conditions.push(fanConditionOne);
|
||||||
|
|
||||||
|
//since the measurement describers function toStored does a conversion into celsius for temperature if the users pref is fahrenheit we need to convert the preset value into fahrenheit
|
||||||
|
if (user.tempUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT) {
|
||||||
|
tempDefault = Math.round((tempDefault * (9 / 5) + 32) * 100) / 100;
|
||||||
|
}
|
||||||
|
let tempVal = describeMeasurement(
|
||||||
|
quack.MeasurementType.MEASUREMENT_TYPE_TEMPERATURE,
|
||||||
|
sensor.settings.type,
|
||||||
|
sensor.settings.subtype,
|
||||||
|
undefined,
|
||||||
|
user
|
||||||
|
).toStored(tempDefault);
|
||||||
|
|
||||||
|
let fanConditionTwo = pond.InteractionCondition.create({
|
||||||
|
measurementType: quack.MeasurementType.MEASUREMENT_TYPE_TEMPERATURE,
|
||||||
|
comparison:
|
||||||
|
tempComparison === "greater"
|
||||||
|
? quack.RelationalOperator.RELATIONAL_OPERATOR_GREATER_THAN
|
||||||
|
: quack.RelationalOperator.RELATIONAL_OPERATOR_LESS_THAN,
|
||||||
|
value: Math.round(tempVal) //and then round the converted value since the interaction does not take decimals
|
||||||
|
});
|
||||||
|
conditions.push(fanConditionTwo);
|
||||||
|
|
||||||
|
interaction.conditions = conditions;
|
||||||
|
//set the output mode to auto in the fan so that when the components are updated it uses the new mode
|
||||||
|
fan.settings.defaultOutputState = quack.OutputMode.OUTPUT_MODE_AUTO
|
||||||
|
return interaction;
|
||||||
|
};
|
||||||
|
|
||||||
|
//this function just takes in the sets as they change and creates the list of conflicting interactions and the settings to create the new ones and returns them
|
||||||
|
const createInteractions = (sets: ComponentSet[]) => {
|
||||||
|
if(!selectedDevice) return undefined //if there is no device that was selected, do nothing
|
||||||
|
let multiInteractionSettings: pond.MultiInteractionSettings = pond.MultiInteractionSettings.create()
|
||||||
|
let conflictingInteractions: Interaction[] = []
|
||||||
|
let linkedComponents = deviceComponents.get(selectedDevice.id());
|
||||||
|
//loop through the sets to find interactions to remove as well as set the new ones
|
||||||
|
sets.forEach((set) => {
|
||||||
|
//loop through the controllers
|
||||||
|
set.controllers.forEach(controller => {
|
||||||
|
//filter the conflicting interactions for that controller
|
||||||
|
let c = existingInteractions.filter(i => {
|
||||||
|
let conflicting = false;
|
||||||
|
if (linkedComponents) {
|
||||||
|
linkedComponents.forEach(comp => {
|
||||||
|
if (sameComponentID(comp.location(), i.settings.sink)) {
|
||||||
|
conflicting = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return conflicting;
|
||||||
|
});
|
||||||
|
|
||||||
|
conflictingInteractions = conflictingInteractions.concat(c)
|
||||||
|
multiInteractionSettings.interactions.push(buildFanInteraction(set.sensor, controller, "greater", "less"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
cables.forEach(cable => {
|
||||||
|
console.log(cable.name())
|
||||||
|
let c = existingInteractions.filter(i => {
|
||||||
|
if (sameComponentID(cable.location(), i.settings.source) && !i.settings.sink && i.settings.notifications?.notify) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
conflictingInteractions = conflictingInteractions.concat(c)
|
||||||
|
})
|
||||||
|
|
||||||
|
setComponentSets([...sets])
|
||||||
|
return {
|
||||||
|
conflicting: conflictingInteractions,
|
||||||
|
toAdd: multiInteractionSettings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const stepper = () => {
|
||||||
|
return (
|
||||||
|
<Stepper
|
||||||
|
activeStep={currentStep}
|
||||||
|
alternativeLabel
|
||||||
|
classes={{
|
||||||
|
root: classes.stepper
|
||||||
|
}}>
|
||||||
|
{steps.map((s, i) => (
|
||||||
|
<Step key={i}>
|
||||||
|
<StepLabel>{s.label}</StepLabel>
|
||||||
|
</Step>
|
||||||
|
))}
|
||||||
|
</Stepper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const deviceSelector = () => {
|
||||||
|
return (
|
||||||
|
<Autocomplete
|
||||||
|
disablePortal
|
||||||
|
options={options}
|
||||||
|
value={deviceOption}
|
||||||
|
fullWidth
|
||||||
|
getOptionLabel={option => option.label || ""}
|
||||||
|
onChange={(_, newValue) => {
|
||||||
|
if(newValue){
|
||||||
|
setSelectedDevice(newValue.device);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
renderInput={params => <TextField {...params} variant="outlined" label="Device" />}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const deviceStep = () => {
|
||||||
|
|
||||||
export default function HydratingMode(){
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
|
<Typography>Devices</Typography>
|
||||||
|
{deviceSelector()}
|
||||||
|
{interactionLoading ? <CircularProgress /> :
|
||||||
|
<ConditioningSelector
|
||||||
|
plenums={plenums}
|
||||||
|
ambients={ambients}
|
||||||
|
fans={fans}
|
||||||
|
heaters={[]}
|
||||||
|
//presets={presets}
|
||||||
|
binMode={pond.BinMode.BIN_MODE_HYDRATING}
|
||||||
|
updateSets={(sets) => {
|
||||||
|
//update the component sets that will be used for the interactions
|
||||||
|
//when the sets change it will create the interactions and any conflicting ones that need to be removed will be put into a list
|
||||||
|
//then when the submit button gets clicked it will use the conflicting list and toAdd to remove conflicting interactions and add the new ones
|
||||||
|
let i = createInteractions(sets)
|
||||||
|
if(i !== undefined){
|
||||||
|
setConflictingInteractions(i.conflicting)
|
||||||
|
setInteractionsToAdd(i.toAdd)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//this step will use the conflicting interactions and interactions to add to display them and allow users to make changes
|
||||||
|
const interactionStep = () => {
|
||||||
|
console.log(interactionsToAdd)
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography>Interactions</Typography>
|
||||||
|
{interactionsToAdd?.interactions.map((interaction, index) => {
|
||||||
|
let temp = Interaction.create()
|
||||||
|
temp.settings = interaction
|
||||||
|
let sink = sinkMap.get(componentIDToString(interaction.sink))
|
||||||
|
let source = sourceMap.get(componentIDToString(interaction.source))
|
||||||
|
if(sink && source){
|
||||||
|
return (
|
||||||
|
<ConditionDisplay
|
||||||
|
key={index}
|
||||||
|
grain={grain}
|
||||||
|
customGrain={customGrain}
|
||||||
|
interaction={temp}
|
||||||
|
sink={sink}
|
||||||
|
source={source}
|
||||||
|
changeConditions={(newSettings) => {
|
||||||
|
console.log(newSettings)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const stepperContent = () => {
|
||||||
|
switch(currentStep){
|
||||||
|
case 1:
|
||||||
|
return interactionStep()
|
||||||
|
default:
|
||||||
|
return deviceStep()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = () => {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{/* close - tells the parent to close the dialog without doing anything, always visible */}
|
||||||
|
<Button onClick={cancel}>Close</Button>
|
||||||
|
{/* back - goes back to the previous step, hidden on the forst step */}
|
||||||
|
{currentStep !== 0 && <Button onClick={() => {setCurrentStep(currentStep-1)}}>Back</Button>}
|
||||||
|
{/* next - goes to the next step, hidden on the last step */}
|
||||||
|
{currentStep !== steps.length - 1 && <Button onClick={() => {setCurrentStep(currentStep+1)}}>Next</Button>}
|
||||||
|
{/* confirm - tells the parent to build the stages using the data, only visible on the last step */}
|
||||||
|
{currentStep === steps.length - 1 && interactionsToAdd && selectedDevice && <Button onClick={() => {confirm([{ toRemove: conflictingInteractions, deviceId: selectedDevice.id(), toAdd: interactionsToAdd, controllers: componentSets.flatMap(set => set.controllers)}])}}>Confirm</Button>}
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<DialogTitle>Bin Hydration</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
{stepper()}
|
||||||
|
{stepperContent()}
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
{actions()}
|
||||||
|
</DialogActions>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue