From f3fc533401b86a7f5bf0bcdcb9830d3ab6d91c68 Mon Sep 17 00:00:00 2001 From: FrancoisGe Date: Mon, 7 Nov 2022 08:26:19 +0000 Subject: [PATCH] [FIX] web: search in a m2o block the ui Before this commit, performing a search in a m2o can block your ui despite the result already being displayed. Why? When you perform your search in a m2o, a set of RPC queries are made with the different search values (name_search). If the last search value (the one that will be used by the m2o in its autocomplete) has already been resolved, but one of the other RPCs has still not been resolved, then the screen will remain blocked until all the rpc's have been resolved. Solution: Since we are only interested in the last rpc, we will cancel all the others. So with each new rpc, we will cancel the previous one. How to reproduce: - Go to a form view with a m2o field - Edit this field +- slowly (several rpc will be done with different values) - Receive the result of the search. (The autocomplete is displayed with the right values) Before this commit: If one of the other rpc's is not yet resolved, the ui will block until all rpc's are resolved. After this commit: The ui will not block. closes odoo/odoo#105286 X-original-commit: 1700416551725a70eca5597b6e106b43282c00d2 Signed-off-by: Samuel Degueldre --- addons/web/static/src/legacy/js/core/ajax.js | 21 ++++++++++++++----- .../src/legacy/js/fields/relational_fields.js | 7 +++++-- .../tests/legacy/helpers/mock_server.js | 8 ++++--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/addons/web/static/src/legacy/js/core/ajax.js b/addons/web/static/src/legacy/js/core/ajax.js index bc0c40b9522..71484e5c9d8 100644 --- a/addons/web/static/src/legacy/js/core/ajax.js +++ b/addons/web/static/src/legacy/js/core/ajax.js @@ -97,11 +97,22 @@ function _genericJsonRpc (fct_name, params, settings, fct) { }); // FIXME: jsonp? - promise.abort = function () { - rejection({ - message: "XmlHttpRequestError abort", - event: $.Event('abort') - }); + /** + * @param {Boolean} rejectError Returns an error if true. Allows you to cancel + * ignored rpc's in order to unblock the ui and not display an error. + */ + promise.abort = function (rejectError = true) { + if (rejectError) { + rejection({ + message: "XmlHttpRequestError abort", + event: $.Event('abort') + }); + } + + if (!shadow) { + core.bus.trigger('rpc_response'); + } + if (xhr.abort) { xhr.abort(); } diff --git a/addons/web/static/src/legacy/js/fields/relational_fields.js b/addons/web/static/src/legacy/js/fields/relational_fields.js index faf94e7b057..d5de3734b5f 100644 --- a/addons/web/static/src/legacy/js/fields/relational_fields.js +++ b/addons/web/static/src/legacy/js/fields/relational_fields.js @@ -640,7 +640,10 @@ var FieldMany2One = AbstractField.extend({ domain.push(['id', 'not in', blackListedIds]); } - const nameSearch = this._rpc({ + if (this.lastNameSearch) { + this.lastNameSearch.abort(false) + } + this.lastNameSearch = this._rpc({ model: this.field.relation, method: "name_search", kwargs: { @@ -651,7 +654,7 @@ var FieldMany2One = AbstractField.extend({ context, } }); - const results = await this.orderer.add(nameSearch); + const results = await this.orderer.add(this.lastNameSearch); // Format results to fit the options dropdown let values = results.map((result) => { diff --git a/addons/web/static/tests/legacy/helpers/mock_server.js b/addons/web/static/tests/legacy/helpers/mock_server.js index b3737fe7e8d..b1989eb4c6f 100644 --- a/addons/web/static/tests/legacy/helpers/mock_server.js +++ b/addons/web/static/tests/legacy/helpers/mock_server.js @@ -163,9 +163,11 @@ var MockServer = Class.extend({ if (abort) { abort = abort.bind(def); } else { - abort = function () { - throw new Error("Can't abort this request"); - }; + abort = function (rejectError = true) { + if (rejectError) { + throw new Error("XmlHttpRequestError abort"); + } + } } def = def.then(function (result) {