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);