Skip to content
Permalink
Browse files

[IMP] web: Add support of button type object on One2Many KanbanRecord

Apply same logic as in the ListRenderer: buttons with type="object" are
disabled for no saved yet records, as calling the python method with no
id would make no sense.

To avoid to expose this logic inside all Kanban views, we define a
specific KanbanRecord Class for the One2many case.

This could be refactored to prevent from duplicating this logic in list
and kanban views.

Task: 1945006
  • Loading branch information...
res-odoo committed Mar 12, 2019
1 parent bbedcdb commit 0d8f49a3fbc6e0907a98f84124f1c405c15b36a2
@@ -21,6 +21,7 @@ var dialogs = require('web.view_dialogs');
var core = require('web.core');
var data = require('web.data');
var Dialog = require('web.Dialog');
var KanbanRecord = require('web.KanbanRecord');
var KanbanRenderer = require('web.KanbanRenderer');
var ListRenderer = require('web.ListRenderer');
var Pager = require('web.Pager');
@@ -1397,6 +1398,59 @@ var FieldX2Many = AbstractField.extend({
},
});

var One2ManyKanbanRecord = KanbanRecord.extend({
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------

/**
* Apply same logic as in the ListRenderer: buttons with type="object"
* are disabled for no saved yet records, as calling the python method
* with no id would make no sense.
*
* To avoid to expose this logic inside all Kanban views, we define
* a specific KanbanRecord Class for the One2many case.
*
* This could be refactored to prevent from duplicating this logic in
* list and kanban views.
*
* @private
*/
_postProcessObjectButtons: function () {
var self = this;
// if the res_id is defined, it's already correctly handled by the Kanban record global event click
if (!this.state.res_id) {
this.$('.oe_kanban_action[data-type=object]').each(function (index, button) {
var $button = $(button);
if ($button.attr('warn')) {
$button.on('click', function (e) {
e.stopPropagation();
self.do_warn(_t('Warning'), _t('Please click on the "save" button first.'));
});
} else {
$button.attr('disabled', 'disabled');
}
});
}
},
/**
* @override
* @private
*/
_render: function () {
var self = this;
return this._super.apply(this, arguments).then(function () {
self._postProcessObjectButtons();
});
},
});

var One2ManyKanbanRenderer = KanbanRenderer.extend({
config: _.extend({}, KanbanRenderer.prototype.config, {
KanbanRecord: One2ManyKanbanRecord,
}),
});

