[FIX] web: spam new event creates multiple modals

On the Time Off, spam click to create a new event, each click opens a
new event form modal.

When the modal form fields have not been cached yet, the frontend
fetches them and delay the modal form opening after those fields have
been fetched. As the interface is still available. It is possible to
re-click multiple time during the fetch, each click schedules a new
modal form. When the first finally shows, they all stack on screen.

opw-203577

closes odoo/odoo#35098

Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
This commit is contained in:
Julien Castiaux
2019-08-02 11:42:27 +00:00
parent 6ee3950bcf
commit e26a5e46ff
2 changed files with 62 additions and 2 deletions
@@ -55,6 +55,7 @@ var CalendarController = AbstractController.extend({
this.readonlyFormViewId = params.readonlyFormViewId;
this.mapping = params.mapping;
this.context = params.context;
this.previousOpen = null;
// The quickCreating attribute ensures that we don't do several create
this.quickCreating = false;
},
@@ -271,7 +272,8 @@ var CalendarController = AbstractController.extend({
title += ': ' + this.renderer.arch.attrs.string;
}
if (this.eventOpenPopup) {
new dialogs.FormViewDialog(self, {
if (this.previousOpen) { this.previousOpen.close(); }
this.previousOpen = new dialogs.FormViewDialog(self, {
res_model: this.modelName,
context: context,
title: title,
@@ -283,7 +285,8 @@ var CalendarController = AbstractController.extend({
}
self.reload();
},
}).open();
});
this.previousOpen.open();
} else {
this.do_action({
type: 'ir.actions.act_window',
@@ -5,6 +5,7 @@ var AbstractStorageService = require('web.AbstractStorageService');
var CalendarView = require('web.CalendarView');
var CalendarRenderer = require('web.CalendarRenderer');
var Dialog = require('web.Dialog');
var ViewDialogs = require('web.view_dialogs');
var fieldUtils = require('web.field_utils');
var mixins = require('web.mixins');
var RamStorage = require('web.RamStorage');
@@ -465,6 +466,62 @@ QUnit.module('Views', {
calendar.destroy();
});
QUnit.test('open multiple event form at the same time', function (assert) {
assert.expect(2);
var def = $.Deferred();
var counter = 0;
testUtils.mock.patch(ViewDialogs.FormViewDialog, {
open: function () {
counter++;
this.options = _.omit(this.options, 'fields_view'); // force loadFieldView
return this._super.apply(this, arguments);
},
loadFieldView: function () {
var self = this;
var args = arguments;
var _super = this._super;
return def.then(function () {
return _super.apply(self, args);
});
},
});
var event = $.Event();
var calendar = createView({
View: CalendarView,
model: 'event',
data: this.data,
arch:
'<calendar class="o_calendar_test" '+
'string="Events" ' +
'event_open_popup="true" '+
'date_start="start" '+
'quick_add="False" '+
'date_stop="stop" '+
'all_day="allday" '+
'mode="month" '+
'readonly_form_view_id="1">'+
'<field name="name"/>'+
'</calendar>',
archs: archs,
viewOptions: {
initialDate: initialDate,
},
});
var $cell = calendar.$('.fc-day-grid .fc-row:eq(2) .fc-day:eq(2)');
for (var i = 0; i < 5; i++) {
testUtils.dom.triggerMouseEvent($cell, "mousedown");
testUtils.dom.triggerMouseEvent($cell, "mouseup");
}
def.resolve();
assert.equal(counter, 5, "there should had been 5 attemps to open a modal")
assert.containsOnce($('body'), '.modal', "there should be only one open modal");
calendar.destroy();
});
QUnit.test('create event with timezone in week mode European locale', function (assert) {
assert.expect(5);