diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js
index c9803a5b142..1dfdc5be860 100644
--- a/addons/web_editor/static/src/js/editor/snippets.options.js
+++ b/addons/web_editor/static/src/js/editor/snippets.options.js
@@ -1601,6 +1601,7 @@ const SnippetOptionWidget = Widget.extend({
tagName: 'we-customizeblock-option',
custom_events: {
'user_value_update': '_onUserValueUpdate',
+ 'user_value_widget_critical': '_onUserValueWidgetCritical',
},
/**
* Indicates if the option should be displayed in the button group at the
@@ -2546,6 +2547,14 @@ const SnippetOptionWidget = Widget.extend({
});
}
},
+ /**
+ * @private
+ */
+ _onUserValueWidgetCritical() {
+ this.trigger_up('remove_snippet', {
+ $snippet: this.$target,
+ });
+ },
});
const registry = {};
diff --git a/addons/website/static/src/js/content/website_root.js b/addons/website/static/src/js/content/website_root.js
index dedf5c94359..fa2a01eecd2 100644
--- a/addons/website/static/src/js/content/website_root.js
+++ b/addons/website/static/src/js/content/website_root.js
@@ -1,15 +1,14 @@
odoo.define('website.root', function (require) {
'use strict';
-var core = require('web.core');
+const ajax = require('web.ajax');
+const {_t} = require('web.core');
var Dialog = require('web.Dialog');
const KeyboardNavigationMixin = require('web.KeyboardNavigationMixin');
const session = require('web.session');
var publicRootData = require('web.public.root');
require("web.zoomodoo");
-var _t = core._t;
-
var websiteRootRegistry = publicRootData.publicRootRegistry;
var WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMixin, {
@@ -20,8 +19,10 @@ var WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMixin, {
'shown.bs.modal': '_onModalShown',
}),
custom_events: _.extend({}, publicRootData.PublicRoot.prototype.custom_events || {}, {
+ 'gmap_api_request': '_onGMapAPIRequest',
+ 'gmap_api_key_request': '_onGMapAPIKeyRequest',
'ready_to_clean_for_save': '_onWidgetsStopRequest',
- seo_object_request: '_onSeoObjectRequest',
+ 'seo_object_request': '_onSeoObjectRequest',
}),
/**
@@ -90,6 +91,21 @@ var WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMixin, {
'edit_translations': !!html.dataset.edit_translations,
}, this._super.apply(this, arguments));
},
+ /**
+ * @private
+ * @param {boolean} [refetch=false]
+ */
+ async _getGMapAPIKey(refetch) {
+ if (refetch || !this._gmapAPIKeyProm) {
+ this._gmapAPIKeyProm = new Promise(async resolve => {
+ const data = await this._rpc({
+ route: '/website/google_maps_api_key',
+ });
+ resolve(JSON.parse(data).google_maps_api_key || '');
+ });
+ }
+ return this._gmapAPIKeyProm;
+ },
/**
* @override
*/
@@ -102,6 +118,50 @@ var WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMixin, {
}
return registry;
},
+ /**
+ * @private
+ * @param {boolean} [editableMode=false]
+ * @param {boolean} [refetch=false]
+ */
+ async _loadGMapAPI(editableMode, refetch) {
+ // Note: only need refetch to reload a configured key and load the
+ // library. If the library was loaded with a correct key and that the
+ // key changes meanwhile... it will not work but we can agree the user
+ // can bother to reload the page at that moment.
+ if (refetch || !this._gmapAPILoading) {
+ this._gmapAPILoading = new Promise(async resolve => {
+ const key = await this._getGMapAPIKey(refetch);
+
+ window.odoo_gmap_api_post_load = (async function odoo_gmap_api_post_load() {
+ await this._startWidgets(undefined, {editableMode: editableMode});
+ resolve(key);
+ }).bind(this);
+
+ if (!key) {
+ if (!editableMode && session.is_admin) {
+ this.displayNotification({
+ type: 'warning',
+ sticky: true,
+ message:
+ $('
').append(
+ $('', {text: _t("Cannot load google map.")}),
+ $('
'),
+ $('', {
+ href: "/web#action=website.action_website_configuration",
+ text: _t("Check your configuration."),
+ }),
+ )[0].outerHTML,
+ });
+ }
+ resolve(false);
+ this._gmapAPILoading = false;
+ return;
+ }
+ await ajax.loadJS(`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&callback=odoo_gmap_api_post_load&key=${key}`);
+ });
+ }
+ return this._gmapAPILoading;
+ },
/**
* Toggles the fullscreen mode.
*
@@ -163,6 +223,24 @@ var WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMixin, {
};
window.location.href = _.str.sprintf("/website/lang/%(lang)s?r=%(url)s%(hash)s", redirect);
},
+ /**
+ * @private
+ * @param {OdooEvent} ev
+ */
+ async _onGMapAPIRequest(ev) {
+ ev.stopPropagation();
+ const apiKey = await this._loadGMapAPI(ev.data.editableMode, ev.data.refetch);
+ ev.data.onSuccess(apiKey);
+ },
+ /**
+ * @private
+ * @param {OdooEvent} ev
+ */
+ async _onGMapAPIKeyRequest(ev) {
+ ev.stopPropagation();
+ const apiKey = await this._getGMapAPIKey(ev.data.refetch);
+ ev.data.onSuccess(apiKey);
+ },
/**
/**
* Checks information about the page SEO object.
diff --git a/addons/website/static/src/js/editor/snippets.editor.js b/addons/website/static/src/js/editor/snippets.editor.js
index ca231278fd1..8e48424b853 100644
--- a/addons/website/static/src/js/editor/snippets.editor.js
+++ b/addons/website/static/src/js/editor/snippets.editor.js
@@ -1,16 +1,23 @@
odoo.define('website.snippet.editor', function (require) {
'use strict';
-const {_t} = require('web.core');
+const {qweb, _t} = require('web.core');
+const Dialog = require('web.Dialog');
const weSnippetEditor = require('web_editor.snippet.editor');
const wSnippetOptions = require('website.editor.snippets.options');
const FontFamilyPickerUserValueWidget = wSnippetOptions.FontFamilyPickerUserValueWidget;
weSnippetEditor.Class.include({
+ xmlDependencies: (weSnippetEditor.Class.prototype.xmlDependencies || [])
+ .concat(['/website/static/src/xml/website.editor.xml']),
events: _.extend({}, weSnippetEditor.Class.prototype.events, {
'click .o_we_customize_theme_btn': '_onThemeTabClick',
}),
+ custom_events: Object.assign({}, weSnippetEditor.Class.prototype.custom_events, {
+ 'gmap_api_request': '_onGMapAPIRequest',
+ 'gmap_api_key_request': '_onGMapAPIKeyRequest',
+ }),
tabs: _.extend({}, weSnippetEditor.Class.prototype.tabs, {
THEME: 'theme',
}),
@@ -31,6 +38,55 @@ weSnippetEditor.Class.include({
return this._super(...arguments);
},
+ /**
+ * Depending of the demand, reconfigure they gmap key or configure it
+ * if not already defined.
+ *
+ * @private
+ * @param {boolean} [reconfigure=false]
+ * @param {boolean} [onlyIfUndefined=false]
+ */
+ async _configureGMapAPI({reconfigure, onlyIfUndefined}) {
+ const apiKey = await new Promise(resolve => {
+ this.getParent().trigger_up('gmap_api_key_request', {
+ onSuccess: key => resolve(key),
+ });
+ });
+ if (!reconfigure && (apiKey || !onlyIfUndefined)) {
+ return false;
+ }
+ let websiteId;
+ this.trigger_up('context_get', {
+ callback: ctx => websiteId = ctx['website_id'],
+ });
+ return new Promise(resolve => {
+ let invalidated = false;
+ const dialog = new Dialog(this, {
+ size: 'medium',
+ title: _t("Google Map API Key"),
+ buttons: [
+ {text: _t("Save"), classes: 'btn-primary', close: true, click: async () => {
+ const newAPIKey = dialog.$('#api_key_input').val() || false;
+ await this._rpc({
+ model: 'website',
+ method: 'write',
+ args: [
+ [websiteId],
+ {google_maps_api_key: newAPIKey},
+ ],
+ });
+ invalidated = true;
+ }},
+ {text: _t("Cancel"), close: true}
+ ],
+ $content: $(qweb.render('website.s_google_map_modal', {
+ apiKey: apiKey,
+ })),
+ });
+ dialog.on('closed', this, () => resolve(invalidated));
+ dialog.open();
+ });
+ },
/**
* @override
*/
@@ -44,6 +100,23 @@ weSnippetEditor.Class.include({
}
return finalOptions;
},
+ /**
+ * @private
+ * @param {OdooEvent} ev
+ * @param {string} gmapRequestEventName
+ */
+ async _handleGMapRequest(ev, gmapRequestEventName) {
+ ev.stopPropagation();
+ const reconfigured = await this._configureGMapAPI({
+ reconfigure: ev.data.reconfigure,
+ onlyIfUndefined: ev.data.configureIfNecessary,
+ });
+ this.getParent().trigger_up(gmapRequestEventName, {
+ refetch: reconfigured,
+ editableMode: true,
+ onSuccess: key => ev.data.onSuccess(key),
+ });
+ },
/**
* @override
*/
@@ -56,6 +129,20 @@ weSnippetEditor.Class.include({
// Handlers
//--------------------------------------------------------------------------
+ /**
+ * @private
+ * @param {OdooEvent} ev
+ */
+ _onGMapAPIRequest(ev) {
+ this._handleGMapRequest(ev, 'gmap_api_request');
+ },
+ /**
+ * @private
+ * @param {OdooEvent} ev
+ */
+ _onGMapAPIKeyRequest(ev) {
+ this._handleGMapRequest(ev, 'gmap_api_key_request');
+ },
/**
* @private
*/
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index 981ca05e387..db2d33585f4 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -211,8 +211,133 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({
},
});
+const GPSPicker = InputUserValueWidget.extend({
+ events: { // Explicitely not consider all InputUserValueWidget events
+ 'blur input': '_onInputBlur',
+ },
+
+ /**
+ * @constructor
+ */
+ init() {
+ this._super(...arguments);
+ this._gmapCacheGPSToPlace = {};
+ },
+ /**
+ * @override
+ */
+ async willStart() {
+ await this._super(...arguments);
+ this._gmapLoaded = await new Promise(resolve => {
+ this.trigger_up('gmap_api_request', {
+ editableMode: true,
+ configureIfNecessary: true,
+ onSuccess: key => resolve(!!key),
+ });
+ });
+ if (!this._gmapLoaded) {
+ this.trigger_up('user_value_widget_critical');
+ return;
+ }
+ },
+ /**
+ * @override
+ */
+ async start() {
+ await this._super(...arguments);
+ this.el.classList.add('o_we_large_input');
+ if (!this._gmapLoaded) {
+ return;
+ }
+
+ this._gmapAutocomplete = new google.maps.places.Autocomplete(this.inputEl, {types: ['geocode']});
+ google.maps.event.addListener(this._gmapAutocomplete, 'place_changed', this._onPlaceChanged.bind(this));
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ getMethodsParams: function (methodName) {
+ return Object.assign({gmapPlace: this._gmapPlace || {}}, this._super(...arguments));
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _updateUI: async function () {
+ await this._super(...arguments);
+
+ await new Promise(resolve => {
+ const gps = this._value;
+ if (this._gmapCacheGPSToPlace[gps]) {
+ this._gmapPlace = this._gmapCacheGPSToPlace[gps];
+ resolve();
+ return;
+ }
+ const service = new google.maps.places.PlacesService(document.createElement('div'));
+ const p = gps.substring(1).slice(0, -1).split(',');
+ const location = new google.maps.LatLng(p[0] || 0, p[1] || 0);
+ service.nearbySearch({
+ // Do a 'nearbySearch' followed by 'getDetails' to avoid using
+ // GMap Geocoder which the user may not have enabled... but
+ // ideally Geocoder should be used to get the exact location at
+ // those coordinates and to limit billing query count.
+ location: location,
+ radius: 1,
+ }, (results, status) => {
+ const GMAP_CRITICAL_ERRORS = [google.maps.places.PlacesServiceStatus.REQUEST_DENIED, google.maps.places.PlacesServiceStatus.UNKNOWN_ERROR];
+ if (status === google.maps.places.PlacesServiceStatus.OK) {
+ service.getDetails({
+ placeId: results[0].place_id,
+ fields: ['geometry', 'formatted_address'],
+ }, (place, status) => {
+ resolve();
+ if (status === google.maps.places.PlacesServiceStatus.OK) {
+ this._gmapCacheGPSToPlace[gps] = place;
+ this._gmapPlace = place;
+ } else if (GMAP_CRITICAL_ERRORS.includes(status)) {
+ this.trigger_up('user_value_widget_critical');
+ }
+ });
+ } else if (GMAP_CRITICAL_ERRORS.includes(status)) {
+ resolve();
+ this.trigger_up('user_value_widget_critical');
+ }
+ });
+ });
+ this.inputEl.value = this._gmapPlace.formatted_address;
+ },
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onPlaceChanged(ev) {
+ const gmapPlace = this._gmapAutocomplete.getPlace();
+ if (gmapPlace && gmapPlace.geometry) {
+ this._gmapPlace = gmapPlace;
+ const location = this._gmapPlace.geometry.location;
+ this._value = `(${location.lat()},${location.lng()})`;
+ this._gmapCacheGPSToPlace[this._value] = gmapPlace;
+ this._onUserValueChange(ev);
+ }
+ },
+});
+
options.userValueWidgetsRegistry['we-urlpicker'] = UrlPickerUserValueWidget;
options.userValueWidgetsRegistry['we-fontfamilypicker'] = FontFamilyPickerUserValueWidget;
+options.userValueWidgetsRegistry['we-gpspicker'] = GPSPicker;
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
diff --git a/addons/website/static/src/scss/website.wysiwyg.scss b/addons/website/static/src/scss/website.wysiwyg.scss
index 8364bbac507..8a6c6fceeda 100644
--- a/addons/website/static/src/scss/website.wysiwyg.scss
+++ b/addons/website/static/src/scss/website.wysiwyg.scss
@@ -135,3 +135,12 @@ we-collapse {
border-width: 4px;
border-bottom: none !important;
}
+
+.pac-container { // google map autosuggestion
+ z-index: $zindex-modal-backdrop; // > $o-we-zindex
+ min-width: 400px;
+
+ &:after {
+ display: none;
+ }
+}
diff --git a/addons/website/static/src/snippets/s_google_map/000.js b/addons/website/static/src/snippets/s_google_map/000.js
index a59162a5f1a..1fa5d3d74aa 100644
--- a/addons/website/static/src/snippets/s_google_map/000.js
+++ b/addons/website/static/src/snippets/s_google_map/000.js
@@ -1,13 +1,8 @@
odoo.define('website.s_google_map', function (require) {
'use strict';
-const ajax = require('web.ajax');
-const {_t} = require('web.core');
const publicWidget = require('web.public.widget');
-let googleScriptLoadedResolve = null;
-const googleScriptLoaded = new Promise(resolve => googleScriptLoadedResolve = resolve);
-
publicWidget.registry.GoogleMap = publicWidget.Widget.extend({
selector: '.s_google_map',
disabledInEditableMode: false,
@@ -31,42 +26,12 @@ publicWidget.registry.GoogleMap = publicWidget.Widget.extend({
await this._super(...arguments);
if (typeof google !== 'object' || typeof google.maps !== 'object') {
- if (!publicWidget.registry.GoogleMap.isScriptLoading) {
- publicWidget.registry.GoogleMap.isScriptLoading = true;
- const self = this;
- window.odoo_s_google_map_redraw_all = function odoo_s_google_map_redraw_all() {
- for (const map of $('section.s_google_map')) {
- self.trigger_up('widgets_start_request', {
- editableMode: self.editableMode,
- $target: $(map),
- });
- }
- publicWidget.registry.GoogleMap.isScriptLoading = false;
- googleScriptLoadedResolve();
- };
-
- const data = await this._rpc({
- route: '/website/google_maps_api_key',
+ await new Promise(resolve => {
+ this.trigger_up('gmap_api_request', {
+ editableMode: this.editableMode,
+ onSuccess: () => resolve(),
});
-
- const key = JSON.parse(data).google_maps_api_key;
- if (!key) {
- publicWidget.registry.GoogleMap.isScriptLoading = false;
- if (this.editableMode) {
- this.$loadingWarning = $('', {
- class: 'alert alert-warning alert-link',
- }).append($('', {
- href: "#",
- text: _t("Cannot load google map, check your configuration !"),
- })).click(function (e) {
- window.location.href = "/web#action=website.action_website_configuration";
- });
- this.$('.map_container').append(this.$loadingWarning);
- }
- return;
- }
- await ajax.loadJS(`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&callback=odoo_s_google_map_redraw_all&key=${key}`);
- }
+ });
// The animation will be restarted for all maps as soon as the
// google map script has been executed.
return;
@@ -127,25 +92,5 @@ publicWidget.registry.GoogleMap = publicWidget.Widget.extend({
map.setMapTypeId('map_style');
}
},
- /**
- * @override
- */
- destroy() {
- this._super(...arguments);
- if (this.$loadingWarning) {
- this.$loadingWarning.remove();
- }
- },
});
-
-// This allows to save if the google maps script is already loading or not.
-// This script cannot be loaded 2 times, so if we have 2 snippets in the same
-// page we don't want to load the script 2 times.
-// And we cannot put the script in an asset because we don't want to load it
-// on each page, but only on pages with a google maps snippet...
-publicWidget.registry.GoogleMap.prototype.isScriptLoading = false;
-
-return {
- googleScriptLoaded: googleScriptLoaded,
-};
});
diff --git a/addons/website/static/src/snippets/s_google_map/000.scss b/addons/website/static/src/snippets/s_google_map/000.scss
index 4e13cb07941..9a8df732775 100644
--- a/addons/website/static/src/snippets/s_google_map/000.scss
+++ b/addons/website/static/src/snippets/s_google_map/000.scss
@@ -5,9 +5,8 @@ $s-google-map-desc-hover-bg: theme-color('primary') !default;
$s-google-map-desc-hover-alpha: 0.55 !default;
.s_google_map {
- height: 100%;
- min-height: 100px;
position: relative;
+ min-height: 100px;
.map_container {
@include o-position-absolute(0, 0, 0, 0);
@@ -16,8 +15,8 @@ $s-google-map-desc-hover-alpha: 0.55 !default;
@include o-position-absolute(auto, 0, 0, 0);
z-index: 99;
padding: 0 1em;
- background: rgba($s-google-map-desc-bg , $s-google-map-desc-alpha);
- color: color-yiq(rgba($s-google-map-desc-bg , $s-google-map-desc-alpha));
+ background: rgba($s-google-map-desc-bg, $s-google-map-desc-alpha);
+ color: color-yiq(rgba($s-google-map-desc-bg, $s-google-map-desc-alpha));
transition: background-color 250ms ease;
font {
@@ -41,14 +40,3 @@ $s-google-map-desc-hover-alpha: 0.55 !default;
color: color-yiq(rgba($s-google-map-desc-hover-bg, $s-google-map-desc-hover-alpha));
}
}
-
-#mapModal {
- z-index: 3000;
-}
-.pac-container { // google map autosuggestion
- z-index: 3001;
-
- &:after {
- display: none;
- }
-}
diff --git a/addons/website/static/src/snippets/s_google_map/options.js b/addons/website/static/src/snippets/s_google_map/options.js
index 9b27d815a66..6aad46f12ad 100644
--- a/addons/website/static/src/snippets/s_google_map/options.js
+++ b/addons/website/static/src/snippets/s_google_map/options.js
@@ -1,78 +1,56 @@
odoo.define('options.s_google_map_options', function (require) {
'use strict';
-const {Dialog} = require('web_editor.widget');
-const {_t, qweb} = require('web.core');
+const {_t} = require('web.core');
const options = require('web_editor.snippets.options');
-const {googleScriptLoaded} = require('website.s_google_map');
options.registry.GoogleMap = options.Class.extend({
- xmlDependencies: ['/website/static/src/xml/s_google_map_modal.xml'],
- defaultLocation: '(50.854975,4.3753899)',
-
- /**
- * @override
- */
- onBuilt() {
- this._super(...arguments);
-
- let widget = null;
- this.trigger_up('user_value_widget_request', {
- name: 'map_options_opt',
- onSuccess: _widget => widget = _widget,
- });
- widget.$el.click();
- },
//--------------------------------------------------------------------------
// Options
//--------------------------------------------------------------------------
- /**
- * Opens the customization dialog.
- *
- * @see this.selectClass for parameters
- */
- async map(previewMode, widgetValue, params) {
- await new Promise(resolve => {
- this.dialog = new Dialog(this, {
- size: 'medium',
- title: _t("Customize your map"),
- buttons: [
- {text: _t("Save"), classes: 'btn-primary', close: true, click: () => {
- if (!this.dialog.$('#placeBk').val()) {
- this.dialog.$('#placeBk').val(this.defaultLocation);
- }
- this.$target[0].dataset.mapGps = this.dialog.$('#placeBk').val();
- this.$target[0].dataset.pinStyle = this.dialog.$('#pin_style').val();
- this.$target[0].dataset.pinAddress = this.dialog.$('#pin_address').val();
- }},
- {text: _t("Cancel"), close: true}
- ],
- $content: $(qweb.render('website.s_google_map_modal'))
- });
-
- this.dialog.opened().then(() => {
- this.dialog.$('#pin_address').val(this.$target[0].dataset.pinAddress);
- this.dialog.$('#pin_style').val(this.$target[0].dataset.pinStyle);
- this.dialog.$('#placeBk').val(this.$target[0].dataset.mapGps);
- const autocomplete = new google.maps.places.Autocomplete(this.dialog.$('#pin_address').get(0), {types: ['geocode']});
- google.maps.event.addListener(autocomplete, 'place_changed', () => {
- const place = autocomplete.getPlace();
- this.dialog.$('#placeBk').val(place.geometry ? place.geometry.location : this.defaultLocation);
- });
- });
-
- this.dialog.on('closed', this, () => resolve());
-
- googleScriptLoaded.then(() => this.dialog.open());
- });
- },
/**
* @see this.selectClass for parameters
*/
resetMapColor(previewMode, widgetValue, params) {
this.$target[0].dataset.mapColor = '';
},
+ /**
+ * @see this.selectClass for parameters
+ */
+ setFormattedAddress(previewMode, widgetValue, params) {
+ this.$target[0].dataset.pinAddress = params.gmapPlace.formatted_address;
+ },
+ /**
+ * @see this.selectClass for parameters
+ */
+ async showDescription(previewMode, widgetValue, params) {
+ const descriptionEl = this.$target[0].querySelector('.description');
+ if (widgetValue && !descriptionEl) {
+ this.$target.append($(`
+
+ ${_t('Visit us:')}
+ ${_t('Our office is located in the northeast of Brussels. TEL (555) 432 2365')}
+
`)
+ );
+ } else if (!widgetValue && descriptionEl) {
+ descriptionEl.remove();
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _computeWidgetState(methodName, params) {
+ if (methodName === 'showDescription') {
+ return this.$target[0].querySelector('.description') ? 'true' : '';
+ }
+ return this._super(...arguments);
+ },
});
});
diff --git a/addons/website/static/src/xml/s_google_map_modal.xml b/addons/website/static/src/xml/s_google_map_modal.xml
deleted file mode 100644
index 407e27d5acb..00000000000
--- a/addons/website/static/src/xml/s_google_map_modal.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml
index bea9661aa21..f024202d523 100644
--- a/addons/website/static/src/xml/website.editor.xml
+++ b/addons/website/static/src/xml/website.editor.xml
@@ -107,6 +107,35 @@
+
+
Use Google Map on your website (Contact Us page, snippets, etc).
+
+
diff --git a/addons/website/views/snippets/s_google_map.xml b/addons/website/views/snippets/s_google_map.xml
index 43bab6f3956..2781ec1ebd0 100644
--- a/addons/website/views/snippets/s_google_map.xml
+++ b/addons/website/views/snippets/s_google_map.xml
@@ -4,18 +4,22 @@
-
- Visit us:
- Our office is located in the northeast of Brussels. TEL (555) 432 2365
-
-
+
-
-
Map Options
+
+
+
+ Default
+ Flat
+
RoadMap
Terrain
@@ -45,6 +49,7 @@
data-img="/website/static/src/snippets/s_google_map/img/thumbs/map-bw.jpg"/>
+
diff --git a/addons/website/views/snippets/snippets.xml b/addons/website/views/snippets/snippets.xml
index 8044c97df55..b7cac8ddbb2 100644
--- a/addons/website/views/snippets/snippets.xml
+++ b/addons/website/views/snippets/snippets.xml
@@ -374,7 +374,7 @@
t-att-data-selector="so_snippet_addition_selector"
data-drop-in=":not(p).oe_structure:not(.oe_structure_solo), :not(p)[data-oe-type=html], :not(p).oe_structure.oe_structure_solo:not(:has(> section, > div))"/>
-
blockquote, .s_card:not(.s_timeline_card), .s_alert, .o_facebook_page, .s_share, .s_rating, .s_hr, .s_countdown, .s_chart, .s_text_highlight, .s_progress_bar, .s_badge
+
blockquote, .s_card:not(.s_timeline_card), .s_alert, .o_facebook_page, .s_share, .s_rating, .s_hr, .s_google_map, .s_countdown, .s_chart, .s_text_highlight, .s_progress_bar, .s_badge