ToolJet/frontend/src/Editor/Components/Map.jsx

143 lines
4 KiB
React
Raw Normal View History

import React, { useEffect, useState, useCallback } from 'react';
2021-05-16 05:26:31 +00:00
import config from 'config';
2021-05-16 06:03:26 +00:00
import { GoogleMap, LoadScript } from '@react-google-maps/api';
import { Marker } from '@react-google-maps/api';
2021-05-16 18:13:57 +00:00
import { resolveReferences } from '@/_helpers/utils';
import { Autocomplete } from '@react-google-maps/api';
2021-05-16 05:26:31 +00:00
export const Map = function Map({
id,
width,
height,
component,
onComponentClick,
currentState,
onComponentOptionChanged,
onComponentOptionsChanged,
2021-05-16 05:26:31 +00:00
onEvent
}) {
2021-05-16 06:03:26 +00:00
const center = component.definition.properties.initialLocation.value;
2021-05-16 06:25:48 +00:00
const defaultMarkerValue = component.definition.properties.defaultMarkers.value;
let defaultMarkers = []
try {
2021-05-16 18:13:57 +00:00
defaultMarkers = defaultMarkerValue
} catch (err) { console.log(err); }
2021-05-16 08:56:18 +00:00
const addNewMarkersProp = component.definition.properties.addNewMarkers;
const canAddNewMarkers = addNewMarkersProp ? addNewMarkersProp.value : false;
2021-05-16 05:26:31 +00:00
const [gmap, setGmap] = useState(null);
const [autoComplete, setAutoComplete] = useState(null);
2021-05-16 18:13:57 +00:00
const [mapCenter, setMapCenter] = useState(resolveReferences(JSON.parse(center), currentState, false));
const [markers, setMarkers] = useState(resolveReferences(defaultMarkers, currentState, []));
useEffect(() => {
2021-05-16 18:13:57 +00:00
setMarkers(resolveReferences(defaultMarkers, currentState, false));
}, [currentState]);
2021-05-16 05:26:31 +00:00
const containerStyle = {
width,
height
};
function handleMapClick(e) {
2021-05-16 08:56:18 +00:00
if(!canAddNewMarkers) { return }
const lat = e.latLng.lat();
const lng = e.latLng.lng();
const newMarkers = markers;
newMarkers.push({ lat, lng });
setMarkers(newMarkers);
2021-05-16 10:11:55 +00:00
onComponentOptionChanged(component, 'markers', newMarkers).then(() => onEvent('onCreateMarker', { component }));
}
2021-05-16 05:26:31 +00:00
function handleBoundsChange() {
const mapBounds = gmap.getBounds();
const bounds = {
northEast: mapBounds.getNorthEast().toJSON(),
southWest: mapBounds.getSouthWest().toJSON(),
}
const newCenter = gmap.center.toJSON();
setMapCenter(newCenter);
onComponentOptionsChanged(component, [
['bounds', bounds],
['center', newCenter]
2021-05-16 09:09:24 +00:00
]).then(() => onEvent('onBoundsChange', { component }));
}
const onLoad = useCallback(
2021-05-16 18:13:57 +00:00
function onLoad(mapInstance) {
setGmap(mapInstance);
2021-05-16 18:13:57 +00:00
onComponentOptionsChanged(component, [
['center', mapInstance.center.toJSON()]
])
}
)
2021-05-16 10:11:55 +00:00
function handleMarkerClick(index) {
onComponentOptionChanged(component,
'selectedMarker', markers[index]
).then(() => onEvent('onMarkerClick', { component }));
}
function onPlaceChanged() {
const location = autoComplete.getPlace().geometry.location.toJSON();
setMapCenter(location);
}
function onAutocompleteLoad(autocompleteInstance) {
setAutoComplete(autocompleteInstance);
}
2021-05-16 05:26:31 +00:00
return (
<div style={{ width, height }} onClick={() => onComponentClick(id, component)} className="map-widget">
2021-05-16 05:26:31 +00:00
<LoadScript
googleMapsApiKey={config.GOOGLE_MAPS_API_KEY}
libraries={["places"]}
2021-05-16 05:26:31 +00:00
>
<GoogleMap
center={mapCenter}
2021-05-16 05:26:31 +00:00
mapContainerStyle={containerStyle}
zoom={12}
options={{
streetViewControl: false,
mapTypeControl: false,
draggable: true
2021-05-16 05:26:31 +00:00
}}
onLoad={onLoad}
onClick={handleMapClick}
onDragEnd={handleBoundsChange}
2021-05-16 05:26:31 +00:00
>
<Autocomplete
onPlaceChanged={onPlaceChanged}
onLoad={onAutocompleteLoad}
>
<input
type="text"
placeholder="Search"
className="place-search-input"
/>
</Autocomplete>
2021-05-16 18:13:57 +00:00
{Array.isArray(markers) &&
<>
{markers.map((marker, index) =>
<Marker
position={marker}
label={marker.label}
onClick={(e) => handleMarkerClick(index)}
/>
)}
</>
}
2021-05-16 05:26:31 +00:00
</GoogleMap>
</LoadScript>
</div>
);
};