diff options
| author | Aaron Bohy <aab@odoo.com> | 2019-02-19 10:10:47 +0000 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2019-02-26 08:26:51 +0000 |
| commit | 6a8e1b53e3a01a74aa21b834964994e8d186b653 (patch) | |
| tree | 5c0d9090324775757300692ef1d4c7b6281ec15f /addons/web/static/src | |
| parent | a76a958ca8479c3ea0c480bac730f7bfd62ce1d5 (diff) | |
[FIX] web: search more in many2one: filter on ids
Let's assume a many2one field with a lot of possible values. The
user clicks on 'Search More...'. In the opened dialog, only 160
records are available (their ids have been obtained with a
name_search, with the optional text the user could have typed in
the many2one input).
Before 4cd379cf, that extra domain on ids was removed automatically
as soon as the user interacted with the search view in the dialog.
This was especially useful when there were more than 160 records.
However, this was rather an happy coincidence than a designed
feature.
From 4cd379cf, the ids selection was added to the initial domain
of the list, so they couldn't be removed from the domain
afterwards. The user was thus stucked with its preselected 160
records.
This rev. doesn't restore the former behavior, but rather improves
the current one, as follows:
- when there is no text in the many2one input (i.e. no value to
filter on), we bypass the name_search, s.t. all records are
available in the dialog
- when there is some text in the input, we perform a name_search (as
before) to get a list of record ids, and we add a special filter
to the search view in the dialog (the filter on those ids), s.t.
the user can remove it if he wants to access the remaining records.
- finally, the limit is now set to 320, to mitigate the problem
Issue reported on the saas-12.1 migration pad.
closes odoo/odoo#31232
Diffstat (limited to 'addons/web/static/src')
4 files changed, 52 insertions, 8 deletions
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 14eb10c663c..6005c9f1a66 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -107,6 +107,7 @@ var FieldMany2One = AbstractField.extend({ 'click': '_onClick', }), AUTOCOMPLETE_DELAY: 200, + SEARCH_MORE_LIMIT: 320, /** * @override @@ -501,18 +502,33 @@ var FieldMany2One = AbstractField.extend({ values.push({ label: _t("Search More..."), action: function () { - self._rpc({ + var prom; + if (search_val !== '') { + prom = self._rpc({ model: self.field.relation, method: 'name_search', kwargs: { name: search_val, args: domain, operator: "ilike", - limit: 160, + limit: self.SEARCH_MORE_LIMIT, context: context, }, - }) - .then(self._searchCreatePopup.bind(self, "search")); + }); + } + $.when(prom).then(function (results) { + var dynamicFilters; + if (results) { + var ids = _.map(results, function (x) { + return x[0]; + }); + dynamicFilters = [{ + description: _.str.sprintf(_t('Quick search: %s'), search_val), + domain: [['id', 'in', ids]], + }]; + } + self._searchCreatePopup("search", false, {}, dynamicFilters); + }); }, classname: 'o_m2o_dropdown_option', }); @@ -555,19 +571,25 @@ var FieldMany2One = AbstractField.extend({ /** * all search/create popup handling * + * TODO: ids argument is no longer used, remove it in master (as well as + * initial_ids param of the dialog) + * * @private * @param {any} view * @param {any} ids * @param {any} context + * @param {Object[]} [dynamicFilters=[]] filters to add to the search view + * in the dialog (each filter has keys 'description' and 'domain') */ - _searchCreatePopup: function (view, ids, context) { + _searchCreatePopup: function (view, ids, context, dynamicFilters) { var self = this; return new dialogs.SelectCreateDialog(this, _.extend({}, this.nodeOptions, { res_model: this.field.relation, domain: this.record.getDomain({fieldName: this.name}), context: _.extend({}, this.record.getContext(this.recordParams), context || {}), + dynamicFilters: dynamicFilters || [], title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + this.string, - initial_ids: ids ? _.map(ids, function (x) { return x[0]; }) : undefined, + initial_ids: ids, initial_view: view, disable_multiple_selection: true, no_create: !self.can_create, diff --git a/addons/web/static/src/js/views/abstract_view.js b/addons/web/static/src/js/views/abstract_view.js index 5921c1b4bc3..a2e6c5e699c 100644 --- a/addons/web/static/src/js/views/abstract_view.js +++ b/addons/web/static/src/js/views/abstract_view.js @@ -78,6 +78,8 @@ var AbstractView = Factory.extend({ * @param {string} [params.controllerState] * @param {string} [params.displayName] * @param {Array[]} [params.domain=[]] + * @param {Object[]} [params.dynamicFilters] transmitted to the + * ControlPanelView * @param {number[]} [params.ids] * @param {boolean} [params.isEmbedded=false] * @param {Object} [params.searchQuery={}] @@ -165,6 +167,7 @@ var AbstractView = Factory.extend({ this.controlPanelParams = { action: action, activateDefaultFavorite: params.activateDefaultFavorite, + dynamicFilters: params.dynamicFilters, breadcrumbs: params.breadcrumbs, context: this.loadParams.context, domain: this.loadParams.domain, diff --git a/addons/web/static/src/js/views/control_panel/control_panel_view.js b/addons/web/static/src/js/views/control_panel/control_panel_view.js index edda0e3c9ac..c81093f28ff 100644 --- a/addons/web/static/src/js/views/control_panel/control_panel_view.js +++ b/addons/web/static/src/js/views/control_panel/control_panel_view.js @@ -43,8 +43,12 @@ var ControlPanelView = Factory.extend({ * breadcrumbs won't be rendered * @param {boolean} [params.withSearchBar=true] if set to false, no default * search bar will be rendered - * @param {boolean} [activateDefaultFavorite=false] determine if the default - * custom filters can be activated + * @param {boolean} [params.activateDefaultFavorite] determine if the + * default custom filters can be activated + * @param {Object[]} [params.dynamicFilters=[]] filters to add to the + * search (in addition to those described in the arch), each filter being + * an object with keys 'description' (what is displayed in the searchbar) + * and 'domain' */ init: function (params) { var self = this; @@ -103,6 +107,19 @@ var ControlPanelView = Factory.extend({ INTERVAL_OPTIONS = INTERVAL_OPTIONS.map(function (option) { return _.extend(option, {description: option.description.toString()}); }); + + // add a filter group with the dynamic filters, if any + if (params.dynamicFilters && params.dynamicFilters.length) { + var dynamicFiltersGroup = params.dynamicFilters.map(function (filter) { + return { + description: filter.description, + domain: JSON.stringify(filter.domain), + isDefault: true, + type: 'filter', + }; + }); + this.loadParams.groups.unshift(dynamicFiltersGroup); + } }, //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/js/views/view_dialogs.js b/addons/web/static/src/js/views/view_dialogs.js index fb9cd5afa0c..96f6286cd3e 100644 --- a/addons/web/static/src/js/views/view_dialogs.js +++ b/addons/web/static/src/js/views/view_dialogs.js @@ -304,6 +304,7 @@ var SelectCreateDialog = ViewDialog.extend({ * - list_view_options: dict of options to pass to the List View * - on_selected: optional callback to execute when records are selected * - disable_multiple_selection: true to allow create/select multiple records + * - dynamicFilters: filters to add to the searchview */ init: function () { this._super.apply(this, arguments); @@ -346,6 +347,7 @@ var SelectCreateDialog = ViewDialog.extend({ controlPanelFieldsView: fieldsViews.search, }, action_buttons: false, + dynamicFilters: this.options.dynamicFilters, context: this.context, domain: domain, hasSelectors: !this.options.disable_multiple_selection, |
