[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:
@@ -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 & subtitles">
|
||||
<template id="s_mega_menu_big_icons_subtitles" name="Menu - Big icons & 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 & subtitles">
|
||||
<template id="s_mega_menu_images_subtitles" name="Menu - images & 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 & logos">
|
||||
<template id="s_mega_menu_menus_logos" name="Menus & 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,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>
|
||||
|
||||
Reference in New Issue
Block a user