added the bin fans table to the bins page
This commit is contained in:
parent
2e3458cc22
commit
6b5697e075
2 changed files with 268 additions and 3 deletions
265
src/bin/BinFansStatusTable.tsx
Normal file
265
src/bin/BinFansStatusTable.tsx
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
import {
|
||||
Box,
|
||||
Button,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
Grid2 as Grid,
|
||||
IconButton
|
||||
} from "@mui/material";
|
||||
// import { getTableIcons } from "common/ResponsiveTable";
|
||||
// import MaterialTable, { Column } from "material-table";
|
||||
import { Bin } from "models";
|
||||
import { useBinAPI, useGlobalState, useSnackbar } from "providers";
|
||||
import fans from "fans/fans_client.json";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { getThemeType } from "theme";
|
||||
import AerationFanIcon from "products/AgIcons/AerationFanIcon";
|
||||
import FanPicker from "fans/fanPicker";
|
||||
import ResponsiveDialog from "common/ResponsiveDialog";
|
||||
import { useMobile } from "hooks";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import ResponsiveTable, { Column } from "common/ResponsiveTable";
|
||||
import { cloneDeep } from "lodash";
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
dark: {
|
||||
backgroundColor: getThemeType() === "light" ? "rgb(245, 245, 245)" : "rgb(50, 50, 50)",
|
||||
padding: 5
|
||||
},
|
||||
light: {
|
||||
backgroundColor: getThemeType() === "light" ? "rgb(235, 235, 235)" : "rgb(60, 60, 60)",
|
||||
padding: 5
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
interface jsonFan {
|
||||
id: number;
|
||||
name: string;
|
||||
kind: string;
|
||||
rpm: number;
|
||||
diameter: number;
|
||||
horsepower: number;
|
||||
}
|
||||
|
||||
interface BinRow {
|
||||
bin: Bin;
|
||||
fan?: jsonFan;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
isLoading: boolean;
|
||||
bins: Bin[];
|
||||
getControllerInfo?: (totalControllers: number, onControllers: number) => void;
|
||||
}
|
||||
|
||||
export default function BinsFansStatusTable(props: Props) {
|
||||
const [{ as }] = useGlobalState();
|
||||
const binAPI = useBinAPI();
|
||||
const { bins, isLoading, getControllerInfo } = props;
|
||||
const { openSnack } = useSnackbar();
|
||||
const [tableData, setTableData] = useState<BinRow[]>([]);
|
||||
const [displayedRows, setDisplayedRows] = useState<BinRow[]>([]);
|
||||
const [fanMap, setFanMap] = useState<Map<number, jsonFan>>(new Map());
|
||||
const isMobile = useMobile();
|
||||
const [tablePage, setTablePage] = useState(0);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
const [openPickerDialog, setOpenPickerDialog] = useState(false);
|
||||
const [selectedBinRow, setSelectedBinRow] = useState<BinRow | undefined>();
|
||||
const [newFanID, setNewFanID] = useState<number | undefined>();
|
||||
const classes = useStyles();
|
||||
|
||||
useEffect(()=>{
|
||||
let clone: BinRow[] = cloneDeep(tableData)
|
||||
let rows = clone.splice(tablePage * pageSize, pageSize)
|
||||
setDisplayedRows(rows)
|
||||
},[tableData, tablePage, pageSize])
|
||||
|
||||
//define the columns for the desktop table
|
||||
const columns: Column<BinRow>[] = [
|
||||
{
|
||||
title: "Set Fan",
|
||||
cellStyle: {padding: 2},
|
||||
render: (row) => <Box>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setSelectedBinRow(row);
|
||||
setOpenPickerDialog(true);
|
||||
}}
|
||||
>
|
||||
<AerationFanIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
},
|
||||
{
|
||||
title: "Bin",
|
||||
cellStyle: {padding: 2},
|
||||
render: (row) => <Box>{row.bin.settings.name}</Box>
|
||||
},
|
||||
{
|
||||
title: "Bin Fan",
|
||||
cellStyle: {padding: 2},
|
||||
hidden: isMobile,
|
||||
render: row => {
|
||||
if (row.fan) {
|
||||
return <Box>{row.fan.name}</Box>
|
||||
} else {
|
||||
return <Box>"No Fan Set on Bin"</Box>
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Fan Type",
|
||||
cellStyle: {padding: 2},
|
||||
hidden: isMobile,
|
||||
render: (row) => <Box>{row.fan?.kind}</Box>
|
||||
},
|
||||
{
|
||||
title: "Horsepower",
|
||||
cellStyle: {padding: 2},
|
||||
hidden: isMobile,
|
||||
render: (row) => <Box>{row.fan?.horsepower}</Box>
|
||||
},
|
||||
//the controllers
|
||||
{
|
||||
title: "Fan Controllers",
|
||||
cellStyle: {padding: 2},
|
||||
render: row => {
|
||||
if (row.bin.status.fans.length > 0) {
|
||||
return (
|
||||
<Grid container direction="column" alignItems="center">
|
||||
{row.bin.status.fans.map((binFan, i) => (
|
||||
<Grid
|
||||
key={i}
|
||||
container
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
className={i % 2 === 0 ? classes.dark : classes.light}>
|
||||
<Grid>{binFan.name}</Grid>
|
||||
<Grid>{binFan.state ? "On" : "Off"}</Grid>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
);
|
||||
} else {
|
||||
return <Box>No Controllers attached to this bin</Box>
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
//build the fanmap
|
||||
let fanMap: Map<number, jsonFan> = new Map();
|
||||
fans["bulk"].forEach(fan => {
|
||||
fanMap.set(fan.id, fan);
|
||||
});
|
||||
setFanMap(fanMap);
|
||||
|
||||
let data: BinRow[] = [];
|
||||
let dataMap: Map<string, BinRow> = new Map();
|
||||
let totalControllers = 0;
|
||||
let onControllers = 0;
|
||||
bins.forEach(bin => {
|
||||
//put the bin in the row
|
||||
let row: BinRow = {
|
||||
bin: bin
|
||||
};
|
||||
//if the bin has a fan id set get it from the json and put it in the row data
|
||||
if (bin.fanID() !== 0) {
|
||||
row.fan = fanMap.get(bin.fanID());
|
||||
}
|
||||
data.push(row);
|
||||
dataMap.set(bin.key(), row);
|
||||
|
||||
//add to the controller numbers
|
||||
bin.status.fans.forEach(fan => {
|
||||
//add to the total for each fan
|
||||
totalControllers++;
|
||||
//if the fan is on add to the count for controllers that are on
|
||||
if (fan.state) {
|
||||
onControllers++;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTableData(data);
|
||||
//setTableDataMap(dataMap)
|
||||
if (getControllerInfo) {
|
||||
getControllerInfo(totalControllers, onControllers);
|
||||
}
|
||||
}, [as, bins, getControllerInfo]);
|
||||
|
||||
const updateBinFan = () => {
|
||||
if (selectedBinRow && newFanID) {
|
||||
//use the bin api to update the bin in the selected row
|
||||
let bin = selectedBinRow.bin;
|
||||
bin.settings.fanId = newFanID;
|
||||
binAPI
|
||||
.updateBin(bin.key(), bin.settings)
|
||||
.then(resp => {
|
||||
//when an update succeeds update the table with the fan information
|
||||
//let dataMap = tableDataMap
|
||||
selectedBinRow.bin = bin;
|
||||
selectedBinRow.fan = fanMap.get(newFanID);
|
||||
openSnack("Updated bin with new fan");
|
||||
//close dialog
|
||||
setOpenPickerDialog(false);
|
||||
})
|
||||
.catch(err => {
|
||||
openSnack("failed to update bin with new fan");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const fanPickerDialog = () => {
|
||||
return (
|
||||
<ResponsiveDialog
|
||||
open={openPickerDialog}
|
||||
onClose={() => {
|
||||
setOpenPickerDialog(false);
|
||||
}}>
|
||||
<DialogContent>
|
||||
<FanPicker
|
||||
updateFan={fanID => {
|
||||
setNewFanID(fanID);
|
||||
}}
|
||||
useCardView
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setOpenPickerDialog(false);
|
||||
}}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={updateBinFan} variant="contained" color="primary">
|
||||
Confirm
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</ResponsiveDialog>
|
||||
);
|
||||
};
|
||||
|
||||
//function to make the table
|
||||
const fanStatusTable = () => {
|
||||
return (
|
||||
<ResponsiveTable
|
||||
rows={displayedRows}
|
||||
isLoading={isLoading}
|
||||
columns={columns}
|
||||
page={tablePage}
|
||||
pageSize={pageSize}
|
||||
total={tableData.length}
|
||||
setPage={(page)=>{setTablePage(page)}}
|
||||
handleRowsPerPageChange={(e)=>{setPageSize(e.target.value)}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<React.Fragment>
|
||||
{fanStatusTable()}
|
||||
{fanPickerDialog()}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue