diff --git a/addons/mail/static/src/js/form_renderer.js b/addons/mail/static/src/js/form_renderer.js index 520827d7695..9d9532e2171 100644 --- a/addons/mail/static/src/js/form_renderer.js +++ b/addons/mail/static/src/js/form_renderer.js @@ -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; + }, +}); + }); diff --git a/addons/mail/static/src/js/thread_field.js b/addons/mail/static/src/js/thread_field.js index 0d7635cae8b..75e379e6ea1 100644 --- a/addons/mail/static/src/js/thread_field.js +++ b/addons/mail/static/src/js/thread_field.js @@ -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); } }, diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js index c650f8c10c9..409b729fc78 100644 --- a/addons/mail/static/tests/chatter_tests.js +++ b/addons/mail/static/tests/chatter_tests.js @@ -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: '
', + 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];