SSR-776 PR Feedback Make Google Maps component more generic

This commit is contained in:
Josh Dassinger 2024-08-30 11:36:05 -05:00
parent 6933a7ade7
commit 563d9f18ab
4 changed files with 37 additions and 39 deletions

View file

@ -159,7 +159,7 @@ describe('Google Map', () => {
const zipCode = '00882';
const [address1, address2, position1, position2] = ['a1', 'a2', 'p1', 'p2'];
const providers = [
const markers = [
{
fullAddress: address1
},
@ -186,7 +186,7 @@ describe('Google Map', () => {
return Promise.resolve(result);
});
const propsData = { providers, zipCode };
const propsData = { markers, zipCode };
const { wrapper } = getMountedComponent({}, {}, propsData);
await awaitingSetupTicks(wrapper);
@ -251,7 +251,7 @@ describe('Google Map', () => {
}
return Promise.resolve(result);
});
const providers = [
const markers = [
{
fullAddress: address1
},
@ -262,7 +262,7 @@ describe('Google Map', () => {
// Act
const { wrapper } = getMountedComponent({}, { zipCode });
await awaitingSetupTicks(wrapper);
await wrapper.vm.$options.watch.providers.call(wrapper.vm, providers);
await wrapper.vm.$options.watch.markers.call(wrapper.vm, markers);
await awaitingSetupTicks(wrapper);
// Assert

View file

@ -8,7 +8,7 @@
export default {
name: 'google-map',
props: {
providers: Array,
markers: Array,
zipCode: String
},
data() {
@ -24,12 +24,12 @@ export default {
}
},
watch: {
async providers(newProviders) {
await this.createMapWithMarkersForAddresses(newProviders);
async markers(newMarkers) {
await this.createMapWithMarkersForAddresses(newMarkers);
}
},
async beforeMount() {
await this.createMapWithMarkersForAddresses(this.providers);
await this.createMapWithMarkersForAddresses(this.markers);
},
methods: {
async getMap(center) {
@ -51,59 +51,58 @@ export default {
this.geocoder = new Geocoder();
}
},
async addMarkersToMap(map, providers) {
async addMarkersToMap(map, markers) {
const { AdvancedMarkerElement, PinElement } = await window.google.maps.importLibrary('marker');
providers?.forEach((provider, index) => {
const pin = new PinElement({
markers?.forEach((marker, index) => {
const pinElement = new PinElement({
glyph: String.fromCharCode('A'.charCodeAt(0) + index),
glyphColor: '#000000',
borderColor: '#000000'
});
const marker = new AdvancedMarkerElement({
const markerElement = new AdvancedMarkerElement({
map,
position: provider.position,
title: provider.companyName,
content: pin.element,
position: marker.position,
title: marker.title,
content: pinElement.element,
zIndex: 1000 - index
});
this.createMarkerInfoWindows(marker, provider);
this.createMarkerInfoWindows(markerElement, marker);
});
},
createMarkerInfoWindows(marker, provider) {
const directionsUrl = this.createGetDirectionsUrl(provider);
createMarkerInfoWindows(markerElement, marker) {
const directionsUrl = this.createGetDirectionsUrl(marker);
const content = `<div>
<span style="color: black; font-weight:bold"> ${provider.companyName} </span>
<br /> ${provider.addressLine1}
<br /> ${provider.addressLine2}
<span style="color: black; font-weight:bold"> ${marker.title} </span>
${marker.addressLines?.map((address) => `<br/> ${address} `).join()}
<br /> <a href="${directionsUrl}" target="_blank">Get directions</a>
</div>`;
const infoWindow = new window.google.maps.InfoWindow({ content });
marker.addListener('click', () => {
markerElement.addListener('click', () => {
this.infoWindow?.close();
this.infoWindow = infoWindow;
infoWindow.open(marker.map, marker);
infoWindow.open(markerElement.map, markerElement);
});
},
createGetDirectionsUrl(provider) {
return `https://maps.google.com/maps?saddr=&daddr=${encodeURIComponent(provider.fullAddress)}`;
createGetDirectionsUrl(marker) {
return `https://maps.google.com/maps?saddr=&daddr=${encodeURIComponent(marker.fullAddress)}`;
},
async getLocationsFromAddresses(providers) {
async getLocationsFromAddresses(markers) {
await this.setGeocoder();
const geocodeShopAddressPromises = providers?.map((provider) => this.geocoder.geocode({ address: provider.fullAddress })) ?? [];
const geocodeShopAddressPromises = markers?.map((marker) => this.geocoder.geocode({ address: marker.fullAddress })) ?? [];
const geocodeShopAddressResults = await Promise.all(geocodeShopAddressPromises);
return providers?.map((provider, index) => {
return markers?.map((marker, index) => {
const results = geocodeShopAddressResults[index]?.results;
let position = null;
if (results && results.length > 0) {
position = results[0].geometry?.location;
}
return { ...provider, position };
}).filter((provider) => provider.position != null) ?? [];
return { ...marker, position };
}).filter((marker) => marker.position != null) ?? [];
},
async getBoundsFromAddress(address) {
await this.setGeocoder();
@ -112,14 +111,14 @@ export default {
? result.results[0].geometry?.bounds
: null;
},
async createMapWithMarkersForAddresses(providers) {
const providerPositions = await this.getLocationsFromAddresses(providers);
async createMapWithMarkersForAddresses(markers) {
const markerPositions = await this.getLocationsFromAddresses(markers);
const zipBounds = await this.getBoundsFromAddress(this.zipCodeAddress);
const map = await this.getMap(zipBounds?.getCenter());
await this.addMarkersToMap(map, providerPositions);
await this.addMarkersToMap(map, markerPositions);
const positionsToDisplay = providerPositions.map((provider) => provider.position)
const positionsToDisplay = markerPositions.map((marker) => marker.position)
.concat(zipBounds?.getNorthEast(), zipBounds?.getSouthWest());
const bounds = this.getBounds(positionsToDisplay);
map.fitBounds(bounds);

View file

@ -177,7 +177,7 @@ describe('TPA search page', () => {
// Assert
expect(map.exists()).toBeTruthy();
expect(map.classes()).toContain('mb-4');
expect(map.props().providers.map((p) => p.fullAddress)).toEqual(expectedAddresses);
expect(map.props().markers.map((p) => p.fullAddress)).toEqual(expectedAddresses);
expect(map.props().zipCode).toBe(zipCode);
});
test('search radius filter', async () => {

View file

@ -46,7 +46,7 @@
<googleMap
id="map"
class="mb-4"
:providers="providerAddresses"
:markers="providerAddresses"
:zipCode="mapZipCode" />
<Form
id="providerSelectionForm"
@ -282,10 +282,9 @@ export default {
},
providerAddresses() {
return this.providers?.map((provider) => ({
...provider,
title: provider.companyName,
fullAddress: this.getFullProviderAddress(provider),
addressLine1: this.getProviderAddress(provider),
addressLine2: this.getProviderCityZipState(provider)
addressLines: [this.getProviderAddress(provider), this.getProviderCityZipState(provider)]
})) ?? [];
},
providerButtonData() {