[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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user