summaryrefslogtreecommitdiff
path: root/addons/web/static
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2018-01-19 08:39:26 +0100
committerAaron Bohy <aab@odoo.com>2018-01-19 09:57:41 +0100
commitac0e4528904064cc85fe47ef3a2d211edd634f0c (patch)
tree60a13b445a7f048eccd331ca1c1fede077ac2989 /addons/web/static
parent66a95d91aa8e64f8a791c0be9a43c9d4446d2a1e (diff)
[FIX] web: Kanban: create several records on slow network
Before this rev., it crashed when the user used the quick create to create several records (very quickly, or on a slow network), e.g. on crm.lead (there must be a date field on the kanban record to reproduce the crash). The crash occurred when the 'read' RPCs for the created records return misordered. For instance: 1) 'name_create' record 1 (called and returned) 2) call 'read' for record 1 3) 'name_create' record 2 (called and returned) 4) call 'read' for record 2 5) 'read' for record 2 returns 6) 'read' for record 1 returns At step 5, the kanban column was updated with the new state, but this state already contained record 1, which wasn't fetched yet. This rev. ensures that the created records are added to the state once they are fetched and ready to be displayed, not before.
Diffstat (limited to 'addons/web/static')
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_model.js16
-rw-r--r--addons/web/static/tests/views/kanban_tests.js74
2 files changed, 83 insertions, 7 deletions
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 aba59555e93..df6172f0d8b 100644
--- a/addons/web/static/src/js/views/kanban/kanban_model.js
+++ b/addons/web/static/src/js/views/kanban/kanban_model.js
@@ -22,6 +22,7 @@ var KanbanModel = BasicModel.extend({
* @returns {Deferred<string>} resolves to the local id of the new record
*/
addRecordToGroup: function (groupID, resId) {
+ var self = this;
var group = this.localData[groupID];
var new_record = this._makeDataPoint({
res_id: resId,
@@ -31,15 +32,16 @@ var KanbanModel = BasicModel.extend({
viewType: group.viewType,
parentID: groupID,
});
- group.data.unshift(new_record.id);
- group.res_ids.unshift(resId);
- group.count++;
-
- // update the res_ids and count of the parent
- this.localData[group.parentID].count++;
- this._updateParentResIDs(group);
return this._fetchRecord(new_record).then(function (result) {
+ group.data.unshift(new_record.id);
+ group.res_ids.unshift(resId);
+ group.count++;
+
+ // update the res_ids and count of the parent
+ self.localData[group.parentID].count++;
+ self._updateParentResIDs(group);
+
return result.id;
});
},
diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js
index 8d39a5ec21e..c14e9807361 100644
--- a/addons/web/static/tests/views/kanban_tests.js
+++ b/addons/web/static/tests/views/kanban_tests.js
@@ -546,6 +546,80 @@ QUnit.module('Views', {
kanban.destroy();
});
+ QUnit.test('quick create several records on slow network', function (assert) {
+ assert.expect(6);
+
+ var self = this;
+ var def;
+ var kanban = createView({
+ View: KanbanView,
+ model: 'partner',
+ data: this.data,
+ arch: '<kanban class="o_kanban_test" on_create="quick_create">' +
+ '<field name="bar"/>' +
+ '<templates><t t-name="kanban-box">' +
+ '<div><field name="foo"/></div>' +
+ '</t></templates></kanban>',
+ groupBy: ['bar'],
+ mockRPC: function (route, args) {
+ var result = this._super.apply(this, arguments);
+ if (args.method === 'name_create') {
+ return result.then(function (result) {
+ // simulate a dynamic default value for foo based on display_name,
+ // so that we can check that the record has been fetched before
+ // being displayed
+ var newRec = _.findWhere(self.data.partner.records, {id: result[0]});
+ newRec.foo = newRec.display_name;
+ return result;
+ });
+ }
+ if (args.method === 'read') {
+ return $.when(def).then(_.constant(result));
+ }
+ return result;
+ },
+ });
+
+ assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record').length, 1,
+ "first column should contain one record");
+
+ // click to add a record, and add two in a row (first one will be delayed)
+ kanban.$('.o_kanban_header .o_kanban_quick_add i').first().click();
+
+ assert.strictEqual(kanban.$('.o_kanban_quick_create').length, 1,
+ "the quick create should be open");
+
+ def = $.Deferred();
+ kanban.$('.o_kanban_quick_create input')
+ .val('new partner 1')
+ .trigger($.Event('keypress', {
+ which: $.ui.keyCode.ENTER,
+ keyCode: $.ui.keyCode.ENTER,
+ }));
+ var firstDef = def;
+ def = null;
+ kanban.$('.o_kanban_quick_create input')
+ .val('new partner 2')
+ .trigger($.Event('keypress', {
+ which: $.ui.keyCode.ENTER,
+ keyCode: $.ui.keyCode.ENTER,
+ }));
+
+ assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record').length, 2,
+ "first column should now contain two records");
+ assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record:first').text(),
+ 'new partner 2', "new record should have been fetched");
+
+ firstDef.resolve();
+
+ assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record').length, 3,
+ "first column should now contain three records");
+ assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record:first').text(),
+ 'new partner 1', "new record should have been fetched");
+
+ kanban.destroy();
+ });
+
QUnit.test('quick create fail in grouped', function (assert) {
assert.expect(7);