new table for the fields dashboard, map rendering in row

This commit is contained in:
csawatzky 2025-08-05 16:50:58 -06:00
parent ad479e2b45
commit 781b52afd8
2 changed files with 148 additions and 51 deletions

View file

@ -9,7 +9,8 @@ import {
TableContainer, TableContainer,
TableHead, TableHead,
TableRow, TableRow,
Tabs Tabs,
Typography
} from "@mui/material"; } from "@mui/material";
import React, { useCallback, useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { useMobile, useSnackbar } from "hooks"; import { useMobile, useSnackbar } from "hooks";
@ -19,6 +20,8 @@ import { Field } from "models";
import GrainDescriber from "grain/GrainDescriber"; import GrainDescriber from "grain/GrainDescriber";
import { pond } from "protobuf-ts/pond"; import { pond } from "protobuf-ts/pond";
import HarvestSettings from "harvestPlan/HarvestSettings"; import HarvestSettings from "harvestPlan/HarvestSettings";
import ResponsiveTable, { Column } from "common/ResponsiveTable";
import FieldMinimap from "./Fieldminimap";
interface TabPanelProps { interface TabPanelProps {
children?: React.ReactNode; children?: React.ReactNode;
@ -46,10 +49,13 @@ export default function FieldList() {
const isMobile = useMobile(); const isMobile = useMobile();
const fieldAPI = useFieldAPI(); const fieldAPI = useFieldAPI();
const { openSnack } = useSnackbar(); const { openSnack } = useSnackbar();
const [fields, setFields] = useState<Field[]>([]);
const [value, setValue] = React.useState(0); const [value, setValue] = React.useState(0);
const [openHarvestSettings, setOpenHarvestSettings] = useState(false); const [openHarvestSettings, setOpenHarvestSettings] = useState(false);
const [fieldForPlan, setFieldForPlan] = useState(Field.create()); const [fieldForPlan, setFieldForPlan] = useState(Field.create());
const [fields, setFields] = useState<Field[]>([]); //all fields
const [adaptiveFields, setAdaptiveFields] = useState<Field[]>([])
const [jdFields, setJDFields] = useState<Field[]>([])
const [cnhFields, setCNHFields] = useState<Field[]>([])
const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => { const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => {
setValue(newValue); setValue(newValue);
@ -59,7 +65,7 @@ export default function FieldList() {
fieldAPI fieldAPI
.listFields(500, 0, "asc", "fieldName", undefined, as) .listFields(500, 0, "asc", "fieldName", undefined, as)
.then(resp => { .then(resp => {
setFields(resp.data.fields.map(f => Field.any(f))); setAdaptiveFields(resp.data.fields.map(f => Field.any(f)));
// resp.data.fields.forEach(f => { // resp.data.fields.forEach(f => {
// if (f.settings) { // if (f.settings) {
// fieldAPI.updateField(f.settings.key, f.settings); // fieldAPI.updateField(f.settings.key, f.settings);
@ -75,7 +81,11 @@ export default function FieldList() {
loadFields(); loadFields();
}, [loadFields]); }, [loadFields]);
const calcTotalAcres = () => { useEffect(()=>{
setFields(adaptiveFields.concat(jdFields, cnhFields))
},[adaptiveFields,jdFields,cnhFields])
const calcTotalAcres = (fields: Field[]) => {
let totalAcres = 0; let totalAcres = 0;
fields.forEach(field => { fields.forEach(field => {
totalAcres += field.acres(); totalAcres += field.acres();
@ -84,31 +94,104 @@ export default function FieldList() {
return totalAcres; return totalAcres;
}; };
const listFieldsInfo = fields.map((field, index) => ( // const fieldList = (fields: Field[]) => {
<TableRow key={index}> // return fields.map((field, index) => (
<TableCell>{field.fieldName()}</TableCell> // <TableRow key={index}>
<TableCell>{field.landLoc()}</TableCell> // <TableCell>{field.fieldName()}</TableCell>
<TableCell> // <TableCell>{field.landLoc()}</TableCell>
{field.crop() === pond.Grain.GRAIN_CUSTOM // <TableCell>
? field.customType() // {field.crop() === pond.Grain.GRAIN_CUSTOM
: GrainDescriber(field.crop()).name} // ? field.customType()
</TableCell> // : GrainDescriber(field.crop()).name}
<TableCell>{field.calculateAcres()}</TableCell> // </TableCell>
<TableCell> // <TableCell>{field.calculateAcres()}</TableCell>
{field.permissions.includes(pond.Permission.PERMISSION_WRITE) && ( // <TableCell>
<Button // {field.permissions.includes(pond.Permission.PERMISSION_WRITE) && (
variant="contained" // <Button
color="primary" // variant="contained"
onClick={() => { // color="primary"
setFieldForPlan(field); // onClick={() => {
setOpenHarvestSettings(true); // setFieldForPlan(field);
}}> // setOpenHarvestSettings(true);
New Crop Plan // }}>
</Button> // New Crop Plan
)} // </Button>
</TableCell> // )}
</TableRow> // </TableCell>
)); // </TableRow>
// ));
// }
// const fieldTable = (fields: Field[]) => {
// return (
// <TableContainer component={Paper}>
// <Table style={{ minWidth: 1000 }}>
// <TableHead>
// <TableRow>
// <TableCell>Field Name</TableCell>
// <TableCell>Land Location</TableCell>
// <TableCell>Main Crop Type</TableCell>
// <TableCell>Acres ({calcTotalAcres(fields)} Total)</TableCell>
// <TableCell>Create New Plan</TableCell>
// </TableRow>
// </TableHead>
// <TableBody>{fieldList(fields)}</TableBody>
// </Table>
// </TableContainer>
// )
// }
const columns: Column<Field>[] = [
{
title: "View",
render: row => {
return (
<Box height={200} width={200}>
<FieldMinimap field={row} />
</Box>
)
}
},
{
title: "Field Name",
render: row => {
return <Typography>{row.name()}</Typography>
}
},
{
title: "Current Crop",
render: row => {
return <Typography>{row.crop()}</Typography>
}
},
{
title: "Acres",
render: row => {
return <Typography>{row.acres()}</Typography>
}
},
{
title: "Actions",
render: row => {
return <Typography>Field Actions Here</Typography>
}
}
]
const fieldTable = (fields: Field[]) => {
return (
<ResponsiveTable<Field>
columns={columns}
rows={fields}
setPage={()=>{}}
hidePagination
handleRowsPerPageChange={()=>{}}
page={0}
pageSize={10}
total={fields.length}
/>
)
}
return ( return (
<Box> <Box>
@ -116,33 +199,23 @@ export default function FieldList() {
value={value} value={value}
onChange={handleChange} onChange={handleChange}
TabIndicatorProps={{ style: { background: "rgba(255,255,0,255)" } }}> TabIndicatorProps={{ style: { background: "rgba(255,255,0,255)" } }}>
<Tab label="Field Overview" /> <Tab label="All" />
{/* {!isMobile && <Tab label="Current Harvest Plans" />} <Tab label="Adaptive" />
{!isMobile && <Tab label="Plan History" />} */} <Tab label="John Deere" />
<Tab label="Case New Holland" />
</Tabs> </Tabs>
<TabPanelMine index={0} value={value}> <TabPanelMine index={0} value={value}>
<TableContainer component={Paper}> {fieldTable(fields)}
<Table style={{ minWidth: 1000 }}>
<TableHead>
<TableRow>
<TableCell>Field Name</TableCell>
<TableCell>Land Location</TableCell>
<TableCell>Main Crop Type</TableCell>
<TableCell>Acres ({calcTotalAcres()} Total)</TableCell>
<TableCell>Create New Plan</TableCell>
</TableRow>
</TableHead>
<TableBody>{listFieldsInfo}</TableBody>
</Table>
</TableContainer>
</TabPanelMine> </TabPanelMine>
{/* need to re-factor the harvest table file before restoring these functions */} <TabPanelMine index={1} value={value}>
{/* <TabPanelMine index={1} value={value}> {fieldTable(adaptiveFields)}
<HarvestTable fields={fields} display="current" />
</TabPanelMine> </TabPanelMine>
<TabPanelMine index={2} value={value}> <TabPanelMine index={2} value={value}>
<HarvestTable fields={fields} display="history" /> {fieldTable(jdFields)}
</TabPanelMine> */} </TabPanelMine>
<TabPanelMine index={3} value={value}>
{fieldTable(cnhFields)}
</TabPanelMine>
<HarvestSettings <HarvestSettings
open={openHarvestSettings} open={openHarvestSettings}
close={() => setOpenHarvestSettings(false)} close={() => setOpenHarvestSettings(false)}

View file

@ -0,0 +1,24 @@
import { Box } from "@mui/material";
import { Field } from "models";
import { useRef } from "react";
import Map, { MapRef } from "react-map-gl/mapbox";
import 'mapbox-gl/dist/mapbox-gl.css';
interface Props {
field?: Field
}
export default function FieldMinimap(props: Props) {
const { field } = props
const MAPBOX_TOKEN = import.meta.env.VITE_MAPBOX_ACCESS_TOKEN;
return (
<Map
style={{width: "100%", height: "100%"}}
mapboxAccessToken={MAPBOX_TOKEN}
mapStyle="mapbox://styles/mapbox/satellite-streets-v11"
/>
)
}