Merge branch 'master' into object_status

This commit is contained in:
csawatzky 2026-01-06 10:57:26 -06:00
commit f06bcf9535
11 changed files with 72 additions and 104 deletions

View file

@ -12,6 +12,7 @@ import { makeStyles } from '@mui/styles'
import { CssBaseline, Theme } from '@mui/material'
import { AppThemeProvider } from 'theme/AppThemeProvider'
import HTTPProvider from 'providers/http'
import { useSnackbar } from 'hooks'
// import FirmwareLoader from './FirmwareLoader'
const reducer = (state: GlobalState, action: GlobalStateAction): GlobalState => {
@ -64,6 +65,7 @@ export default function UserWrapper(props: Props) {
const useAuth = useAuth0();
const hasFetched = useRef(false);
const [global, setGlobal] = useState<undefined | GlobalState>(undefined)
const snackbar = useSnackbar()
const user_id = or(useAuth.user?.sub, "")
@ -81,7 +83,8 @@ export default function UserWrapper(props: Props) {
backgroundTasksComplete: false,
firmware: new Map()
})
}).catch(() => {
}).catch((err) => {
snackbar.error("get user and team: "+err)
userAPI.getUser(user_id).then(user => {
setGlobal({
user: user ? user : User.create(),
@ -92,7 +95,8 @@ export default function UserWrapper(props: Props) {
backgroundTasksComplete: false,
firmware: new Map()
})
}).catch(() => {
}).catch((err) => {
snackbar.error("get user: "+err)
setGlobal(globalDefault)
})

View file

@ -261,32 +261,39 @@ export default function BinCard(props: Props) {
let val;
let useEMC = false;
switch (valDisplay) {
case "average":
if (average?.emc) {
useEMC = true;
val = average.emc;
} else {
val = average?.humid;
}
break;
case "low":
if (coldNode?.emc) {
useEMC = true;
val = coldNode.emc;
} else {
val = coldNode?.humid;
}
break;
case "high":
if (hotNode?.emc) {
useEMC = true;
val = hotNode.emc;
} else {
val = hotNode?.humid;
}
break;
//taking the switch cases out so that the node always displays the average for the moisture/humidity
if (average?.emc) {
useEMC = true;
val = average.emc;
} else {
val = average?.humid;
}
// switch (valDisplay) {
// case "average":
// if (average?.emc) {
// useEMC = true;
// val = average.emc;
// } else {
// val = average?.humid;
// }
// break;
// case "low":
// if (coldNode?.emc) {
// useEMC = true;
// val = coldNode.emc;
// } else {
// val = coldNode?.humid;
// }
// break;
// case "high":
// if (hotNode?.emc) {
// useEMC = true;
// val = hotNode.emc;
// } else {
// val = hotNode?.humid;
// }
// break;
// }
if (val !== undefined && !isNaN(val)) {
display = val.toFixed(2);
@ -332,7 +339,8 @@ export default function BinCard(props: Props) {
color="textSecondary"
noWrap
style={{ fontSize: "0.5rem" }}>
{valDisplay === "high" ? "High" : valDisplay === "low" ? "Low" : "Average"}
{/* {valDisplay === "high" ? "High" : valDisplay === "low" ? "Low" : "Average"} */}
Average
</Typography>
</Box>
</Grid>

View file

@ -258,7 +258,7 @@ export default function BinVisualizer(props: Props) {
//const [highTempCable, setHighTempCable] = useState<GrainCable>();
//const [lowTempCable, setLowTempCable] = useState<GrainCable>();
//the switch value to determine what to display in the grain condition box
const [valueDisplay, setValueDisplay] = useState<"low" | "avg" | "high">("avg");
const [valueDisplay, setValueDisplay] = useState<"low" | "avg" | "high">("high");
//the variables to be able to change the grain type through a unique dialog outside of the settings
const [grainChangeDialog, setGrainChangeDialog] = useState(false);
const grainOptions = GrainOptions();

View file

@ -56,55 +56,6 @@ export default function GateDevice(props: Props) {
const [lastTemps, setLastTemps] = useState({ t1: 0, t2: 0 });
const [lastPressures, setLastPressures] = useState({ p1: 0, p2: 0 });
// const StyledToggleButtonGroup = withStyles(theme => ({
// grouped: {
// margin: theme.spacing(-0.5),
// border: "none",
// padding: theme.spacing(1),
// "&:not(:first-child):not(:last-child)": {
// borderRadius: 24,
// marginRight: theme.spacing(0.5),
// marginLeft: theme.spacing(0.5)
// },
// "&:first-child": {
// borderRadius: 24,
// marginLeft: theme.spacing(0.25)
// },
// "&:last-child": {
// borderRadius: 24,
// marginRight: theme.spacing(0.25)
// }
// },
// root: {
// backgroundColor: darken(
// theme.palette.background.paper,
// getThemeType() === "light" ? 0.05 : 0.25
// ),
// borderRadius: 24,
// content: "border-box"
// }
// }))(ToggleButtonGroup);
// const StyledToggle = withStyles({
// root: {
// backgroundColor: "transparent",
// overflow: "visible",
// content: "content-box",
// "&$selected": {
// backgroundColor: "gold",
// color: "black",
// borderRadius: 24,
// fontWeight: "bold"
// },
// "&$selected:hover": {
// backgroundColor: "rgb(255, 255, 0)",
// color: "black",
// borderRadius: 24
// }
// },
// selected: {}
// })(ToggleButton);
useEffect(() => {
if (comprehensiveDevice.device) {
setDevice(Device.any(comprehensiveDevice.device));
@ -141,7 +92,7 @@ export default function GateDevice(props: Props) {
c.status.measurement[0].values[0] &&
c.status.measurement[0].values[0].values[1]
) {
setPCAFanOn(c.status.measurement[0].values[0].values[1] > 250); //apx 1 iwg
setPCAFanOn(c.status.measurement[0].values[0].values[1] > 996); //apx 4 iwg
}
break;
default:
@ -338,11 +289,11 @@ export default function GateDevice(props: Props) {
return (
<Grid
container
direction={(isMobile) ? "column" : "row"}
// direction={(isMobile) ? "column" : "row"}
width="100%"
alignItems="center"
//alignItems="center"
>
<Grid size={{ sm: 12, lg: isMobile || drawerView ? 12 : 4}} style={{ padding: 10 }}>
<Grid width={"100%"} size={{ sm: 12, lg: isMobile || drawerView ? 12 : 4}} style={{ padding: 10 }}>
<Box
display="flex"
justifyContent="space-between"
@ -363,7 +314,7 @@ export default function GateDevice(props: Props) {
]}
/>
</Box>
<Card raised>
<Card>
<GateSVG
finalTemp={
gate.gateMutations[device.id().toString()] &&

View file

@ -70,8 +70,9 @@ export default function GateFlowGraph(props: Props) {
const classes = useStyles();
const [flowEvents, setFlowEvents] = useState<pond.AirFlowEvent[]>([]);
const [eventsLoading, setEventsLoading] = useState(false);
const eventThreshold = 5;
const idleFlow = 2.44;
//these two constants could be entered by the user at time of retrieval
const eventThreshold = 5; //the threshold that if crossed from one measurement to the next during a flow event will end the current flow event and start a new one
const idleFlow = 3.5; //the mass air flow that must be crossed in order to start a flow event, anything below this will not start an event but must go below this to end an event
useEffect(() => {
if (loadingChartData) return;
@ -102,7 +103,6 @@ export default function GateFlowGraph(props: Props) {
timestamp: time.valueOf(),
value: val.airFlow ?? 0
};
data.push(newPoint);
if (!recent || recent.timestamp < newPoint.timestamp) {
recent = newPoint;

View file

@ -27,6 +27,7 @@ import React, { useEffect, useState } from "react";
import { avg } from "utils";
import GateFlowGraph from "./GateFlowGraph";
import { makeStyles } from "@mui/styles";
import { cloneDeep } from "lodash";
interface Props {
gate: Gate;
@ -245,7 +246,9 @@ export default function GateGraphs(props: Props) {
const graphHeader = (comp: Component) => {
const componentIcon = GetComponentIcon(comp.settings.type, comp.settings.subtype, themeType);
console.log(comp)
let measurement = cloneDeep(comp.status.measurement)
let umArray = measurement.map(um => UnitMeasurement.create(um, user))
return (
<CardHeader
avatar={
@ -260,9 +263,7 @@ export default function GateGraphs(props: Props) {
subheader={
<UnitMeasurementSummary
component={comp}
reading={UnitMeasurement.convertLastMeasurement(
comp.status.measurement.map(um => UnitMeasurement.create(um, user)) ?? []
)}
reading={UnitMeasurement.convertLastMeasurement(umArray)}
/>
}
/>

View file

@ -333,7 +333,7 @@ export default function GateSVG(props: Props) {
const deviceCheckIn = () => {
return (
<g key={"deviceCheckIn"}>
<text x={95} y={12} fontSize={7} fontWeight={650} fill={"white"}>
<text x={85} y={12} fontSize={7} fontWeight={650} fill={"white"}>
Last Checked In: {moment(checkInTime).fromNow()}
</text>
</g>
@ -342,7 +342,7 @@ export default function GateSVG(props: Props) {
return (
<React.Fragment>
<Box height={"100%"} maxWidth={isMobile ? 360 : 460} margin="auto">
<Box height={"100%"} maxWidth={isMobile ? 400 : 460} margin="auto">
<svg
width={"100%"}
height={"100%"}

View file

@ -196,9 +196,10 @@ export default function Bins(props: Props) {
const { openSnack } = useSnackbar();
// const history = useHistory();
const navigate = useNavigate()
const [cardValDisplay, setCardValDisplay] = useState<"high" | "low" | "average">("average");
const [cardValDisplay, setCardValDisplay] = useState<"high" | "low" | "average">("high");
const [teamsDialog, setTeamsDialog] = useState(false)
const snackbar = useSnackbar()
// const [scrollTranslations, setScrollTranslations] = useState({
// bins: 0,
@ -261,10 +262,12 @@ export default function Bins(props: Props) {
if (doneLoadingPage && grainBins.length < 1 && grainBags.length < 1) {
teamAPI.listTeams(1, 0).then(resp => {
// console.log(resp.data.teams)
if (resp.data.teams.length > 0) {
if (resp.data?.teams?.length > 0) {
// console.log("should?")
setTeamsDialog(true)
}
}).catch(err => {
snackbar.error("error listing teams: "+err)
})
}
}, [doneLoadingPage, grainBins, grainBags])

View file

@ -158,9 +158,9 @@ export default function DevicePage() {
if (length > 0) {
warningString = warningString + " through " + getContextTypes()[length - 1];
}
snackbar.warning(warningString);
snackbar.warning("page data warning: "+warningString);
} else {
snackbar.error(err);
snackbar.error("page data error: "+err);
}
})
.finally(() => setLoading(false));
@ -174,7 +174,7 @@ export default function DevicePage() {
}
})
.catch(err => {
console.log(err)
console.log("load port scan: "+err)
})
}

View file

@ -181,7 +181,8 @@ export default function Terminals(props: Props) {
const load = useCallback(() => {
if(loading) return
setLoading(true)
terminalAPI.listTerminals(200, 0, "asc", "name", as).then(resp => {
terminalAPI.listTerminals(200, 0, "asc", "name", undefined, as).then(resp => {
console.log(resp.data)
if(resp.data.terminals){
setTerminals(resp.data.terminals.map(a => Terminal.any(a)));
}

View file

@ -166,7 +166,7 @@ export default function UserMenu() {
);
};
if (user.id().length < 1) return unauthenticatedUserMenu()
if (user.id()?.length < 1) return unauthenticatedUserMenu()
const hasAdmin = user.hasFeature ? user.hasFeature("admin") : false;
@ -182,7 +182,7 @@ export default function UserMenu() {
<UserTeamName user={user} team={team} />
</Box>
<Box style={{ marginLeft: theme.spacing(1) }}>
{picture && hasTeams && team.id().length > 0 ? (
{picture && hasTeams && team.id()?.length > 0 ? (
<div>
<UserAvatar
user={user}
@ -238,7 +238,7 @@ export default function UserMenu() {
{hasTeams && (
<MenuItem
onClick={() => {
if (as.length > 1) {
if (as?.length > 1) {
user.settings.useTeam = false;
dispatch({ key: "as", value: "" });
userAPI.updateUser(user.id(), user.protobuf()).then(_resp => {
@ -252,13 +252,13 @@ export default function UserMenu() {
});
}
}}
disabled={user.settings.defaultTeam.length < 1}
disabled={user.settings.defaultTeam?.length < 1}
aria-label="Open Team Menu"
dense>
<ListItemIcon>
<Checkbox
disabled={user.settings.defaultTeam.length < 1}
checked={as.length > 1}
disabled={user.settings.defaultTeam?.length < 1}
checked={as?.length > 1}
style={{ margin: 0, padding: 0 }}
/>
</ListItemIcon>