diff --git a/src/Map/src/Bridge/Google/CHANGELOG.md b/src/Map/src/Bridge/Google/CHANGELOG.md index bfaea94609e..e6cba70ad61 100644 --- a/src/Map/src/Bridge/Google/CHANGELOG.md +++ b/src/Map/src/Bridge/Google/CHANGELOG.md @@ -1,5 +1,26 @@ # CHANGELOG +## 2.27 + +- Fix `InfoWindow` compatibility with new `Circle` and `Rectangle` supported elements. + + This fix led to a refactoring that can impact the `InfoWindow` position when used with `Polygon` or `Polyline`, + because their shapes are too complex. + Instead, listen to the `ux:map:info-window:before-create` event to set the position manually. + ```js + this.element.addEventListener('ux:map:info-window:before-create', (event) => { + const { google, element, definition } = event.detail; + + if (element instanceof google.maps.Polygon) { + // Set the position to the center of the polygon + const bounds = new google.maps.LatLngBounds(); + + element.getPath().forEach((latLng) => bounds.extend(latLng)); + definition.infoWindow.rawOptions.position = bounds.getCenter(); + } + }); + ``` + ## 2.25 - Downgrade PHP requirement from 8.3 to 8.1 diff --git a/src/Map/src/Bridge/Google/assets/dist/map_controller.d.ts b/src/Map/src/Bridge/Google/assets/dist/map_controller.d.ts index 2bb32519e15..63691d2fbb1 100644 --- a/src/Map/src/Bridge/Google/assets/dist/map_controller.d.ts +++ b/src/Map/src/Bridge/Google/assets/dist/map_controller.d.ts @@ -37,7 +37,7 @@ export default class extends AbstractMapController; - element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline; + element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline | google.maps.Circle | google.maps.Rectangle; }): google.maps.InfoWindow; protected doFitBoundsToMarkers(): void; private createTextOrElement; diff --git a/src/Map/src/Bridge/Google/assets/dist/map_controller.js b/src/Map/src/Bridge/Google/assets/dist/map_controller.js index b88e665b382..73850804df7 100644 --- a/src/Map/src/Bridge/Google/assets/dist/map_controller.js +++ b/src/Map/src/Bridge/Google/assets/dist/map_controller.js @@ -294,40 +294,36 @@ class map_controller extends default_1 { rectangle.setMap(null); } doCreateInfoWindow({ definition, element, }) { - const { headerContent, content, extra, rawOptions = {}, ...otherOptions } = definition; - const infoWindow = new _google.maps.InfoWindow({ + const { headerContent, content, opened, autoClose, rawOptions = {} } = definition; + let position = null; + if (element instanceof google.maps.Circle) { + position = element.getCenter(); + } + else if (element instanceof google.maps.Rectangle) { + position = element.getBounds()?.getCenter() || null; + } + else if (element instanceof google.maps.Polygon || element instanceof google.maps.Polyline) ; + const infoWindowOptions = { headerContent: this.createTextOrElement(headerContent), content: this.createTextOrElement(content), - ...otherOptions, + position, ...rawOptions, - }); - if (element instanceof google.maps.marker.AdvancedMarkerElement) { - element.addListener('click', () => { - if (definition.autoClose) { - this.closeInfoWindowsExcept(infoWindow); - } - infoWindow.open({ map: this.map, anchor: element }); - }); - if (definition.opened) { - infoWindow.open({ map: this.map, anchor: element }); + }; + const infoWindow = new _google.maps.InfoWindow(infoWindowOptions); + element.addListener('click', (event) => { + if (autoClose) { + this.closeInfoWindowsExcept(infoWindow); } - } - else if (element instanceof google.maps.Polygon) { - element.addListener('click', (event) => { - if (definition.autoClose) { - this.closeInfoWindowsExcept(infoWindow); - } + if (infoWindowOptions.position === null) { infoWindow.setPosition(event.latLng); - infoWindow.open(this.map); - }); - if (definition.opened) { - const bounds = new google.maps.LatLngBounds(); - element.getPath().forEach((point) => { - bounds.extend(point); - }); - infoWindow.setPosition(bounds.getCenter()); - infoWindow.open({ map: this.map, anchor: element }); } + infoWindow.open({ map: this.map, anchor: element }); + }); + if (opened) { + if (autoClose) { + this.closeInfoWindowsExcept(infoWindow); + } + infoWindow.open({ map: this.map, anchor: element }); } return infoWindow; } diff --git a/src/Map/src/Bridge/Google/assets/src/map_controller.ts b/src/Map/src/Bridge/Google/assets/src/map_controller.ts index 4a1bfd82147..6037fb0cc68 100644 --- a/src/Map/src/Bridge/Google/assets/src/map_controller.ts +++ b/src/Map/src/Bridge/Google/assets/src/map_controller.ts @@ -296,45 +296,53 @@ export default class extends AbstractMapController< element, }: { definition: InfoWindowWithoutPositionDefinition; - element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline; + element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline | google.maps.Circle | google.maps.Rectangle; }): google.maps.InfoWindow { - const { headerContent, content, extra, rawOptions = {}, ...otherOptions } = definition; + const { headerContent, content, opened, autoClose, rawOptions = {} } = definition; + + let position: google.maps.LatLng | null = null; + if (element instanceof google.maps.Circle) { + position = element.getCenter(); + } else if (element instanceof google.maps.Rectangle) { + position = element.getBounds()?.getCenter() || null; + } else if (element instanceof google.maps.Polygon || element instanceof google.maps.Polyline) { + // Note: We do not compute the center of Polygons or Polylines here, since shapes can be complex. + // Instead, listen to the `ux:map:polygon:before-create` or `ux:map:polyline:before-create` events to set the position manually. + // ```js + // const bounds = new google.maps.LatLngBounds(); + // element.getPath().forEach((latLng) => bounds.extend(latLng)); + // event.definition.infoWindow.rawOptions.position = bounds.getCenter(); + // ``` + } - const infoWindow = new _google.maps.InfoWindow({ + const infoWindowOptions: google.maps.InfoWindowOptions = { headerContent: this.createTextOrElement(headerContent), content: this.createTextOrElement(content), - ...otherOptions, + position, ...rawOptions, - }); + }; - if (element instanceof google.maps.marker.AdvancedMarkerElement) { - element.addListener('click', () => { - if (definition.autoClose) { - this.closeInfoWindowsExcept(infoWindow); - } - infoWindow.open({ map: this.map, anchor: element }); - }); + const infoWindow = new _google.maps.InfoWindow(infoWindowOptions); - if (definition.opened) { - infoWindow.open({ map: this.map, anchor: element }); + element.addListener('click', (event: google.maps.MapMouseEvent) => { + if (autoClose) { + this.closeInfoWindowsExcept(infoWindow); } - } else if (element instanceof google.maps.Polygon) { - element.addListener('click', (event: any) => { - if (definition.autoClose) { - this.closeInfoWindowsExcept(infoWindow); - } + + // Don't override the position if it was already set (e.g. through "rawOptions") + if (infoWindowOptions.position === null) { infoWindow.setPosition(event.latLng); - infoWindow.open(this.map); - }); - - if (definition.opened) { - const bounds = new google.maps.LatLngBounds(); - element.getPath().forEach((point: google.maps.LatLng) => { - bounds.extend(point); - }); - infoWindow.setPosition(bounds.getCenter()); - infoWindow.open({ map: this.map, anchor: element }); } + + infoWindow.open({ map: this.map, anchor: element }); + }); + + if (opened) { + if (autoClose) { + this.closeInfoWindowsExcept(infoWindow); + } + + infoWindow.open({ map: this.map, anchor: element }); } return infoWindow;