[FIX] web: update column data when adding a record in a kanban

When a record was added in a kanban thanks to the quick create, column
tooltip and column progressbar were not updating the values they showed.
Now, adding/deleting records updates the whole column as the update
operations.

Thanks to @kig-odoo for the test.

Note: to backport (partially)
This commit is contained in:
qsm-odoo
2017-09-30 18:39:13 +02:00
parent a09462b7fc
commit 1d34e269da
4 changed files with 89 additions and 102 deletions
@@ -18,7 +18,6 @@ var KanbanColumn = Widget.extend({
template: 'KanbanView.Group',
custom_events: {
cancel_quick_create: '_onCancelQuickCreate',
kanban_record_delete: '_onDeleteRecord',
quick_create_add_record: '_onQuickCreateAddRecord',
tweak_column: '_onTweakColumn',
tweak_column_records: '_onTweakColumnRecords',
@@ -45,7 +44,6 @@ var KanbanColumn = Widget.extend({
this.id = data.res_id || value;
this.folded = !data.isOpen;
this.has_active_field = 'active' in data.fields;
this.size = data.count;
this.fields = data.fields;
this.records = [];
this.modelName = data.model;
@@ -59,7 +57,7 @@ var KanbanColumn = Widget.extend({
this.records_deletable = options.records_deletable;
this.relation = options.relation;
this.offset = 0;
this.remaining = this.size - this.data_records.length;
this.remaining = data.count - this.data_records.length;
if (options.hasProgressBar) {
this.barOptions = {
@@ -95,7 +93,7 @@ var KanbanColumn = Widget.extend({
this.$header = this.$('.o_kanban_header');
for (var i = 0; i < this.data_records.length; i++) {
this.addRecord(this.data_records[i], {no_update: true});
this._addRecord(this.data_records[i]);
}
this.$header.find('.o_kanban_header_title').tooltip();
@@ -112,7 +110,6 @@ var KanbanColumn = Widget.extend({
cursor: 'move',
over: function () {
self.$el.addClass('o_kanban_hover');
self._update();
},
out: function () {
self.$el.removeClass('o_kanban_hover');
@@ -145,7 +142,20 @@ var KanbanColumn = Widget.extend({
defs.push(this.progressBar.appendTo(this.$header));
}
return $.when.apply($, defs).then(this._update.bind(this));
var title = this.folded ? this.title + ' (' + this.data.count + ')' : this.title;
this.$header.find('.o_column_title').text(title);
this.$el.toggleClass('o_column_folded', this.folded && !config.device.isMobile);
var tooltip = this.data.count + _t(' records');
tooltip = '<p>' + tooltip + '</p>' + this.tooltipInfo;
this.$header.find('.o_kanban_header_title').tooltip({html: true}).attr('data-original-title', tooltip);
if (!this.remaining) {
this.$('.o_kanban_load_more').remove();
} else {
this.$('.o_kanban_load_more').html(QWeb.render('KanbanView.LoadMore', {widget: this}));
}
return $.when.apply($, defs);
},
//--------------------------------------------------------------------------
@@ -163,19 +173,30 @@ var KanbanColumn = Widget.extend({
this.quickCreateWidget = new RecordQuickCreate(this, width);
this.quickCreateWidget.insertAfter(this.$header);
},
/**
* @returns {Boolean} true iff the column is empty
*/
isEmpty: function () {
return !this.records.length;
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* Adds a record in the column.
*
* @private
* @param {Object} recordState
* @param {Object} options
* @params {string} options.position 'before' to add the record at the top,
* added at the bottom by default
* @params {Boolean} options.no_update set to true not to update the column
* @param {Object} [options]
* @param {string} [options.position]
* 'before' to add at the top, add at the bottom by default
*/
addRecord: function (recordState, options) {
_addRecord: function (recordState, options) {
var record = new KanbanRecord(this, recordState, this.record_options);
this.records.push(record);
if (options.position === 'before') {
if (options && options.position === 'before') {
record.insertAfter(this.quickCreateWidget ? this.quickCreateWidget.$el : this.$header);
} else {
var $load_more = this.$('.o_kanban_load_more');
@@ -185,33 +206,7 @@ var KanbanColumn = Widget.extend({
record.appendTo(this.$el);
}
}
if (!options.no_update) {
this._update();
}
},
/**
* @returns {Boolean} true iff the column is empty
*/
isEmpty: function () {
return !this.records.length;
},
/**
* Updates the column progressBar and sets the new data. New data are
* supposed to already match column rendering (except for the progressBar).
*
* @param {Object} data
*/
updateProgressBar: function (data) {
this.data = data;
if (!this.folded && this.progressBar) {
this.progressBar.update(this.data);
}
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* Destroys the QuickCreate widget.
*
@@ -231,25 +226,6 @@ var KanbanColumn = Widget.extend({
});
return ids;
},
/**
* @private
*/
_update: function () {
var title = this.folded ? this.title + ' (' + this.size + ')' : this.title;
this.$header.find('.o_column_title').text(title);
this.$header.find('.o-kanban-count').text(this.records.length);
this.$el.toggleClass('o_column_folded', this.folded && !config.device.isMobile);
var tooltip = this.size + _t(' records');
tooltip = '<p>' + tooltip + '</p>' + this.tooltipInfo;
this.$header.find('.o_kanban_header_title').tooltip({html: true}).attr('data-original-title', tooltip);
if (!this.remaining) {
this.$('.o_kanban_load_more').remove();
} else {
this.$('.o_kanban_load_more').html(QWeb.render('KanbanView.LoadMore', {widget: this}));
}
this.updateProgressBar(this.data);
},
//--------------------------------------------------------------------------
// Handlers
@@ -298,19 +274,6 @@ var KanbanColumn = Widget.extend({
}),
}).open();
},
/**
* @private
* @param {OdooEvent} event
*/
_onDeleteRecord: function (event) {
var self = this;
event.data.parent_id = this.db_id;
event.data.after = function cleanup() {
var index = self.records.indexOf(event.data.record);
self.records.splice(index, 1);
self._update();
};
},
/**
* @private
* @param {MouseEvent} event
@@ -24,6 +24,7 @@ var KanbanColumnProgressBar = Widget.extend({
this._super.apply(this, arguments);
this.columnID = options.columnID;
this.columnState = columnState;
// <progressbar/> attributes
this.fieldName = columnState.progressBarValues.field;
@@ -70,37 +71,27 @@ var KanbanColumnProgressBar = Widget.extend({
}
}
return this._super.apply(this, arguments);
},
return this._super.apply(this, arguments).then(function () {
// This should be executed when the progressbar is fully rendered
// and is in the DOM, this happens to be always the case with
// current use of progressbars
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
var subgroupCounts = {};
_.each(self.colors, function (val, key) {
var subgroupCount = self.columnState.progressBarValues.counts[key] || 0;
if (self.activeFilter === key && subgroupCount === 0) {
self.activeFilter = false;
}
subgroupCounts[key] = subgroupCount;
});
/**
* Updates internal data and rendering according to new received column
* state.
*
* @param {Object} columnState
*/
update: function (columnState) {
var self = this;
var subgroupCounts = {};
_.each(self.colors, function (val, key) {
var subgroupCount = columnState.progressBarValues.counts[key] || 0;
if (self.activeFilter === key && subgroupCount === 0) {
self.activeFilter = false;
}
subgroupCounts[key] = subgroupCount;
self.groupCount = self.columnState.count;
self.subgroupCounts = subgroupCounts;
self.prevTotalCounterValue = self.totalCounterValue;
self.totalCounterValue = self.sumField ? (self.columnState.aggregateValues[self.sumField] || 0) : self.columnState.count;
self._notifyState();
self._render();
});
this.groupCount = columnState.count;
this.subgroupCounts = subgroupCounts;
this.prevTotalCounterValue = this.totalCounterValue;
this.totalCounterValue = this.sumField ? (columnState.aggregateValues[this.sumField] || 0) : columnState.count;
this._notifyState();
this._render();
},
//--------------------------------------------------------------------------
@@ -353,10 +353,13 @@ var KanbanController = BasicController.extend({
.addRecordToGroup(columnState.id, records[0])
.then(function (db_id) {
self._updateEnv();
column.addRecord(self.model.get(db_id), {position: 'before'});
if (event.data.openRecord) {
self.trigger_up('open_record', {id: db_id, mode: 'edit'});
}
var columnState = self.model.getColumn(db_id);
return self.renderer.updateColumn(columnState.id, columnState).then(function () {
if (event.data.openRecord) {
self.trigger_up('open_record', {id: db_id, mode: 'edit'});
}
});
});
}
},
@@ -2061,6 +2061,36 @@ QUnit.module('Views', {
kanban.destroy();
});
QUnit.test('column progressbars on quick create properly update counter', function (assert) {
assert.expect(1);
var kanban = createView({
View: KanbanView,
model: 'partner',
data: this.data,
arch:
'<kanban>' +
'<progressbar field="foo" colors=\'{"yop": "success", "gnap": "warning", "blip": "danger"}\'/>' +
'<templates><t t-name="kanban-box">' +
'<div>' +
'<field name="name"/>' +
'</div>' +
'</t></templates>' +
'</kanban>',
groupBy: ['bar'],
});
var initialCount = parseInt(kanban.$('.o_kanban_counter_side').eq(1).text());
kanban.$('.o_kanban_quick_add').eq(1).click();
kanban.$('.o_input').val('Test');
kanban.$('.o_kanban_add').click();
var lastCount = parseInt(kanban.$('.o_kanban_counter_side').eq(1).text());
assert.strictEqual(lastCount, initialCount + 1,
"kanban counters should have updated on quick create");
kanban.destroy();
});
QUnit.test('keep adding quickcreate in first column after a record from this column was moved', function (assert) {
assert.expect(2);