[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 <sad@odoo.com>
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user