[14.0][MIG] web_edit_user_filter: Migration to 14.0

pull/2017/head
Roberto Fichera 2021-09-05 12:51:18 +02:00
parent c97e91ebd8
commit b38dda69c3
10 changed files with 401 additions and 252 deletions

View File

@ -14,13 +14,13 @@ Edit User Filters
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github
:target: https://github.com/OCA/web/tree/12.0/web_edit_user_filter
:target: https://github.com/OCA/web/tree/14.0/web_edit_user_filter
:alt: OCA/web
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/web-12-0/web-12-0-web_edit_user_filter
:target: https://translation.odoo-community.org/projects/web-14-0/web-14-0-web_edit_user_filter
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/162/12.0
:target: https://runbot.odoo-community.org/runbot/162/14.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@ -43,8 +43,12 @@ Edit a favourite filter:
#. Go to a list or kanban view;
#. open the advanced search options;
#. open the 'Favorites' menu;
#. Select a filter and click on the star icon of the filter name
#. click on the pencil icon to start editing the filter.
.. image:: https://raw.githubusercontent.com/web_edit_user_filter/static/description/select_facet.png
:alt: Select Facet
Edit a facet:
#. Click on the facet;
@ -66,7 +70,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_edit_user_filter%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_edit_user_filter%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
@ -76,12 +80,13 @@ Credits
Authors
~~~~~~~
* Onestein
*
Contributors
~~~~~~~~~~~~
* Dennis Sluijk <d.sluijk@onestein.nl>
* Roberto Fichera <roberto.fichera@levelprime.com>
Maintainers
~~~~~~~~~~~
@ -96,6 +101,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/web <https://github.com/OCA/web/tree/12.0/web_edit_user_filter>`_ project on GitHub.
This module is part of the `OCA/web <https://github.com/OCA/web/tree/14.0/web_edit_user_filter>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -4,13 +4,13 @@
{
"name": "Edit User Filters",
"category": "Extra Tools",
"version": "12.0.1.0.2",
"development_status": "Production/Stable",
"author": "Onestein,Odoo Community Association (OCA)",
"license": "AGPL-3",
"version": "14.0.1.0.0",
"author": "Onestein,Level Prime Srl,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/web",
"development_status": "Production/Stable",
"license": "AGPL-3",
"depends": ["web"],
"data": ["templates/assets.xml"],
"qweb": ["static/src/xml/backend.xml"],
"qweb": ["static/src/xml/backend.xml", "static/src/xml/search_extended.xml"],
"installable": True,
}

View File

@ -1 +1,2 @@
* Dennis Sluijk <d.sluijk@onestein.nl>
* Roberto Fichera <roberto.fichera@levelprime.com>

View File

@ -3,8 +3,12 @@ Edit a favourite filter:
#. Go to a list or kanban view;
#. open the advanced search options;
#. open the 'Favorites' menu;
#. Select a filter and click on the star icon of the filter name
#. click on the pencil icon to start editing the filter.
.. image:: /web_edit_user_filter/static/description/select_facet.png
:alt: Select Facet
Edit a facet:
#. Click on the facet;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
<title>Edit User Filters</title>
<style type="text/css">
@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/web/tree/12.0/web_edit_user_filter"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/web-12-0/web-12-0-web_edit_user_filter"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/162/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/web/tree/14.0/web_edit_user_filter"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/web-14-0/web-14-0-web_edit_user_filter"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/162/14.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>In standard Odoo you can edit user filters via the debug module.
The problem is that normal users often dont have access to this menu therefore cant adjust filters once theyre saved.
This module makes this feature available for normal users with a user friendly interface.
@ -393,8 +393,10 @@ It also adds the ability to adjust facets (a single part of the filter).</p>
<li>Go to a list or kanban view;</li>
<li>open the advanced search options;</li>
<li>open the Favorites menu;</li>
<li>Select a filter and click on the star icon of the filter name</li>
<li>click on the pencil icon to start editing the filter.</li>
</ol>
<img alt="Select Facet" src="https://raw.githubusercontent.com/web_edit_user_filter/static/description/select_facet.png" />
<p>Edit a facet:</p>
<ol class="arabic simple">
<li>Click on the facet;</li>
@ -415,7 +417,7 @@ It also adds the ability to adjust facets (a single part of the filter).</p>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_edit_user_filter%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_edit_user_filter%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
@ -423,13 +425,14 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id5">Authors</a></h2>
<ul class="simple">
<li>Onestein</li>
<li></li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id6">Contributors</a></h2>
<ul class="simple">
<li>Dennis Sluijk &lt;<a class="reference external" href="mailto:d.sluijk&#64;onestein.nl">d.sluijk&#64;onestein.nl</a>&gt;</li>
<li>Roberto Fichera &lt;<a class="reference external" href="mailto:roberto.fichera&#64;levelprime.com">roberto.fichera&#64;levelprime.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
@ -439,7 +442,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/web/tree/12.0/web_edit_user_filter">OCA/web</a> project on GitHub.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/web/tree/14.0/web_edit_user_filter">OCA/web</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,264 +1,331 @@
/* Copyright 2019 Onestein
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
/*
* Copyright 2019 Onestein
* Copyright 2021 Level Prime Srl - Roberto Fichera <roberto.fichera@levelprime.com>
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
*/
odoo.define("web_edit_user_filter", function (require) {
odoo.define("web_edit_user_filter/static/src/js/backend.js", function (require) {
"use strict";
var FavoriteMenu = require("web.FavoriteMenu"),
core = require("web.core"),
SearchView = require("web.SearchView");
var core = require("web.core");
var qweb = core.qweb;
var _t = core._t;
FavoriteMenu.include({
/**
* Adds the facets data to the filter.
*
* @override
* @private
*/
_createFilter: function (filter) {
var facets = [];
this.query.each(function (facet) {
var json_facet = facet.attributes;
json_facet.values = facet.get("values");
_.each(json_facet.values, function (value, i) {
if (
typeof value.value === "object" &&
value.value !== null &&
"attrs" in value.value
) {
json_facet.values[i] = {
attrs: value.value.attrs,
const {patch} = require("web.utils");
const components = {
SearchBar: require("web.SearchBar"),
CustomFavoriteItem: require("web.CustomFavoriteItem"),
ControlPanelModelExtension: require("web/static/src/js/control_panel/control_panel_model_extension.js"),
};
patch(
components.ControlPanelModelExtension,
"web_edit_user_filter/static/src/js/backend.js",
{
_favoriteToIrFilter(favorite) {
var irFilter = this._super(...arguments);
if ("facet" in favorite) {
irFilter.facet = favorite.facet;
}
});
if ("field" in json_facet) {
json_facet.field = {
attrs: json_facet.field.attrs,
};
}
facets.push(json_facet);
});
filter.facet = JSON.stringify(facets);
return this._super(filter);
return irFilter;
},
/**
* Adds the edit button to the favourite filter menu item.
*
* @override
* Returns a filter of type 'favorite' starting from an ir_filter comming from db.
* @private
* @param {Object} irFilter
* @returns {Object}
*/
append_filter: function (filter) {
var self = this;
var res = this._super(filter);
var key = this.key_for(filter);
this.$filters[key].append(
$("<span>", {
class: "fa fa-pencil o-edit-user-filter",
on: {
click: function (event) {
event.stopImmediatePropagation();
self._unpackFilter(filter);
_irFilterToFavorite(irFilter) {
var favorite = this._super(...arguments);
if (irFilter.facet) {
favorite.facet = irFilter.facet;
}
return favorite;
},
},
})
}
);
return res;
},
patch(
components.CustomFavoriteItem,
"web_edit_user_filter/static/src/js/backend.js",
{
// ---------------------------------------------------------------------
// Private
// ---------------------------------------------------------------------
/**
* Unpacks a saved filter and updates the search view's facets.
*
* @private
*/
_unpackFilter: function (filter) {
_saveFavorite() {
if (!this.state.description.length) {
this.env.services.notification.notify({
message: this.env._t(
"A name for your favorite filter is required."
),
type: "danger",
});
return this.descriptionRef.el.focus();
}
const favorites = this.model.get(
"filters",
(f) => f.type === "favorite"
);
if (favorites.some((f) => f.description === this.state.description)) {
this.env.services.notification.notify({
message: this.env._t("Filter with same name already exists."),
type: "danger",
});
return this.descriptionRef.el.focus();
}
var facets = this.model.get("facets");
this.model.dispatch("createNewFavorite", {
type: "favorite",
description: this.state.description,
isDefault: this.state.isDefault,
isShared: this.state.isShared,
facet: JSON.stringify(facets),
});
// Reset state
Object.assign(this.state, {
description: this.env.action.name || "",
isDefault: false,
isShared: false,
open: false,
});
},
}
);
patch(components.SearchBar, "web_edit_user_filter/static/src/js/backend.js", {
mounted() {
var self = this;
var facets = JSON.parse(filter.facet);
this._super(...arguments);
$(".o_searchview").on("click", ".o_searchview_facet", function () {
$(this).popover("dispose");
if ($(this).hasClass("o_facet_remove")) {
return;
}
var facet_type = $(this).attr("data-type");
var facetId = $(this).attr("data-gp");
self._process_filters($(this), facet_type, facetId);
});
var new_facets = [];
this.query.reset([]);
return this;
},
_.each(facets, function (segment) {
if (segment.cat === "groupByCategory") {
_.each(segment.values, function (value) {
var groupBy = _.find(self.searchview.groupbysMapping, function (
mapping
) {
_process_filters($el, facet_type, facetId) {
var self = this;
var selectedFacet = self.model.get("filters").filter(function (facet) {
return (
mapping.groupby.attrs.context === value.attrs.context
facet.type === facet_type &&
facet.groupId === facetId &&
facet.isActive === true
);
});
var eventData = {
category: "groupByCategory",
itemId: groupBy.groupbyId,
isActive: true,
groupId: groupBy.groupId,
};
self.trigger_up("menu_item_toggled", eventData);
});
} else if (segment.cat === "filterCategory") {
var new_filters = [];
_.each(segment.values, function (value) {
if (value.attrs.name) {
var filterDomain = _.find(
self.searchview.filtersMapping,
function (mapping) {
return (
mapping.filter.attrs.name === value.attrs.name
if (!selectedFacet.length) {
return;
}
if (facet_type === "favorite") {
var FavFacets = [];
var currentFacet = self.model.get(
"filters",
(f) => f.type === "favorite" && f.groupId === facetId
);
}
if (currentFacet[0].groupBys.length) {
_.each(currentFacet[0].groupBys, function (description) {
FavFacets.push(
self.model.get(
"filters",
(f) =>
f.type === "groupBy" && f.fieldName === description
)[0]
);
var eventData = {
category: "filterCategory",
itemId: filterDomain.filterId,
isActive: true,
groupId: filterDomain.groupId,
};
self.trigger_up("menu_item_toggled", eventData);
} else {
new_filters.push({
groupId: null,
filter: {
tag: "filter",
attrs: value.attrs,
},
itemId: _.uniqueId("__filter__"),
});
}
});
self.trigger_up("new_filters", new_filters);
} else {
var search_widget = _.find(self.searchview.search_fields, function (
f
) {
return f.attrs.name === segment.field.attrs.name;
});
new_facets.push({
category: segment.category,
field: search_widget,
values: segment.values,
});
}
});
this.query.add(new_facets);
},
});
SearchView.include({
/**
* Removes a value from a facet.
*
* @private
* @param {Backbone.Model} model
* @param {Integer|Object} value The value to remove
*/
_removeValue: function (model, value) {
var toRemove = model.values.filter(function (v) {
if (typeof v.attributes.value === "object") {
return v.attributes.value.attrs.domain === value;
}
return v.attributes.value.toString() === value;
});
model.values.remove(toRemove);
},
/**
* Renders a popover for a facet.
*
* @private
* @param {jQuery} $facet Element of the facet
* @param {Backbone.Model} model
*/
_renderPopover: function ($facet, model) {
var self = this;
var $facet = $($el);
var $content = $(
qweb.render("web_edit_user_filter.Popover", {
values: model.get("values"),
values: selectedFacet,
})
);
// Cannot use Widget.events here because renderFacets is
// triggered apart from renderElement
$content.find(".list-group-item").click(function () {
self._removeValue(model, $(this).attr("data-value"));
$content.find(".list-group-item").on("click", function () {
var PopOverContainer = $(".o_searchview");
var type = $(this).data("type");
var facetIdEl = $(this).data("id");
if (type === "filter") {
var FacetSelected = self.model.get(
"filters",
(f) => f.id === facetIdEl && f.type === "filter"
);
if (FacetSelected[0].hasOptions) {
var OptionSelected = FacetSelected[0].options.filter(function (
option
) {
return option.isActive === true;
});
_.each(OptionSelected, function (option) {
self.model.dispatch(
"toggleFilterWithOptions",
facetIdEl,
option.id
);
});
} else {
self.model.dispatch("toggleFilter", facetIdEl);
}
} else if (type === "groupBy") {
self.model.dispatch("toggleFilter", facetIdEl);
} else if (type === "favorite") {
event.stopImmediatePropagation();
var facet = self.model.get(
"filters",
(f) => f.type === type && f.groupId === facetIdEl
);
if (facet.length) {
self._unpackFilter(facet[0]);
} else {
self.env.services.notification.notify({
message: self.env._t(
"In order to edit newly added 'Favorite filters, you need to refresh the page first. \n Kindly refresh the page and try again."
),
type: "warning",
});
}
}
$(this).remove();
$(PopOverContainer).find(".popover").popover("hide");
});
var $container = $(".o_searchview");
$facet.popover({
title: _t("Edit Facet"),
title: _t(
'Edit Filters <a href="#" class="close" data-dismiss="alert">&times;</a>'
),
template: qweb.render("web_edit_user_filter.PopoverTemplate"),
content: $content,
container: this.$el,
container: $container,
html: true,
trigger: "manual",
placement: "bottom",
animation: false,
});
var PopOverContainer = $(".o_searchview");
$(PopOverContainer).find(".popover").popover("hide");
$facet.popover("show");
},
/**
* Hides all popovers.
*
* @private
*/
_hidePopovers: function () {
this.$el.find(".popover").popover("hide");
},
/**
* @override
*/
renderFacets: function () {
_unpackFilter(filter) {
var self = this;
var res = this._super.apply(this, arguments);
this.$el.find(".o-edit-user-filter-popover").remove();
_.each(this.input_subviews, function (input_subview) {
if (
!input_subview.model ||
input_subview.model.attributes.is_custom_filter
) {
return;
self.model.dispatch("toggleFilter", filter.id);
var facets = JSON.parse(filter.facet);
var convFacets = [];
_.each(facets, function (facet) {
if (facet.type === "filter") {
_.each(facet.values, function (fc) {
var fetchedFilter = self.model.get(
"filters",
(f) => f.description === fc && f.type === "filter"
);
if (fetchedFilter.length) {
convFacets.push(
self.model.get(
"filters",
(f) => f.description === fc && f.type === "filter"
)
);
} else {
var tentativeFilter = self.model.get(
"filters",
(f) =>
f.description === facet.title && f.type === "filter"
);
if (tentativeFilter.length) {
_.each(tentativeFilter, function (f) {
if (f.hasOptions) {
var trueOption = "";
_.each(f.options, function (option) {
var str = fc
.split(": ")
.pop()
.split(" ")[0];
if (str === option.description) {
trueOption = option.id;
}
input_subview.$el.addClass("o-edit-user-filter-editable");
self._renderPopover(input_subview.$el, input_subview.model);
input_subview.$el.click(function () {
self._hidePopovers();
input_subview.$el.popover("show");
});
if (trueOption !== "") {
self.model.dispatch(
"toggleFilterWithOptions",
f.id,
trueOption
);
}
}
});
return res;
},
/**
* @override
*/
start: function () {
var self = this;
var res = this._super.apply(this, arguments);
this._proxyHidePopovers = this.proxy("_hidePopovers");
$(document).click(this._proxyHidePopovers);
return res;
},
/**
* @override
*/
destroy: function () {
var res = this._super.apply(this, arguments);
$(document).unbind("click", this._proxyHidePopovers);
return res;
} else {
const preFilter = {
description: facet.title,
domain: filter.domain,
type: "filter",
};
self.model.dispatch("createNewFilters", [preFilter]);
}
}
});
} else if (facet.type === "groupBy") {
_.each(facet.values, function (fc) {
var fetchedGroup = self.model.get(
"filters",
(f) => f.description === fc && f.type === "groupBy"
);
if (fetchedGroup.length) {
convFacets.push(
self.model.get(
"filters",
(f) => f.description === fc && f.type === "groupBy"
)
);
} else {
var tentativeFilter = self.model.get(
"filters",
(f) =>
f.description === facet.title &&
f.type === "groupBy"
);
if (tentativeFilter.length) {
_.each(tentativeFilter, function (f) {
if (f.hasOptions) {
var trueOption = "";
_.each(f.options, function (option) {
var str = fc
.split(": ")
.pop()
.split(" ")[0];
if (str === option.description) {
trueOption = option.id;
}
});
if (trueOption !== "") {
self.model.dispatch(
"toggleFilterWithOptions",
f.id,
trueOption
);
}
}
});
}
}
});
}
});
if (convFacets.length) {
_.each(convFacets, function (facet) {
self.model.dispatch("toggleFilter", facet[0].id);
});
}
},
});
$(document).on("click", ".popover .close", function () {
$(this).parents(".popover").popover("hide");
});
});

View File

@ -6,18 +6,35 @@
<div class="list-group">
<t t-foreach="values" t-as="value">
<t t-if="value.type != 'favorite'">
<a
class="list-group-item list-group-item-action"
t-attf-data-value="#{typeof value.value === 'object' ? value.value.attrs.domain : value.value}"
t-att-data-type="value.type"
t-att-data-id="value.id"
>
<span>
<t t-esc="value.label" />
<t t-esc="value.description" />
</span>
<button class="btn btn-sm btn-link pull-right">
<span class="fa fa-close" />
</button>
</a>
</t>
<t t-if="value.type == 'favorite'">
<a
class="list-group-item list-group-item-action"
t-att-data-type="value.type"
t-att-data-id="value.id"
>
<span>
<t t-esc="value.description" />
</span>
<button class="btn btn-sm btn-link pull-right">
<span class="fa fa-pencil o-edit-user-filter" />
</button>
</a>
</t>
</t>
</div>
</div>
@ -28,4 +45,5 @@
<div class="popover-body" />
</div>
</t>
</template>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
<t
t-name="SearchExtender"
t-inherit="web.SearchBar"
t-inherit-mode="extension"
owl="1"
>
<xpath expr="//div[hasclass('o_searchview_facet')]" position="replace">
<div
t-foreach="model.get('facets')"
t-as="facet"
t-key="facet_index"
tabindex="0"
class="o_searchview_facet"
role="img"
aria-label="search"
t-on-keydown="_onFacetKeydown(facet, facet_index)"
t-att-data-type="facet.type"
t-att-data-gp="facet.groupId"
>
<span
t-if="facet.icon"
t-attf-class="o_searchview_facet_label {{ facet.icon }}"
/>
<span t-else="" class="o_searchview_facet_label" t-esc="facet.title" />
<div class="o_facet_values">
<t
t-foreach="facet.values"
t-as="facetValue"
t-key="facetValue_index"
>
<span
t-if="!facetValue_first"
class="o_facet_values_sep"
t-esc="facet.separator"
/>
<span class="o_facet_value" t-esc="facetValue" />
</t>
</div>
<i
class="fa fa-sm fa-remove o_facet_remove"
role="img"
aria-label="Remove"
title="Remove"
t-on-click="_onFacetRemove(facet)"
/>
</div>
</xpath>
</t>
</templates>