[IMP] website, *: use widgets to display mega menu templates

*: web_editor

The masonry templates selection SnippetOption has been abstracted so
that mega menus content can also be replaced with template content.

Part of https://github.com/odoo/odoo/pull/71143
task-2502208

Part-of: odoo/odoo#71143
This commit is contained in:
Younn Olivier
2021-09-02 14:14:50 +00:00
committed by qsm-odoo
parent 63a3ba4a42
commit a57cda43c3
14 changed files with 171 additions and 124 deletions
@@ -6605,6 +6605,111 @@ registry.MultipleItems = SnippetOptionWidget.extend({
_removeItemCallback($target) {},
});
registry.SelectTemplate = SnippetOptionWidget.extend({
custom_events: Object.assign({}, SnippetOptionWidget.prototype.custom_events, {
'user_value_widget_opening': '_onWidgetOpening',
}),
/**
* @constructor
*/
init() {
this._super(...arguments);
this.containerSelector = '';
this.selectTemplateWidgetName = '';
},
/**
* @constructor
*/
async start() {
this.containerEl = this.containerSelector ? this.$target.find(this.containerSelector)[0] : this.$target[0];
this._templates = {};
return this._super(...arguments);
},
//--------------------------------------------------------------------------
// Options
//--------------------------------------------------------------------------
/**
* Changes the masonry snippet layout.
*
* @see this.selectClass for parameters
*/
async selectTemplate(previewMode, widgetValue, params) {
await this._templatesLoading;
if (previewMode === 'reset') {
if (!this.beforePreviewNodes) {
// FIXME should not be necessary: only needed because we have a
// strange 'reset' sent after a non-preview
return;
}
// Empty the container and restore the original content
while (this.containerEl.lastChild) {
this.containerEl.removeChild(this.containerEl.lastChild);
}
for (const node of this.beforePreviewNodes) {
this.containerEl.appendChild(node);
}
this.beforePreviewNodes = null;
return;
}
if (!this.beforePreviewNodes) {
// We are about the apply a template on non-previewed content,
// save that content's nodes.
this.beforePreviewNodes = [...this.containerEl.childNodes];
}
// Empty the container and add the template content
while (this.containerEl.lastChild) {
this.containerEl.removeChild(this.containerEl.lastChild);
}
this.containerEl.insertAdjacentHTML('beforeend', this._templates[widgetValue]);
if (!previewMode) {
// The original content to keep saved has to be retrieved just
// before the preview (if we save it now, we might miss other items
// added by other options or custo).
this.beforePreviewNodes = null;
}
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
* @param {OdooEvent} ev
*/
_onWidgetOpening(ev) {
if (this._templatesLoading || ev.target.getName() !== this.selectTemplateWidgetName) {
return;
}
const templateParams = ev.target.getMethodsParams('selectTemplate');
const proms = templateParams.possibleValues.map(async xmlid => {
if (!xmlid) {
return;
}
// TODO should be better and retrieve all rendering in one RPC (but
// those ~10 RPC are only done once per edit mode if the option is
// opened, so I guess this is acceptable).
this._templates[xmlid] = await this._rpc({
model: 'ir.ui.view',
method: 'render_public_asset',
args: [`${xmlid}`, {}],
kwargs: {
context: this.options.context,
},
});
});
this._templatesLoading = Promise.all(proms);
},
});
return {
SnippetOptionWidget: SnippetOptionWidget,
snippetOptionRegistry: registry,
@@ -3148,6 +3148,35 @@ options.registry.WebsiteAnimate = options.Class.extend({
},
});
/**
* Replaces current target with the specified template layout
*/
options.registry.MegaMenuLayout = options.registry.SelectTemplate.extend({
/**
* @override
*/
init() {
this._super(...arguments);
this.selectTemplateWidgetName = 'mega_menu_template_opt';
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @override
*/
_computeWidgetState: function (methodName, params) {
if (methodName === 'selectTemplate') {
const templateDefiningClass = this.containerEl.querySelector('section')
.classList.value.split(' ').filter(cl => cl.startsWith('s_mega_menu'))[0];
return `website.${templateDefiningClass}`;
}
return this._super(...arguments);
},
});
return {
UrlPickerUserValueWidget: UrlPickerUserValueWidget,
FontFamilyPickerUserValueWidget: FontFamilyPickerUserValueWidget,
@@ -2,98 +2,13 @@
import options from 'web_editor.snippets.options';
options.registry.MasonryLayout = options.Class.extend({
custom_events: Object.assign({}, options.Class.prototype.custom_events, {
'user_value_widget_opening': '_onWidgetOpening',
}),
options.registry.MasonryLayout = options.registry.SelectTemplate.extend({
/**
* @constructor
*/
async start() {
this.containerEl = this.$target.find('> .container, > .container-fluid, > .o_container_small')[0];
this._templates = {};
return this._super(...arguments);
},
//--------------------------------------------------------------------------
// Options
//--------------------------------------------------------------------------
/**
* Changes the masonry snippet layout.
*
* @see this.selectClass for parameters
*/
async selectMasonryTemplate(previewMode, widgetValue, params) {
await this._templatesLoading;
if (previewMode === 'reset') {
if (!this.beforePreviewNodes) {
// FIXME should not be necessary: only needed because we have a
// strange 'reset' sent after a non-preview
return;
}
// Empty the container and restore the original content
while (this.containerEl.lastChild) {
this.containerEl.removeChild(this.containerEl.lastChild);
}
for (const node of this.beforePreviewNodes) {
this.containerEl.appendChild(node);
}
this.beforePreviewNodes = null;
return;
}
if (!this.beforePreviewNodes) {
// We are about the apply a template on non-previewed content,
// save that content's nodes.
this.beforePreviewNodes = [...this.containerEl.childNodes];
}
// Empty the container and add the template content
while (this.containerEl.lastChild) {
this.containerEl.removeChild(this.containerEl.lastChild);
}
this.containerEl.insertAdjacentHTML('beforeend', this._templates[widgetValue]);
if (!previewMode) {
// The original content to keep saved has to be retrieved just
// before the preview (if we save it now, we might miss other items
// added by other options or custo).
this.beforePreviewNodes = null;
}
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
* @param {OdooEvent} ev
*/
_onWidgetOpening(ev) {
if (this._templatesLoading || ev.target.getName() !== 'masonry_template_opt') {
return;
}
const templateParams = ev.target.getMethodsParams('selectMasonryTemplate');
const proms = templateParams.possibleValues.map(async xmlid => {
if (!xmlid) {
return;
}
// TODO should be better and retrieve all rendering in one RPC (but
// those ~10 RPC are only done once per edit mode if masonry snippet
// option is opened, so I guess this is acceptable).
this._templates[xmlid] = await this._rpc({
model: 'ir.ui.view',
method: 'render_public_asset',
args: [`${xmlid}`, {}],
kwargs: {
context: this.options.context,
},
});
});
this._templatesLoading = Promise.all(proms);
init() {
this._super(...arguments);
this.containerSelector = '> .container, > .container-fluid, > .o_container_small';
this.selectTemplateWidgetName = 'masonry_template_opt';
},
});
@@ -258,43 +258,43 @@
data-attribute-name="masonryTemplate"
data-attribute-default-value="default">
<we-button title="Default"
data-select-masonry-template="website.s_masonry_block_default_template"
data-select-template="website.s_masonry_block_default_template"
data-select-data-attribute="default"
data-img="/website/static/src/img/snippets_options/masonry_template_default.svg"/>
<we-button title="Default Reversed"
data-select-masonry-template="website.s_masonry_block_reversed_template"
data-select-template="website.s_masonry_block_reversed_template"
data-select-data-attribute="default_reversed"
data-img="/website/static/src/img/snippets_options/masonry_template_reversed.svg"/>
<we-button title="Images"
data-select-masonry-template="website.s_masonry_block_images_template"
data-select-template="website.s_masonry_block_images_template"
data-select-data-attribute="images"
data-img="/website/static/src/img/snippets_options/masonry_template_images.svg"/>
<we-button title="Image Text Image"
data-select-masonry-template="website.s_masonry_block_image_texts_image_template"
data-select-template="website.s_masonry_block_image_texts_image_template"
data-select-data-attribute="image_text_image"
data-img="/website/static/src/img/snippets_options/masonry_template_image_texts_image.svg"/>
<we-button title="Mosaic"
data-select-masonry-template="website.s_masonry_block_mosaic_template"
data-select-template="website.s_masonry_block_mosaic_template"
data-select-data-attribute="mosaic"
data-img="/website/static/src/img/snippets_options/masonry_template_mosaic.svg"/>
<we-button title="Text Image Text"
data-select-masonry-template="website.s_masonry_block_texts_image_texts_template"
data-select-template="website.s_masonry_block_texts_image_texts_template"
data-select-data-attribute="text_image_text"
data-img="/website/static/src/img/snippets_options/masonry_template_texts_image_texts.svg"/>
<we-button title="Alternate Text"
data-select-masonry-template="website.s_masonry_block_alternation_text_template"
data-select-template="website.s_masonry_block_alternation_text_template"
data-select-data-attribute="alternate_text"
data-img="/website/static/src/img/snippets_options/masonry_template_alternate_texts.svg"/>
<we-button title="Alternate Text Image"
data-select-masonry-template="website.s_masonry_block_alternation_text_image_template"
data-select-template="website.s_masonry_block_alternation_text_image_template"
data-select-data-attribute="alternate_text_image"
data-img="/website/static/src/img/snippets_options/masonry_template_alternate_text_image.svg"/>
<we-button title="Alternate Image Text"
data-select-masonry-template="website.s_masonry_block_alternation_image_text_template"
data-select-template="website.s_masonry_block_alternation_image_text_template"
data-select-data-attribute="alternate_image_text"
data-img="/website/static/src/img/snippets_options/masonry_template_alternate_image_text.svg"/>
<we-button title="Alternate Text Image Text"
data-select-masonry-template="website.s_masonry_block_alternation_text_image_text_template"
data-select-template="website.s_masonry_block_alternation_text_image_text_template"
data-select-data-attribute="alternate_text_image_text"
data-img="/website/static/src/img/snippets_options/masonry_template_alternate_text_image_text.svg"/>
</we-select>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_big_icons_subtitles" name="Menu - Big icons &amp; subtitles">
<template id="s_mega_menu_big_icons_subtitles" name="Menu - Big icons &amp; subtitles" groups="base.group_user">
<section class="s_mega_menu_big_icons_subtitles pt24 pb24" data-oe-shape-data="{'shape':'web_editor/Zigs/03','flip':[]}">
<div class="o_we_shape o_web_editor_Zigs_03"/>
<div class="container" >
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_cards" name="Menu - Cards">
<template id="s_mega_menu_cards" name="Menu - Cards" groups="base.group_user">
<section class="s_mega_menu_cards pt16 pb16">
<div class="container">
<nav class="row">
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_images_subtitles" name="Menu - images &amp; subtitles">
<template id="s_mega_menu_images_subtitles" name="Menu - images &amp; subtitles" groups="base.group_user">
<section class="s_mega_menu_images_subtitles pt16 pb16">
<div class="container">
<div class="row">
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_little_icons" name="Menu - Little icons">
<template id="s_mega_menu_little_icons" name="Menu - Little icons" groups="base.group_user">
<section class="s_mega_menu_little_icons overflow-hidden">
<div class="container">
<div class="row">
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_menu_image_menu" name="Menu - Image - Menu">
<template id="s_mega_menu_menu_image_menu" name="Menu - Image - Menu" groups="base.group_user">
<section class="s_mega_menu_menu_image_menu py-4">
<div class="container">
<div class="row align-items-center">
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_menus_logos" name="Menus &amp; logos">
<template id="s_mega_menu_menus_logos" name="Menus &amp; logos" groups="base.group_user">
<section class="s_mega_menu_menus_logos overflow-hidden">
<div class="container">
<div class="row">
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_multi_menus" name="Multi-Menus">
<template id="s_mega_menu_multi_menus" name="Multi-Menus" groups="base.group_user">
<section class="s_mega_menu_multi_menus py-4">
<div class="container">
<div class="row">
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_odoo_menu" name="Odoo Menu">
<template id="s_mega_menu_odoo_menu" name="Odoo Menu" groups="base.group_user">
<section class="s_mega_menu_odoo_menu pt16">
<div class="container">
<div class="row">
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_mega_menu_thumbnails" name="Menu - Thumbnails">
<template id="s_mega_menu_thumbnails" name="Menu - Thumbnails" groups="base.group_user">
<section class="s_mega_menu_thumbnails pt24">
<div class="container">
<div class="row justify-content-center">
+13 -15
View File
@@ -13,20 +13,6 @@
<t id="default_snippets">
<t t-set="cta_btn_text" t-value="False"/>
<t t-set="cta_btn_href">/contactus</t>
<div id="snippet_mega_menu" class="o_panel d-none">
<div class="o_panel_header">Mega Menu</div>
<div class="o_panel_body">
<t t-snippet="website.s_mega_menu_multi_menus" t-thumbnail="/website/static/src/img/snippets_thumbs/s_mega_menu_multi_menus.svg"/>
<t t-snippet="website.s_mega_menu_menu_image_menu" t-thumbnail="/website/static/src/img/snippets_thumbs/s_mega_menu_menu_image_menu.svg"/>
<t t-snippet="website.s_mega_menu_odoo_menu" t-thumbnail="/website/static/src/img/snippets_thumbs/s_mega_menu_odoo_menu.svg"/>
<t t-snippet="website.s_mega_menu_little_icons" t-thumbnail="/website/static/src/img/snippets_thumbs/s_mega_menu_little_icons.svg"/>
<t t-snippet="website.s_mega_menu_big_icons_subtitles" t-thumbnail="/website/static/src/img/snippets_thumbs/s_mega_menu_big_icons_subtitles.svg"/>
<t t-snippet="website.s_mega_menu_images_subtitles" t-thumbnail="/website/static/src/img/snippets_thumbs/s_mega_menu_images_subtitles.svg"/>
<t t-snippet="website.s_mega_menu_menus_logos" t-thumbnail="/website/static/src/img/snippets_thumbs/s_mega_menu_menus_logos.svg"/>
<t t-snippet="website.s_mega_menu_thumbnails" t-thumbnail="/website/static/src/img/snippets_thumbs/s_mega_menu_thumbnails.svg"/>
<t t-snippet="website.s_mega_menu_cards" t-thumbnail="/website/static/src/img/snippets_thumbs/s_mega_menu_cards.svg"/>
</div>
</div>
<div id="snippet_structure" class="o_panel">
<div class="o_panel_header">Structure</div>
@@ -1000,7 +986,19 @@
</div>
<!-- Mega Menu settings -->
<div data-selector=".o_mega_menu">
<div data-js="MegaMenuLayout" data-selector=".o_mega_menu">
<we-select string="Template"
data-name="mega_menu_template_opt">
<we-button data-select-label="Multi Menus" title="Multi Menus" data-select-template="website.s_mega_menu_multi_menus" data-img="/website/static/src/img/snippets_thumbs/s_mega_menu_multi_menus.svg">Multi Menus</we-button>
<we-button data-select-label="Image Menu" title="Image Menu" data-select-template="website.s_mega_menu_menu_image_menu" data-img="/website/static/src/img/snippets_thumbs/s_mega_menu_menu_image_menu.svg">Image Menu</we-button>
<we-button data-select-label="Odoo Menu" title="Odoo Menu" data-select-template="website.s_mega_menu_odoo_menu" data-img="/website/static/src/img/snippets_thumbs/s_mega_menu_odoo_menu.svg">Odoo Menu</we-button>
<we-button data-select-label="Little Icons" title="Little Icons" data-select-template="website.s_mega_menu_little_icons" data-img="/website/static/src/img/snippets_thumbs/s_mega_menu_little_icons.svg">Little Icons</we-button>
<we-button data-select-label="Big Icons Subtitles" title="Big Icons Subtitles" data-select-template="website.s_mega_menu_big_icons_subtitles" data-img="/website/static/src/img/snippets_thumbs/s_mega_menu_big_icons_subtitles.svg">Big Icons Subtitles</we-button>
<we-button data-select-label="Images Subtitles" title="Images Subtitles" data-select-template="website.s_mega_menu_images_subtitles" data-img="/website/static/src/img/snippets_thumbs/s_mega_menu_images_subtitles.svg">Images Subtitles</we-button>
<we-button data-select-label="Logos" title="Logos" data-select-template="website.s_mega_menu_menus_logos" data-img="/website/static/src/img/snippets_thumbs/s_mega_menu_menus_logos.svg">Logos</we-button>
<we-button data-select-label="Thumbnails" title="Thumbnails" data-select-template="website.s_mega_menu_thumbnails" data-img="/website/static/src/img/snippets_thumbs/s_mega_menu_thumbnails.svg">Thumbnails</we-button>
<we-button data-select-label="Cards" title="Cards" data-select-template="website.s_mega_menu_cards" data-img="/website/static/src/img/snippets_thumbs/s_mega_menu_cards.svg">Cards</we-button>
</we-select>
<we-select string="Size">
<we-button data-select-class="">Full-Width</we-button>
<we-button data-select-class="o_mega_menu_container_size">Narrow</we-button>