var FieldOne2Many = FieldX2Many.extend({
className: 'o_field_one2many',
supportedFieldTypes: ['one2many'],
@@ -1450,6 +1504,16 @@ var FieldOne2Many = FieldX2Many.extend({
// Private
//--------------------------------------------------------------------------

/**
* @override
* @private
*/
_getRenderer: function () {
if (this.view.arch.tag === 'kanban') {
return One2ManyKanbanRenderer;
}
return this._super.apply(this, arguments);
},
/**
* Overrides to only render the buttons if the 'create' action is available.
*
@@ -5,6 +5,7 @@ var AbstractField = require('web.AbstractField');
var concurrency = require('web.concurrency');
var FormView = require('web.FormView');
var ListRenderer = require('web.ListRenderer');
var NotificationService = require('web.NotificationService');
var relationalFields = require('web.relational_fields');
var testUtils = require('web.test_utils');
var fieldUtils = require('web.field_utils');
@@ -5418,6 +5419,127 @@ QUnit.module('fields', {}, function () {
form.destroy();
});

QUnit.test('one2many field with virtual ids with kanban button', function (assert) {
assert.expect(20);

this.data.partner.records[0].p = [4];

var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form>' +
'<field name="p" mode="kanban">' +
'<kanban>' +
'<templates>' +
'<field name="foo"/>' +
'<t t-name="kanban-box">' +
'<div>' +
'<span><t t-esc="record.foo.value"/></span>' +
'<button type="object" class="btn btn-link fa fa-shopping-cart" name="button_warn" string="button_warn" warn="warn" />' +
'<button type="object" class="btn btn-link fa fa-shopping-cart" name="button_disabled" string="button_disabled" />' +
'</div>' +
'</t>' +
'</templates>' +
'</kanban>' +
'</field>' +
'</form>',
archs: {
'partner,false,form': '<form><field name="foo"/></form>',
},
res_id: 1,
services: {
notification: NotificationService.extend({
notify: function (params) {
assert.step(params.type);
}
}),
},
intercepts: {
execute_action: function (event) {
assert.step(event.data.action_data.name + '_' + event.data.env.model + '_' + event.data.env.currentID);
event.data.on_success();
},
},
});

// 1. Define all css selector
var oKanbanView = '.o_field_widget .o_kanban_view';
var oKanbanRecordActive = oKanbanView + ' .o_kanban_record:not(.o_kanban_ghost)';
var oAllKanbanButton = oKanbanRecordActive + ' button[data-type="object"]';
var btn1 = oKanbanRecordActive + ':nth-child(1) button[data-type="object"]';
var btn2 = oKanbanRecordActive + ':nth-child(2) button[data-type="object"]';
var btn1Warn = btn1 + '[data-name="button_warn"]';
var btn1Disabled = btn1 + '[data-name="button_disabled"]';
var btn2Warn = btn2 + '[data-name="button_warn"]';
var btn2Disabled = btn2 + '[data-name="button_disabled"]';

// check if we already have one kanban card
assert.containsOnce(form, oKanbanView, "should have one inner kanban view for the one2many field");
assert.strictEqual(form.$(oKanbanRecordActive).length, 1, "should have one kanban records yet");
// we have 2 button
assert.strictEqual(form.$(oAllKanbanButton).length, 2, "should have 2 button type object");
// Disabled ?
assert.strictEqual(form.$(oAllKanbanButton + '[disabled]').length, 0, "should not have button type object disabled");

// click on the button
testUtils.dom.click(form.$(btn1Disabled));
testUtils.dom.click(form.$(btn1Warn));

// switch to edit mode
testUtils.form.clickEdit(form);

// click on existing buttons
testUtils.dom.click(form.$(btn1Disabled));
testUtils.dom.click(form.$(btn1Warn));

// create new kanban
testUtils.dom.click(form.$('.o_field_widget .o-kanban-button-new'));

// save & close the modal
assert.strictEqual($('.modal-content input.o_field_widget').val(), 'My little Foo Value',
"should already have the default value for field foo");
testUtils.dom.click($('.modal-content .btn-primary').first());

// check new item
assert.strictEqual(form.$(oAllKanbanButton).length, 4, "should have 4 buttons type object");
assert.strictEqual(form.$(btn1).length, 2, "should have 2 buttons type object in area 1");
assert.strictEqual(form.$(btn2).length, 2, "should have 2 buttons type object in area 2");
assert.strictEqual(form.$(oAllKanbanButton + '[disabled]').length, 1, "should have 1 button type object disabled");

assert.strictEqual(form.$(btn2Disabled).attr('disabled'), 'disabled', 'Should have a button type object disabled in area 2');
assert.strictEqual(form.$(btn2Warn).attr('disabled'), undefined, 'Should have a button type object not disabled in area 2');
assert.strictEqual(form.$(btn2Warn).attr('warn'), 'warn', 'Should have a button type object with warn attr in area 2');

// click all buttons
testUtils.dom.click(form.$(btn1Disabled));
testUtils.dom.click(form.$(btn1Warn));
testUtils.dom.click(form.$(btn2Disabled));
testUtils.dom.click(form.$(btn2Warn));

// save the form
testUtils.form.clickSave(form);

assert.strictEqual(form.$(oAllKanbanButton + '[disabled]').length, 0, "should not have button type object disabled after save");

// click all buttons
testUtils.dom.click(form.$(btn1Disabled));
testUtils.dom.click(form.$(btn1Warn));
testUtils.dom.click(form.$(btn2Disabled));
testUtils.dom.click(form.$(btn2Warn));

assert.verifySteps([
"button_disabled_partner_4",
"button_disabled_partner_4",
"button_disabled_partner_4",
"warning",
"button_disabled_partner_4",
"button_disabled_partner_8"
],"should have triggered theses 6 steps");

form.destroy();
});

QUnit.test('focusing fields in one2many list', function (assert) {
assert.expect(2);

0 comments on commit 0d8f49a

Please sign in to comment.
You can’t perform that action at this time.