[FIX] web_editor: properly cache editor name_search when no selected ids

When a snippet option uses a m2m widget, the domain used for the
internal m2o widget which allows to select records evolves to receive
the subdomain `['id', 'not in', <selected-ids>]` with `<selected-ids>`
indicating the m2m records which are already selected.

M2o rpc are cached... based on the whole query object from which they
are created. The domain is part of that query object.

Both those concepts actually conflicted: the initial RPC when no ID is
selected was made with no subdomain, while the subsequent RPC when no ID
is selected were made with the `['id', 'not in', []]` subdomain. The
cache system did treat the resulting domains as different requests. Now
we avoid adding the useless `['id', 'not in', []]` subdomain as it
should already have been done without a cache system in place.

Note: this was particularly visible because all main snippets have the
"Conditional Visibility" option which uses 3 m2m widgets. At each drop
of such main snippet in the page, the option is created and the 3 m2m
widgets made their RPC with the initial domain. Then on click on the
snippet, a new RPC was made with the problematic subdomain, making the
first click on snippets being needlessly slower.
In the future, the system should be further improved to not require
those RPC on initial drop and clicks, especially as the "Conditional
Visibility" m2m widgets are hidden by default. This fix focuses on
fixing the generic m2m widgets.

X-original-commit: 017a468547eafa3e34f584379d3f05b3ed1db487
Part-of: odoo/odoo#102800
This commit is contained in:
qsm-odoo
2022-10-10 11:57:02 +02:00
parent 40ca30a12e
commit 83c2e98678
@@ -1963,12 +1963,21 @@ const ListUserValueWidget = UserValueWidget.extend({
if (this.createWidget) {
const selectedIds = currentValues.map(({ id }) => id)
.filter(id => typeof id === 'number');
const selectedIdsDomain = ['id', 'not in', selectedIds];
// Note: it's important to simplify the domain at its maximum as the
// rpc using it are cached. Similar domains should be written the
// same way for the cache to work.
const selectedIdsDomain = selectedIds.length ? ['id', 'not in', selectedIds] : null;
const selectedIdsDomainIndex = this.createWidget.options.domain.findIndex(domain => domain[0] === 'id' && domain[1] === 'not in');
if (selectedIdsDomainIndex > -1) {
this.createWidget.options.domain[selectedIdsDomainIndex] = selectedIdsDomain;
if (selectedIdsDomain) {
this.createWidget.options.domain[selectedIdsDomainIndex] = selectedIdsDomain;
} else {
this.createWidget.options.domain.splice(selectedIdsDomainIndex, 1);
}
} else {
this.createWidget.options.domain = [...this.createWidget.options.domain, selectedIdsDomain];
if (selectedIdsDomain) {
this.createWidget.options.domain = [...this.createWidget.options.domain, selectedIdsDomain];
}
}
this.createWidget.setValue('');
this.createWidget.inputEl.value = '';