summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Geubelle <mge@odoo.com>2018-04-11 14:47:03 +0200
committerMartin Geubelle <mge@odoo.com>2018-04-12 10:10:08 +0200
commit729ff2d35eeac7db8cf5fa16009d5c918ee1dd5b (patch)
treedf6a065d95e69cb63f27f3943640c4dba3e37389
parent73425edfe9e03c8ea7e97ab9d7cd6eddec718849 (diff)
[FIX] web: update column in grouped kanban
In a kanban grouped by many2one with a progressbar, after emptying a column by moving all records, the column wasn't correctly updated. This was causing, in the best case, a record duplication or, in the worst case, a traceback. This issue comes from the fact that, with a progressbar, a read_group is performed each time a record is moved. When the group (column) becomes empty, the read_group won't return this group even though the group still appears in the kankan. When moving back the record in this empty column, there is a desynchronization between the kanban controller data and the model. To fix this issue, an option `keepEmptyGroups` is passed when performing the mentioned read_group ; this mimics the kanban display that keeps empty groups displayed and there is no desync anymore. Fixes #23982
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js13
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_model.js5
-rw-r--r--addons/web/static/tests/views/kanban_tests.js45
3 files changed, 62 insertions, 1 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 979f8ae3fec..0b2d35cb89f 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -3166,6 +3166,9 @@ var BasicModel = AbstractModel.extend({
* @param {Object} [options]
* @param {string[]} [options.fieldNames] the fields to fetch for a record
* @param {boolean} [options.onlyGroups=false]
+ * @param {boolean} [options.keepEmptyGroups=false] if set, the groups not
+ * present in the read_group anymore (empty groups) will stay in the
+ * datapoint (used to mimic the kanban renderer behaviour for example)
* @returns {Deferred}
*/
_load: function (dataPoint, options) {
@@ -3796,6 +3799,16 @@ var BasicModel = AbstractModel.extend({
defs.push(self._load(newGroup, options));
}
});
+ if (options && options.keepEmptyGroups) {
+ // Find the groups that were available in a previous
+ // readGroup but are not there anymore.
+ // Note that these groups are put after existing groups so
+ // the order is not conserved. A sort *might* be useful.
+ var emptyGroupsIDs = _.difference(_.pluck(previousGroups, 'id'), list.data);
+ _.each(emptyGroupsIDs, function (groupID) {
+ list.data.push(groupID);
+ });
+ }
return $.when.apply($, defs).then(function () {
// generate the res_ids of the main list, being the concatenation
// of the fetched res_ids in each group
diff --git a/addons/web/static/src/js/views/kanban/kanban_model.js b/addons/web/static/src/js/views/kanban/kanban_model.js
index 0b0ec09ddf4..427d10f6032 100644
--- a/addons/web/static/src/js/views/kanban/kanban_model.js
+++ b/addons/web/static/src/js/views/kanban/kanban_model.js
@@ -369,7 +369,10 @@ var KanbanModel = BasicModel.extend({
while (element) {
if (element.progressBar) {
return def.then(function (data) {
- return self._load(element, {onlyGroups: true}).then(function () {
+ return self._load(element, {
+ keepEmptyGroups: true,
+ onlyGroups: true,
+ }).then(function () {
return data;
});
});
diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js
index a820eeb4876..190d94a6c7f 100644
--- a/addons/web/static/tests/views/kanban_tests.js
+++ b/addons/web/static/tests/views/kanban_tests.js
@@ -2544,6 +2544,51 @@ QUnit.module('Views', {
kanban.destroy();
});
+ QUnit.test('drag & drop records grouped by m2o with progressbar', function (assert) {
+ assert.expect(4);
+
+ this.data.partner.records[0].product_id = false;
+
+ 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="int_field"/>' +
+ '</div>' +
+ '</t></templates>' +
+ '</kanban>',
+ groupBy: ['product_id'],
+ mockRPC: function (route, args) {
+ if (route === '/web/dataset/resequence') {
+ return $.when(true);
+ }
+ return this._super(route, args);
+ },
+ });
+
+ assert.strictEqual(kanban.$('.o_kanban_group:eq(0) .o_kanban_counter_side').text(), "1",
+ "counter should contain the correct value");
+
+ testUtils.dragAndDrop(kanban.$('.o_kanban_group:eq(0) .o_kanban_record:eq(0)'), kanban.$('.o_kanban_group:eq(1)'));
+ assert.strictEqual(kanban.$('.o_kanban_group:eq(0) .o_kanban_counter_side').text(), "0",
+ "counter should contain the correct value");
+
+ testUtils.dragAndDrop(kanban.$('.o_kanban_group:eq(1) .o_kanban_record:eq(2)'), kanban.$('.o_kanban_group:eq(0)'));
+ assert.strictEqual(kanban.$('.o_kanban_group:eq(0) .o_kanban_counter_side').text(), "1",
+ "counter should contain the correct value");
+
+ testUtils.dragAndDrop(kanban.$('.o_kanban_group:eq(0) .o_kanban_record:eq(0)'), kanban.$('.o_kanban_group:eq(1)'));
+ assert.strictEqual(kanban.$('.o_kanban_group:eq(0) .o_kanban_counter_side').text(), "0",
+ "counter should contain the correct value");
+
+ kanban.destroy();
+ });
+
QUnit.test('keep adding quickcreate in first column after a record from this column was moved', function (assert) {
assert.expect(2);