diff --git a/package-lock.json b/package-lock.json
index ec3e66c9..dfc18b01 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8107,7 +8107,7 @@
},
"node_modules/@oneblink/types": {
"version": "1.0.0",
- "resolved": "git+ssh://git@github.com/oneblink/types.git#c08a0237ec63b79deeda8abb503d79c58e29eb04",
+ "resolved": "git+ssh://git@github.com/oneblink/types.git#79d9b22b0c234fed9763f8fd0c7b686070064d23",
"dev": true,
"license": "GPL-3.0-only",
"dependencies": {
diff --git a/src/components/renderer/OneBlinkFormElements.tsx b/src/components/renderer/OneBlinkFormElements.tsx
index fc0d2643..4a0d6ed3 100644
--- a/src/components/renderer/OneBlinkFormElements.tsx
+++ b/src/components/renderer/OneBlinkFormElements.tsx
@@ -39,6 +39,7 @@ import FormElementLocation, {
import FormElementGeoscapeAddress from '../../form-elements/FormElementGeoscapeAddress'
import FormElementCompliance from '../../form-elements/FormElementCompliance'
import FormElementPointAddress from '../../form-elements/FormElementPointAddress'
+import FormElementGoogleAddress from '../../form-elements/FormElementGoogleAddress'
import FormElementBoolean from '../../form-elements/FormElementBoolean'
import FormElementCivicaStreetName from '../../form-elements/FormElementCivicaStreetName'
import FormElementCivicaNameRecord from '../../form-elements/FormElementCivicaNameRecord'
@@ -50,6 +51,7 @@ import {
CivicaTypes,
FormTypes,
GeoscapeTypes,
+ GoogleTypes,
MiscTypes,
PointTypes,
SubmissionTypes,
@@ -846,6 +848,31 @@ const FormElementSwitch = React.memo(function OneBlinkFormElement({
)
}
+ case 'googleAddress': {
+ const v = value as GoogleTypes.GoogleMapsAddress | undefined
+ return (
+
+ ['onChange']
+ }
+ validationMessage={validationMessage}
+ displayValidationMessage={displayValidationMessage}
+ {...dirtyProps}
+ />
+
+ )
+ }
case 'boolean': {
return (
{
+ if (isLoaded) {
+ return new google.maps.Map(document.createElement('div'))
+ }
+ }, [isLoaded])
+
const handleSearch = React.useCallback(
async (input: string, abortSignal: AbortSignal) => {
setError(undefined)
@@ -56,6 +62,12 @@ function FormElementGoogleAddress({
input,
},
(predictions, status) => {
+ if (
+ status === google.maps.places.PlacesServiceStatus.ZERO_RESULTS
+ ) {
+ resolve([])
+ return
+ }
if (status !== google.maps.places.PlacesServiceStatus.OK) {
reject('Google Places service not available')
return
@@ -106,46 +118,70 @@ function FormElementGoogleAddress({
setIsLoadingAddressDetails(true)
try {
//this should not happen, we can't get a place Id without google being present
- if (!isLoaded) {
+ if (!isLoaded || !dummyMap) {
throw new OneBlinkAppsError(
'An unknown error has occurred. Please contact support if the problem persists.',
{
originalError: new Error(
- 'google places library has not be initialised',
+ 'Google Places library has not be initialised',
),
},
)
}
- const placeService = new google.maps.places.Place({ id: placeId })
- const { place } = await placeService.fetchFields({
- fields: [
- 'id',
- 'displayName',
- 'formattedAddress',
- 'location',
- 'addressComponents',
- 'servesBeer',
- ],
- })
+ const placeService = new google.maps.places.PlacesService(dummyMap)
+ const place = await new Promise(
+ (resolve, reject) => {
+ placeService.getDetails(
+ {
+ placeId,
+ fields: [
+ 'place_id',
+ 'formatted_address',
+ 'geometry',
+ 'address_components',
+ ],
+ },
+ (place, status) => {
+ if (
+ status !== google.maps.places.PlacesServiceStatus.OK ||
+ !place
+ ) {
+ reject(
+ `Could not find address details for place with id: ${placeId}`,
+ )
+ return
+ }
+ resolve(place)
+ },
+ )
+ },
+ )
onChange(element, { value: place })
} catch (newError) {
if (isMounted.current) {
- setError(newError as Error)
+ setError(
+ new OneBlinkAppsError(
+ 'An unknown error has occurred. Please contact support if the problem persists.',
+ {
+ originalError: newError as Error,
+ },
+ ),
+ )
}
}
if (isMounted.current) {
setIsLoadingAddressDetails(false)
}
},
- [isMounted, onChange, element, isLoaded],
+ [isMounted, onChange, element, isLoaded, dummyMap],
)
// Ensure the label is set if the value is set outside of this component
React.useEffect(() => {
if (value) {
- const newLabel = value.formattedAddress || value.id
- setLabel(newLabel)
+ const newLabel = value.formatted_address || value.place_id
+ setLabel(newLabel ?? '')
}
}, [value])
diff --git a/src/hooks/useGoogle.ts b/src/hooks/useGoogle.ts
index 484ebc3f..af215e5a 100644
--- a/src/hooks/useGoogle.ts
+++ b/src/hooks/useGoogle.ts
@@ -1,12 +1,18 @@
-import { useJsApiLoader } from '@react-google-maps/api'
+import * as React from 'react'
+import { useJsApiLoader, Libraries } from '@react-google-maps/api'
import useGoogleMapsApiKey from './useGoogleMapsApiKey'
export default function useGoogle() {
const key = useGoogleMapsApiKey()
+ const libraries = React.useMemo(
+ () => ['maps', 'marker', 'places'],
+ [],
+ )
+
const { isLoaded } = useJsApiLoader({
googleMapsApiKey: key ?? '',
- libraries: ['maps', 'marker', 'places'],
+ libraries,
})
return { isLoaded }
diff --git a/src/services/form-validation.ts b/src/services/form-validation.ts
index e73dfb1d..f7553719 100644
--- a/src/services/form-validation.ts
+++ b/src/services/form-validation.ts
@@ -387,6 +387,7 @@ export function generateValidationSchema(
case 'abn':
case 'geoscapeAddress':
case 'pointAddress':
+ case 'googleAddress':
case 'civicaStreetName':
case 'autocomplete':
case 'radio':
diff --git a/src/services/generate-default-data.ts b/src/services/generate-default-data.ts
index 01d48eca..bc99f801 100644
--- a/src/services/generate-default-data.ts
+++ b/src/services/generate-default-data.ts
@@ -289,6 +289,13 @@ function parsePreFillData(
}
})
}
+ case 'googleAddress': {
+ return parseUnknownAsRecord(value, (record) => {
+ if (parseStringValue(record.place_id)) {
+ return record
+ }
+ })
+ }
case 'freshdeskDependentField': {
return parseUnknownAsRecord(value, (record) => {
if (
@@ -470,6 +477,7 @@ export default function generateDefaultData(
case 'freshdeskDependentField':
case 'geoscapeAddress':
case 'pointAddress':
+ case 'googleAddress':
case 'civicaStreetName':
case 'abn':
case 'bsb':