294 lines
No EOL
9.2 KiB
TypeScript
294 lines
No EOL
9.2 KiB
TypeScript
import {
|
|
Accordion,
|
|
AccordionDetails,
|
|
AccordionSummary,
|
|
Box,
|
|
Button,
|
|
Grid2,
|
|
IconButton,
|
|
Paper,
|
|
Stack,
|
|
Tab,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableContainer,
|
|
TableHead,
|
|
TableRow,
|
|
Tabs,
|
|
Typography
|
|
} from "@mui/material";
|
|
import React, { useCallback, useEffect, useState } from "react";
|
|
import { useMobile, useSnackbar, useUserAPI } from "hooks";
|
|
import { useGlobalState, useFieldAPI, useJohnDeereProxyAPI, useCNHiProxyAPI } from "providers";
|
|
//import HarvestTable from "harvestPlan/HarvestTable";
|
|
import { Field, fieldScope, teamScope } from "models";
|
|
import GrainDescriber from "grain/GrainDescriber";
|
|
import { pond } from "protobuf-ts/pond";
|
|
import HarvestSettings from "harvestPlan/HarvestSettings";
|
|
import ResponsiveTable, { Column } from "common/ResponsiveTable";
|
|
import FieldMinimap from "./Fieldminimap";
|
|
import FieldActions from "./FieldActions";
|
|
import FieldSettings from "./FieldSettings";
|
|
import { ArrowForward, ExpandMore, Settings } from "@mui/icons-material";
|
|
import { cloneDeep } from "lodash";
|
|
import ShareAllFields from "./ShareAllFields";
|
|
import EventBlocker from "common/EventBlocker";
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
interface TabPanelProps {
|
|
children?: React.ReactNode;
|
|
index: any;
|
|
value: any;
|
|
}
|
|
|
|
export default function FieldList() {
|
|
const [{ as }] = useGlobalState();
|
|
const isMobile = useMobile();
|
|
const fieldAPI = useFieldAPI();
|
|
const jdAPI = useJohnDeereProxyAPI();
|
|
const cnhAPI = useCNHiProxyAPI();
|
|
const { openSnack } = useSnackbar();
|
|
const [tabValue, setTabValue] = React.useState(0);
|
|
const [openHarvestSettings, setOpenHarvestSettings] = useState(false);
|
|
// const [fieldForPlan, setFieldForPlan] = useState(Field.create());
|
|
const [fields, setFields] = useState<Field[]>([]);
|
|
const [total, setTotal] = useState(0)
|
|
const [rowsPerPage, setRowsPerPage] = useState(5)
|
|
const [page, setPage] = useState(0)
|
|
const [selectedField, setSelectedField] = useState<Field>()
|
|
const [openFieldSettings, setOpenFieldSettings] = useState(false)
|
|
const [shareOpen, setShareOpen] = useState(false)
|
|
const navigate = useNavigate();
|
|
|
|
const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => {
|
|
setTabValue(newValue);
|
|
setPage(0)
|
|
};
|
|
|
|
const loadAdaptiveFields = useCallback(() => {
|
|
fieldAPI
|
|
.listFields(rowsPerPage, page*rowsPerPage, "asc", "fieldName", undefined, as)
|
|
.then(resp => {
|
|
setFields(resp.data.fields.map(f => Field.create(f)));
|
|
setTotal(resp.data.total)
|
|
})
|
|
.catch(err => {
|
|
openSnack("Failed to load Fields");
|
|
});
|
|
}, [fieldAPI, as, openSnack, page, rowsPerPage]);
|
|
|
|
const loadJDFields = useCallback(() => {
|
|
jdAPI.listFields(rowsPerPage, page*rowsPerPage, as)
|
|
.then(resp => {
|
|
resp.data.fields ? setFields(resp.data.fields.map(f => Field.create(f))) : setFields([])
|
|
}).catch(err => {
|
|
openSnack("Failed to load John Deere Fields");
|
|
})
|
|
},[jdAPI, as, openSnack, page, rowsPerPage])
|
|
|
|
const loadCNHFields = useCallback(() => {
|
|
cnhAPI.listFields(rowsPerPage, page*rowsPerPage, as)
|
|
.then(resp => {
|
|
resp.data.fields ? setFields(resp.data.fields.map(f => Field.create(f))) : setFields([])
|
|
}).catch(err => {
|
|
openSnack("Failed to load John Deere Fields");
|
|
})
|
|
},[cnhAPI, as, openSnack, page, rowsPerPage])
|
|
|
|
useEffect(() => {
|
|
//based on the current tab load the correct fields
|
|
switch(tabValue){
|
|
case 0:
|
|
loadAdaptiveFields();
|
|
break;
|
|
case 1:
|
|
loadJDFields();
|
|
break;
|
|
case 2:
|
|
loadCNHFields();
|
|
break;
|
|
}
|
|
}, [loadAdaptiveFields, loadJDFields, loadCNHFields, tabValue]);
|
|
|
|
const calcTotalAcres = (fields: Field[]) => {
|
|
let totalAcres = 0;
|
|
fields.forEach(field => {
|
|
totalAcres += field.acres();
|
|
});
|
|
totalAcres = Math.round(totalAcres);
|
|
return totalAcres;
|
|
};
|
|
|
|
const goTo = (field: Field) => {
|
|
let path = field.key();
|
|
navigate(path, { state: {field: field, permissions: field.permissions} });
|
|
}
|
|
|
|
const fieldActions = (field: Field) => {
|
|
return (
|
|
<EventBlocker>
|
|
<IconButton
|
|
onClick={() => {
|
|
setSelectedField(field)
|
|
setOpenFieldSettings(true)
|
|
}}><Settings /></IconButton>
|
|
<FieldActions field={field} permissions={field.permissions} refreshCallback={()=>{}}/>
|
|
{isMobile && <IconButton onClick={() => {goTo(field)}}><ArrowForward /></IconButton>}
|
|
</EventBlocker>
|
|
)
|
|
}
|
|
|
|
const columns: Column<Field>[] = [
|
|
{
|
|
title: "View",
|
|
render: row => {
|
|
return (
|
|
<Box margin={1} height={200} width={200}>
|
|
<FieldMinimap field={row} squared borderSpacing={0.001}/>
|
|
</Box>
|
|
)
|
|
}
|
|
},
|
|
{
|
|
title: "Field Name",
|
|
render: row => {
|
|
return <Typography paddingLeft={2}>{row.name()}</Typography>
|
|
}
|
|
},
|
|
{
|
|
title: "Current Crop",
|
|
render: row => {
|
|
return <Typography paddingLeft={2}>{GrainDescriber(row.crop()).name}</Typography>
|
|
}
|
|
},
|
|
{
|
|
title: "Acres",
|
|
render: row => {
|
|
return <Typography paddingLeft={2}>{row.acres()}</Typography>
|
|
}
|
|
},
|
|
{
|
|
title: "Actions",
|
|
hidden: tabValue > 0,
|
|
render: row => fieldActions(row)
|
|
}
|
|
]
|
|
|
|
const fieldTable = (fields: Field[]) => {
|
|
return (
|
|
<ResponsiveTable<Field>
|
|
columns={columns}
|
|
rows={fields}
|
|
onRowClick={(row) => {
|
|
!isMobile && goTo(row)
|
|
}}
|
|
setPage={(newPage)=>{
|
|
setPage(newPage)
|
|
}}
|
|
handleRowsPerPageChange={(e)=>{setRowsPerPage(e.target.value)}}
|
|
page={page}
|
|
pageSize={rowsPerPage}
|
|
total={total}
|
|
resizeable
|
|
loadMore={() => {
|
|
let currentFields = cloneDeep(fields)
|
|
switch(tabValue){
|
|
case 0:
|
|
fieldAPI.listFields(rowsPerPage, currentFields.length, "asc", "fieldName", undefined, as).then(resp => {
|
|
setFields(currentFields.concat(resp.data.fields.map(f => Field.create(f))))
|
|
}).catch(err => {
|
|
openSnack("Failed to load more fields")
|
|
})
|
|
break;
|
|
case 1:
|
|
jdAPI.listFields(rowsPerPage, currentFields.length, as).then(resp => {
|
|
resp.data.fields ? setFields(currentFields.concat(resp.data.fields.map(f => Field.create(f)))) : setFields([])
|
|
}).catch(err => {
|
|
openSnack("Failed to load more fields")
|
|
})
|
|
break;
|
|
case 2:
|
|
cnhAPI.listFields(rowsPerPage, currentFields.length, as).then(resp => {
|
|
resp.data.fields ? setFields(currentFields.concat(resp.data.fields.map(f => Field.create(f)))) : setFields([])
|
|
}).catch(err => {
|
|
openSnack("Failed to load more fields")
|
|
})
|
|
break;
|
|
}
|
|
}}
|
|
renderMobile={(row, index) => {
|
|
return (
|
|
<Accordion>
|
|
<AccordionSummary expandIcon={<ExpandMore />}>
|
|
<Grid2 alignItems="center" width="100%" container direction={"row"} justifyContent="space-between" wrap="nowrap">
|
|
<Grid2>
|
|
<Typography textAlign="center">
|
|
{row.name()}
|
|
</Typography>
|
|
</Grid2>
|
|
<Grid2>
|
|
{fieldActions(row)}
|
|
</Grid2>
|
|
</Grid2>
|
|
</AccordionSummary>
|
|
<AccordionDetails>
|
|
<Grid2 alignItems="center" width="100%" container direction={"row"} justifyContent="space-between" wrap="nowrap">
|
|
<Grid2 size={6}>
|
|
<Box height={150} width="100%">
|
|
<FieldMinimap field={row} borderSpacing={0.001} squared />
|
|
</Box>
|
|
</Grid2>
|
|
<Grid2 size={6}>
|
|
<Stack spacing={2}>
|
|
<Typography textAlign="center">{row.grainName()}</Typography>
|
|
<Typography textAlign="center">{row.acres()} Acres</Typography>
|
|
</Stack>
|
|
<Button variant="contained" color="primary">Go</Button>
|
|
</Grid2>
|
|
</Grid2>
|
|
</AccordionDetails>
|
|
</Accordion>
|
|
)
|
|
}}
|
|
/>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Box>
|
|
<Button
|
|
onClick={()=>{setShareOpen(true)}}
|
|
variant="contained"
|
|
color="primary">
|
|
Share All
|
|
</Button>
|
|
<Tabs
|
|
value={tabValue}
|
|
onChange={handleChange}
|
|
TabIndicatorProps={{ style: { background: "rgba(255,255,0,255)" } }}>
|
|
<Tab label="Adaptive" />
|
|
<Tab label="John Deere" />
|
|
<Tab label="Case New Holland" />
|
|
</Tabs>
|
|
{fieldTable(fields)}
|
|
{/* <HarvestSettings
|
|
open={openHarvestSettings}
|
|
close={() => setOpenHarvestSettings(false)}
|
|
field={fieldForPlan}
|
|
/> */}
|
|
<FieldSettings
|
|
selectedField={selectedField}
|
|
removeField={() => {
|
|
//will need to re-load the fields after one is deleted
|
|
loadAdaptiveFields()
|
|
}}
|
|
open={openFieldSettings}
|
|
onClose={() => {
|
|
setOpenFieldSettings(false);
|
|
}}
|
|
/>
|
|
<ShareAllFields open={shareOpen} close={() => {setShareOpen(false)}}/>
|
|
</Box>
|
|
);
|
|
} |