diff options
| author | qsm-odoo <qsm@odoo.com> | 2020-07-27 10:24:44 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2020-07-28 07:45:40 +0000 |
| commit | 430b5b669f8dc42c7bd5ed08de3e080fb0200ac2 (patch) | |
| tree | f7126b2021c397df3bdf1d0803c680f8c698b187 /addons | |
| parent | 59d46b51b137715143d35ca749226316c3a0a5ec (diff) | |
[IMP] website, *: move all google map options to left panel
*: web_editor
-> Introduce the we-gpspicker widget and improve the way the gmap lib
is loaded (for Odoo / multiple snippets / ...).
Part of https://github.com/odoo/odoo/pull/49101
task-2091396
Diffstat (limited to 'addons')
12 files changed, 398 insertions, 174 deletions
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', }), /** @@ -91,6 +92,21 @@ var WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMixin, { }, 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 */ _getPublicWidgetsRegistry: function (options) { @@ -103,6 +119,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: + $('<div/>').append( + $('<span/>', {text: _t("Cannot load google map.")}), + $('<br/>'), + $('<a/>', { + 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. * * @private @@ -164,6 +224,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', }), @@ -32,6 +39,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 */ _getScrollOptions(options = {}) { @@ -45,6 +101,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 */ _updateLeftPanelContent: function ({content, tab}) { @@ -58,6 +131,20 @@ weSnippetEditor.Class.include({ /** * @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 */ _onThemeTabClick: async function (ev) { this._addTabLoading(this.tabs.THEME); 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 = $('<div/>', { - class: 'alert alert-warning alert-link', - }).append($('<a/>', { - 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()); - }); + resetMapColor(previewMode, widgetValue, params) { + this.$target[0].dataset.mapColor = ''; }, /** * @see this.selectClass for parameters */ - resetMapColor(previewMode, widgetValue, params) { - this.$target[0].dataset.mapColor = ''; + 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($(` + <div class="description"> + <font>${_t('Visit us:')}</font> + <span>${_t('Our office is located in the northeast of Brussels. TEL (555) 432 2365')}</span> + </div>`) + ); + } 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 @@ -<?xml version="1.0" encoding="UTF-8"?> -<templates xml:space="preserve"> - <div t-name="website.s_google_map_modal"> - <div class="form-group form-row"> - <label for="pin_address" class="col-md-3 col-form-label text-right">Address</label> - <div class="col-md-9"> - <div class="input-group"> - <div class="input-group-prepend"> - <div class="input-group-text"><i class="fa fa-building-o"/></div> - </div> - <input type="text" class="form-control" id="pin_address" placeholder="Your address"/> - <input type="hidden" id="placeBk"/> - </div> - </div> - <div class="col-md-9 offset-md-3"> - <small class="form-text">e.g. De Brouckere, Brussels, Belgium</small> - </div> - </div> - <div class="form-group form-row"> - <label for="pin_style" class="col-md-3 col-form-label text-right">Marker Style</label> - <div class="col-md-9"> - <select id="pin_style" name="pin_style" class="col-md-5"> - <option value="flat">Flat</option> - <option>Default</option> - </select> - </div> - </div> - </div> -</templates> 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 @@ </we-row> </div> </t> + <div t-name="website.s_google_map_modal"> + <p>Use Google Map on your website (Contact Us page, snippets, etc).</p> + <div class="form-group row mb-0"> + <label class="col-sm-2 col-form-label" for="pin_address">API Key</label> + <div class="col"> + <div class="input-group"> + <div class="input-group-prepend"> + <div class="input-group-text"><i class="fa fa-key"/></div> + </div> + <input type="text" class="form-control" id="api_key_input" + t-att-value="apiKey or ''" + placeholder="BSgzTvR5L1GB9jriT451iTN4huVPxHmltG6T6eo"/> + </div> + <div class="small form-text text-muted"> + Hint: How to use Google Map on your website (Contact Us page and as a snippet) + <br/> + <a target="_blank" href="https://console.developers.google.com/flows/enableapi?apiid=maps_backend,static_maps_backend&keyType=CLIENT_SIDE&reusekey=true"> + <i class="fa fa-arrow-right"/> + Create a Google Project and Get a Key + </a> + <br/> + <a target="_blank" href="https://cloud.google.com/maps-platform/pricing"> + <i class="fa fa-arrow-right"/> + Enable billing on your Google Project + </a> + </div> + </div> + </div> + </div> <!-- Theme - custom code --> <div t-name="website.custom_code_dialog_content"> 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 @@ <template name="Google Map" id="s_google_map"> <section class="s_google_map pt256 pb256" data-map-type="ROADMAP" data-map-color="" data-map-zoom="12" data-map-gps="(50.854975,4.3753899)" data-pin-style="flat"> <div class="map_container"/> - <div class="description"> - <font>Visit us:</font> - <span>Our office is located in the northeast of Brussels. TEL (555) 432 2365</span> - </div> </section> </template> <!-- Snippet's Options --> -<template id="s_google_map_option" inherit_id="website.snippet_options"> +<template id="s_google_map_options" inherit_id="website.snippet_options"> <xpath expr="//div[@data-js='parallax']" position="before"> - <div data-js="GoogleMap" data-selector="section.s_google_map"> - <we-button data-name="map_options_opt" data-map="" data-no-preview="true">Map Options</we-button> + <div data-js="GoogleMap" data-selector=".s_google_map"> + <we-gpspicker string="Address" + data-select-data-attribute="" data-attribute-name="mapGps" + data-set-formatted-address="" + placeholder="e.g. De Brouckere, Brussels, Belgium" + data-no-preview="true"/> + <we-select string="Marker style" data-attribute-name="pinStyle"> + <we-button data-select-data-attribute="">Default</we-button> + <we-button data-select-data-attribute="flat">Flat</we-button> + </we-select> <we-select string="Type" data-no-preview="true" data-reset-map-color="" data-attribute-name="mapType"> <we-button data-name="roadmap_opt" data-select-data-attribute="ROADMAP">RoadMap</we-button> <we-button data-select-data-attribute="TERRAIN">Terrain</we-button> @@ -45,6 +49,7 @@ data-img="/website/static/src/snippets/s_google_map/img/thumbs/map-bw.jpg"/> </we-select> <we-input string="Zoom" data-select-data-attribute="12" data-no-preview="true" data-attribute-name="mapZoom" data-step="1"/> + <we-checkbox string="Description" data-no-preview="true" data-show-description="true"/> </div> </xpath> </template> 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))"/> - <t t-set="so_content_addition_selector" t-translation="off">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</t> + <t t-set="so_content_addition_selector" t-translation="off">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</t> <div id="so_content_addition" t-att-data-selector="so_content_addition_selector" t-attf-data-drop-near="p, h1, h2, h3, .row > div > img, #{so_content_addition_selector}" |
