diff --git a/src/bin/BinTour.tsx b/src/bin/BinTour.tsx
index a685ada..e885527 100644
--- a/src/bin/BinTour.tsx
+++ b/src/bin/BinTour.tsx
@@ -1,6 +1,6 @@
// import { useAuth0 } from "@auth0/auth0-react";
import { Typography } from "@mui/material";
-import Tour from "common/Tour";
+import Tour, { TourStep } from "common/Tour";
import { random } from "lodash";
import moment from "moment";
import { useGlobalState, useSnackbar, useUserAPI } from "providers";
@@ -8,8 +8,13 @@ import React, { useEffect, useState } from "react";
import { Step } from "react-joyride";
// import Emoji from "react-emoji-render";
-export default function BinTour() {
+interface Props {
+ setDetailTabState?: ( detail: "inventory" | "sensors" | "analytics" | "presets" | "alerts" | "transactions", buttonIndex: number) => void
+}
+
+export default function BinTour(props: Props) {
// const { userID } = useAuth0();
+ const {setDetailTabState} = props
const [{ user }, dispatch] = useGlobalState();
const userID = user.id()
const { error } = useSnackbar();
@@ -35,8 +40,8 @@ export default function BinTour() {
}
};
- const getTourSteps = (): Step[] => {
- let steps: Step[] = [
+ const getTourSteps = (): TourStep[] => {
+ let steps: TourStep[] = [
{
title: (
@@ -103,24 +108,12 @@ export default function BinTour() {
disableBeacon: false
},
{
- title: "Graphs",
+ title: "View Other Data",
content: (
- Bin related analytics are displayed here.
-
-
- ),
- target: "#tour-graphs",
- placement: "left",
- disableBeacon: false
- },
- {
- title: "Choose your graphs",
- content: (
-
-
- Use this tab to view other sets of data. Sensors must be attached to view sensor data.
+ Use these tabs to view other Bin Details such as inventory levels over time,
+ alerts and interactions for connected components, and data for attached sensors
),
@@ -128,6 +121,122 @@ export default function BinTour() {
placement: "bottom",
disableBeacon: false
},
+ {
+ title: "Inventory",
+ content: (
+
+
+ The inventory tab shows your bins inventory level over a specified window as well as the times the bin mode was changed.
+
+
+ ),
+ target: "#tour-details",
+ placement: "left-start",
+ disableBeacon: false,
+ onNext: () => {
+ if (setDetailTabState) setDetailTabState("sensors", 1)
+ }
+ },
+ {
+ title: "Sensors",
+ content: (
+
+
+ The sensors tab shows readings from attached sensors over time
+
+
+ ),
+ target: "#tour-details",
+ placement: "left-start",
+ disableBeacon: false,
+ onNext: () => {
+ if (setDetailTabState) setDetailTabState("analytics", 2)
+ }
+ },
+ {
+ title: "Analytics",
+ content: (
+
+
+ The analysis tab shows analytic bin data using attached sensors
+
+
+ ),
+ target: "#tour-details",
+ placement: "left-start",
+ disableBeacon: false,
+ onNext: () => {
+ if (setDetailTabState) setDetailTabState("alerts", 3)
+ }
+ },
+ {
+ title: "Alerts and Interactions",
+ content: (
+
+
+ The Alerts tab allows you to view or add any new interactions or alerts for connected components
+ and displays recent notifications from those alerts
+
+
+ ),
+ target: "#tour-details",
+ placement: "left-start",
+ disableBeacon: false,
+ onNext: () => {
+ if (setDetailTabState) setDetailTabState("presets", 4)
+ }
+ },
+ {
+ title: "Bin Mode Presets",
+ content: (
+
+
+ The Presets tab allows you to create custom presets for the interactions for a device when changing bin modes
+
+
+ ),
+ target: "#tour-details",
+ placement: "left-start",
+ disableBeacon: false,
+ onNext: () => {
+ if (setDetailTabState) setDetailTabState("transactions", 5)
+ }
+ },
+ {
+ title: "Bin Transactions",
+ content: (
+
+
+ The transactions tab allows view any pending transaction when using a hybrid inventory control
+
+
+ ),
+ target: "#tour-details",
+ placement: "left-start",
+ disableBeacon: false,
+ onNext: () => {
+ if (setDetailTabState) setDetailTabState("inventory", 0)
+ }
+ },
+ {
+ title: "Bin Conditions",
+ content: (
+
+
+ This section will display conditions based on the bin mode
+
+
+ Storage Mode: simply displays the Storage conditions by itself with the target temperature and moisture set in the bin settings
+
+
+ Other Modes: will display the interactions for the bins devices that are controlling a fan or heater on the bin as well as the storage conditions
+
+
+ ),
+ target: "#tour-conditions",
+ placement: "right",
+ disableBeacon: false
+ },
{
title: "Change Mode",
content: (
@@ -138,12 +247,15 @@ export default function BinTour() {
- Storage mode: default
-
- Drying mode: use heat to dry grain ☀️
+ Cooldown mode: use fans to hold bin temperature lower ❆❅
+ {/* */}
+
+ -
+ Drying mode: use heat to dry grain ☀️ (only visible when the target moisture is lower than the starting moisture in the bin settings)
{/* */}
-
- Cooldown mode: use fans to hold bin temperature lower ❆❅
- {/* */}
+ Hydrating mode: use humid air to hydrate grain (only visible when the target moisture is higher than the starting moisture in the bin settings)
diff --git a/src/bin/BinVisualizerV2.tsx b/src/bin/BinVisualizerV2.tsx
index 7d99671..baa27f6 100644
--- a/src/bin/BinVisualizerV2.tsx
+++ b/src/bin/BinVisualizerV2.tsx
@@ -1727,32 +1727,34 @@ export default function BinVisualizer(props: Props) {
{modeChangeInProgress &&
}
- {
- setModeStorage()
+
+ {
+ setModeStorage()
+ }
+ },
+ {
+ title: "Cooldown",
+ function: () => {
+ setModeCooldown()
+ }
+ },
+ {
+ title: bin.settings.inventory && bin.settings.inventory?.initialMoisture < bin.settings.inventory?.targetMoisture ? "Hydrating" : "Drying",
+ function: () => {
+ // setShowInputMoisture(true)
+ setModeConditioning() //will set it to either drying or hydrating based on the initial and target moisture
+ }
}
- },
- {
- title: "Cooldown",
- function: () => {
- setModeCooldown()
- }
- },
- {
- title: bin.settings.inventory && bin.settings.inventory?.initialMoisture < bin.settings.inventory?.targetMoisture ? "Hydrating" : "Drying",
- function: () => {
- // setShowInputMoisture(true)
- setModeConditioning() //will set it to either drying or hydrating based on the initial and target moisture
- }
- }
- ]}
- toggledButtons={determineToggle(mode)}
- toggle
- />
+ ]}
+ toggledButtons={determineToggle(mode)}
+ toggle
+ />
+
);
};
diff --git a/src/common/ButtonGroup.tsx b/src/common/ButtonGroup.tsx
index 3c2c64c..e326d64 100644
--- a/src/common/ButtonGroup.tsx
+++ b/src/common/ButtonGroup.tsx
@@ -57,6 +57,7 @@ interface Props {
* When true will disable all of the buttons in the group, will be overridded by individual buttons disabled state in the button data
*/
disableAll?: boolean
+
}
const useStyles = makeStyles((theme: Theme) => {
diff --git a/src/pages/Bin.tsx b/src/pages/Bin.tsx
index 9fa36b6..cc667d8 100644
--- a/src/pages/Bin.tsx
+++ b/src/pages/Bin.tsx
@@ -195,6 +195,7 @@ export default function Bin(props: Props) {
const [headspaceCO2, setHeadspaceCO2] = useState([]);
const [heaters, setHeaters] = useState([]);
const [fans, setFans] = useState([]);
+ const [activeDetails, setActiveDetails] = useState([0])
const [detail, setDetail] = useState<
"inventory" | "sensors" | "analytics" | "presets" | "alerts" | "transactions"
>("inventory");
@@ -805,7 +806,7 @@ export default function Bin(props: Props) {
{overview()}
{preferences && binComponents(preferences)}
-
+
{(bin.settings.mode === pond.BinMode.BIN_MODE_DRYING ||
bin.settings.mode === pond.BinMode.BIN_MODE_HYDRATING ||
bin.settings.mode === pond.BinMode.BIN_MODE_COOLDOWN) && (
@@ -824,34 +825,53 @@ export default function Bin(props: Props) {
-
-
-
+
+ setDetail("inventory")
+ function: () => {
+ setDetail("inventory")
+ setActiveDetails([0])
+ }
},
{
title: "Sensors",
- function: () => setDetail("sensors")
+ function: () => {
+ setDetail("sensors")
+ setActiveDetails([1])
+ }
},
{
title: "Analysis",
- function: () => setDetail("analytics")
+ function: () => {
+ setDetail("analytics")
+ setActiveDetails([2])
+ }
},
{
title: "Alerts",
- function: () => setDetail("alerts")
+ function: () => {
+ setDetail("alerts")
+ setActiveDetails([3])
+ }
},
{
title: "Presets",
- function: () => setDetail("presets")
+ function: () => {
+ setDetail("presets")
+ setActiveDetails([4])
+ }
},
{
title: "Transactions",
- function: () => setDetail("transactions")
+ function: () => {
+ setDetail("transactions")
+ setActiveDetails([5])
+ }
}
]}
/>
@@ -880,23 +900,27 @@ export default function Bin(props: Props) {
/>
)}
- {(detail === "inventory" || detail === "sensors" || detail === "analytics") && (
-
- )}
{detail === "transactions" &&
+
+
}
+ {(detail === "inventory" || detail === "sensors" || detail === "analytics") && (
+
+
+
+ )}
@@ -1141,7 +1165,11 @@ export default function Bin(props: Props) {
{objectTeams()}
{deviceMenu()}
-
+ {
+ setDetail(detail)
+ setActiveDetails([buttonIndex])
+ }}/>
);
}
diff --git a/src/pages/SignupCallback.tsx b/src/pages/SignupCallback.tsx
index a22dbfc..43c8c5b 100644
--- a/src/pages/SignupCallback.tsx
+++ b/src/pages/SignupCallback.tsx
@@ -1,13 +1,15 @@
import { useDeviceAPI, useMobile, useUserAPI } from "hooks";
import PageContainer from "./PageContainer";
import { useEffect, useState } from "react";
-import { Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Divider, Typography } from "@mui/material";
+import { Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Divider, Grid2, MenuItem, TextField, Typography } from "@mui/material";
import { useBinAPI, useGlobalState, useTeamAPI } from "providers";
import { CheckCircleOutline } from "@mui/icons-material";
import { green } from "@mui/material/colors";
import Tour, { TourStep } from "common/Tour";
import Emoji from "react-emoji-render";
import { getWhitelabel, IsAdaptiveAgriculture } from "services/whiteLabel";
+import { pond } from "protobuf-ts/pond";
+import { User } from "models";
// import { color } from "framer-motion";
// interface Props {
@@ -21,7 +23,7 @@ export default function SignupCallback () {
const deviceAPI = useDeviceAPI();
const binAPI = useBinAPI();
const isMobile = useMobile()
- const [{ user }] = useGlobalState();
+ const [globalState, dispatch] = useGlobalState();
const whiteLabel = getWhitelabel()
const [loading, setLoading] = useState(false)
@@ -35,6 +37,7 @@ export default function SignupCallback () {
const [doneBins, setDoneBins] = useState(false)
const [doneTeams, setDoneTeams] = useState(false)
const [doneDevices, setDoneDevices] = useState(false)
+ const [user, setUser] = useState(globalState.user);
useEffect(() => {
setLoading(true)
@@ -55,6 +58,124 @@ export default function SignupCallback () {
return loading === false && doneBins && doneTeams && doneDevices
}
+ const changePressureUnit = (value: any) => {
+ let updatedUser = User.clone(user)
+ let pressureUnit: pond.PressureUnit;
+ switch (value) {
+ case 1:
+ pressureUnit = pond.PressureUnit.PRESSURE_UNIT_KILOPASCALS;
+ break;
+ case 2:
+ pressureUnit = pond.PressureUnit.PRESSURE_UNIT_INCHES_OF_WATER;
+ break;
+ default:
+ pressureUnit = pond.PressureUnit.PRESSURE_UNIT_UNKNOWN;
+ break;
+ }
+ updatedUser.settings.pressureUnit = pressureUnit;
+ setUser(updatedUser)
+ };
+
+ const changeTemperatureUnit = (value: any) => {
+ let updatedUser = User.clone(user);
+ let temperatureUnit: pond.TemperatureUnit;
+ switch (value) {
+ case 1:
+ temperatureUnit = pond.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS;
+ break;
+ case 2:
+ temperatureUnit = pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT;
+ break;
+ default:
+ temperatureUnit = pond.TemperatureUnit.TEMPERATURE_UNIT_UNKNOWN;
+ break;
+ }
+ updatedUser.settings.temperatureUnit = temperatureUnit;
+ setUser(updatedUser);
+ };
+
+ const unitPreferences = () => {
+ const { pressureUnit, temperatureUnit, distanceUnit, grainUnit } = user.settings;
+ return (
+
+
+ changePressureUnit(event.target.value)}
+ margin="normal"
+ variant="outlined"
+ InputLabelProps={{ shrink: true }}>
+
+
+
+
+
+ changeTemperatureUnit(event.target.value)}
+ margin="normal"
+ variant="outlined"
+ InputLabelProps={{ shrink: true }}>
+
+
+
+
+
+ changeDistanceUnit(event.target.value)}
+ margin="normal"
+ variant="outlined"
+ InputLabelProps={{ shrink: true }}>
+
+
+
+
+ {IsAdaptiveAgriculture() && (
+
+ changeGrainUnit(event.target.value)}
+ margin="normal"
+ variant="outlined"
+ InputLabelProps={{ shrink: true }}>
+
+
+
+
+ )}
+
+ );
+ };
+
const content = () => {
return (
@@ -104,12 +225,17 @@ export default function SignupCallback () {
content: (
<>
- In the user menu, you can make changes to your profile, and adjust unit preferences.
+ In the user menu, you can make changes to your profile, such as adjusting unit preferences.
If you are part of a team, you can select it here as well.
+
+
+ Set your unit preferences here now, they can be changed later from this menu:
+
+ {unitPreferences()}
>
),
target: "#tour-user-menu",
@@ -150,35 +276,104 @@ export default function SignupCallback () {
target: "#tour-dashboard",
placement: "right"
})
- if (IsAdaptiveAgriculture()) steps.push({
- title: "Bins",
+ steps.push({
+ title: "Tasks",
content: (
<>
- You can view your bins and their inventory here.
+ You can view and create tasks here and assign a start and end time for them.
- If you are viewing as a team, your team's bins will be displayed here instead.
+ If you are viewing as a team you will see the teams tasks, you can even assign tasks to team members.
>
),
- target: "#tour-bins",
- placement: "right",
- disableBeacon: true,
+ target: "#tour-tasks",
+ placement: "right"
})
+ //tasks step
+ if (IsAdaptiveAgriculture()) {
+ steps.push({
+ title: "Visual Farm",
+ content: (
+ <>
+
+ You can view your Visual Farm here, it will allow tou to draw fields and plot bins an a map.
+
+
+
+ If you are viewing as a team, your team's fields and bins will be displayed here instead.
+
+ >
+ ),
+ target: "#tour-visual-farm",
+ placement: "right",
+ disableBeacon: true,
+ })
+ steps.push({
+ title: "Fields",
+ content: (
+ <>
+
+ You can view your fields you have drawn on the map here.
+
+
+
+ If you are viewing as a team, your team's fields will be displayed here instead.
+
+ >
+ ),
+ target: "#tour-field-list",
+ placement: "right",
+ disableBeacon: true,
+ })
+ steps.push({
+ title: "Bins",
+ content: (
+ <>
+
+ You can view your bins and their inventory here.
+
+
+
+ If you are viewing as a team, your team's bins will be displayed here instead.
+
+ >
+ ),
+ target: "#tour-bins",
+ placement: "right",
+ disableBeacon: true,
+ })
+ steps.push({
+ title: "Contracts",
+ content: (
+ <>
+
+ You can view and track any contracts you have created here.
+
+
+
+ If you are viewing as a team, your team's contracts will be displayed here instead.
+
+ >
+ ),
+ target: "#tour-contracts",
+ placement: "right",
+ disableBeacon: true,
+ })
+ }
return steps;
};
const endTour = () => {
setIsTourRunning(false);
- // if (user) {
- // user.status.finishedBinIntro = moment().toJSON();
- // userAPI
- // .updateUser(userID, user.protobuf())
- // .then(() => dispatch({ key: "user", value: user }))
- // .catch((err: any) => error(err));
- // }
+ if (user) {
+ userAPI
+ .updateUser(user.id(), user.protobuf())
+ .then(() => dispatch({ key: "user", value: user }))
+ .catch((err: any) => console.error(err));
+ }
};
const closeDialog = () => {