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

View file

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

View file

@ -177,7 +177,7 @@ describe('TPA search page', () => {
// Assert // Assert
expect(map.exists()).toBeTruthy(); expect(map.exists()).toBeTruthy();
expect(map.classes()).toContain('mb-4'); 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); expect(map.props().zipCode).toBe(zipCode);
}); });
test('search radius filter', async () => { test('search radius filter', async () => {

View file

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