[FIX] mail: keep model informed of new messages

Do not forward-port this after 11.0

After sending a message, if one switched in edit mode in the form view, the
created message disappeared.

This is because the model is not aware of messages (they are created through
their own routes, message are not handled as other one2many fields with commands)
and the widget was reset with a new datapoint instance when switching in edit mode.

In this rev. we keep the model informed of the new messages by directly writing
the message ids in the datapoint.

Note that the includes on FormController and BasicModel are one in the
form_renderer.js file to fix this issue in existing database without adding
files. Another revision will be done in master to add the correct files.

opw-781353
This commit is contained in:
Martin Geubelle
2017-11-17 10:47:49 +01:00
parent 745d00362a
commit ab900bb62a
3 changed files with 133 additions and 0 deletions
@@ -1,7 +1,9 @@
odoo.define('mail.form_renderer', function (require) {
"use strict";
var BasicModel = require('web.BasicModel');
var Chatter = require('mail.Chatter');
var FormController = require('web.FormController');
var FormRenderer = require('web.FormRenderer');
/**
@@ -88,4 +90,51 @@ FormRenderer.include({
},
});
/**
* Include the FormController and BasicModel to update the datapoint on the
* model when a message is posted.
*/
FormController.include({
custom_events: _.extend({}, FormController.prototype.custom_events, {
new_message: '_onNewMessage',
}),
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
* @param {OdooEvent} event
* @param {string} event.data.id datapointID
* @param {integer[]} event.data.msgIDs list of message ids
*/
_onNewMessage: function (event) {
this.model.updateMessageIDs(event.data.id, event.data.msgIDs);
},
});
BasicModel.include({
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* Update the message ids on a datapoint.
*
* Note that we directly update the res_ids on the datapoint as the message
* has already been posted ; this change can't be handled 'normally' with
* x2m commands because the change won't be saved as a normal field.
*
* @param {string} id
* @param {integer[]} msgIDs
*/
updateMessageIDs: function (id, msgIDs) {
var element = this.localData[id];
element.res_ids = msgIDs;
element.count = msgIDs.length;
},
});
});
@@ -107,6 +107,10 @@ var ThreadField = AbstractField.extend(chat_mixin, {
_onNewMessage: function (message) {
if (message.model === this.model && message.res_id === this.res_id) {
this.msgIDs.unshift(message.id);
this.trigger_up('new_message', {
id: this.value.id,
msgIDs: this.msgIDs,
});
this._fetchAndRenderThread(this.msgIDs);
}
},
+80
View File
@@ -494,6 +494,86 @@ 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);
var messages = [];
var bus = new Bus();
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form string="Partners">' +
'<sheet>' +
'<field name="foo"/>' +
'</sheet>' +
'<div class="oe_chatter">' +
'<field name="message_ids" widget="mail_thread" options="{\'display_log_button\': True}"/>' +
'</div>' +
'</form>',
res_id: 2,
session: {},
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();
var requested_msgs = _.filter(messages, function (msg) {
return _.contains(event.data.options.ids, msg.id);
});
event.data.callback($.when(requested_msgs));
},
post_message: function (event) {
event.stopPropagation();
messages.push({
attachment_ids: [],
author_id: ["42", "Me"],
body: event.data.message.content,
date: moment(), // now
displayed_author: "Me",
id: 42,
is_note: event.data.message.subtype === 'mail.mt_note',
is_starred: false,
model: 'partner',
res_id: 2,
});
bus.trigger('new_message', {
id: 42,
model: event.data.options.model,
res_id: event.data.options.res_id,
});
},
get_bus: function (event) {
event.stopPropagation();
event.data.callback(bus);
},
},
});
assert.strictEqual(form.$('.o_thread_message').length, 0, "thread should not contain messages");
// send a message
form.$('.o_chatter_button_new_message').click();
form.$('.oe_chatter .o_composer_text_field:first()').val("My first message");
form.$('.oe_chatter .o_composer_button_send').click();
assert.strictEqual(form.$('.o_thread_message').length, 1, "thread should contain a message");
assert.ok(form.$('.o_thread_message:first() .o_thread_message_core').text().indexOf('My first message') >= 0,
"the message's body should be correct");
// switch in edit mode
form.$buttons.find('.o_form_button_edit').click();
assert.strictEqual(form.$('.o_thread_message').length, 1, "thread should contain a message");
assert.ok(form.$('.o_thread_message:first() .o_thread_message_core').text().indexOf('My first message') >= 0,
"the message's body should be correct");
form.destroy();
});
QUnit.test('form activity widget: schedule next activity', function (assert) {
assert.expect(5);
this.data.partner.records[0].activity_ids = [1];