759 lines
27 KiB
TypeScript
759 lines
27 KiB
TypeScript
import {
|
|
TextField,
|
|
DialogContent,
|
|
DialogActions,
|
|
Button,
|
|
Box,
|
|
DialogTitle,
|
|
Autocomplete
|
|
} from "@mui/material";
|
|
import React, { useCallback, useState } from "react";
|
|
import "mapbox-gl/dist/mapbox-gl.css";
|
|
import { pond } from "protobuf-ts/pond";
|
|
import { useDeviceAPI, useGroupAPI, useMobile, useSnackbar } from "hooks";
|
|
import { useEffect } from "react";
|
|
import { useGlobalState, useSiteAPI } from "providers";
|
|
import ResponsiveDialog from "common/ResponsiveDialog";
|
|
import { Device, Group, Site } from "models";
|
|
// import GroupSettingsIcon from "@material-ui/icons/Settings";
|
|
import MapBase, { ViewData } from "maps/MapBase";
|
|
import ConstructionMapTools from "maps/mapObjectTools/constructionMapTools";
|
|
import { MarkerData } from "maps/mapMarkers/Markers";
|
|
import { clone } from "lodash";
|
|
import NexusSTIcon from "products/Construction/NexusSTIcon";
|
|
import DeviceDrawer from "maps/mapDrawers/DeviceDrawer";
|
|
//import { Autocomplete } from "@material-ui/lab";
|
|
import JobsiteIcon from "products/Construction/JobSiteIcon";
|
|
import SiteDrawer from "maps/mapDrawers/SiteDrawer";
|
|
import DeviceGroupIcon from "products/Construction/DeviceGroupIcon";
|
|
import GroupDrawer from "maps/mapDrawers/GroupDrawer";
|
|
import { Result } from "@mapbox/mapbox-gl-geocoder";
|
|
//import { GeocoderObject } from "maps/mapControllers/Geocoder";
|
|
|
|
interface Props {
|
|
setSiteCallback?: React.Dispatch<React.SetStateAction<pond.SiteSettings | undefined>>;
|
|
disableDrawer?: boolean;
|
|
startingView?: ViewData;
|
|
}
|
|
|
|
export default function ConstructionMapController(props: Props) {
|
|
const transDuration = 3000;
|
|
const [{ user, as }] = useGlobalState();
|
|
const [currentView, setCurrentView] = useState<ViewData>(
|
|
props.startingView
|
|
? props.startingView
|
|
: {
|
|
latitude: 52.1579,
|
|
longitude: -106.6702,
|
|
zoom: user.settings.mapZoom
|
|
}
|
|
);
|
|
const [newLong, setNewLong] = useState(0);
|
|
const [newLat, setNewLat] = useState(0);
|
|
const [siteName, setSiteName] = useState("");
|
|
const siteAPI = useSiteAPI();
|
|
const [openSiteDrawer, setOpenSiteDrawer] = useState(false);
|
|
const [SiteDialog, setSiteDialog] = useState(false);
|
|
const [sites, setSites] = useState<Map<string, Site>>(new Map());
|
|
const { openSnack } = useSnackbar();
|
|
const deviceAPI = useDeviceAPI();
|
|
const [loadingSites, setLoadingSites] = useState(false);
|
|
const [loadingDevices, setLoadingDevices] = useState(false);
|
|
//map that is the site id as the key with and array of heater data objects (heaters for that site)
|
|
const [heaterMap, setHeaterMap] = useState<Map<string, pond.ObjectHeaterData[]>>(
|
|
new Map<string, pond.ObjectHeaterData[]>()
|
|
);
|
|
const groupAPI = useGroupAPI();
|
|
const [groups, setGroups] = useState<Map<string, Group>>(new Map());
|
|
const [openMarkerDialog, setOpenMarkerDialog] = useState(false);
|
|
const [selectKey, setSelectKey] = useState("");
|
|
const [endTime, setEndTime] = useState(0);
|
|
const [devOps, setDevOps] = useState<Device[]>([]);
|
|
const [groupOps, setGroupOps] = useState<Group[]>([]);
|
|
const [devices, setDevices] = useState<Map<string, Device>>(new Map<string, Device>());
|
|
const [openDevDrawer, setOpenDevDrawer] = useState(false);
|
|
const [openGroupDrawer, setOpenGroupDrawer] = useState(false);
|
|
const [markerType, setMarkerType] = useState<pond.ObjectType>(0);
|
|
const [devMarkerData, setDevMarkerData] = useState<Map<string, MarkerData>>(new Map());
|
|
const [siteMarkerData, setSiteMarkerData] = useState<Map<string, MarkerData>>(new Map());
|
|
const [groupMarkerData, setGroupMarkerData] = useState<Map<string, MarkerData>>(new Map());
|
|
const [objectKey, setObjectKey] = useState<string>("");
|
|
const isMobile = useMobile();
|
|
const [markers, setMarkers] = useState<MarkerData[]>([]);
|
|
const [displayMarkerTitle, setDisplayMarkerTitle] = useState(false);
|
|
const zoomLevels = {
|
|
far: 14,
|
|
close: 18
|
|
};
|
|
const [customGeoSearchEntries, setCustomGeoSearchEntries] = useState<Result[]>([]);
|
|
const [siteSearchEntries, setSiteSearchEntries] = useState<Result[]>([]);
|
|
const [deviceSearchEntries, setDeviceSearchEntries] = useState<Result[]>([]);
|
|
const [groupSearchEntries, setGroupSearchEntries] = useState<Result[]>([]);
|
|
|
|
//this click delay is implemented to fix an issue with touch screens that caused the drawer to close immediately after opening
|
|
const clickDelay = () => {
|
|
let endTime = new Date().valueOf() + 1000;
|
|
setEndTime(endTime);
|
|
};
|
|
|
|
const closeDrawers = () => {
|
|
setOpenDevDrawer(false);
|
|
setOpenSiteDrawer(false);
|
|
};
|
|
|
|
//makes sure all of the Fields are filled out on the first form of the dialog otherwise the next button is disabled
|
|
const formComplete = () => {
|
|
if (siteName.length < 1) {
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//save the new site to the database
|
|
const saveSite = () => {
|
|
let newSite = Site.create();
|
|
newSite.settings.userId = user.id();
|
|
newSite.settings.siteName = siteName;
|
|
newSite.settings.objectKey = user.id();
|
|
newSite.settings.longitude = newLong;
|
|
newSite.settings.latitude = newLat;
|
|
|
|
siteAPI
|
|
.addSite(newSite.settings, as)
|
|
.then(resp => {
|
|
openSnack("Added new Site Location");
|
|
loadSites();
|
|
})
|
|
.catch(err => {
|
|
openSnack("Failed to add site");
|
|
});
|
|
setSiteDialog(false);
|
|
};
|
|
|
|
//load the sites from the database and set the markers for each of them
|
|
const loadSites = useCallback(() => {
|
|
if (loadingSites) return;
|
|
setLoadingSites(true);
|
|
let s: Map<string, Site> = new Map();
|
|
let sm: Map<string, MarkerData> = new Map();
|
|
let hMap: Map<string, pond.ObjectHeaterData[]> = new Map<string, pond.ObjectHeaterData[]>();
|
|
let searchEntries: Result[] = [];
|
|
siteAPI
|
|
.listSitesPageData(50, 0, "asc", "key", undefined, as)
|
|
.then(resp => {
|
|
if(resp.data.sites){
|
|
resp.data.sites.forEach(site => {
|
|
if (!site) return;
|
|
let newSite: Site = Site.any(site.site);
|
|
s.set(newSite.key(), newSite);
|
|
//if there is no long/lat on the site give it a default of saskatoon
|
|
if (!newSite.longitude() || !newSite.latitude()) {
|
|
newSite.settings.latitude = 52.1579;
|
|
newSite.settings.longitude = -106.6702;
|
|
}
|
|
let siteMarker: MarkerData = {
|
|
colour: newSite.settings.theme?.color ?? "blue",
|
|
longitude: newSite.longitude(),
|
|
latitude: newSite.latitude(),
|
|
title: newSite.siteName(),
|
|
markerIcon: <JobsiteIcon type="light" size={50 * 0.6} />,
|
|
details: [newSite.siteName()],
|
|
clickFunc: (e, i, isMobile) => {
|
|
closeDrawers();
|
|
setObjectKey(newSite.key());
|
|
setOpenSiteDrawer(true);
|
|
moveMap(newSite.latitude(), newSite.longitude(), zoomLevels.far, isMobile);
|
|
},
|
|
updateFunc: location => {
|
|
if (newSite.settings) {
|
|
updateSiteMarkers(newSite, location.longitude, location.latitude);
|
|
}
|
|
}
|
|
};
|
|
sm.set(newSite.key(), siteMarker);
|
|
hMap.set(newSite.key(), site.heaterData);
|
|
searchEntries.push({
|
|
id: newSite.key(),
|
|
center: [newSite.longitude(), newSite.latitude()],
|
|
place_name: newSite.siteName(),
|
|
place_type: ["site"]
|
|
} as Result);
|
|
});
|
|
}
|
|
setSiteMarkerData(sm);
|
|
setSites(s);
|
|
setLoadingSites(false);
|
|
setHeaterMap(hMap);
|
|
setSiteSearchEntries(searchEntries);
|
|
})
|
|
.catch(err => {
|
|
openSnack("Failed to load sites");
|
|
});
|
|
}, [siteAPI, openSnack, as]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
const loadDevices = useCallback(() => {
|
|
if (loadingDevices) return;
|
|
setLoadingDevices(true);
|
|
deviceAPI
|
|
.list(500, 0, "asc", "name", undefined, undefined, undefined, undefined, undefined, true, undefined, undefined,undefined,undefined,undefined,as)
|
|
.then(resp => {
|
|
let devOps: Device[] = []; //only devices that are not mapped
|
|
let deviceMap: Map<string, Device> = new Map<string, Device>(); // all devices
|
|
let m = clone(devMarkerData);
|
|
let searchEntries: Result[] = [];
|
|
resp.data.comprehensiveDevices.forEach(cd => {
|
|
if (cd.device?.settings?.deviceId) {
|
|
let dev = Device.any(cd.device);
|
|
deviceMap.set(dev.id().toString(), dev);
|
|
let devLoc = dev.location();
|
|
if (
|
|
devLoc.longitude &&
|
|
devLoc.longitude !== 0 &&
|
|
devLoc.latitude &&
|
|
devLoc.latitude !== 0
|
|
) {
|
|
let devMarker: MarkerData = {
|
|
colour: dev.settings.theme?.color || "blue",
|
|
title: dev.name(),
|
|
longitude: devLoc.longitude,
|
|
latitude: devLoc.latitude,
|
|
markerIcon: <NexusSTIcon size={50 * 0.6} type="light" />,
|
|
details: [dev.name()],
|
|
clickFunc: (e, i, isMobile) => {
|
|
closeDrawers();
|
|
clickDelay();
|
|
setObjectKey(dev.id().toString());
|
|
setOpenDevDrawer(true);
|
|
moveMap(devLoc.latitude, devLoc.longitude, zoomLevels.far, isMobile);
|
|
},
|
|
updateFunc: location => {
|
|
if (dev.settings) {
|
|
updateDeviceMarkers(dev, location.longitude, location.latitude);
|
|
}
|
|
}
|
|
};
|
|
m.set(dev.id().toString(), devMarker);
|
|
searchEntries.push({
|
|
id: dev.id().toString(),
|
|
center: [devLoc.longitude, devLoc.latitude],
|
|
place_name: dev.name(),
|
|
place_type: ["device"]
|
|
} as Result);
|
|
} else {
|
|
devOps.push(dev);
|
|
}
|
|
}
|
|
});
|
|
setDevices(deviceMap);
|
|
setDevOps(devOps);
|
|
setLoadingDevices(false);
|
|
setDevMarkerData(m);
|
|
setDeviceSearchEntries(searchEntries);
|
|
})
|
|
.catch(err => {
|
|
openSnack("Failed to Load Devices");
|
|
});
|
|
}, [deviceAPI, openSnack, as]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
const loadGroups = useCallback(() => {
|
|
groupAPI
|
|
.listGroups(50, 0)
|
|
.then(resp => {
|
|
let gMap: Map<string, Group> = new Map();
|
|
let groupMarkers: Map<string, MarkerData> = new Map();
|
|
let groupOps: Group[] = [];
|
|
let searchEntries: Result[] = [];
|
|
resp.data.groups.forEach((g: pond.Group) => {
|
|
let group = Group.any(g);
|
|
gMap.set(group.id().toString(), group);
|
|
if (
|
|
group.settings.longitude &&
|
|
group.settings.longitude !== 0 &&
|
|
group.settings.latitude &&
|
|
group.settings.latitude !== 0
|
|
) {
|
|
let marker: MarkerData = {
|
|
colour: "blue",
|
|
longitude: group.settings.longitude,
|
|
latitude: group.settings.latitude,
|
|
title: group.name(),
|
|
markerIcon: <DeviceGroupIcon type="light" size={50 * 0.6} />,
|
|
details: [group.name()],
|
|
clickFunc: (e, i, isMobile) => {
|
|
closeDrawers();
|
|
clickDelay();
|
|
setObjectKey(group.id().toString());
|
|
setOpenGroupDrawer(true);
|
|
moveMap(
|
|
group.settings.latitude,
|
|
group.settings.longitude,
|
|
zoomLevels.far,
|
|
isMobile
|
|
);
|
|
},
|
|
updateFunc: location => {
|
|
if (group) {
|
|
if (group.settings) {
|
|
let dataClone = clone(groupMarkerData);
|
|
updateGroupMarkers(group, location.longitude, location.latitude);
|
|
marker.longitude = location.longitude;
|
|
marker.latitude = location.latitude;
|
|
dataClone.set(group.id().toString(), marker);
|
|
setGroupMarkerData(dataClone);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
groupMarkers.set(group.id().toString(), marker);
|
|
searchEntries.push({
|
|
id: group.id().toString(),
|
|
center: [group.settings.longitude, group.settings.latitude],
|
|
place_name: group.name(),
|
|
place_type: ["group"]
|
|
} as Result);
|
|
} else {
|
|
groupOps.push(group);
|
|
}
|
|
});
|
|
setGroups(gMap);
|
|
setGroupMarkerData(groupMarkers);
|
|
setGroupOps(groupOps);
|
|
setGroupSearchEntries(searchEntries);
|
|
})
|
|
.catch(err => {
|
|
//openSnack("Failed to load Groups"); //backend function errors when there are no groups
|
|
});
|
|
}, [groupAPI]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
useEffect(() => {
|
|
loadSites();
|
|
loadDevices();
|
|
loadGroups();
|
|
}, [loadSites, loadDevices, loadGroups, as]);
|
|
|
|
//assemble the different objects markerdata into a single array to pass to the map
|
|
useEffect(() => {
|
|
let dArray = Array.from(devMarkerData.values());
|
|
let sArray = Array.from(siteMarkerData.values());
|
|
let gArray = Array.from(groupMarkerData.values());
|
|
setMarkers(dArray.concat(sArray, gArray));
|
|
}, [devMarkerData, siteMarkerData, groupMarkerData]);
|
|
|
|
//assemble the different object search entries into one array to pass to the map
|
|
useEffect(() => {
|
|
setCustomGeoSearchEntries(siteSearchEntries.concat(deviceSearchEntries, groupSearchEntries));
|
|
}, [deviceSearchEntries, siteSearchEntries, groupSearchEntries]);
|
|
|
|
//the entry fields for the first part of the stepper
|
|
const siteDetailsForm = () => {
|
|
return (
|
|
<Box>
|
|
<TextField
|
|
value={siteName}
|
|
color="primary"
|
|
autoFocus
|
|
margin="dense"
|
|
id="name"
|
|
label="Site Name"
|
|
type="text"
|
|
fullWidth
|
|
onChange={e => setSiteName(e.target.value)}></TextField>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
//dialog the renders the forms for creating a new site
|
|
const dialogForSite = () => {
|
|
return (
|
|
<ResponsiveDialog
|
|
fullWidth
|
|
fullScreen={false}
|
|
open={SiteDialog}
|
|
onClose={() => {
|
|
setSiteDialog(false);
|
|
}}>
|
|
<DialogTitle>Enter Name of Site</DialogTitle>
|
|
<DialogContent>{siteDetailsForm()}</DialogContent>
|
|
<DialogActions>
|
|
<Button
|
|
onClick={() => {
|
|
setSiteDialog(false);
|
|
}}
|
|
color="primary">
|
|
Cancel
|
|
</Button>
|
|
<Button onClick={saveSite} color="primary" disabled={!formComplete()}>
|
|
Add Site
|
|
</Button>
|
|
</DialogActions>
|
|
</ResponsiveDialog>
|
|
);
|
|
};
|
|
|
|
const markerDialog = () => {
|
|
return (
|
|
<ResponsiveDialog
|
|
open={openMarkerDialog}
|
|
onClose={() => {
|
|
setOpenMarkerDialog(false);
|
|
}}>
|
|
<DialogTitle>Place Marker</DialogTitle>
|
|
<DialogContent>
|
|
<Box width={300}>
|
|
{markerType === pond.ObjectType.OBJECT_TYPE_DEVICE && (
|
|
<Autocomplete
|
|
id="autoYardList"
|
|
options={devOps}
|
|
getOptionLabel={(option: Device) => option.name()}
|
|
fullWidth
|
|
onChange={(e, val) => {
|
|
val && setSelectKey(val.id().toString());
|
|
}}
|
|
renderInput={params => <TextField {...params} label="Device" />}
|
|
/>
|
|
)}
|
|
{markerType === pond.ObjectType.OBJECT_TYPE_GROUP && (
|
|
<Autocomplete
|
|
id="autoYardList"
|
|
options={groupOps}
|
|
getOptionLabel={(option: Group) => option.name()}
|
|
fullWidth
|
|
onChange={(e, val) => {
|
|
val && setSelectKey(val.id().toString());
|
|
}}
|
|
renderInput={params => <TextField {...params} label="Group" />}
|
|
/>
|
|
)}
|
|
</Box>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Box>
|
|
<Button onClick={closeNewMarkerDialog}>Cancel</Button>
|
|
<Button onClick={setMarker}>Plot New Marker</Button>
|
|
</Box>
|
|
</DialogActions>
|
|
</ResponsiveDialog>
|
|
);
|
|
};
|
|
|
|
const setMarker = () => {
|
|
if (markerType === pond.ObjectType.OBJECT_TYPE_DEVICE) {
|
|
let dev = devices.get(selectKey);
|
|
if (dev) {
|
|
let key = dev.id().toString();
|
|
let location = dev.location();
|
|
let newDevMarker: MarkerData = {
|
|
colour: dev.settings.theme?.color || "blue",
|
|
title: dev.name(),
|
|
longitude: newLong,
|
|
latitude: newLat,
|
|
markerIcon: <NexusSTIcon size={50 * 0.6} type="light" />,
|
|
details: [dev.name()],
|
|
clickFunc: (e, i, isMobile) => {
|
|
closeDrawers();
|
|
clickDelay();
|
|
setObjectKey(key);
|
|
setOpenDevDrawer(true);
|
|
moveMap(location.latitude, location.longitude, zoomLevels.far, isMobile);
|
|
},
|
|
updateFunc: location => {
|
|
if (dev) {
|
|
if (dev.settings) {
|
|
let dataClone = clone(devMarkerData);
|
|
updateDeviceMarkers(dev, location.longitude, location.latitude);
|
|
newDevMarker.longitude = location.longitude;
|
|
newDevMarker.latitude = location.latitude;
|
|
dataClone.set(key, newDevMarker);
|
|
setDevMarkerData(dataClone);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
let devMarkers = clone(devMarkerData);
|
|
devMarkers.set(key, newDevMarker);
|
|
setDevMarkerData(devMarkers);
|
|
updateDeviceMarkers(dev, newLong, newLat);
|
|
}
|
|
}
|
|
if (markerType === pond.ObjectType.OBJECT_TYPE_GROUP) {
|
|
let group = groups.get(selectKey);
|
|
if (group) {
|
|
let key = group.id().toString();
|
|
let long = group.settings.longitude;
|
|
let lat = group.settings.latitude;
|
|
let newMarker: MarkerData = {
|
|
colour: "blue",
|
|
title: group.name(),
|
|
longitude: newLong,
|
|
latitude: newLat,
|
|
markerIcon: <DeviceGroupIcon type="light" size={50 * 0.6} />,
|
|
details: [group.name()],
|
|
clickFunc: (e, i, isMobile) => {
|
|
closeDrawers();
|
|
clickDelay();
|
|
setObjectKey(key);
|
|
setOpenGroupDrawer(true);
|
|
moveMap(lat, long, zoomLevels.far, isMobile);
|
|
},
|
|
updateFunc: location => {
|
|
if (group) {
|
|
if (group.settings) {
|
|
let dataClone = clone(groupMarkerData);
|
|
updateGroupMarkers(group, location.longitude, location.latitude);
|
|
newMarker.longitude = location.longitude;
|
|
newMarker.latitude = location.latitude;
|
|
dataClone.set(key, newMarker);
|
|
setGroupMarkerData(dataClone);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
let groupMarkers = clone(groupMarkerData);
|
|
groupMarkers.set(key, newMarker);
|
|
setGroupMarkerData(groupMarkers);
|
|
updateGroupMarkers(group, newLong, newLat);
|
|
}
|
|
}
|
|
closeNewMarkerDialog();
|
|
};
|
|
|
|
const closeNewMarkerDialog = () => {
|
|
if (new Date().valueOf() > endTime) {
|
|
setOpenMarkerDialog(false);
|
|
setSelectKey("");
|
|
}
|
|
};
|
|
|
|
const updateDeviceMarkers = (device: Device, long: number, lat: number) => {
|
|
device.settings.longitude = long;
|
|
device.settings.latitude = lat;
|
|
deviceAPI
|
|
.update(device.id(), device.settings, as)
|
|
.then(resp => {
|
|
openSnack("Device location Updated");
|
|
if (devOps.includes(device)) {
|
|
devOps.splice(devOps.indexOf(device), 1);
|
|
}
|
|
})
|
|
.catch(err => {
|
|
openSnack("Could not update Device Location");
|
|
});
|
|
};
|
|
|
|
const updateGroupMarkers = (group: Group, long: number, lat: number) => {
|
|
group.settings.longitude = long;
|
|
group.settings.latitude = lat;
|
|
groupAPI
|
|
.updateGroup(group.id(), group.settings)
|
|
.then(resp => {
|
|
openSnack("Group location Updated");
|
|
if (groupOps.includes(group)) {
|
|
groupOps.splice(groupOps.indexOf(group), 1);
|
|
}
|
|
})
|
|
.catch(err => {
|
|
openSnack("Could not update Group Location");
|
|
});
|
|
};
|
|
|
|
const updateSiteMarkers = (site: Site, long: number, lat: number) => {
|
|
site.settings.longitude = long;
|
|
site.settings.latitude = lat;
|
|
siteAPI
|
|
.updateSite(site.key(), site.settings, undefined, as)
|
|
.then(resp => {
|
|
openSnack("Site location updated");
|
|
})
|
|
.catch(err => {
|
|
openSnack("Could not update site location");
|
|
});
|
|
};
|
|
|
|
const moveMap = (
|
|
lat: number,
|
|
long: number,
|
|
zoom: number,
|
|
mobileOffset?: boolean,
|
|
center?: boolean
|
|
) => {
|
|
let xOff = !mobileOffset ? -250 : undefined;
|
|
let yOff = mobileOffset ? -150 : undefined;
|
|
|
|
setCurrentView({
|
|
latitude: lat,
|
|
longitude: long,
|
|
zoom: zoom,
|
|
transitionDuration: transDuration,
|
|
xOffset: center ? 0 : xOff,
|
|
yOffset: center ? 0 : yOff
|
|
});
|
|
};
|
|
|
|
return (
|
|
<Box style={{ height: "100%" }}>
|
|
<MapBase
|
|
placingMarker={markerType !== pond.ObjectType.OBJECT_TYPE_UNKNOWN}
|
|
displayMarkerTitles={displayMarkerTitle}
|
|
customSearchEntries={customGeoSearchEntries}
|
|
geocoderResultFunction={result => {
|
|
//open drawer
|
|
setObjectKey(result.id?.toString() ?? "");
|
|
if (result.place_type.includes("site")) {
|
|
setOpenSiteDrawer(true);
|
|
} else if (result.place_type.includes("device")) {
|
|
setOpenDevDrawer(true);
|
|
} else if (result.place_type.includes("group")) {
|
|
setOpenGroupDrawer(true);
|
|
}
|
|
}}
|
|
geocoderTransitionFunction={result => {
|
|
//override the geocoders transition with our own
|
|
let long = result.center[0];
|
|
let lat = result.center[1];
|
|
if (long && lat) {
|
|
let centered = true;
|
|
let zoom = zoomLevels.far;
|
|
if (
|
|
result.place_type.includes("site") ||
|
|
result.place_type.includes("device") ||
|
|
result.place_type.includes("group")
|
|
) {
|
|
centered = false;
|
|
}
|
|
moveMap(lat, long, zoom, isMobile, centered);
|
|
}
|
|
}}
|
|
mapTools={
|
|
<ConstructionMapTools
|
|
toggleMarkerType={setMarkerType}
|
|
toggleMarkerDisplay={setDisplayMarkerTitle}
|
|
/>
|
|
}
|
|
mapClick={e => {
|
|
if (markerType !== pond.ObjectType.OBJECT_TYPE_UNKNOWN) {
|
|
setNewLong(e.lngLat.lng);
|
|
setNewLat(e.lngLat.lat);
|
|
if (markerType === pond.ObjectType.OBJECT_TYPE_SITE) {
|
|
setSiteDialog(true);
|
|
} else {
|
|
setOpenMarkerDialog(true);
|
|
}
|
|
}
|
|
}}
|
|
currentView={currentView}
|
|
markerData={markers}
|
|
/>
|
|
{dialogForSite()}
|
|
{markerDialog()}
|
|
{objectKey !== "" && (
|
|
<React.Fragment>
|
|
<DeviceDrawer
|
|
open={openDevDrawer}
|
|
onClose={() => {
|
|
if (new Date().valueOf() > endTime) {
|
|
setOpenDevDrawer(false);
|
|
setObjectKey("");
|
|
}
|
|
}}
|
|
selectedDevice={objectKey}
|
|
devices={devices}
|
|
removeMarker={key => {
|
|
if (new Date().valueOf() > endTime) {
|
|
//use the key to remove it from the map of yard markers which should cause the markerData array to update
|
|
let newMarkers = clone(devMarkerData);
|
|
newMarkers.delete(key);
|
|
setDevMarkerData(newMarkers);
|
|
//adds it back to the options
|
|
let dev = devices.get(key);
|
|
if (dev) {
|
|
devOps.push(dev);
|
|
}
|
|
}
|
|
}}
|
|
updateMarker={(key, objectSettings) => {
|
|
if (new Date().valueOf() > endTime) {
|
|
let newMarkers = clone(devMarkerData);
|
|
let toupdate = newMarkers.get(key);
|
|
if (toupdate) {
|
|
if (objectSettings.theme) {
|
|
toupdate.colour = objectSettings.theme.color;
|
|
}
|
|
}
|
|
setDevMarkerData(newMarkers);
|
|
}
|
|
}}
|
|
moveMap={(long, lat) => {
|
|
moveMap(lat, long, zoomLevels.far, isMobile);
|
|
}}
|
|
/>
|
|
<SiteDrawer
|
|
open={openSiteDrawer}
|
|
sites={sites}
|
|
heaters={heaterMap}
|
|
selectedSite={objectKey}
|
|
onClose={() => {
|
|
if (new Date().valueOf() > endTime) {
|
|
setOpenSiteDrawer(false);
|
|
setObjectKey("");
|
|
}
|
|
}}
|
|
moveMap={(long, lat) => {
|
|
moveMap(lat, long, zoomLevels.far, isMobile);
|
|
}}
|
|
removeMarker={key => {
|
|
if (new Date().valueOf() > endTime) {
|
|
//use the key to remove it from the map of yard markers which should cause the markerData array to update
|
|
let newMarkers = clone(siteMarkerData);
|
|
newMarkers.delete(key);
|
|
setSiteMarkerData(newMarkers);
|
|
}
|
|
}}
|
|
updateMarker={(key, objectSettings) => {
|
|
if (new Date().valueOf() > endTime) {
|
|
let newMarkers = clone(siteMarkerData);
|
|
let toupdate = newMarkers.get(key);
|
|
if (toupdate) {
|
|
if (objectSettings.theme) {
|
|
toupdate.colour = objectSettings.theme.color;
|
|
}
|
|
}
|
|
setSiteMarkerData(newMarkers);
|
|
}
|
|
}}
|
|
reLoadSites={() => {
|
|
loadSites();
|
|
}}
|
|
/>
|
|
<GroupDrawer
|
|
open={openGroupDrawer}
|
|
groups={groups}
|
|
moveMap={(long, lat) => {
|
|
moveMap(lat, long, zoomLevels.far, isMobile);
|
|
}}
|
|
onClose={() => {
|
|
if (new Date().valueOf() > endTime) {
|
|
setOpenGroupDrawer(false);
|
|
setObjectKey("");
|
|
}
|
|
}}
|
|
removeMarker={key => {
|
|
if (new Date().valueOf() > endTime) {
|
|
//use the key to remove it from the map of yard markers which should cause the markerData array to update
|
|
let newMarkers = clone(groupMarkerData);
|
|
newMarkers.delete(key);
|
|
setGroupMarkerData(newMarkers);
|
|
//adds it back to the options
|
|
let group = groups.get(key);
|
|
if (group) {
|
|
groupOps.push(group);
|
|
}
|
|
}
|
|
}}
|
|
selectedGroup={objectKey}
|
|
/>
|
|
</React.Fragment>
|
|
)}
|
|
</Box>
|
|
);
|
|
}
|