mirror of
https://github.com/OCA/web.git
synced 2025-02-22 13:21:25 +02:00
Merge branch '11.0-web_advanced_search_x2x-mig' into 11.0
This commit is contained in:
68
web_advanced_search/README.rst
Normal file
68
web_advanced_search/README.rst
Normal file
@@ -0,0 +1,68 @@
|
||||
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
|
||||
=========================================
|
||||
Search for x2x records in advanced search
|
||||
=========================================
|
||||
|
||||
Standard behavior in advanced search for one2many, many2many and many2one fields is to do a `name_search`. This often is not satisfactionary as you might want to search for other properties. There might also be cases where you don't exactly know what you're searching for, then a list of possible options is necessary too. This module enables you to have a full search view to select the record in question, and either select specific records or select them using a search query of its own.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
To use this module, you need to:
|
||||
|
||||
* open the advanced search options in a search view
|
||||
* select a one2many, many2many or many2one field
|
||||
* select operator `is equal to` or `is not equal to`
|
||||
* the textfield changes to a many2one selection field where you can search for the record in question
|
||||
* click *Apply*
|
||||
|
||||
To search for properties of linked records (ie invoices for customers with a credit limit higher than X):
|
||||
|
||||
* open the advanced search options in a search view
|
||||
* select a one2many, many2many or many2one field
|
||||
* select operator `is in selection`
|
||||
* in the search view that pops up, select the criteria
|
||||
* select the records you want, or select the top corner box to select all matching records with that criteria
|
||||
* click *Select*
|
||||
|
||||
Note that you can stack searching for properties: Simply add another advanced search in the selection search window. You can do this indefinetely, so it is possible to search for moves belonging to a journal which has a user who is member of a certain group etc.
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/162/10.0
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
* When you use *is in selection* search system and choose a domain, it gets
|
||||
immediately applied, so to add a new condition, you will have to use again
|
||||
the *Filters* menu.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Holger Brunn <hbrunn@therp.nl>
|
||||
* Vicent Cubells <vicent.cubells@tecnativa.com>
|
||||
* Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
* Rami Alwafaie <rami.alwafaie@initos.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
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.
|
||||
|
||||
To contribute to this module, please visit https://odoo-community.org.
|
||||
0
web_advanced_search/__init__.py
Normal file
0
web_advanced_search/__init__.py
Normal file
27
web_advanced_search/__openerp__.py
Normal file
27
web_advanced_search/__openerp__.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright 2015 Therp BV <http://therp.nl>
|
||||
# Copyright 2017 Tecnativa - Vicent Cubells
|
||||
# Copyright 2018 Tecnativa - Jairo Llopis
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "Advanced search",
|
||||
"version": "11.0.1.0.0",
|
||||
"author": "Therp BV, "
|
||||
"Tecnativa, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"category": "Usability",
|
||||
"summary": "Easier and more powerful searching tools",
|
||||
"website": "https://github.com/OCA/web",
|
||||
"depends": [
|
||||
'web',
|
||||
],
|
||||
"data": [
|
||||
'views/templates.xml',
|
||||
],
|
||||
"qweb": [
|
||||
'static/src/xml/web_advanced_search.xml',
|
||||
],
|
||||
"installable": True,
|
||||
"application": False,
|
||||
}
|
||||
26
web_advanced_search/i18n/de.po
Normal file
26
web_advanced_search/i18n/de.po
Normal file
@@ -0,0 +1,26 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_search_x2x
|
||||
#
|
||||
# Translators:
|
||||
# Rudolf Schnapka <rs@techno-flex.de>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-03 03:49+0000\n"
|
||||
"PO-Revision-Date: 2018-01-03 03:49+0000\n"
|
||||
"Last-Translator: Rudolf Schnapka <rs@techno-flex.de>, 2018\n"
|
||||
"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: web_advanced_search_x2x
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_search_x2x/static/src/js/web_advanced_search_x2x.js:38
|
||||
#, python-format
|
||||
msgid "is in selection"
|
||||
msgstr "Ist in Auswahl"
|
||||
26
web_advanced_search/i18n/es.po
Normal file
26
web_advanced_search/i18n/es.po
Normal file
@@ -0,0 +1,26 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_search_x2x
|
||||
#
|
||||
# Translators:
|
||||
# OCA Transbot <transbot@odoo-community.org>, 2017
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-03 03:49+0000\n"
|
||||
"PO-Revision-Date: 2018-01-03 03:49+0000\n"
|
||||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
|
||||
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: web_advanced_search_x2x
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_search_x2x/static/src/js/web_advanced_search_x2x.js:38
|
||||
#, python-format
|
||||
msgid "is in selection"
|
||||
msgstr "está en la selección"
|
||||
26
web_advanced_search/i18n/fr.po
Normal file
26
web_advanced_search/i18n/fr.po
Normal file
@@ -0,0 +1,26 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_search_x2x
|
||||
#
|
||||
# Translators:
|
||||
# OCA Transbot <transbot@odoo-community.org>, 2017
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-03 03:49+0000\n"
|
||||
"PO-Revision-Date: 2018-01-03 03:49+0000\n"
|
||||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
|
||||
"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#. module: web_advanced_search_x2x
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_search_x2x/static/src/js/web_advanced_search_x2x.js:38
|
||||
#, python-format
|
||||
msgid "is in selection"
|
||||
msgstr "parmi la sélection"
|
||||
27
web_advanced_search/i18n/hr.po
Normal file
27
web_advanced_search/i18n/hr.po
Normal file
@@ -0,0 +1,27 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_search_x2x
|
||||
#
|
||||
# Translators:
|
||||
# Bole <bole@dajmi5.com>, 2017
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-03 03:49+0000\n"
|
||||
"PO-Revision-Date: 2018-01-03 03:49+0000\n"
|
||||
"Last-Translator: Bole <bole@dajmi5.com>, 2017\n"
|
||||
"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n"
|
||||
"Language: hr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
|
||||
#. module: web_advanced_search_x2x
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_search_x2x/static/src/js/web_advanced_search_x2x.js:38
|
||||
#, python-format
|
||||
msgid "is in selection"
|
||||
msgstr "je u odabiru"
|
||||
26
web_advanced_search/i18n/nl.po
Normal file
26
web_advanced_search/i18n/nl.po
Normal file
@@ -0,0 +1,26 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_search_x2x
|
||||
#
|
||||
# Translators:
|
||||
# OCA Transbot <transbot@odoo-community.org>, 2017
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-03 03:49+0000\n"
|
||||
"PO-Revision-Date: 2018-01-03 03:49+0000\n"
|
||||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
|
||||
"Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: web_advanced_search_x2x
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_search_x2x/static/src/js/web_advanced_search_x2x.js:38
|
||||
#, python-format
|
||||
msgid "is in selection"
|
||||
msgstr "is in selectie"
|
||||
27
web_advanced_search/i18n/nl_NL.po
Normal file
27
web_advanced_search/i18n/nl_NL.po
Normal file
@@ -0,0 +1,27 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_search_x2x
|
||||
#
|
||||
# Translators:
|
||||
# Peter Hageman <hageman.p@gmail.com>, 2017
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-03 03:49+0000\n"
|
||||
"PO-Revision-Date: 2018-01-03 03:49+0000\n"
|
||||
"Last-Translator: Peter Hageman <hageman.p@gmail.com>, 2017\n"
|
||||
"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/"
|
||||
"teams/23907/nl_NL/)\n"
|
||||
"Language: nl_NL\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: web_advanced_search_x2x
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_search_x2x/static/src/js/web_advanced_search_x2x.js:38
|
||||
#, python-format
|
||||
msgid "is in selection"
|
||||
msgstr "Is in selectie"
|
||||
28
web_advanced_search/i18n/pt_BR.po
Normal file
28
web_advanced_search/i18n/pt_BR.po
Normal file
@@ -0,0 +1,28 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_search_x2x
|
||||
#
|
||||
# Translators:
|
||||
# Rodrigo de Almeida Sottomaior Macedo <rmsolucoeseminformatic4@gmail.com>, 2017
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-03 03:49+0000\n"
|
||||
"PO-Revision-Date: 2018-01-03 03:49+0000\n"
|
||||
"Last-Translator: Rodrigo de Almeida Sottomaior Macedo "
|
||||
"<rmsolucoeseminformatic4@gmail.com>, 2017\n"
|
||||
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/"
|
||||
"teams/23907/pt_BR/)\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#. module: web_advanced_search_x2x
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_search_x2x/static/src/js/web_advanced_search_x2x.js:38
|
||||
#, python-format
|
||||
msgid "is in selection"
|
||||
msgstr "Está em seleção"
|
||||
22
web_advanced_search/i18n/web_advanced_search.pot
Normal file
22
web_advanced_search/i18n/web_advanced_search.pot
Normal file
@@ -0,0 +1,22 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_search_x2x
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: web_advanced_search_x2x
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_search_x2x/static/src/js/web_advanced_search_x2x.js:38
|
||||
#, python-format
|
||||
msgid "is in selection"
|
||||
msgstr ""
|
||||
|
||||
5
web_advanced_search/readme/CONTRIBUTORS.rst
Normal file
5
web_advanced_search/readme/CONTRIBUTORS.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
* Holger Brunn <hbrunn@therp.nl>
|
||||
* Vicent Cubells <vicent.cubells@tecnativa.com>
|
||||
* Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
* Rami Alwafaie <rami.alwafaie@initos.com>
|
||||
* Jose Mª Bernet <josemaria.bernet@guadaltech.es>
|
||||
1
web_advanced_search/readme/DESCRIPTION.rst
Normal file
1
web_advanced_search/readme/DESCRIPTION.rst
Normal file
@@ -0,0 +1 @@
|
||||
More powerful and easy to use search, especially for related fields.
|
||||
14
web_advanced_search/readme/ROADMAP.rst
Normal file
14
web_advanced_search/readme/ROADMAP.rst
Normal file
@@ -0,0 +1,14 @@
|
||||
Improvements to the ``domain`` widget, not exclusively related to this addon:
|
||||
|
||||
* Use relational widgets when filtering a relational field
|
||||
* Allow to filter field names
|
||||
|
||||
Improvements to the search view in this addon:
|
||||
|
||||
* Use widgets ``one2many_tags`` when searching ``one2many`` fields
|
||||
* Use widgets ``many2many_tags`` when searching ``many2many`` fields
|
||||
* Allow to edit current full search using the advanced domain editor
|
||||
* Allow to edit individually any facet from current search using the
|
||||
advanced domain editor
|
||||
* Beautiful, human-readable, domain representation when adding an
|
||||
advanced filter
|
||||
21
web_advanced_search/readme/USAGE.rst
Normal file
21
web_advanced_search/readme/USAGE.rst
Normal file
@@ -0,0 +1,21 @@
|
||||
To use this module, you need to:
|
||||
|
||||
* Open *Filters* in a search view
|
||||
* Select any relational field
|
||||
* Select operator `is equal to` or `is not equal to`
|
||||
* The text field changes to a relational selection field where you
|
||||
can search for the record in question
|
||||
* Click *Apply*
|
||||
|
||||
To search for properties of linked records (ie invoices for customers
|
||||
with a credit limit higher than X):
|
||||
|
||||
* Open *Filters* in a search view
|
||||
* Select *Add Advanced Filter*
|
||||
* Edit the advanced filter
|
||||
* Click *Save*
|
||||
|
||||
Note that you can stack searching for properties: Simply add another
|
||||
advanced search in the selection search window. You can do
|
||||
this indefinetely, so it is possible to search for moves belonging
|
||||
to a journal which has a user who is member of a certain group etc.
|
||||
BIN
web_advanced_search/static/description/icon.png
Normal file
BIN
web_advanced_search/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
13
web_advanced_search/static/src/css/web_advanced_search.less
Normal file
13
web_advanced_search/static/src/css/web_advanced_search.less
Normal file
@@ -0,0 +1,13 @@
|
||||
.o_search_options {
|
||||
.o_filters_menu {
|
||||
.o_filter_condition {
|
||||
max-width: inherit;
|
||||
|
||||
.o_searchview_extended_prop_value {
|
||||
.o_field_domain {
|
||||
min-width: 30vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
web_advanced_search/static/src/js/human_domain.js
Normal file
86
web_advanced_search/static/src/js/human_domain.js
Normal file
@@ -0,0 +1,86 @@
|
||||
/* Copyright 2018 Tecnativa - Jairo Llopis
|
||||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
||||
|
||||
odoo.define("web_advanced_search.human_domain", function (require) {
|
||||
"use strict";
|
||||
|
||||
var DomainSelector = require("web.DomainSelector");
|
||||
|
||||
var join_mapping = {
|
||||
"&": _(" and "),
|
||||
"|": _(" or "),
|
||||
"!": _(" is not "),
|
||||
};
|
||||
|
||||
// HACK I should extend classes, but they are not exposed
|
||||
// TODO Remove file when merged https://github.com/odoo/odoo/pull/25922
|
||||
var human_domain_methods = {
|
||||
DomainTree: function () {
|
||||
var human_domains = [];
|
||||
_.each(this.children, function (child) {
|
||||
human_domains.push(
|
||||
human_domain_methods[child.template].apply(child)
|
||||
);
|
||||
});
|
||||
return _.str.sprintf(
|
||||
"(%s)",
|
||||
human_domains.join(join_mapping[this.operator])
|
||||
);
|
||||
},
|
||||
|
||||
DomainSelector: function () {
|
||||
var result = human_domain_methods.DomainTree.apply(this, arguments);
|
||||
// Remove surrounding parenthesis
|
||||
return result.slice(1, -1);
|
||||
},
|
||||
|
||||
DomainLeaf: function () {
|
||||
var chain = [],
|
||||
operator = this.operator_mapping[this.operator],
|
||||
value = _.str.sprintf('"%s"', this.value);
|
||||
// Humanize chain
|
||||
this.chain.split(".").forEach(function (element, index) {
|
||||
chain.push(
|
||||
_.findWhere(
|
||||
this.fieldSelector.pages[index],
|
||||
{name: element}
|
||||
).string || element
|
||||
);
|
||||
}, this);
|
||||
// Special beautiness for some values
|
||||
if (this.operator === "=" && _.isBoolean(this.value)) {
|
||||
operator = this.operator_mapping[this.value ? "set" : "not set"];
|
||||
value = "";
|
||||
} else if (_.isArray(this.value)) {
|
||||
value = _.str.sprintf('["%s"]', this.value.join('", "'));
|
||||
}
|
||||
return _.str.sprintf(
|
||||
"%s %s %s",
|
||||
chain.join("→"),
|
||||
operator || this.operator,
|
||||
value
|
||||
).trim();
|
||||
},
|
||||
};
|
||||
|
||||
function getHumanDomain (parent, model, domain, options) {
|
||||
var domain_selector = new DomainSelector(
|
||||
parent,
|
||||
model,
|
||||
domain,
|
||||
options
|
||||
);
|
||||
var dummy_parent = $("<div>");
|
||||
domain_selector.appendTo(dummy_parent);
|
||||
var result = human_domain_methods.DomainSelector.apply(
|
||||
domain_selector
|
||||
);
|
||||
domain_selector.destroy();
|
||||
dummy_parent.destroy();
|
||||
return result;
|
||||
}
|
||||
|
||||
return {
|
||||
getHumanDomain: getHumanDomain,
|
||||
};
|
||||
});
|
||||
293
web_advanced_search/static/src/js/web_advanced_search.js
Normal file
293
web_advanced_search/static/src/js/web_advanced_search.js
Normal file
@@ -0,0 +1,293 @@
|
||||
/* Copyright 2015 Therp BV <http://therp.nl>
|
||||
* Copyright 2017-2018 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
||||
|
||||
odoo.define("web_advanced_search", function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require("web.core");
|
||||
var Domain = require("web.Domain");
|
||||
var DomainSelectorDialog = require("web.DomainSelectorDialog");
|
||||
var field_registry = require("web.field_registry");
|
||||
var FieldManagerMixin = require("web.FieldManagerMixin");
|
||||
var FilterMenu = require("web.FilterMenu");
|
||||
var human_domain = require("web_advanced_search.human_domain");
|
||||
var SearchView = require("web.SearchView");
|
||||
var Widget = require("web.Widget");
|
||||
var Char = core.search_filters_registry.get("char");
|
||||
|
||||
SearchView.include({
|
||||
custom_events: _.extend({}, SearchView.prototype.custom_events, {
|
||||
"get_dataset": "_on_get_dataset",
|
||||
}),
|
||||
|
||||
/**
|
||||
* Add or update a `dataset` attribute in event target
|
||||
*
|
||||
* The search view dataset includes things such as the model, which
|
||||
* is required to make some parts of search views smarter.
|
||||
*
|
||||
* @param {OdooEvent} event The target will get the dataset.
|
||||
*/
|
||||
_on_get_dataset: function (event) {
|
||||
event.target.dataset = this.dataset;
|
||||
event.stopPropagation();
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* An almost dummy search proposition, to use with domain widget
|
||||
*/
|
||||
var AdvancedSearchProposition = Widget.extend({
|
||||
init: function (parent, model, domain) {
|
||||
this._super(parent);
|
||||
this.model = model;
|
||||
this.domain = new Domain(domain);
|
||||
},
|
||||
|
||||
get_filter: function () {
|
||||
var domain_array = this.domain.toArray();
|
||||
return {
|
||||
attrs: {
|
||||
domain: domain_array,
|
||||
// TODO Remove when merged
|
||||
// https://github.com/odoo/odoo/pull/25922
|
||||
string: human_domain.getHumanDomain(
|
||||
this,
|
||||
this.model,
|
||||
domain_array
|
||||
),
|
||||
},
|
||||
children: [],
|
||||
tag: "filter",
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
// Add advanced search features
|
||||
FilterMenu.include({
|
||||
custom_events: _.extend({}, FilterMenu.prototype.custom_events, {
|
||||
"domain_selected": "advanced_search_commit",
|
||||
}),
|
||||
|
||||
events: _.extend({}, FilterMenu.prototype.events, {
|
||||
"click .o_add_advanced_search": "advanced_search_open",
|
||||
}),
|
||||
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.trigger_up("get_dataset");
|
||||
},
|
||||
|
||||
/**
|
||||
* Open advanced search dialog
|
||||
*
|
||||
* @returns {$.Deferred} The opening dialog itself.
|
||||
*/
|
||||
advanced_search_open: function () {
|
||||
var domain_selector_dialog = new DomainSelectorDialog(
|
||||
this,
|
||||
this.dataset.model,
|
||||
"[]",
|
||||
{
|
||||
debugMode: core.debug,
|
||||
readonly: false,
|
||||
}
|
||||
);
|
||||
// Add 1st domain node by default
|
||||
domain_selector_dialog.domainSelector._onAddFirstButtonClick();
|
||||
return domain_selector_dialog.open();
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply advanced search on dialog save
|
||||
*
|
||||
* @param {OdooEvent} event A `domain_selected` event from the dialog.
|
||||
*/
|
||||
advanced_search_commit: function (event) {
|
||||
_.invoke(this.propositions, "destroy");
|
||||
var proposition = new AdvancedSearchProposition(
|
||||
this,
|
||||
this.dataset.model,
|
||||
event.data.domain
|
||||
);
|
||||
this.propositions = [proposition];
|
||||
this.commit_search();
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* A search field for relational fields.
|
||||
*
|
||||
* It implements and extends the `FieldManagerMixin`, and acts as if it
|
||||
* were a reduced dummy controller. Some actions "mock" the underlying
|
||||
* model, since sometimes we use a char widget to fill related fields
|
||||
* (which is not supported by that widget), and fields need an underlying
|
||||
* model implementation, which can only hold fake data, given a search view
|
||||
* has no data on it by definition.
|
||||
*/
|
||||
var Relational = Char.extend(FieldManagerMixin, {
|
||||
tagName: "div",
|
||||
className: "x2x_container",
|
||||
attributes: {},
|
||||
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
// To make widgets work, we need a model and an empty record
|
||||
FieldManagerMixin.init.call(this);
|
||||
this.trigger_up("get_dataset");
|
||||
// Make equal and not equal appear 1st and 2nd
|
||||
this.operators = _.sortBy(
|
||||
this.operators,
|
||||
function(op) {
|
||||
switch(op.value) {
|
||||
case "=":
|
||||
return -2;
|
||||
case "!=":
|
||||
return -1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
// Create dummy record with only the field the user is searching
|
||||
var params = {
|
||||
fieldNames: [this.field.name],
|
||||
modelName: this.dataset.model,
|
||||
context: this.dataset.context,
|
||||
// res_id: "virtual_0",
|
||||
fields: {},
|
||||
type: "record",
|
||||
viewType: "default",
|
||||
fieldsInfo: {
|
||||
default: {},
|
||||
},
|
||||
};
|
||||
// See https://stackoverflow.com/a/11508530/1468388
|
||||
params.fields[this.field.name] = _.omit(this.field, "onChange");
|
||||
params.fieldsInfo.default[this.field.name] = {};
|
||||
// Emulate `model.load()`, without RPC-calling `default_get()`
|
||||
this.datapoint_id = this.model._makeDataPoint(params).id;
|
||||
this.model.applyDefaultValues(
|
||||
this.datapoint_id,
|
||||
{},
|
||||
params.fieldNames
|
||||
);
|
||||
// To generate a new fake ID
|
||||
this._fake_id = -1;
|
||||
},
|
||||
|
||||
start: function () {
|
||||
var result = this._super.apply(this, arguments);
|
||||
// Render the initial widget
|
||||
result.done($.proxy(this, "show_inputs", $("<input value='='/>")));
|
||||
return result;
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
if (this._field_widget) {
|
||||
this._field_widget.destroy();
|
||||
}
|
||||
this.model.destroy();
|
||||
delete this.record;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
_get_record: function () {
|
||||
return this.model.get(this.datapoint_id);
|
||||
},
|
||||
|
||||
show_inputs: function ($operator) {
|
||||
// Get widget class to be used
|
||||
switch ($operator.val()) {
|
||||
case "=":
|
||||
case "!=":
|
||||
this._field_widget_name = "many2one";
|
||||
break;
|
||||
default:
|
||||
this._field_widget_name = "char";
|
||||
}
|
||||
var _Widget = field_registry.get(this._field_widget_name);
|
||||
// Destroy previous widget, if any
|
||||
if (this._field_widget) {
|
||||
this._field_widget.destroy();
|
||||
delete this._field_widget;
|
||||
}
|
||||
// Create new widget
|
||||
var options = {
|
||||
mode: "edit",
|
||||
attrs: {
|
||||
options: {
|
||||
no_create_edit: true,
|
||||
no_create: true,
|
||||
no_open: true,
|
||||
no_quick_create: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
this._field_widget = new _Widget(
|
||||
this,
|
||||
this.field.name,
|
||||
this._get_record(),
|
||||
options
|
||||
);
|
||||
this._field_widget.appendTo(this.$el);
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
_applyChanges: function (dataPointID, changes, event) {
|
||||
// Make char updates look like valid x2one updates
|
||||
if (_.isNaN(changes[this.field.name].id)) {
|
||||
changes[this.field.name] = {
|
||||
id: this._fake_id--,
|
||||
display_name: event.target.lastSetValue,
|
||||
};
|
||||
}
|
||||
return FieldManagerMixin._applyChanges.apply(this, arguments);
|
||||
},
|
||||
|
||||
_confirmChange: function (id, fields, event) {
|
||||
this.datapoint_id = id;
|
||||
return this._field_widget.reset(this._get_record(), event);
|
||||
},
|
||||
|
||||
get_value: function () {
|
||||
try {
|
||||
switch (this._field_widget_name) {
|
||||
case "many2one":
|
||||
return this._field_widget.value.res_id;
|
||||
default:
|
||||
return this._field_widget.value.data.display_name;
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.name === "TypeError") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
try {
|
||||
switch (this._field_widget_name) {
|
||||
case "many2one":
|
||||
return this._field_widget.value.data.display_name;
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
} catch (error) {
|
||||
if (error.name === "TypeError") {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Register search filter widgets
|
||||
core.search_filters_registry
|
||||
.add("many2many", Relational)
|
||||
.add("many2one", Relational)
|
||||
.add("one2many", Relational);
|
||||
|
||||
return {
|
||||
AdvancedSearchProposition: AdvancedSearchProposition,
|
||||
Relational: Relational,
|
||||
};
|
||||
});
|
||||
13
web_advanced_search/static/src/xml/web_advanced_search.xml
Normal file
13
web_advanced_search/static/src/xml/web_advanced_search.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright 2017-2018 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<templates>
|
||||
<t t-extend="SearchView.FilterMenu">
|
||||
<t t-jquery=".o_filters_menu" t-operation="append">
|
||||
<li class="divider"/>
|
||||
<li>
|
||||
<a class="o_add_advanced_search">Add Advanced Filter</a>
|
||||
</li>
|
||||
</t>
|
||||
</t>
|
||||
</templates>
|
||||
14
web_advanced_search/views/templates.xml
Normal file
14
web_advanced_search/views/templates.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright 2017-2018 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
|
||||
<template id="assets_backend" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" href="/web_advanced_search/static/src/css/web_advanced_search.less"/>
|
||||
<script type="text/javascript" src="/web_advanced_search/static/src/js/human_domain.js"/>
|
||||
<script type="text/javascript" src="/web_advanced_search/static/src/js/web_advanced_search.js"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user