Part of #11855. Instead of getting the Google Maps API Key from runtime env variables, we get it from the server, as part of the response of `/api/v1/tenant/current`. This doesn't add a database call, just include the env variable name in the response, so shouldn't have any performance impact on the API. On the client though, the Maps API key won't be available, until at least the first call to `/tenant/current` is finished. Also, first big PR in client code. 🙂 Edit: not `/me` anymore, but from `/tenant/current`. --------- Co-authored-by: Pawan Kumar <pawan.stardust@gmail.com> Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
115 lines
3.1 KiB
TypeScript
115 lines
3.1 KiB
TypeScript
import log from "loglevel";
|
|
import React, { useState } from "react";
|
|
import styled from "styled-components";
|
|
import { Wrapper, Status } from "@googlemaps/react-wrapper";
|
|
|
|
import { StyledInputGroup } from "./StyledControls";
|
|
import { isDynamicValue } from "utils/DynamicBindingUtils";
|
|
import BaseControl, { ControlData, ControlProps } from "./BaseControl";
|
|
|
|
const MapStatusText = styled.span`
|
|
font-size: 14px;
|
|
`;
|
|
|
|
const renderMapStatus = (status: Status) => {
|
|
switch (status) {
|
|
case Status.LOADING:
|
|
return <MapStatusText>Loading...</MapStatusText>;
|
|
case Status.FAILURE:
|
|
return <MapStatusText>Error in the component</MapStatusText>;
|
|
case Status.SUCCESS:
|
|
return <MapStatusText>Component loaded....</MapStatusText>;
|
|
}
|
|
};
|
|
class LocationSearchControl extends BaseControl<ControlProps> {
|
|
clearLocation = () => {
|
|
this.updateProperty(this.props.propertyName, {
|
|
lat: -34.397,
|
|
long: 150.644,
|
|
title: "",
|
|
});
|
|
};
|
|
|
|
onLocationSelection = (ref: any) => {
|
|
try {
|
|
// For some places, the length is zero
|
|
const places = ref.getPlaces();
|
|
const location = places[0].geometry.location;
|
|
const title = places[0].formatted_address;
|
|
const lat = location.lat();
|
|
const long = location.lng();
|
|
const value = { lat, long, title };
|
|
this.updateProperty(this.props.propertyName, value, true);
|
|
} catch (e) {
|
|
if (ref && ref.getPlaces)
|
|
log.debug("Error selecting location:", ref.getPlaces());
|
|
else {
|
|
log.debug("Error selecting location - searchBox not found");
|
|
}
|
|
}
|
|
};
|
|
|
|
onSearchBoxMounted = (ref: any) => {
|
|
if (window) {
|
|
const searchBox = new window.google.maps.places.SearchBox(ref);
|
|
searchBox.addListener("places_changed", () => {
|
|
this.onLocationSelection(searchBox);
|
|
});
|
|
}
|
|
};
|
|
|
|
render() {
|
|
return (
|
|
<Wrapper
|
|
apiKey={this.props.widgetProperties.googleMapsApiKey}
|
|
libraries={["geometry", "drawing", "places"]}
|
|
render={renderMapStatus}
|
|
>
|
|
<MapScriptWrapper
|
|
clearLocation={this.clearLocation}
|
|
onSearchBoxMounted={this.onSearchBoxMounted}
|
|
propertyValue={this.props.propertyValue}
|
|
/>
|
|
</Wrapper>
|
|
);
|
|
}
|
|
|
|
static getControlType() {
|
|
return "LOCATION_SEARCH";
|
|
}
|
|
|
|
static canDisplayValueInUI(config: ControlData, value: any): boolean {
|
|
return !isDynamicValue(value);
|
|
}
|
|
}
|
|
|
|
interface MapScriptWrapperProps {
|
|
onSearchBoxMounted: (ref: any) => void;
|
|
clearLocation: () => void;
|
|
propertyValue: any;
|
|
}
|
|
|
|
function MapScriptWrapper(props: MapScriptWrapperProps) {
|
|
const [title, setTitle] = useState("");
|
|
|
|
return (
|
|
<div data-standalone-searchbox="">
|
|
<StyledInputGroup
|
|
dataType="text"
|
|
defaultValue={title || props.propertyValue?.title}
|
|
onChange={(value: string) => {
|
|
if (value === "") {
|
|
props.clearLocation();
|
|
}
|
|
setTitle(value);
|
|
}}
|
|
placeholder="Enter location"
|
|
ref={props.onSearchBoxMounted}
|
|
tabIndex={-1}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default LocationSearchControl;
|