[FIX] mail: reply message from inbox

Revision on https://github.com/odoo/odoo/commit/cd34f6de727d5b3858420cff3c9d3c5995c4e75c

Before the commit above, it was possible to reply to a message
from Inbox. Those messages were linked to a document, and replying
to any of them put a response in the related document.

This feature has been broken since the commit above: the reply
icon was only shown on messages linked to a channel, instead of
message linked to a document. Also, it was erroneously prompting
that the message was sent to the channel, even though it was not
the case.

This commit fixes the issue by toggling the visibility of the
reply icon, so that it is shown only for messages that come from
a document. Also, since posting a message requires a thread, this
commit added the possibility to post a message from a mailbox,
which instead posts the message to the related document thread.

Task-ID 1912647

closes odoo/odoo#29028
This commit is contained in:
Alexandre Kühn
2018-11-26 14:12:50 +00:00
parent 889bdd3569
commit 6f7a04be0b
4 changed files with 106 additions and 2 deletions
+5 -1
View File
@@ -1321,12 +1321,16 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
*/
_onPostMessage: function (messageData) {
var self = this;
var options = {};
if (this._selectedMessage) {
messageData.subtype = this._selectedMessage.isNote() ? 'mail.mt_note': 'mail.mt_comment';
messageData.subtype_id = false;
messageData.message_type = 'comment';
options.documentID = this._selectedMessage.getDocumentID();
options.documentModel = this._selectedMessage.getDocumentModel();
}
this._thread.postMessage(messageData)
this._thread.postMessage(messageData, options)
.then(function () {
if (self._selectedMessage) {
self._renderSnackbar('mail.discuss.MessageSentSnackbar', {
@@ -189,6 +189,27 @@ var Mailbox = SearchableThread.extend({
throw (_.str(_t("Missing domain for mailbox with ID '%s'"), this._id));
}
},
/**
* Post a message from inbox. This is used when using the 'reply' feature
* on a message that is linked to a document thread.
*
* @override
* @private
* @param {Object} messageData
* @param {Object} options
* @param {integer} options.documentID
* @param {string} options.documentModel
* @returns {$.Promise}
*/
_postMessage: function (messageData, options) {
var documentThread = this.call(
'mail_service',
'getDocumentThread',
options.documentModel,
options.documentID
);
return documentThread.postMessage(messageData);
},
});
return Mailbox;
+1 -1
View File
@@ -338,7 +338,7 @@
<i t-if="options.displayStars and !message.isSystemNotification() and !message.needsModeration()"
t-att-class="'fa fa-lg o_thread_icon o_thread_message_star ' + (message.isStarred() ? 'fa-star' : 'fa-star-o')"
t-att-data-message-id="message.getID()" title="Mark as Todo" role="img" aria-label="Mark as Todo"/>
<i t-if="message.originatesFromChannel() and options.displayReplyIcons"
<i t-if="message.isLinkedToDocumentThread() and options.displayReplyIcons"
class="fa fa-reply o_thread_icon o_thread_message_reply"
t-att-data-message-id="message.getID()" title="Reply" role="img" aria-label="Reply"/>
<i t-if="message.isNeedaction() and options.displayMarkAsRead"
+79
View File
@@ -1068,5 +1068,84 @@ QUnit.test('mark all messages as read from Inbox', function (assert) {
});
});
QUnit.test('reply to message from inbox', function (assert) {
var done = assert.async();
assert.expect(11);
var self = this;
this.data['mail.message'].records = [{
author_id: [5, 'Demo User'],
body: '<p>test 1</p>',
id: 1,
needaction: true,
needaction_partner_ids: [3],
res_id: 100,
model: 'some.document',
record_name: 'SomeDocument',
}];
this.data.initMessaging = {
needaction_inbox_counter: 1,
};
createDiscuss({
id: 1,
context: {},
params: {},
data: this.data,
services: this.services,
session: { partner_id: 3 },
mockRPC: function (route, args) {
if (args.method === 'message_post') {
assert.step(args.method);
assert.strictEqual(args.model, 'some.document',
"should post message to correct document model");
assert.strictEqual(args.args[0], 100,
"should post message to correct document ID");
self.data['mail.message'].records.push({
author_id: [3, 'Me'],
body: args.kwargs.body,
id: 2,
res_id: 100,
model: 'some.document',
record_name: 'SomeDocument',
});
return $.when(2);
}
return this._super.apply(this, arguments);
},
})
.then(function (discuss) {
assert.strictEqual(discuss.$('.o_mail_discuss_item.o_active').data('thread-id'),
'mailbox_inbox',
"Inbox should be selected by default");
assert.containsOnce(discuss, '.o_thread_message',
"should display a single message in inbox");
assert.strictEqual(discuss.$('.o_thread_message').data('message-id'), 1,
"message should be linked to correct message");
assert.containsOnce(discuss.$('.o_thread_message'), '.o_thread_message_reply',
"should display the reply icon for message linked to a document");
testUtils.dom.click(discuss.$('.o_thread_message_reply'));
var $composer = discuss.$('.o_thread_composer_extended');
assert.isVisible($composer,
"extended composer should become visible");
assert.strictEqual($composer.find('.o_composer_subject input').val(),
'Re: SomeDocument',
"composer should have copied document name as subject of message");
var $textarea = $composer.find('.o_composer_input textarea').first();
testUtils.fields.editInput($textarea, 'someContent');
assert.containsOnce($composer, '.o_composer_button_send',
"should have button to send reply message");
testUtils.dom.click($composer.find('.o_composer_button_send'));
assert.verifySteps(['message_post']);
discuss.destroy();
done();
});
});
});
});