frontend/src/maps/mapDrawers/DeviceDrawer.tsx

154 lines
4.4 KiB
TypeScript

import { Box } from "@mui/material";
import DisplayDrawer from "common/DisplayDrawer";
import DeviceViewer from "device/DeviceViewer";
import MapMarkerSettings from "maps/MapMarkerSettings";
import { Device } from "models";
import { pond } from "protobuf-ts/pond";
import { useDeviceAPI, useGlobalState, useSnackbar } from "providers";
import React, { useEffect, useState } from "react";
interface Props {
open: boolean;
onClose: () => void;
selectedDevice: string;
devices: Map<string, Device>;
removeMarker: (key: string) => void;
updateMarker: (key: string, newSettings: pond.DeviceSettings) => void;
moveMap: (long: number, lat: number) => void;
}
export default function DeviceDrawer(props: Props) {
const { open, onClose, selectedDevice, devices, removeMarker, updateMarker, moveMap } = props;
const [{as}] = useGlobalState();
const [device, setDevice] = useState<Device>(Device.create());
const [openMarkerSettings, setOpenMarkerSettings] = useState(false);
const deviceAPI = useDeviceAPI();
const { openSnack } = useSnackbar();
useEffect(() => {
let d = devices.get(selectedDevice);
if (d) {
setDevice(d);
}
}, [selectedDevice, devices]);
const closeDrawer = () => {
onClose();
};
const displayNext = () => {
let devArr = Array.from(devices.values());
let index = devArr.indexOf(device);
let found = false;
do {
if (index === devArr.length - 1) {
index = 0;
} else {
index++;
}
let nextDev = devArr[index];
if (
nextDev.location().longitude !== 0 &&
nextDev.location().longitude !== 0 &&
nextDev.location().latitude !== undefined &&
nextDev.location().longitude !== undefined
) {
setDevice(nextDev);
moveMap(nextDev.location().longitude, nextDev.location().latitude);
found = true;
}
} while (!found);
};
const displayPrev = () => {
let devArr = Array.from(devices.values());
let index = devArr.indexOf(device);
let found = false;
do {
if (index === 0) {
index = devArr.length - 1;
} else {
index--;
}
let nextDev = devArr[index];
if (
nextDev.location().longitude !== 0 &&
nextDev.location().longitude !== 0 &&
nextDev.location().latitude !== undefined &&
nextDev.location().longitude !== undefined
) {
setDevice(nextDev);
moveMap(nextDev.location().longitude, nextDev.location().latitude);
found = true;
}
} while (!found);
};
const drawerBody = () => {
return device.id() !== 0 ? <DeviceViewer device={device} isMobile={true} /> : <Box></Box>;
};
/**
* function to remove the marker and coordinates from the object
*/
const remove = () => {
//set the long/lat of the yard to 0 and call an update
let settings = device.settings;
settings.longitude = 0;
settings.latitude = 0;
deviceAPI
.update(device.id(), settings, as)
.then(resp => {
openSnack("Marker Removed");
//then use the removeMarker prop function to update the markers in the parent map
removeMarker(device.id().toString());
})
.catch(err => {
openSnack("Failed to remove marker");
});
};
/**
* function to update the settings of the marker
*/
const update = () => {
setOpenMarkerSettings(true);
};
return (
<React.Fragment>
<DisplayDrawer
open={open}
onClose={closeDrawer}
displayNext={displayNext}
displayPrev={displayPrev}
title={device.name()}
width={"40vw"}
drawerBody={drawerBody()}
updateElement={update}
removeElement={remove}
/>
<MapMarkerSettings
close={() => {
setOpenMarkerSettings(false);
}}
open={openMarkerSettings}
theme={device.settings.theme ?? pond.ObjectTheme.create()}
colourControl
updateObject={newTheme => {
let settings = device.settings;
settings.theme = newTheme;
deviceAPI
.update(device.id(), settings, as)
.then(resp => {
openSnack("marker settings updated");
updateMarker(device.id().toString(), settings);
})
.catch(() => {
openSnack("failed to update marker settings");
});
}}
/>
</React.Fragment>
);
}