Allow to search on related field in search box

The server adds to the definition of the fields, the definition of relation
fields up to specific deep level.
The clients use this relation fields definition to extend the domain parser
with those fields using a dot notation. But those "dotted fields" are not
shown in the search filter to not bloat the popup as it is dedicated to
learning.
In addition, Dict fields are also filled with relation fields coming from the
keys defined in the schema model. As the size can very large, it is possible
to deactivate this feature from the configuration.

issue8293
review259391005
This commit is contained in:
Cédric Krier
2019-06-16 15:44:14 +02:00
parent 4b436df20b
commit f841fd1bc7
4 changed files with 83 additions and 15 deletions
+1
View File
@@ -1,3 +1,4 @@
* Support relation fields in domain parser
* Add view modified
* Add Dict widget for tree view
+17 -4
View File
@@ -994,15 +994,28 @@
init: function(fields, context) {
this.fields = {};
this.strings = {};
this.update_fields(fields);
this.context = context;
this.update_fields(fields);
},
update_fields: function(fields) {
update_fields: function(fields, prefix, string_prefix) {
prefix = prefix || '';
string_prefix = string_prefix || '';
for (var name in fields) {
var field = fields[name];
if (field.searchable || (field.searchable === undefined)) {
this.fields[name] = field;
if ((field.searchable || (field.searchable === undefined)) &&
(name !== 'rec_name')) {
field = jQuery.extend({}, field);
var fullname = prefix ? prefix + '.' + name : name;
var string = string_prefix ?
string_prefix + '.' + field.string : field.string;
field.string = string;
field.name = fullname;
this.fields[fullname] = field;
this.strings[field.string.toLowerCase()] = field;
var rfields = field.relation_fields;
if (rfields) {
this.update_fields(rfields, fullname, string);
}
}
}
},
+6 -9
View File
@@ -441,7 +441,8 @@
var field;
for (var f in domain_parser.fields) {
field = domain_parser.fields[f];
if (field.searchable || field.searchable === undefined) {
if ((field.searchable || field.searchable === undefined) &&
!field.name.contains('.')) {
fields.push(field);
}
}
@@ -1633,14 +1634,10 @@
// Add common fields
[
['id', Sao.i18n.gettext('ID'), 'integer'],
['create_uid', Sao.i18n.gettext('Creation User'),
'many2one'],
['create_date', Sao.i18n.gettext('Creation Date'),
'datetime'],
['write_uid', Sao.i18n.gettext('Modification User'),
'many2one'],
['write_date', Sao.i18n.gettext('Modification Date'),
'datetime']
['create_uid', Sao.i18n.gettext('Created by'), 'many2one'],
['create_date', Sao.i18n.gettext('Created at'), 'datetime'],
['write_uid', Sao.i18n.gettext('Modified by'), 'many2one'],
['write_date', Sao.i18n.gettext('Modified at'), 'datetime']
] .forEach(function(e) {
var name = e[0];
var string = e[1];
+59 -2
View File
@@ -1077,7 +1077,16 @@
},
'surname': {
'string': '(Sur)Name'
}
},
'relation': {
'string': "Relation",
'relation': 'relation',
'relation_fields': {
'name': {
'string': "Name",
},
},
},
});
var udlex = function(input) {
var lex = new Sao.common.udlex(input);
@@ -1156,7 +1165,10 @@
]],
['Name: "" <', [
c(['Name', '', '<'])
]]
]],
['Relation.Name: Test', [
c(['Relation.Name', null, 'Test']),
]],
].forEach(function(test) {
var value = test[0];
var result = test[1];
@@ -1457,6 +1469,18 @@
'name': 'many2one',
'type': 'many2one',
},
'relation': {
'string': "Relation",
'relation': 'relation',
'name': 'relation',
'relation_fields': {
'name': {
'string': "Name",
'name': 'name',
'type': 'char',
},
},
},
});
var c = function(value) {
value.clause = true;
@@ -1501,6 +1525,8 @@
[[c(['Many2One', null, ['John', 'Jane']])],
[['many2one.rec_name', 'in', ['John', 'Jane']]]],
[[[c(['John'])]], [[['rec_name', 'ilike', '%John%']]]],
[[c(['Relation.Name', null, "Test"])],
[['relation.name', 'ilike', "%Test%"]]],
].forEach(function(test) {
var value = test[0];
var result = test[1];
@@ -1646,6 +1672,12 @@
'relation': {
'string': 'Relation',
'type': 'many2one',
'relation_fields': {
'name': {
'string': "Name",
'type': 'char',
},
},
},
'relations': {
'string': 'Relations',
@@ -1667,6 +1699,7 @@
QUnit.ok(parser.stringable([['relations', '=', 'Foo']]));
QUnit.ok(parser.stringable([['relations', 'in', ['Foo']]]));
QUnit.ok(!parser.stringable([['relations', 'in', [42]]]));
QUnit.ok(parser.stringable([['relation.name', '=', "Foo"]]));
});
QUnit.test('DomainParser.string', function() {
@@ -1703,6 +1736,12 @@
'string': "Many2One",
'name': 'many2one',
'type': 'many2one',
'relation_fields': {
'name': {
'string': "Name",
'type': 'char',
},
},
},
});
@@ -1751,6 +1790,7 @@
[[['reference', 'in', ['foo', 'bar']]], 'Reference: foo;bar'],
[[['many2one', 'ilike', '%John%']], 'Many2One: John'],
[[['many2one.rec_name', 'in', ['John', 'Jane']]], 'Many2One: John;Jane'],
[[['many2one.name', 'ilike', '%Foo%']], 'Many2One.Name: Foo'],
].forEach(function(test) {
var value = test[0];
var result = test[1];
@@ -2478,6 +2518,23 @@
QUnit.ok(compare(parser.completion(value), expected),
'completion(' + value + ')');
});
parser = new Sao.common.DomainParser({
'relation': {
'name': 'relation',
'string': "Relation",
'type': 'many2one',
'relation_fields': {
'name': {
'name': 'name',
'string': "Name",
'type': 'char',
},
},
},
});
QUnit.ok(compare(parser.completion('Relatio'),
["Relation: ", "Relation.Name: "]));
});
/*