diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 325bb176e61..d50e03540f2 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -1609,7 +1609,7 @@ var FieldOne2Many = FieldX2Many.extend({ fields_view: this.attrs.views && this.attrs.views.form, parentID: this.value.id, viewInfo: this.view, - deletable: this.activeActions.delete, + deletable: this.activeActions.delete && params.deletable, })); }, @@ -1714,7 +1714,7 @@ var FieldOne2Many = FieldX2Many.extend({ on_remove: function () { self._setValue({operation: 'DELETE', ids: [id]}); }, - deletable: this.activeActions.delete, + deletable: this.activeActions.delete && this.view.arch.tag !== 'tree', readonly: this.mode === 'readonly', }); }, @@ -1788,7 +1788,7 @@ var FieldMany2Many = FieldX2Many.extend({ self._setValue({operation: 'FORGET', ids: [ev.data.id]}); }, readonly: this.mode === 'readonly', - deletable: this.activeActions.delete, + deletable: this.activeActions.delete && this.view.arch.tag !== 'tree', string: this.string, }); }, diff --git a/addons/web/static/tests/fields/relational_fields/field_many2many_tests.js b/addons/web/static/tests/fields/relational_fields/field_many2many_tests.js index cf19fe30fe6..ab80fd59983 100644 --- a/addons/web/static/tests/fields/relational_fields/field_many2many_tests.js +++ b/addons/web/static/tests/fields/relational_fields/field_many2many_tests.js @@ -350,7 +350,7 @@ QUnit.module('fields', {}, function () { }); QUnit.test('many2many list (non editable): edition', async function (assert) { - assert.expect(27); + assert.expect(29); this.data.partner.records[0].timmy = [12, 14]; this.data.partner_type.records.push({ id: 15, display_name: "bronze", color: 6 }); @@ -386,10 +386,9 @@ QUnit.module('fields', {}, function () { return this._super.apply(this, arguments); }, }); - - assert.ok(!form.$('.o_list_record_remove').length, + assert.containsNone(form.$('.o_list_record_remove'), 'delete icon should not be visible in readonly'); - assert.ok(!form.$('.o_field_x2many_list_row_add').length, + assert.containsNone(form.$('.o_field_x2many_list_row_add'), '"Add an item" should not be visible in readonly'); await testUtils.form.clickEdit(form); @@ -406,6 +405,9 @@ QUnit.module('fields', {}, function () { // edit existing subrecord await testUtils.dom.click(form.$('.o_list_view tbody tr:first()')); + assert.containsNone($('.modal .modal-footer .o_btn_remove'), + 'there should not be a "Remove" button in the modal footer'); + await testUtils.fields.editInput($('.modal .o_form_view input'), 'new name'); await testUtils.dom.click($('.modal .modal-footer .btn-primary')); assert.strictEqual(form.$('.o_list_view tbody td:first()').text(), 'new name', @@ -413,6 +415,8 @@ QUnit.module('fields', {}, function () { // add new subrecords await testUtils.dom.click(form.$('.o_field_x2many_list_row_add a')); + assert.containsNone($('.modal .modal-footer .o_btn_remove'), + 'there should not be a "Remove" button in the modal footer'); assert.strictEqual($('.modal .o_list_view').length, 1, "a modal should be open"); assert.strictEqual($('.modal .o_list_view .o_data_row').length, 1, diff --git a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js index a0c1b682f17..4df25289083 100644 --- a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js +++ b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js @@ -1478,6 +1478,7 @@ QUnit.module('fields', {}, function () { }, }); + assert.containsOnce(form, '.o_data_row', "the onchange should have created one record in the relation"); @@ -1532,7 +1533,7 @@ QUnit.module('fields', {}, function () { "there should be two records in the one2many in the dialog"); // click on 'Discard' - await testUtils.dom.clickFirst($('.modal-footer .btn-secondary')); + await testUtils.dom.click($('.modal-footer .btn-secondary')); assert.strictEqual($('.modal').length, 0, "dialog should be closed"); @@ -2140,7 +2141,7 @@ QUnit.module('fields', {}, function () { }); QUnit.test('one2many list: unlink two records', async function (assert) { - assert.expect(9); + assert.expect(8); this.data.partner.records[0].p = [1, 2, 4]; var form = await createView({ View: FormView, @@ -2159,12 +2160,12 @@ QUnit.module('fields', {}, function () { var commands = args.args[1].p; assert.strictEqual(commands.length, 3, 'should have generated three commands'); - assert.ok(commands[0][0] === 4 && commands[0][1] === 4, + assert.ok(commands[0][0] === 4 && commands[0][1] === 2, 'should have generated the command 4 (LINK_TO) with id 4'); - assert.ok(commands[1][0] === 3 && commands[1][1] === 1, + assert.ok(commands[1][0] === 4 && commands[1][1] === 4, + 'should have generated the command 4 (LINK_TO) with id 4'); + assert.ok(commands[2][0] === 3 && commands[2][1] === 1, 'should have generated the command 3 (UNLINK) with id 1'); - assert.ok(commands[2][0] === 3 && commands[2][1] === 2, - 'should have generated the command 3 (UNLINK) with id 2'); } return this._super.apply(this, arguments); }, @@ -2187,20 +2188,16 @@ QUnit.module('fields', {}, function () { "should have 2 remove buttons (a record is supposed to have been unlinked)"); await testUtils.dom.click(form.$('tr.o_data_row').first()); - assert.strictEqual($('.modal .modal-footer .o_btn_remove').length, 1, - 'there should be a modal having Remove Button'); - await testUtils.dom.click($('.modal .modal-footer .o_btn_remove')); + assert.containsNone($('.modal .modal-footer .o_btn_remove'), + 'there should not be a modal having Remove Button'); - assert.containsOnce(form, 'td.o_list_record_remove button', - "should have 1 delete button (another record is supposed to have been unlinked)"); - - // save and check that the correct command has been generated + await testUtils.dom.click($('.modal .btn-secondary')) await testUtils.form.clickSave(form); form.destroy(); }); - QUnit.test('one2many list: deleting two records', async function (assert) { - assert.expect(9); + QUnit.test('one2many list: deleting one records', async function (assert) { + assert.expect(7); this.data.partner.records[0].p = [1, 2, 4]; var form = await createView({ View: FormView, @@ -2219,11 +2216,11 @@ QUnit.module('fields', {}, function () { var commands = args.args[1].p; assert.strictEqual(commands.length, 3, 'should have generated three commands'); - assert.ok(commands[0][0] === 4 && commands[0][1] === 4, - 'should have generated the command 4 (LINK_TO) with id 4'); - assert.ok(commands[1][0] === 2 && commands[1][1] === 1, - 'should have generated the command 2 (DELETE) with id 1'); - assert.ok(commands[2][0] === 2 && commands[2][1] === 2, + assert.ok(commands[0][0] === 4 && commands[0][1] === 2, + 'should have generated the command 4 (LINK_TO) with id 2'); + assert.ok(commands[1][0] === 4 && commands[1][1] === 4, + 'should have generated the command 2 (LINK_TO) with id 1'); + assert.ok(commands[2][0] === 2 && commands[2][1] === 1, 'should have generated the command 2 (DELETE) with id 2'); } return this._super.apply(this, arguments); @@ -2244,15 +2241,7 @@ QUnit.module('fields', {}, function () { await testUtils.dom.click(form.$('td.o_list_record_remove button').first()); assert.containsN(form, 'td.o_list_record_remove button', 2, - "should have 2 remove buttons (a record is supposed to have been deleted)"); - - await testUtils.dom.click(form.$('tr.o_data_row').first()); - assert.strictEqual($('.modal .modal-footer .o_btn_remove').length, 1, - 'there should be a modal having Remove Button'); - await testUtils.dom.click($('.modal .modal-footer .o_btn_remove')); - - assert.containsOnce(form, 'td.o_list_record_remove button', - "should have 1 remove button (another record is supposed to have been deleted)"); + "should have 2 remove buttons"); // save and check that the correct command has been generated await testUtils.form.clickSave(form); @@ -5674,6 +5663,41 @@ QUnit.module('fields', {}, function () { form.destroy(); }); + QUnit.test('one2many list edition, no "Remove" button in modal', async function (assert) { + assert.expect(2); + + this.data.partner.fields.foo.default = false; + + var form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
', + res_id: 1, + }); + await testUtils.form.clickEdit(form); + + await testUtils.dom.click(form.$('tbody td.o_field_x2many_list_row_add a')); + assert.containsOnce($(document), $('.modal'), 'there should be a modal opened'); + assert.containsNone($('.modal .modal-footer .o_btn_remove'), + 'modal should not contain a "Remove" button'); + + // Discard a modal + await testUtils.dom.click($('.modal-footer .btn-secondary')); + + await testUtils.form.clickDiscard(form); + form.destroy(); + }); + QUnit.test('x2many fields use their "mode" attribute', async function (assert) { assert.expect(1); @@ -5933,12 +5957,12 @@ QUnit.module('fields', {}, function () { View: FormView, model: 'partner', data: this.data, - arch: '