diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index 688b731ebda..fe17d09060a 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -821,7 +821,7 @@ var SnippetEditor = Widget.extend({ this.$el.find('[data-toggle="dropdown"]').dropdown(); - return Promise.all(defs).then(() => { + return Promise.all(defs).then(async () => { const options = _.sortBy(this.styles, '__order'); const firstOptions = []; options.forEach(option => { @@ -2988,18 +2988,7 @@ var SnippetsMenu = Widget.extend({ if (!ev.currentTarget.classList.contains('active')) { this._activateSnippet(false); this._mutex.exec(() => { - let $pageOptionsTarget = $(); - let i = 0; - const pageOptions = this.templateOptions.filter(template => template.data.pageOptions); - while (!$pageOptionsTarget.length && i < pageOptions.length) { - $pageOptionsTarget = pageOptions[i].selector.all(); - i++; - } - if ($pageOptionsTarget.length) { - this._activateSnippet($pageOptionsTarget); - } else { - this._activateEmptyOptionsTab(); - } + this._activateEmptyOptionsTab(); }); } }, diff --git a/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js b/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js index c6c83d4e3ee..be82db3c0dc 100644 --- a/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js +++ b/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js @@ -49,6 +49,13 @@ export class WysiwygAdapterComponent extends ComponentAdapter { this.pageOptions[optionName] = new PageOption(pageOptionEl, this.websiteService.pageDocument, optionName); } this.editableElements(this.$editable).addClass('o_editable'); + + let switchableRelatedViews = []; + const viewKey = this.websiteService.pageDocument.documentElement.dataset.viewXmlid; + if (this.websiteService.isDesigner && viewKey) { + switchableRelatedViews = this.rpc('/website/get_switchable_related_views', {key: viewKey}); + } + this.switchableRelatedViews = Promise.resolve(switchableRelatedViews); }); useEffect(() => { @@ -667,6 +674,18 @@ export class WysiwygAdapterComponent extends ComponentAdapter { _onMobilePreviewRequest() { this.websiteService.context.isMobile = !this.websiteService.context.isMobile; } + /** + * Called when a child needs to know about the views that can + * be toggled on or off on a specific view related to the editable. + * + * @param event + * @returns {Promise} + * @private + */ + async _onGetSwitchableRelatedViews(event) { + const views = await this.switchableRelatedViews; + event.data.onSuccess(views); + } } WysiwygAdapterComponent.prototype.events = { 'widgets_start_request': '_onRootEventRequest', @@ -684,4 +703,5 @@ WysiwygAdapterComponent.prototype.events = { 'menu_dialog': '_onMenuDialogRequest', 'update_color_previews': '_onColorPreviewsUpdate', 'request_mobile_preview': '_onMobilePreviewRequest', + 'get_switchable_related_views': '_onGetSwitchableRelatedViews', }; diff --git a/addons/website/static/src/js/editor/snippets.editor.js b/addons/website/static/src/js/editor/snippets.editor.js index 870390411f8..c2016be4277 100644 --- a/addons/website/static/src/js/editor/snippets.editor.js +++ b/addons/website/static/src/js/editor/snippets.editor.js @@ -54,43 +54,6 @@ const wSnippetMenu = weSnippetEditor.SnippetsMenu.extend({ this.$body[0].classList.remove('o_animated_text_highlighted'); }, - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - /** - * Adds the "customize_show" templates to the options page of the editor - * panel. - * - * @override - */ - async loadSnippets() { - const viewName = $(this.options.wysiwyg.odooEditor.document.documentElement).data('view-xmlid'); - const snippets = await this._super(...arguments); - if (!viewName) { - return snippets; - } - const $snippets = $(snippets); - return this._rpc({ - route: '/website/get_switchable_related_views', - params: { - key: viewName, - }, - }).then(function (result) { - _.each(result, view => { - $snippets.siblings('#snippet_options').append($(` -
- -
- `)); - }); - return $('
').append($snippets).html(); - }); - }, - //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- @@ -356,6 +319,40 @@ const wSnippetMenu = weSnippetEditor.SnippetsMenu.extend({ throw e; } }, + /** + * @override + */ + _onOptionsTabClick(ev) { + if (!ev.currentTarget.classList.contains('active')) { + this._activateSnippet(false); + this._mutex.exec(async () => { + const switchableViews = await new Promise((resolve, reject) => { + this.trigger_up('get_switchable_related_views', { + onSuccess: resolve, + onFailure: reject, + }); + }); + if (switchableViews.length) { + // These do not need to be awaited as we're in teh context + // of the mutex. + this._activateSnippet(this.$body.find('#wrapwrap > main')); + return; + } + let $pageOptionsTarget = $(); + let i = 0; + const pageOptions = this.templateOptions.filter(template => template.data.pageOptions); + while (!$pageOptionsTarget.length && i < pageOptions.length) { + $pageOptionsTarget = pageOptions[i].selector.all(); + i++; + } + if ($pageOptionsTarget.length) { + this._activateSnippet($pageOptionsTarget); + } else { + this._activateEmptyOptionsTab(); + } + }); + } + }, /** * @private */ diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index 1d4ed893b57..a761faf3486 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -3235,6 +3235,47 @@ options.registry.sizing.include({ } }); +options.registry.SwitchableViews = options.Class.extend({ + /** + * @override + */ + async willStart() { + const _super = this._super.bind(this); + this.switchableRelatedViews = await new Promise((resolve, reject) => { + this.trigger_up('get_switchable_related_views', { + onSuccess: resolve, + onFailure: reject, + }); + }); + return _super(...arguments); + }, + /** + * @override + */ + _renderCustomXML(uiFragment) { + for (const view of this.switchableRelatedViews) { + const weCheckboxEl = document.createElement('we-checkbox'); + weCheckboxEl.setAttribute('string', view.name); + weCheckboxEl.setAttribute('data-customize-website-views', view.key); + weCheckboxEl.setAttribute('data-no-preview', 'true'); + weCheckboxEl.setAttribute('data-reload', '/'); + uiFragment.appendChild(weCheckboxEl); + } + }, + /*** + * @override + */ + _computeVisibility() { + return !!this.switchableRelatedViews.length; + }, + /** + * @override + */ + _checkIfWidgetsUpdateNeedReload() { + return true; + } +}); + return { UrlPickerUserValueWidget: UrlPickerUserValueWidget, FontFamilyPickerUserValueWidget: FontFamilyPickerUserValueWidget, diff --git a/addons/website/static/src/services/website_service.js b/addons/website/static/src/services/website_service.js index 7b58cbcd242..1375de3370c 100644 --- a/addons/website/static/src/services/website_service.js +++ b/addons/website/static/src/services/website_service.js @@ -35,6 +35,7 @@ export const websiteService = { let websiteRootInstance; let Wysiwyg; let isPublisher; + let isDesigner; let hasMultiWebsites; const context = reactive({ showNewContentModal: false, @@ -125,6 +126,9 @@ export const websiteService = { get isPublisher() { return isPublisher === true; }, + get isDesigner() { + return isDesigner === true; + }, get hasMultiWebsites() { return hasMultiWebsites === true; }, @@ -146,8 +150,9 @@ export const websiteService = { }, async fetchWebsites() { // Fetch user groups, before fetching the websites. - [isPublisher, hasMultiWebsites] = await Promise.all([ + [isPublisher, isDesigner, hasMultiWebsites] = await Promise.all([ user.hasGroup('website.group_website_publisher'), + user.hasGroup('website.group_website_designer'), user.hasGroup('website.group_multi_website'), ]); diff --git a/addons/website/static/tests/tours/snippet_popup_add_remove.js b/addons/website/static/tests/tours/snippet_popup_add_remove.js index 7cc04aa6430..f8194f30e95 100644 --- a/addons/website/static/tests/tours/snippet_popup_add_remove.js +++ b/addons/website/static/tests/tours/snippet_popup_add_remove.js @@ -22,7 +22,7 @@ wTourUtils.registerEditionTour('snippet_popup_add_remove', { }, { content: `Remove the s_popup snippet`, in_modal: false, - trigger: '.o_we_customize_panel we-customizeblock-options we-button.oe_snippet_remove:first', + trigger: '.o_we_customize_panel we-customizeblock-options:contains("Popup") we-button.oe_snippet_remove:first', }, { content: 'Check the s_popup was removed', in_modal: false, diff --git a/addons/website/views/snippets/snippets.xml b/addons/website/views/snippets/snippets.xml index 7a6d8a80b73..4cdf7e52337 100644 --- a/addons/website/views/snippets/snippets.xml +++ b/addons/website/views/snippets/snippets.xml @@ -1463,5 +1463,8 @@ data-no-preview="true" data-reload="/"/>
+
+ +