diff --git a/addons/mail/static/src/js/form_renderer.js b/addons/mail/static/src/js/form_renderer.js index 4a0d98da4df..22437a8c18f 100644 --- a/addons/mail/static/src/js/form_renderer.js +++ b/addons/mail/static/src/js/form_renderer.js @@ -53,6 +53,15 @@ FormRenderer.include({ */ _renderNode: function (node) { if (node.tag === 'div' && node.attrs.class === 'oe_chatter') { + if (this.chatter) { + // Detach the chatter before updating the $el. + // This is important because if the view is now in create mode + // (edit mode with no res_id), the chatter will be removed from + // the DOM, and its handlers will be unbound. By detaching it + // beforehand, we ensure to keep its handlers alive so that if + // it is re-appended later, everything will still work properly + this.chatter.$el.detach(); + } if (this.mode === 'edit' && !this.state.data.id) { // there is no chatter in create mode var $div = $('
'); @@ -74,22 +83,6 @@ FormRenderer.include({ return this._super.apply(this, arguments); } }, - /** - * Detaches the chatter before updating the $el. This is important because - * if the view is now in create mode (edit mode with no res_id), the chatter - * will be removed from the DOM, and its handlers will be unbound. By - * detaching it beforehand, we ensure to keep its handlers alive so that if - * it is re-appended later, everything will still work properly. - * - * @override - * @private - */ - _updateView: function () { - if (this.chatter) { - this.chatter.$el.detach(); - } - return this._super.apply(this, arguments); - }, }); /** diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js index 2eacfa34c0e..d4b4c37704d 100644 --- a/addons/mail/static/tests/chatter_tests.js +++ b/addons/mail/static/tests/chatter_tests.js @@ -216,6 +216,66 @@ QUnit.test('chatter is not rendered in mode === create', function (assert) { form.destroy(); }); +QUnit.test('chatter rendering inside the sheet', function (assert) { + assert.expect(4); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '' + + '
' + + '' + + '
' + + '
' + + '
' + + '
' + + '
', + res_id: 2, + mockRPC: function (route, args) { + if (route === "/web/dataset/call_kw/partner/message_get_suggested_recipients") { + return $.when({2: []}); + } + return this._super(route, args); + }, + intercepts: { + get_messages: function (event) { + event.stopPropagation(); + event.data.callback($.when([])); + }, + get_bus: function (event) { + event.stopPropagation(); + event.data.callback(new Bus()); + }, + }, + }); + + assert.strictEqual(form.$('.o_chatter').length, 1, + "chatter should be displayed"); + + form.$buttons.find('.o_form_button_create').click(); + + assert.strictEqual(form.$('.o_chatter').length, 0, + "chatter should not be displayed"); + + form.$('.o_field_char').val('coucou').trigger('input'); + form.$buttons.find('.o_form_button_save').click(); + + assert.strictEqual(form.$('.o_chatter').length, 1, + "chatter should be displayed"); + + // check if chatter buttons still work + form.$('.o_chatter_button_new_message').click(); + assert.strictEqual(form.$('.o_chat_composer:visible').length, 1, + "chatter should be opened"); + + form.destroy(); +}); + QUnit.test('kanban activity widget with no activity', function (assert) { assert.expect(4); @@ -494,7 +554,6 @@ QUnit.test('chatter: post, receive and star messages', function (assert) { }); }); - QUnit.test('chatter: post a message and switch in edit mode', function (assert) { assert.expect(5);