[FIX] web: fix form_view_id attribute in calendar view.

The way the calendar view selected its form view was broken for two
reasons:

- any value given in the form_view_id attribute was kept as string,
  which means that the string value would be sent to the server, and
  this is not good.
- if no value was set, the calendar view then simply did a do_action
  with the form view id set to false, which means that the default form
  view is used.  This is mostly ok, except when we are in the context of
  an action with a form view which is not the default one.  In that
  case, we clearly prefer the form view from the action.

For example, before this commit, the form view in the timesheet
application (community) is not the same as the default form view on
account.analytic.line.

Note that this commit also adds a small tweak to the mock server to
better simulate errors like the web client does (in session.js).
This commit is contained in:
Géry Debongnie
2018-05-02 10:51:45 +02:00
parent 2f5e44d40b
commit e0424b9603
4 changed files with 114 additions and 5 deletions
@@ -112,8 +112,20 @@ var CalendarView = AbstractView.extend({
//if quick_add = is NOT False and IS specified in view, we this one for widgets.QuickCreate'
this.controllerParams.quickAddPop = (!('quick_add' in attrs) || utils.toBoolElse(attrs.quick_add+'', true));
this.controllerParams.disableQuickCreate = params.disable_quick_create || !this.controllerParams.quickAddPop;
// If this field is set ot true, we don't open the event in form view, but in a popup with the view_id passed by this parameter
this.controllerParams.formViewId = !attrs.form_view_id || !utils.toBoolElse(attrs.form_view_id, true) ? false : attrs.form_view_id;
// If form_view_id is set, then the calendar view will open a form view
// with this id, when it needs to edit or create an event.
this.controllerParams.formViewId =
attrs.form_view_id ? parseInt(attrs.form_view_id, 10) : false;
if (!this.controllerParams.formViewId && params.action) {
var formViewDescr = _.find(params.action.views, function (v) {
return v[1] === 'form';
});
if (formViewDescr) {
this.controllerParams.formViewId = formViewDescr[0];
}
}
this.controllerParams.readonlyFormViewId = !attrs.readonly_form_view_id || !utils.toBoolElse(attrs.readonly_form_view_id, true) ? false : attrs.readonly_form_view_id;
this.controllerParams.eventOpenPopup = utils.toBoolElse(attrs.event_open_popup || '', false);
this.controllerParams.mapping = mapping;
@@ -110,14 +110,14 @@ var MockServer = Class.extend({
console.log('%c[rpc] response' + route, 'color: blue; font-weight: bold;', JSON.parse(resultString));
}
return JSON.parse(resultString);
}).fail(function (result) {
}, function (result, event) {
var errorString = JSON.stringify(result || false);
if (logLevel === 1) {
console.log('Mock: (ERROR)' + route, JSON.parse(errorString));
} else if (logLevel === 2) {
console.log('%c[rpc] response (error) ' + route, 'color: orange; font-weight: bold;', JSON.parse(errorString));
}
return JSON.parse(errorString);
return $.Deferred().reject(errorString, event || $.Event());
});
},
@@ -1766,6 +1766,101 @@ QUnit.module('Views', {
calendar.destroy();
});
QUnit.test('form_view_id attribute works (for creating events)', function (assert) {
assert.expect(1);
var calendar = createView({
View: CalendarView,
model: 'event',
data: this.data,
arch: '<calendar class="o_calendar_test" '+
'date_start="start" '+
'date_stop="stop" '+
'mode="month" '+
'form_view_id="42">'+
'<field name="name"/>'+
'</calendar>',
archs: archs,
viewOptions: {
initialDate: initialDate,
},
mockRPC: function (route, args) {
if (args.method === "create") {
// we simulate here the case where a create call with just
// the field name fails. This is a normal flow, the server
// reject the create rpc (quick create), then the web client
// fall back to a form view. This happens typically when a
// model has required fields
return $.Deferred().reject('None shall pass!');
}
return this._super(route, args);
},
intercepts: {
do_action: function (event) {
assert.strictEqual(event.data.action.views[0][0], 42,
"should do a do_action with view id 42");
},
},
});
var $cell = calendar.$('.fc-day-grid .fc-row:eq(2) .fc-day:eq(2)');
testUtils.triggerMouseEvent($cell, "mousedown");
testUtils.triggerMouseEvent($cell, "mouseup");
var $input = $('.modal-body input:first');
$input.val("It's just a fleshwound").trigger('input');
$('.modal button.btn:contains(Create)').trigger('click');
calendar.destroy();
});
QUnit.test('calendar fallback to form view id in action if necessary', function (assert) {
assert.expect(1);
var calendar = createView({
View: CalendarView,
model: 'event',
data: this.data,
arch: '<calendar class="o_calendar_test" '+
'date_start="start" '+
'date_stop="stop" '+
'mode="month"> '+
'<field name="name"/>'+
'</calendar>',
archs: archs,
viewOptions: {
initialDate: initialDate,
action: {views: [[1, 'kanban'], [43, 'form']]}
},
mockRPC: function (route, args) {
if (args.method === "create") {
// we simulate here the case where a create call with just
// the field name fails. This is a normal flow, the server
// reject the create rpc (quick create), then the web client
// fall back to a form view. This happens typically when a
// model has required fields
return $.Deferred().reject('None shall pass!');
}
return this._super(route, args);
},
intercepts: {
do_action: function (event) {
assert.strictEqual(event.data.action.views[0][0], 43,
"should do a do_action with view id 43");
},
},
});
var $cell = calendar.$('.fc-day-grid .fc-row:eq(2) .fc-day:eq(2)');
testUtils.triggerMouseEvent($cell, "mousedown");
testUtils.triggerMouseEvent($cell, "mouseup");
var $input = $('.modal-body input:first');
$input.val("It's just a fleshwound").trigger('input');
$('.modal button.btn:contains(Create)').trigger('click');
calendar.destroy();
});
});
});
+3 -1
View File
@@ -954,7 +954,9 @@ calendar view are:
``readonly_form_view_id``
view to open in readonly mode
``form_view_id``
view to open when the user create or edit an event
view to open when the user create or edit an event. Note that if this attribute
is not set, the calendar view will fall back to the id of the form view in the
current action, if any.
``event_open_popup``
If the option 'event_open_popup' is set to true, then the calendar view will
open events (or records) in a FormViewDialog. Otherwise, it will open events