From d3905b5bb7e8d40a55fb985c58532e8b18a022f3 Mon Sep 17 00:00:00 2001 From: "Dardenne Florent (dafl)" Date: Tue, 16 Aug 2022 10:43:05 +0000 Subject: [PATCH] [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) --- .../src/legacy/js/views/basic/basic_model.js | 21 +------------------ .../views/fields/statusbar/statusbar_field.js | 15 ++----------- .../legacy/fields/relational_fields_tests.js | 6 +++--- .../views/fields/statusbar_field_tests.js | 10 ++++++--- 4 files changed, 13 insertions(+), 39 deletions(-) diff --git a/addons/web/static/src/legacy/js/views/basic/basic_model.js b/addons/web/static/src/legacy/js/views/basic/basic_model.js index 531324d4ecc..e7ebc36e1dd 100644 --- a/addons/web/static/src/legacy/js/views/basic/basic_model.js +++ b/addons/web/static/src/legacy/js/views/basic/basic_model.js @@ -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; - }); }); }, /** diff --git a/addons/web/static/src/views/fields/statusbar/statusbar_field.js b/addons/web/static/src/views/fields/statusbar/statusbar_field.js index d050d4e908e..3fa8ebfb849 100644 --- a/addons/web/static/src/views/fields/statusbar/statusbar_field.js +++ b/addons/web/static/src/views/fields/statusbar/statusbar_field.js @@ -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", { diff --git a/addons/web/static/tests/legacy/fields/relational_fields_tests.js b/addons/web/static/tests/legacy/fields/relational_fields_tests.js index fbba3823add..2ae838787dc 100644 --- a/addons/web/static/tests/legacy/fields/relational_fields_tests.js +++ b/addons/web/static/tests/legacy/fields/relational_fields_tests.js @@ -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'); diff --git a/addons/web/static/tests/views/fields/statusbar_field_tests.js b/addons/web/static/tests/views/fields/statusbar_field_tests.js index 0f14d88a9eb..41cea5f2aa4 100644 --- a/addons/web/static/tests/views/fields/statusbar_field_tests.js +++ b/addons/web/static/tests/views/fields/statusbar_field_tests.js @@ -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(