[IMP] web_editor, *: add snippets search filter
*: website Add a search bar at the top of the "Blocks" tab to filter snippets. Part of https://github.com/odoo/odoo/pull/55272 task-2309832 closes odoo/odoo#55272 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com> Co-authored-by: qsm-odoo <qsm@odoo.com>
This commit is contained in:
committed by
qsm-odoo
co-authored by
qsm-odoo
parent
8a48e99e19
commit
41527531b7
@@ -68,10 +68,11 @@ class QWeb(models.AbstractModel):
|
||||
view_id = View.get_view_id(key)
|
||||
name = View.browse(view_id).name
|
||||
thumbnail = el.attrib.pop('t-thumbnail', "oe-thumbnail")
|
||||
div = u'<div name="%s" data-oe-type="snippet" data-oe-thumbnail="%s" data-oe-snippet-id="%s">' % (
|
||||
div = u'<div name="%s" data-oe-type="snippet" data-oe-thumbnail="%s" data-oe-snippet-id="%s" data-oe-keywords="%s">' % (
|
||||
escape(pycompat.to_text(name)),
|
||||
escape(pycompat.to_text(thumbnail)),
|
||||
escape(pycompat.to_text(view_id)),
|
||||
escape(pycompat.to_text(el.findtext('keywords')))
|
||||
)
|
||||
return [self._append(ast.Str(div))] + self._compile_node(el, options) + [self._append(ast.Str(u'</div>'))]
|
||||
|
||||
|
||||
@@ -809,6 +809,8 @@ var SnippetsMenu = Widget.extend({
|
||||
'click .o_we_invisible_entry': '_onInvisibleEntryClick',
|
||||
'click #snippet_custom .o_delete_btn': '_onDeleteBtnClick',
|
||||
'mousedown': '_onMouseDown',
|
||||
'input .o_snippet_search_filter_input': '_onSnippetSearchInput',
|
||||
'click .o_snippet_search_filter_reset': '_onSnippetSearchResetClick',
|
||||
},
|
||||
custom_events: {
|
||||
'activate_insertion_zones': '_onActivateInsertionZones',
|
||||
@@ -1728,6 +1730,37 @@ var SnippetsMenu = Widget.extend({
|
||||
$snippet.toggleClass('o_disabled', !check);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {string} [search]
|
||||
*/
|
||||
_filterSnippets(search) {
|
||||
const searchInputEl = this.el.querySelector('.o_snippet_search_filter_input');
|
||||
const searchInputReset = this.el.querySelector('.o_snippet_search_filter_reset');
|
||||
if (search !== undefined) {
|
||||
searchInputEl.value = search;
|
||||
} else {
|
||||
search = searchInputEl.value;
|
||||
}
|
||||
search = search.toLowerCase();
|
||||
searchInputReset.classList.toggle('d-none', !search);
|
||||
const strMatches = str => !search || str.toLowerCase().includes(search);
|
||||
for (const panelEl of this.el.querySelectorAll('.o_panel')) {
|
||||
let hasVisibleSnippet = false;
|
||||
const panelTitle = panelEl.querySelector('.o_panel_header').textContent;
|
||||
const isPanelTitleMatch = strMatches(panelTitle);
|
||||
for (const snippetEl of panelEl.querySelectorAll('.oe_snippet')) {
|
||||
const matches = (isPanelTitleMatch
|
||||
|| strMatches(snippetEl.getAttribute('name'))
|
||||
|| strMatches(snippetEl.dataset.oeKeywords || ''));
|
||||
if (matches) {
|
||||
hasVisibleSnippet = true;
|
||||
}
|
||||
snippetEl.classList.toggle('d-none', !matches);
|
||||
}
|
||||
panelEl.classList.toggle('d-none', !hasVisibleSnippet);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {Object} [options={}]
|
||||
@@ -1928,6 +1961,7 @@ var SnippetsMenu = Widget.extend({
|
||||
$(this.customizePanel).append(content);
|
||||
}
|
||||
|
||||
this.$('.o_snippet_search_filter').toggleClass('d-none', tab !== this.tabs.BLOCKS);
|
||||
this.$('#o_scroll').toggleClass('d-none', tab !== this.tabs.BLOCKS);
|
||||
this.customizePanel.classList.toggle('d-none', tab === this.tabs.BLOCKS);
|
||||
|
||||
@@ -2298,6 +2332,22 @@ var SnippetsMenu = Widget.extend({
|
||||
_onUserValueWidgetClosing: function () {
|
||||
this.el.classList.remove('o_we_backdrop');
|
||||
},
|
||||
/**
|
||||
* Called when search input value changed -> adapts the snippets grid.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onSnippetSearchInput: function () {
|
||||
this._filterSnippets();
|
||||
},
|
||||
/**
|
||||
* Called on snippet search filter reset -> clear input field search.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onSnippetSearchResetClick: function () {
|
||||
this._filterSnippets('');
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -197,6 +197,38 @@ body.editor_enable.editor_has_snippets {
|
||||
}
|
||||
}
|
||||
|
||||
// Snippet filter input
|
||||
.o_snippet_search_filter {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: $o-we-sidebar-blocks-content-spacing;
|
||||
|
||||
.o_snippet_search_filter_input {
|
||||
width: 100%;
|
||||
padding: $o-we-sidebar-content-field-clickable-spacing;
|
||||
padding-right: 2em;
|
||||
border: $o-we-sidebar-content-field-border-width solid $o-we-sidebar-content-field-border-color;
|
||||
background-color: $o-we-sidebar-content-field-input-bg;
|
||||
color: inherit;
|
||||
|
||||
&::placeholder {
|
||||
color: $o-we-sidebar-content-field-control-item-color;
|
||||
}
|
||||
&:focus {
|
||||
border-color: $o-we-sidebar-content-field-input-border-color;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
.o_snippet_search_filter_reset {
|
||||
@include o-position-absolute($o-we-sidebar-blocks-content-spacing, $o-we-sidebar-blocks-content-spacing, $o-we-sidebar-blocks-content-spacing);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0 $o-we-sidebar-content-field-clickable-spacing;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
> #o_scroll, > .o_we_customize_panel {
|
||||
flex: 1 1 auto;
|
||||
height: 100%;
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="o_snippet_search_filter">
|
||||
<input type="text" class="o_snippet_search_filter_input" placeholder="Search..."/>
|
||||
<i role="button" class="fa fa-times o_snippet_search_filter_reset d-none"/>
|
||||
</div>
|
||||
|
||||
<div id="o_scroll">
|
||||
<div id="snippet_custom" class="o_panel d-none">
|
||||
<div class="o_panel_header">Custom</div>
|
||||
|
||||
@@ -244,13 +244,23 @@ snippetsEditor.Class.include({
|
||||
*/
|
||||
toggleMegaMenuSnippets: function (show) {
|
||||
setTimeout(() => this._activateSnippet(false));
|
||||
this.$('#snippet_mega_menu').toggleClass('d-none', !show);
|
||||
this._showMegaMenuSnippets = show;
|
||||
this._filterSnippets();
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_filterSnippets(search) {
|
||||
this._super(...arguments);
|
||||
if (!this._showMegaMenuSnippets) {
|
||||
this.el.querySelector('#snippet_mega_menu').classList.add('d-none');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
|
||||
@@ -23,21 +23,49 @@
|
||||
<div id="snippet_structure" class="o_panel">
|
||||
<div class="o_panel_header">Structure</div>
|
||||
<div class="o_panel_body">
|
||||
<t t-snippet="website.s_banner" t-thumbnail="/website/static/src/img/snippets_thumbs/s_banner.svg"/>
|
||||
<t t-snippet="website.s_cover" t-thumbnail="/website/static/src/img/snippets_thumbs/s_cover.svg"/>
|
||||
<t t-snippet="website.s_text_image" t-thumbnail="/website/static/src/img/snippets_thumbs/s_text_image.svg"/>
|
||||
<t t-snippet="website.s_image_text" t-thumbnail="/website/static/src/img/snippets_thumbs/s_image_text.svg"/>
|
||||
<t t-snippet="website.s_title" t-thumbnail="/website/static/src/img/snippets_thumbs/s_title.svg"/>
|
||||
<t t-snippet="website.s_text_block" t-thumbnail="/website/static/src/img/snippets_thumbs/s_text_block.svg"/>
|
||||
<t t-snippet="website.s_numbers" t-thumbnail="/website/static/src/img/snippets_thumbs/s_numbers.svg"/>
|
||||
<t t-snippet="website.s_picture" t-thumbnail="/website/static/src/img/snippets_thumbs/s_picture.svg"/>
|
||||
<t t-snippet="website.s_three_columns" t-thumbnail="/website/static/src/img/snippets_thumbs/s_three_columns.svg"/>
|
||||
<t t-snippet="website.s_color_blocks_2" t-thumbnail="/website/static/src/img/snippets_thumbs/s_color_blocks_2.svg"/>
|
||||
<t t-snippet="website.s_features" t-thumbnail="/website/static/src/img/snippets_thumbs/s_features.svg"/>
|
||||
<t t-snippet="website.s_masonry_block" t-thumbnail="/website/static/src/img/snippets_thumbs/s_masonry_block.svg"/>
|
||||
<t t-snippet="website.s_image_gallery" t-thumbnail="/website/static/src/img/snippets_thumbs/s_image_gallery.svg"/>
|
||||
<t t-snippet="website.s_banner" t-thumbnail="/website/static/src/img/snippets_thumbs/s_banner.svg">
|
||||
<keywords>hero, jumbotron</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_cover" t-thumbnail="/website/static/src/img/snippets_thumbs/s_cover.svg">
|
||||
<keywords>hero, jumbotron</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_text_image" t-thumbnail="/website/static/src/img/snippets_thumbs/s_text_image.svg">
|
||||
<keywords>content</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_image_text" t-thumbnail="/website/static/src/img/snippets_thumbs/s_image_text.svg">
|
||||
<keywords>content</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_title" t-thumbnail="/website/static/src/img/snippets_thumbs/s_title.svg">
|
||||
<keywords>heading, h1</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_text_block" t-thumbnail="/website/static/src/img/snippets_thumbs/s_text_block.svg">
|
||||
<keywords>content</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_numbers" t-thumbnail="/website/static/src/img/snippets_thumbs/s_numbers.svg">
|
||||
<keywords>statistics, stats, KPI</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_picture" t-thumbnail="/website/static/src/img/snippets_thumbs/s_picture.svg">
|
||||
<keywords>image, media, illustration</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_three_columns" t-thumbnail="/website/static/src/img/snippets_thumbs/s_three_columns.svg">
|
||||
<keywords>columns, description</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_color_blocks_2" t-thumbnail="/website/static/src/img/snippets_thumbs/s_color_blocks_2.svg">
|
||||
<keywords>big</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_features" t-thumbnail="/website/static/src/img/snippets_thumbs/s_features.svg">
|
||||
<keywords>promotion, characteristic, quality</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_masonry_block" t-thumbnail="/website/static/src/img/snippets_thumbs/s_masonry_block.svg">
|
||||
<keywords>masonry, grid</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_image_gallery" t-thumbnail="/website/static/src/img/snippets_thumbs/s_image_gallery.svg">
|
||||
<keywords>gallery, carousel</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_images_wall" t-thumbnail="/website/static/src/img/snippets_thumbs/s_images_wall.svg"/>
|
||||
<t t-snippet="website.s_carousel" t-thumbnail="/website/static/src/img/snippets_thumbs/s_carousel.svg"/>
|
||||
<t t-snippet="website.s_carousel" t-thumbnail="/website/static/src/img/snippets_thumbs/s_carousel.svg">
|
||||
<keywords>gallery, carousel</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_media_list" t-thumbnail="/website/static/src/img/snippets_thumbs/s_media_list.svg"/>
|
||||
<t t-snippet="website.s_showcase" t-thumbnail="/website/static/src/img/snippets_thumbs/s_showcase.svg"/>
|
||||
<t t-snippet="website.s_parallax" t-thumbnail="/website/static/src/img/snippets_thumbs/s_parallax.svg"/>
|
||||
@@ -47,19 +75,33 @@
|
||||
<div id="snippet_feature" class="o_panel">
|
||||
<div class="o_panel_header">Features</div>
|
||||
<div class="o_panel_body">
|
||||
<t t-snippet="website.s_comparisons" t-thumbnail="/website/static/src/img/snippets_thumbs/s_comparisons.svg"/>
|
||||
<t t-snippet="website.s_company_team" t-thumbnail="/website/static/src/img/snippets_thumbs/s_company_team.svg"/>
|
||||
<t t-snippet="website.s_call_to_action" t-thumbnail="/website/static/src/img/snippets_thumbs/s_call_to_action.svg"/>
|
||||
<t t-snippet="website.s_references" t-thumbnail="/website/static/src/img/snippets_thumbs/s_references.svg"/>
|
||||
<t t-snippet="website.s_faq_collapse" t-thumbnail="/website/static/src/img/snippets_thumbs/s_faq_collapse.svg"/>
|
||||
<t t-snippet="website.s_comparisons" t-thumbnail="/website/static/src/img/snippets_thumbs/s_comparisons.svg">
|
||||
<keywords>pricing</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_company_team" t-thumbnail="/website/static/src/img/snippets_thumbs/s_company_team.svg">
|
||||
<keywords>organization, structure</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_call_to_action" t-thumbnail="/website/static/src/img/snippets_thumbs/s_call_to_action.svg">
|
||||
<keywords>CTA</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_references" t-thumbnail="/website/static/src/img/snippets_thumbs/s_references.svg">
|
||||
<keywords>customers, clients</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_faq_collapse" t-thumbnail="/website/static/src/img/snippets_thumbs/s_faq_collapse.svg">
|
||||
<keywords>common answers, common questions</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_features_grid" t-thumbnail="/website/static/src/img/snippets_thumbs/s_features_grid.svg"/>
|
||||
<t t-snippet="website.s_table_of_content" t-thumbnail="/website/static/src/img/snippets_thumbs/s_table_of_content.svg"/>
|
||||
<t t-snippet="website.s_product_catalog" t-thumbnail="/website/static/src/img/snippets_thumbs/s_product_catalog.svg"/>
|
||||
<t t-snippet="website.s_product_catalog" t-thumbnail="/website/static/src/img/snippets_thumbs/s_product_catalog.svg">
|
||||
<keywords>menu, pricing</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_product_list" t-thumbnail="/website/static/src/img/snippets_thumbs/s_product_list.svg"/>
|
||||
<t t-snippet="website.s_tabs" t-thumbnail="/website/static/src/img/snippets_thumbs/s_tabs.svg"/>
|
||||
<t t-snippet="website.s_timeline" t-thumbnail="/website/static/src/img/snippets_thumbs/s_timeline.svg"/>
|
||||
<t t-snippet="website.s_process_steps" t-thumbnail="/website/static/src/img/snippets_thumbs/s_process_steps.svg"/>
|
||||
<t t-snippet="website.s_quotes_carousel" t-thumbnail="/website/static/src/img/snippets_thumbs/s_quotes_carousel.svg"/>
|
||||
<t t-snippet="website.s_quotes_carousel" t-thumbnail="/website/static/src/img/snippets_thumbs/s_quotes_carousel.svg">
|
||||
<keywords>testimonials</keywords>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -77,7 +119,9 @@
|
||||
<t id="mass_mailing_newsletter_popup_hook"/>
|
||||
<t t-snippet="website.s_popup" t-thumbnail="/website/static/src/img/snippets_thumbs/s_popup.svg"/>
|
||||
<t t-snippet="website.s_facebook_page" t-thumbnail="/website/static/src/img/snippets_thumbs/s_facebook_page.svg"/>
|
||||
<t t-snippet="website.s_countdown" t-thumbnail="/website/static/src/img/snippets_thumbs/s_countdown.svg"/>
|
||||
<t t-snippet="website.s_countdown" t-thumbnail="/website/static/src/img/snippets_thumbs/s_countdown.svg">
|
||||
<keywords>celebration, launch</keywords>
|
||||
</t>
|
||||
<t id="mail_channel_discussion_group_hook"/>
|
||||
<t id="twitter_favorite_tweets_hook"/>
|
||||
</div>
|
||||
@@ -86,18 +130,28 @@
|
||||
<div id="snippet_content" class="o_panel">
|
||||
<div class="o_panel_header">Inner content</div>
|
||||
<div class="o_panel_body">
|
||||
<t t-snippet="website.s_hr" t-thumbnail="/website/static/src/img/snippets_thumbs/s_hr.svg"/>
|
||||
<t t-snippet="website.s_hr" t-thumbnail="/website/static/src/img/snippets_thumbs/s_hr.svg">
|
||||
<keywords>separator, divider</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_alert" t-thumbnail="/website/static/src/img/snippets_thumbs/s_alert.svg"/>
|
||||
<t t-snippet="website.s_rating" t-thumbnail="/website/static/src/img/snippets_thumbs/s_rating.svg"/>
|
||||
<t t-snippet="website.s_rating" t-thumbnail="/website/static/src/img/snippets_thumbs/s_rating.svg">
|
||||
<keywords>valuation, rank</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_card" t-thumbnail="/website/static/src/img/snippets_thumbs/s_card.svg"/>
|
||||
<t t-snippet="website.s_share" t-thumbnail="/website/static/src/img/snippets_thumbs/s_share.svg"/>
|
||||
<t id="sale_product_search_input_hook"/>
|
||||
<t id="mass_mailing_newsletter_hook"/>
|
||||
<t t-snippet="website.s_text_highlight" t-thumbnail="/website/static/src/img/snippets_thumbs/s_text_highlight.svg"/>
|
||||
<t t-snippet="website.s_chart" t-thumbnail="/website/static/src/img/snippets_thumbs/s_chart.svg"/>
|
||||
<t t-snippet="website.s_progress_bar" t-thumbnail="/website/static/src/img/snippets_thumbs/s_progress_bar.svg"/>
|
||||
<t t-snippet="website.s_chart" t-thumbnail="/website/static/src/img/snippets_thumbs/s_chart.svg">
|
||||
<keywords>chart, table, diagram, pie</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_progress_bar" t-thumbnail="/website/static/src/img/snippets_thumbs/s_progress_bar.svg">
|
||||
<keywords>evolution, growth</keywords>
|
||||
</t>
|
||||
<t t-snippet="website.s_badge" t-thumbnail="/website/static/src/img/snippets_thumbs/s_badge.svg"/>
|
||||
<t t-snippet="website.s_blockquote" t-thumbnail="/website/static/src/img/snippets_thumbs/s_blockquote.svg"/>
|
||||
<t t-snippet="website.s_blockquote" t-thumbnail="/website/static/src/img/snippets_thumbs/s_blockquote.svg">
|
||||
<keywords>cite</keywords>
|
||||
</t>
|
||||
<t id="event_speaker_bio_hook"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user