[FIX] mail: display chatter inside the sheet

Before this revision, it was not possible to display a chatter inside a <sheet>.

As the chatter is reused (when switching in edit, records, etc.), it is detached
(to keep its handlers) before updating the form $el.

The problem here is that the chatter was detached in `_updateView` from
`$form.contents()` where the chatter is a root element ; when setting the form
view html, the chatter was thus still present. This was thus only working
correctly if the chatter was a direct child of <form>.

To keep it displayed in all cases, we now detach it at the chatter node
rendering.

Closes #20032
This commit is contained in:
Martin Geubelle
2017-11-29 11:47:44 +01:00
parent 0d48056d63
commit e63c550ed1
2 changed files with 69 additions and 17 deletions
+9 -16
View File
@@ -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 = $('<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);
},
});
/**
+60 -1
View File
@@ -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: '<form string="Partners">' +
'<sheet>' +
'<field name="foo"/>' +
'<notebook>' +
'<page>' +
'<div class="oe_chatter">' +
'<field name="message_ids" widget="mail_thread"/>' +
'</div>' +
'</page>' +
'</notebook>' +
'</sheet>' +
'</form>',
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);