[FIX] web_editor: fix race condition in option selection

Previously, when selecting certain options, especially ones which had
slow updateUI methods, the selected value was sometimes reset to its
previous value. This was caused by a race condition in which, when a
snippet option updated its value, it would wait for options on the
parent snippet editors to update all of their options' UI, but it
incorrectly only waited for *one* of the snippet editors to finish
instead of waiting for all of them.

This commit fixes that by stopping the event propagation and triggering
a new event that will let the direct parent know when all parent editors
are done updating their options' UI before signalling that the UI update
is done.

task-2487578

closes odoo/odoo#68341

X-original-commit: 7623a0c771495cd41bf40af37c0d2b6e4beb7cdc
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Co-authored-by: Arthur Detroux <ard@odoo.com>
This commit is contained in:
Samuel Degueldre
2021-03-25 12:37:35 +00:00
committed by qsm-odoo
co-authored by Arthur Detroux
parent fd16106199
commit fb05e0f554
@@ -856,18 +856,32 @@ var SnippetEditor = Widget.extend({
* @param {OdooEvent} ev
*/
_onSnippetOptionUpdate: async function (ev) {
const proms1 = Object.keys(this.styles).map(key => {
return this.styles[key].updateUI({
noVisibility: true,
if (ev.target === this) {
return;
}
ev.stopPropagation();
const updateOptionsUI = async () => {
const proms1 = Object.keys(this.styles).map(key => {
return this.styles[key].updateUI({
noVisibility: true,
});
});
});
await Promise.all(proms1);
const proms2 = Object.keys(this.styles).map(key => {
return this.styles[key].updateUIVisibility();
});
await Promise.all(proms2);
await Promise.all(proms1);
const proms2 = Object.keys(this.styles).map(key => {
return this.styles[key].updateUIVisibility();
});
await Promise.all(proms2);
};
// Wait for the current editor's option UI updates and the parent ones
await Promise.all([
updateOptionsUI(),
new Promise(resolve => {
this.trigger_up('snippet_option_update', Object.assign({}, ev.data, {
onSuccess: () => resolve(),
}));
}),
]);
ev.data.onSuccess();
},
/**
@@ -941,6 +955,7 @@ var SnippetsMenu = Widget.extend({
'snippet_editor_destroyed': '_onSnippetEditorDestroyed',
'snippet_removed': '_onSnippetRemoved',
'snippet_cloned': '_onSnippetCloned',
'snippet_option_update': '_onSnippetOptionUpdate',
'snippet_option_visibility_update': '_onSnippetOptionVisibilityUpdate',
'snippet_thumbnail_url_request': '_onSnippetThumbnailURLRequest',
'reload_snippet_dropzones': '_disableUndroppableSnippets',
@@ -2673,6 +2688,14 @@ var SnippetsMenu = Widget.extend({
this._disableUndroppableSnippets();
this._updateInvisibleDOM();
},
/**
* @private
* @param {OdooEvent} ev
*/
_onSnippetOptionUpdate: function (ev) {
ev.stopPropagation();
ev.data.onSuccess();
},
/**
* @private
* @param {OdooEvent} ev