put the first components into the field page

This commit is contained in:
csawatzky 2025-08-29 12:36:45 -06:00
parent 1588905a04
commit 1fbc817abe
4 changed files with 159 additions and 5 deletions

View file

@ -63,6 +63,8 @@ export default function FieldActions(props: Props) {
removeSelf: false removeSelf: false
}); });
console.log(permissions)
const groupMenu = () => { const groupMenu = () => {
const canShare = permissions.includes(pond.Permission.PERMISSION_SHARE); const canShare = permissions.includes(pond.Permission.PERMISSION_SHARE);
const canManageUsers = permissions.includes(pond.Permission.PERMISSION_USERS); const canManageUsers = permissions.includes(pond.Permission.PERMISSION_USERS);

View file

@ -30,9 +30,11 @@ import ResponsiveTable, { Column } from "common/ResponsiveTable";
import FieldMinimap from "./Fieldminimap"; import FieldMinimap from "./Fieldminimap";
import FieldActions from "./FieldActions"; import FieldActions from "./FieldActions";
import FieldSettings from "./FieldSettings"; import FieldSettings from "./FieldSettings";
import { ExpandMore, Settings } from "@mui/icons-material"; import { ArrowForward, ExpandMore, Settings } from "@mui/icons-material";
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import ShareAllFields from "./ShareAllFields"; import ShareAllFields from "./ShareAllFields";
import EventBlocker from "common/EventBlocker";
import { useNavigate } from "react-router-dom";
interface TabPanelProps { interface TabPanelProps {
children?: React.ReactNode; children?: React.ReactNode;
@ -57,6 +59,7 @@ export default function FieldList() {
const [selectedField, setSelectedField] = useState<Field>() const [selectedField, setSelectedField] = useState<Field>()
const [openFieldSettings, setOpenFieldSettings] = useState(false) const [openFieldSettings, setOpenFieldSettings] = useState(false)
const [shareOpen, setShareOpen] = useState(false) const [shareOpen, setShareOpen] = useState(false)
const navigate = useNavigate();
const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => { const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => {
setTabValue(newValue); setTabValue(newValue);
@ -117,16 +120,22 @@ export default function FieldList() {
return totalAcres; return totalAcres;
}; };
const goTo = (field: Field) => {
let path = field.key();
navigate(path, { state: {field: field, permissions: field.permissions} });
}
const fieldActions = (field: Field) => { const fieldActions = (field: Field) => {
return ( return (
<Box> <EventBlocker>
<IconButton <IconButton
onClick={() => { onClick={() => {
setSelectedField(field) setSelectedField(field)
setOpenFieldSettings(true) setOpenFieldSettings(true)
}}><Settings /></IconButton> }}><Settings /></IconButton>
<FieldActions field={field} permissions={field.permissions} refreshCallback={()=>{}}/> <FieldActions field={field} permissions={field.permissions} refreshCallback={()=>{}}/>
</Box> {isMobile && <IconButton onClick={() => {goTo(field)}}><ArrowForward /></IconButton>}
</EventBlocker>
) )
} }
@ -171,6 +180,9 @@ const columns: Column<Field>[] = [
<ResponsiveTable<Field> <ResponsiveTable<Field>
columns={columns} columns={columns}
rows={fields} rows={fields}
onRowClick={(row) => {
!isMobile && goTo(row)
}}
setPage={(newPage)=>{ setPage={(newPage)=>{
setPage(newPage) setPage(newPage)
}} }}
@ -224,7 +236,7 @@ const columns: Column<Field>[] = [
<Grid2 alignItems="center" width="100%" container direction={"row"} justifyContent="space-between" wrap="nowrap"> <Grid2 alignItems="center" width="100%" container direction={"row"} justifyContent="space-between" wrap="nowrap">
<Grid2 size={6}> <Grid2 size={6}>
<Box height={150} width="100%"> <Box height={150} width="100%">
<FieldMinimap field={row} /> <FieldMinimap field={row} borderSpacing={0.001} squared />
</Box> </Box>
</Grid2> </Grid2>
<Grid2 size={6}> <Grid2 size={6}>
@ -232,6 +244,7 @@ const columns: Column<Field>[] = [
<Typography textAlign="center">{row.grainName()}</Typography> <Typography textAlign="center">{row.grainName()}</Typography>
<Typography textAlign="center">{row.acres()} Acres</Typography> <Typography textAlign="center">{row.acres()} Acres</Typography>
</Stack> </Stack>
<Button variant="contained" color="primary">Go</Button>
</Grid2> </Grid2>
</Grid2> </Grid2>
</AccordionDetails> </AccordionDetails>

View file

@ -47,6 +47,7 @@ const Contract = lazy(() => import("pages/Contract"));
const JohnDeere = lazy(() => import("pages/JohnDeere")); const JohnDeere = lazy(() => import("pages/JohnDeere"));
const CNHi = lazy(() => import("pages/CNHi")); const CNHi = lazy(() => import("pages/CNHi"));
const LibraCart = lazy(() => import("pages/LibraCart")); const LibraCart = lazy(() => import("pages/LibraCart"));
const FieldPage = lazy(()=>import("pages/Field"));
export const appendToUrl = (appendage: number | string) => { export const appendToUrl = (appendage: number | string) => {
const basePath = location.pathname.replace(/\/$/, ""); const basePath = location.pathname.replace(/\/$/, "");
@ -70,6 +71,7 @@ export default function Router() {
<Route path="terminals/*" element={<TerminalGatesRoute />} /> <Route path="terminals/*" element={<TerminalGatesRoute />} />
<Route path="jobsites/*" element={<JobsitesRoute />} /> <Route path="jobsites/*" element={<JobsitesRoute />} />
<Route path="heaters/*" element={<ObjectHeatersRoute />} /> <Route path="heaters/*" element={<ObjectHeatersRoute />} />
<Route path="fields/*" element={<FieldsRoute />} />
</Routes> </Routes>
) )
} }
@ -284,6 +286,21 @@ export default function Router() {
); );
}; };
const FieldsRoute = () => {
return (
<Routes>
<Route
path=""
element={<Fields />}
/>
<Route
path="/:fieldID"
element={<FieldPage />}
/>
</Routes>
);
}
if (isLoading) return null; if (isLoading) return null;
// if (!isAuthenticated) { // if (!isAuthenticated) {
// loginWithRedirect() // loginWithRedirect()
@ -325,7 +342,6 @@ export default function Router() {
{user.hasFeature("admin") && {user.hasFeature("admin") &&
<Route path="logs" element={<Logs />} /> <Route path="logs" element={<Logs />} />
} }
<Route path="fields" element={<Fields />} />
<Route path="marketplace" element={<Marketplace />} /> <Route path="marketplace" element={<Marketplace />} />
{user.hasFeature("admin") && ( {user.hasFeature("admin") && (
<Route path="firmware" element={<Firmware />} /> <Route path="firmware" element={<Firmware />} />

123
src/pages/Field.tsx Normal file
View file

@ -0,0 +1,123 @@
import { Field, HarvestPlan } from "models";
import { useGlobalState } from "providers";
import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import PageContainer from "./PageContainer";
import { useMobile } from "hooks";
import { Box, Grid2, IconButton } from "@mui/material";
import FieldActions from "field/FieldActions";
import { Settings } from "@mui/icons-material";
import { pond } from "protobuf-ts/pond";
import FieldMinimap from "field/Fieldminimap";
import Weather from "weather/weather";
import TaskViewer from "tasks/TaskViewer";
import HarvestPlanDisplay from "harvestPlan/HarvestPlanDisplay";
export default function FieldPage() {
const { state } = useLocation();
//const [{ as }] = useGlobalState()
const [field, setField] = useState<Field>(state?.field ? Field.create(state.field) : Field.create())
const [permissions, setPermissions] = useState<pond.Permission[]>(state?.permissions ? state.permissions : [])
const isMobile = useMobile()
const [openFieldSettings, setOpenFieldSettings] = useState(false)
const [planLoading, setPlanLoading] = useState(false)
const [hPlan, setHPlan] = useState<HarvestPlan>(HarvestPlan.create());
const loadField = () => {
}
useEffect(()=>{
if(state.field){
let field = Field.create(state.field)
setField(field)
setPermissions(state.permissions)
}
},[state.field])
const fieldActions = () => {
return (
<Box>
<IconButton
onClick={() => {
setOpenFieldSettings(true)
}}><Settings /></IconButton>
<FieldActions field={field} permissions={permissions} refreshCallback={()=>{}}/>
</Box>
)
}
const map = () => {
return (
<Box height={550}>
<FieldMinimap field={field} borderSpacing={0.001} squared/>
</Box>
)
}
const weather = () => {
return (<Weather longitude={field.center().longitude} latitude={field.center().latitude} />)
}
const harvestPlans = () => {
console.log(permissions)
return (
<HarvestPlanDisplay
plan={hPlan}
permissions={permissions}
planField={field}
loading={planLoading}
fieldList={[field]}
changePlan={updatedPlan => {
if (updatedPlan) {
setHPlan(updatedPlan);
}
}}
/>)
}
const tasks = () => {
let taskLoadKeys: string[] = [];
if (!planLoading) {
field.key() !== "" && taskLoadKeys.push(field.key());
//hPlan.key() !== "" && taskLoadKeys.push(hPlan.key());
}
return (<TaskViewer drawerView objectKey={field.key()} loadKeys={taskLoadKeys} />)
}
const desktopView = () => {
return (
<Grid2 container>
<Grid2 size={4}>
{map()}
</Grid2>
<Grid2 size={3}>
{weather()}
</Grid2>
<Grid2 size={5}>
{tasks()}
</Grid2>
<Grid2 size={12}>
{harvestPlans()}
</Grid2>
</Grid2>
)
}
const mobileView = () => {
return (
<Box>Mobile will just be the drawer view</Box>
)
}
const fieldSettings = () => {
}
return (
<PageContainer>
{fieldActions()}
{isMobile ? mobileView() : desktopView()}
</PageContainer>
)
}