[IMP] web: improve statusbar widget performance

Purpose:
Improve performance/reduce server load for the status bar widget when
the underlying field is a m2o.

Before this commit:

The status bar widget does two calls:
- a search_read request to retrieve ids and folds
- a name_get to retrieve names

With this commit:

The name_get can be avoided to save a call by fetching display_name in
the search_read.
This commit removes the name_get call to retrieve the name directly
from search_read.

task-2919535

closes odoo/odoo#98164

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Dardenne Florent (dafl)
2022-08-23 17:55:18 +02:00
parent 29468b1272
commit d3905b5bb7
4 changed files with 13 additions and 39 deletions
@@ -2914,31 +2914,12 @@ var BasicModel = AbstractModel.extend({
return Promise.resolve();
}
var self = this;
return this._rpc({
model: field.relation,
method: 'search_read',
fields: ["id"].concat(fieldsToRead || []),
fields: ["display_name"].concat(fieldsToRead || []),
context: context,
domain: domain,
})
.then(function (records) {
var ids = _.pluck(records, 'id');
return self._rpc({
model: field.relation,
method: 'name_get',
args: [ids],
context: context,
})
.then(function (name_gets) {
_.each(records, function (rec) {
var name_get = _.find(name_gets, function (n) {
return n[0] === rec.id;
});
rec.display_name = name_get[1];
});
return records;
});
});
},
/**
@@ -190,7 +190,7 @@ StatusBarField.extractProps = ({ attrs, field }) => {
registry.category("fields").add("statusbar", StatusBarField);
export async function preloadStatusBar(orm, record, fieldName) {
const fieldNames = ["id"];
const fieldNames = ["id", "display_name"];
const foldField = record.activeFields[fieldName].options.fold_field;
if (foldField) {
fieldNames.push(foldField);
@@ -203,18 +203,7 @@ export async function preloadStatusBar(orm, record, fieldName) {
}
const relation = record.fields[fieldName].relation;
const records = await orm.searchRead(relation, domain, fieldNames);
const foldMap = {};
for (const rec of records) {
foldMap[rec.id] = rec[foldField];
}
const nameGets = await orm.call(relation, "name_get", [records.map((rec) => rec.id)]);
return nameGets.map((nameGet) => ({
id: nameGet[0],
name: nameGet[1],
isFolded: foldField ? foldMap[nameGet[0]] : false,
}));
return await orm.searchRead(relation, domain, fieldNames);
}
registry.category("preloadedData").add("statusbar", {
@@ -764,7 +764,7 @@ QUnit.module('Legacy relational_fields', {
this.data.partner.records[1].bar = false;
var count = 0;
var nb_fields_fetched;
var fieldsFetched;
var form = await createView({
View: FormView,
model: 'partner',
@@ -778,7 +778,7 @@ QUnit.module('Legacy relational_fields', {
mockRPC: function (route, args) {
if (args.method === 'search_read') {
count++;
nb_fields_fetched = args.kwargs.fields.length;
fieldsFetched = args.kwargs.fields;
}
return this._super.apply(this, arguments);
},
@@ -787,7 +787,7 @@ QUnit.module('Legacy relational_fields', {
});
assert.strictEqual(count, 1, 'once search_read should have been done to fetch the relational values');
assert.strictEqual(nb_fields_fetched, 1, 'search_read should only fetch field id');
assert.deepEqual(fieldsFetched, ['display_name'], 'search_read should only fetch field display_name');
assert.containsN(form, '.o_statusbar_status button:not(.dropdown-toggle)', 2);
assert.containsN(form, '.o_statusbar_status button:disabled', 2);
assert.hasClass(form.$('.o_statusbar_status button[data-value="4"]'), 'btn-primary');
@@ -134,7 +134,7 @@ QUnit.module("Fields", (hooks) => {
serverData.models.partner.records[1].bar = false;
let count = 0;
let fetchFieldCount = 0;
let fieldsFetched = [];
await makeView({
type: "form",
resModel: "partner",
@@ -149,7 +149,7 @@ QUnit.module("Fields", (hooks) => {
mockRPC(route, { method, kwargs }) {
if (method === "search_read") {
count++;
fetchFieldCount = kwargs.fields.length;
fieldsFetched = kwargs.fields;
}
},
});
@@ -159,7 +159,11 @@ QUnit.module("Fields", (hooks) => {
1,
"once search_read should have been done to fetch the relational values"
);
assert.strictEqual(fetchFieldCount, 1, "search_read should only fetch field id");
assert.deepEqual(
fieldsFetched,
["display_name"],
"search_read should only fetch field display_name"
);
assert.containsN(target, ".o_statusbar_status button:not(.dropdown-toggle)", 2);
assert.containsN(target, ".o_statusbar_status button:disabled", 2);
assert.hasClass(