diff options
| author | Martin Trigaux <mat@odoo.com> | 2019-07-16 09:14:17 +0000 |
|---|---|---|
| committer | Martin Trigaux <mat@odoo.com> | 2019-07-16 09:14:17 +0000 |
| commit | cf8e74a1a7d3404f57798573e8b15ce4dc5b9be4 (patch) | |
| tree | bd95e9d20aff9b4f92550bffb2835a55c3698c27 /addons/web/static/src | |
| parent | b67a3bb403b80e98a2b66dcb8cf570d2b156fb68 (diff) | |
| parent | 1bd434da34731b5467cc17fdffe6f3ed5dfea2d4 (diff) | |
[MERGE] Forward port of 12.0 to saas-12.2 up to 1bd434da34731b546
closes odoo/odoo#34901
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Diffstat (limited to 'addons/web/static/src')
| -rw-r--r-- | addons/web/static/src/js/views/basic/basic_model.js | 104 | ||||
| -rw-r--r-- | addons/web/static/src/scss/list_view.scss | 4 |
2 files changed, 103 insertions, 5 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index 95003e2226f..1e6bb9af0f0 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -144,6 +144,8 @@ var BasicModel = AbstractModel.extend({ 'ir.filters', 'ir.ui.view', ], + // FORWARDPORT THIS UP TO 12.2, NOT FURTHER + disableBatchedRPCs: false, // to be overriden in tests /** * @override @@ -154,6 +156,11 @@ var BasicModel = AbstractModel.extend({ // save is performed. this.mutex = new concurrency.Mutex(); + // FORWARDPORT THIS UP TO 12.2, NOT FURTHER + // this array is used to accumulate RPC requests done in the same call + // stack, so that they can be batched in the minimum number of RPCs + this.batchedRPCsRequests = []; + this.localData = Object.create(null); this._super.apply(this, arguments); }, @@ -4103,6 +4110,93 @@ var BasicModel = AbstractModel.extend({ return $.when.apply($, defs); }, + // FORWARDPORT THIS UP TO 12.2, NOT FURTHER + /** + * Empty the pool of accumulated RPC requests: regroup similar requests in + * batches and perform an RPC for each batch. + * + * @private + */ + _performBatchedRPCs: function () { + if (!this.batchedRPCsRequests.length) { + // pool has already been processed + return; + } + + // reset pool of RPC requests + var batchedRPCsRequests = this.batchedRPCsRequests; + this.batchedRPCsRequests = []; + + // batch similar requests + var batches = {}; + var key; + for (var i = 0; i < batchedRPCsRequests.length; i++) { + var request = batchedRPCsRequests[i]; + key = request.model + ',' + JSON.stringify(request.context); + if (!batches[key]) { + batches[key] = _.extend({}, request, {requests: [request]}); + } else { + batches[key].ids = _.uniq(batches[key].ids.concat(request.ids)); + batches[key].fieldNames = _.uniq(batches[key].fieldNames.concat(request.fieldNames)); + batches[key].requests.push(request); + } + } + + // perform batched RPCs + function onSuccess(batch, results) { + for (var i = 0; i < batch.requests.length; i++) { + var request = batch.requests[i]; + var fieldNames = request.fieldNames.concat(['id']); + var filteredResults = results.filter(function (record) { + return request.ids.indexOf(record.id) >= 0; + }).map(function (record) { + return _.pick(record, fieldNames); + }); + request.def.resolve(filteredResults); + } + } + function onFailure(batch, error) { + for (var i = 0; i < batch.requests.length; i++) { + var request = batch.requests[i]; + request.def.reject(error); + } + } + for (key in batches) { + var batch = batches[key]; + this._rpc({ + model: batch.model, + method: 'read', + args: [batch.ids, batch.fieldNames], + context: batch.context, + }).then(onSuccess.bind(null, batch)).fail(onFailure.bind(null, batch)); + } + }, + /** + * This function accumulates RPC requests done in the same call stack, and + * performs them in the next micro task tick so that similar requests can be + * batched in a single RPC. + * + * For now, only 'read' calls are supported. + * + * @private + * @param {Object} params + * @returns {Promise} + */ + _performRPC: function (params) { + // save the RPC request + var def = $.Deferred(); + var request = _.extend({}, params, {def: def}); + this.batchedRPCsRequests.push(request); + + if (this.disableBatchedRPCs) { + this._performBatchedRPCs(); + } else { + // empty the pool of RPC requests in the next tick + setTimeout(this._performBatchedRPCs.bind(this)); + } + + return def; + }, /** * Reads data from server for all missing fields. * @@ -4132,11 +4226,13 @@ var BasicModel = AbstractModel.extend({ var def; if (missingIDs.length && fieldNames.length) { - def = self._rpc({ - model: list.model, - method: 'read', - args: [missingIDs, fieldNames], + // FORWARDPORT THIS UP TO 12.2, NOT FURTHER + def = self._performRPC({ context: list.getContext(), + fieldNames: fieldNames, + ids: missingIDs, + method: 'read', + model: list.model, }); } else { def = $.when(_.map(missingIDs, function (id) { diff --git a/addons/web/static/src/scss/list_view.scss b/addons/web/static/src/scss/list_view.scss index 55f5b755df1..98baf231966 100644 --- a/addons/web/static/src/scss/list_view.scss +++ b/addons/web/static/src/scss/list_view.scss @@ -10,9 +10,11 @@ border-collapse: initial; border-spacing: 0; - // Checkbox in editable list + // Boolean Widgets in editable list // should be clickable and activate the row &.o_editable_list .o_data_row:not(.o_selected_row) .o_data_cell { + &.o_toggle_button_cell:not(.o_readonly_modifier) button, // registry: toggle_button + &.o_boolean_favorite_cell:not(.o_readonly_modifier) .o_favorite, // registry: boolean_favorite .custom-checkbox:not(.o_readonly_modifier) { pointer-events: none; } |
