frontend/src/grainBag/grainBagInventoryGraph.tsx
2026-03-06 10:24:12 -06:00

120 lines
4.2 KiB
TypeScript

import { Box, Card, CircularProgress, Typography } from "@mui/material";
import BarGraph, { BarData } from "charts/BarGraph";
import GrainDescriber from "grain/GrainDescriber";
import { GrainBag } from "models/GrainBag";
import moment, { Moment } from "moment";
import { pond } from "protobuf-ts/pond";
import { useGlobalState, useGrainBagAPI, useSnackbar } from "providers";
import { useEffect, useState } from "react";
import { getGrainUnit } from "utils";
interface Props {
grainBag: GrainBag;
startDate: Moment;
endDate: Moment;
customHeight?: number | string;
}
export default function GrainBagInventoryGraph(props: Props) {
const { grainBag, startDate, endDate, customHeight } = props;
const grainBagAPI = useGrainBagAPI();
const [data, setData] = useState<BarData[]>([]);
const [loadingData, setLoadingData] = useState<boolean>(false);
const { openSnack } = useSnackbar();
const [{as}] = useGlobalState();
useEffect(() => {
if (grainBag.key() && !loadingData) {
setLoadingData(true);
grainBagAPI
.listHistory(grainBag.key(), 500, 0, startDate.toISOString(), endDate.toISOString(), as)
.then(resp => {
let barData: BarData[] = [];
let lastBushels = 0;
resp.data.history.forEach(hist => {
if (hist.object?.grainBagSettings) {
//let time = hist.timestamp;
let val = hist.object.grainBagSettings.currentBushels ?? 0;
if (
getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_TONNE &&
grainBag.bushelsPerTonne() > 1
) {
val = Math.round((val / grainBag.bushelsPerTonne()) * 100) / 100;
}
if(getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_TON && grainBag.bushelsPerTonne() > 1){
val = Math.round((val / (grainBag.bushelsPerTonne() * 0.907)) * 100) / 100;
}
if (val !== lastBushels) {
lastBushels = val;
barData.push({
timestamp: moment(hist.timestamp).valueOf(),
value: val
});
}
}
});
if (barData.length === 0) {
let val = grainBag.bushels()
if(getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_TONNE && grainBag.bushelsPerTonne() > 1){
val = grainBag.bushels() / grainBag.bushelsPerTonne()
}
if(getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_TON && grainBag.bushelsPerTonne() > 1){
val = grainBag.bushels() / (grainBag.bushelsPerTonne() * 0.907)
}
barData.push({
timestamp: moment.now().valueOf(),
value: Math.round(val*100)/100
});
}
setData(barData);
})
.catch(_err => {
openSnack("There was a problem retrieving inventory information");
})
.finally(() => {
setLoadingData(false);
});
}
}, [grainBagAPI, grainBag, startDate, endDate, openSnack]); //eslint-disable-line react-hooks/exhaustive-deps
const maxYAxis = () => {
let val = grainBag.capacity()
if(getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_TONNE){
val = Math.round((val / grainBag.bushelsPerTonne()) * 100) / 100;
}
if(getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_TON && grainBag.bushelsPerTonne() > 1){
val = Math.round((val / (grainBag.bushelsPerTonne() * 0.907)) * 100) / 100;
}
return val
}
return (
<Card raised>
<Box padding={2}>
<Typography variant="h6" style={{ fontWeight: "bold" }}>
Inventory over Time
</Typography>
</Box>
{!loadingData && data.length > 0 ? (
<BarGraph
barColour={
grainBag.storage() === pond.BinStorage.BIN_STORAGE_SUPPORTED_GRAIN
? GrainDescriber(grainBag.grain()).colour
: "yellow"
}
data={data}
yMin={0}
yMax={maxYAxis()}
customHeight={customHeight}
useGradient
labels
labelColour="white"
/>
) : (
<Box height={400} display="flex" justifyContent="center" alignItems="center">
<CircularProgress />
</Box>
)}
</Card>
);
}