summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorMartin Trigaux <mat@odoo.com>2019-07-16 09:14:17 +0000
committerMartin Trigaux <mat@odoo.com>2019-07-16 09:14:17 +0000
commitcf8e74a1a7d3404f57798573e8b15ce4dc5b9be4 (patch)
treebd95e9d20aff9b4f92550bffb2835a55c3698c27 /addons/web/static/src
parentb67a3bb403b80e98a2b66dcb8cf570d2b156fb68 (diff)
parent1bd434da34731b5467cc17fdffe6f3ed5dfea2d4 (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.js104
-rw-r--r--addons/web/static/src/scss/list_view.scss4
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;
}