[FIX] web: Allow default favorite filter over search default

Before this commit, when a search_default on a many2one field tried to
update its label after a name_get, the value was set on its initial
associated query element which could have been erased by a default
favorite.

Now, the model determines whether there is a default favorite before
processing default filters, preventing any unnecessary RPC.

closes odoo/odoo#53840

X-original-commit: ff834d0ba6f9b7eadc23c28dbbf892eba2058583
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Julien Mougenot
2020-06-30 07:22:12 +00:00
parent 7e5ae026fd
commit c96de07f85
2 changed files with 78 additions and 18 deletions
@@ -544,23 +544,13 @@ odoo.define('web.ControlPanelModel', function (require) {
* @private
*/
_activateDefaultFilters() {
const defaultFilters = [];
const defaultFavorites = [];
for (const fId in this.state.filters) {
if (this.state.filters[fId].isDefault) {
if (this.state.filters[fId].type === 'favorite') {
defaultFavorites.push(this.state.filters[fId]);
} else {
defaultFilters.push(this.state.filters[fId]);
}
}
}
if (this.activateDefaultFavorite && defaultFavorites.length) {
if (this.defaultFavoriteId) {
// Activate default favorite
this.toggleFilter(defaultFavorites[0].id);
this.toggleFilter(this.defaultFavoriteId);
} else {
// Activate default filters
defaultFilters
Object.values(this.state.filters)
.filter((f) => f.isDefault && f.type !== 'favorite')
.sort((f1, f2) => (f1.defaultRank || 100) - (f2.defaultRank || 100))
.forEach(f => {
if (f.hasOptions) {
@@ -589,9 +579,9 @@ odoo.define('web.ControlPanelModel', function (require) {
* @private
*/
_addFilters() {
this._createGroupOfFavorites();
this._createGroupOfFiltersFromArch();
this._createGroupOfDynamicFilters();
this._createGroupOfFavorites();
}
/**
@@ -707,6 +697,9 @@ odoo.define('web.ControlPanelModel', function (require) {
this.favoriteFilters.forEach(irFilter => {
const favorite = this._irFilterToFavorite(irFilter);
this._createGroupOfFilters([favorite]);
if (this.activateDefaultFavorite && favorite.isDefault) {
this.defaultFavoriteId = favorite.id;
}
});
}
@@ -721,7 +714,7 @@ odoo.define('web.ControlPanelModel', function (require) {
pregroup.forEach(preFilter => {
const filter = Object.assign(preFilter, { groupId, id: filterId });
this.state.filters[filterId] = filter;
if (filter.isDefault && filter.type === 'field') {
if (!this.defaultFavoriteId && filter.isDefault && filter.type === 'field') {
this._prepareDefaultLabel(filter);
}
filterId++;
@@ -4,9 +4,9 @@ odoo.define('web.control_panel_model_tests', function (require) {
const ControlPanelModel = require('web.ControlPanelModel');
const makeTestEnvironment = require('web.test_env');
function createControlPanelModel(config = {}) {
function createControlPanelModel(config = {}, env, rpc) {
return new ControlPanelModel(Object.assign(
{ env: makeTestEnvironment() },
{ env: makeTestEnvironment(env, rpc) },
config
));
}
@@ -356,5 +356,72 @@ odoo.define('web.control_panel_model_tests', function (require) {
});
QUnit.test('search default field many2one with filter domain', async function (assert) {
assert.expect(3);
const actionContext = {
search_default_bar: 20,
};
const arch = `
<search>
<field name="bar" string="Partner" filter_domain="[('bar', 'ilike', self)]"/>
</search>`;
const fields = this.fields;
const model = createControlPanelModel(
{ viewInfo: { arch, fields }, actionContext }, {},
async function mockRPC(route, params) {
assert.deepEqual(params, {
args: [20],
kwargs: {},
method: "name_get",
model: "partner",
});
return [[20, "Gandalf"]];
}
);
// Labels not fetched: self = undefined
assert.throws(() => model.getQuery());
await model.isReady;
// Labels fetched: domain should be ready
assert.deepEqual(model.getQuery().domain, [["bar", "ilike", "Gandalf"]]);
});
QUnit.test('search default field many2one with filter domain and default favorite', async function (assert) {
assert.expect(2);
const actionContext = {
search_default_bar: 20,
};
const arch = `
<search>
<field name="bar" string="Partner" filter_domain="[('bar', 'ilike', self)]"/>
</search>`;
const favoriteFilters = [{
domain: "[('user_id', '=', uid)]",
id: 5,
is_default: true,
name: 'Sorted filter',
user_id: [2, "Mitchell Admin"],
}];
const fields = this.fields;
const model = createControlPanelModel(
{ viewInfo: { arch, favoriteFilters, fields }, actionContext },
{ session: { user_context: { uid: 2 } } },
async function mockRPC() {
throw new Error("There should be no name_get");
}
);
// Labels not fetched, but favorite overrides search_default
assert.deepEqual(model.getQuery().domain, [["user_id", "=", 2]]);
await model.isReady;
// domain should be the same
assert.deepEqual(model.getQuery().domain, [["user_id", "=", 2]]);
});
});
});