From d2cb04c7a5ff19ebcd6130e8466059fc50dcc668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Mon, 18 Jan 2016 11:58:04 +0100 Subject: [PATCH] [FIX] web_kanban: fix race conditions on do_search The do_search method was clearly written by someone who doesn't understand how asynchronous code works. If several do_search are quickly called in succession, there is no guarantee that the do_load calls will return in the chronological order, so it could happen that the kanban view render an inconsistent state. This commit makes sure that only the last search entered is rendered. --- .../web_kanban/static/src/js/kanban_view.js | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/addons/web_kanban/static/src/js/kanban_view.js b/addons/web_kanban/static/src/js/kanban_view.js index 6d9c9baec06..fd7d2f9c9ed 100644 --- a/addons/web_kanban/static/src/js/kanban_view.js +++ b/addons/web_kanban/static/src/js/kanban_view.js @@ -80,7 +80,7 @@ var KanbanView = View.extend({ this.model = dataset.model; this.quick_creatable = options.quick_creatable; this.no_content_msg = options.action && (options.action.get_empty_list_help || options.action.help); - + this.search_orderer = new utils.DropMisordered(); }, view_loading: function(fvg) { @@ -108,16 +108,32 @@ var KanbanView = View.extend({ }, do_search: function(domain, context, group_by) { - this.search_domain = domain; - this.search_context = context; - this.group_by_field = group_by[0] || this.default_group_by; - this.grouped = group_by.length || this.default_group_by; + var self = this; + var group_by_field = group_by[0] || this.default_group_by; + var field = this.fields_view.fields[group_by_field]; + var grouped_by_m2o = field && (field.type === 'many2one'); - var field = this.fields_view.fields[this.group_by_field]; - this.grouped_by_m2o = field && (field.type === 'many2one'); - this.relation = this.grouped_by_m2o ? field.relation : undefined; + var options = { + search_domain: domain, + search_context: context, + group_by_field: group_by_field, + grouped: group_by.length || this.default_group_by, + grouped_by_m2o: grouped_by_m2o, + relation: (grouped_by_m2o ? field.relation : undefined), + }; - return this.load_data() + return this.search_orderer + .add(options.grouped ? this.load_groups(options) : this.load_records()) + .then(function (data) { + _.extend(self, options); + if (options.grouped) { + var new_ids = _.union.apply(null, _.map(data.groups, function (group) { + return group.dataset.ids; + })); + self.dataset.alter_ids(new_ids); + } + self.data = data; + }) .then(this.proxy('render')) .then(this.proxy('update_pager')); }, @@ -131,20 +147,6 @@ var KanbanView = View.extend({ this.do_search(this.search_domain, this.search_context, [this.group_by_field]); }, - load_data: function () { - var self = this; - var deferred = this.grouped ? this.load_groups() : this.load_records(); - return deferred.then(function (data) { - self.data = data; - if (self.grouped) { - var new_ids = _.union.apply(null, _.map(data.groups, function (group) { - return group.dataset.ids; - })); - self.dataset.alter_ids(new_ids); - } - }); - }, - load_records: function (offset, dataset) { var options = { 'limit': this.limit, @@ -162,13 +164,13 @@ var KanbanView = View.extend({ }); }, - load_groups: function () { + load_groups: function (options) { var self = this; - var group_by_field = this.group_by_field || this.default_group_by; - this.fields_keys = _.uniq(this.fields_keys.concat(group_by_field)); + var group_by_field = options.group_by_field; + var fields_keys = _.uniq(this.fields_keys.concat(group_by_field)); - return new Model(this.model, this.search_context, this.search_domain) - .query(this.fields_keys) + return new Model(this.model, options.search_context, options.search_domain) + .query(fields_keys) .group_by([group_by_field]) .then(function (groups) { @@ -205,8 +207,8 @@ var KanbanView = View.extend({ // fetch group data (display information) var group_ids = _.without(_.map(groups, function (elem) { return elem.attributes.value[0];}), undefined); - if (self.grouped_by_m2o && group_ids.length) { - return new data.DataSet(self, self.relation) + if (options.grouped_by_m2o && group_ids.length) { + return new data.DataSet(self, options.relation) .read_ids(group_ids, _.union(['display_name'], group_by_fields_to_read)) .then(function(results) { _.each(groups, function (group) { @@ -223,7 +225,7 @@ var KanbanView = View.extend({ _.each(groups, function (group) { var value = group.attributes.value; group.id = value instanceof Array ? value[0] : value; - var field = self.fields_view.fields[self.group_by_field]; + var field = self.fields_view.fields[options.group_by_field]; if (field && field.type === "selection") { value= _.find(field.selection, function (s) { return s[0] === group.id; }); }