[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.
This commit is contained in:
Géry Debongnie
2016-01-18 16:30:19 +01:00
parent 24c41e3d31
commit d2cb04c7a5
+33 -31
View File
@@ -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; });
}