summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorAlexandre Kühn <aku@odoo.com>2019-06-13 13:53:01 +0000
committerAlexandre Kühn <aku@odoo.com>2019-07-16 14:36:44 +0000
commitbdf45dca506f9938bfcd3a7acc8757a16d701d05 (patch)
treedbe074599045aef04eb18935eef2859d555a14c5 /addons
parent4bde721f925bfe3d1e867565490d3830da150dcc (diff)
[FIX] mail: auto-update out-of-office info on im_status change
Before this commit, chat window's out-of-office info did not change when direct partner's `im_status` is/was on 'leave'. Users had to reload page to see updated out-of-office info. Task-ID 2007663
Diffstat (limited to 'addons')
-rw-r--r--addons/mail/static/src/js/models/threads/dm_chat.js13
-rw-r--r--addons/mail/static/src/js/services/mail_status_manager.js32
-rw-r--r--addons/mail/static/src/js/services/mail_window_manager.js13
-rw-r--r--addons/mail/static/src/js/thread_windows/thread_window.js18
-rw-r--r--addons/mail/static/src/xml/thread_window.xml19
-rw-r--r--addons/mail/static/tests/thread_window/basic_thread_window_tests.js113
6 files changed, 201 insertions, 7 deletions
diff --git a/addons/mail/static/src/js/models/threads/dm_chat.js b/addons/mail/static/src/js/models/threads/dm_chat.js
index c0ba9c527b0..78cc01a7044 100644
--- a/addons/mail/static/src/js/models/threads/dm_chat.js
+++ b/addons/mail/static/src/js/models/threads/dm_chat.js
@@ -101,6 +101,19 @@ var DMChat = TwoUserChannel.extend(ChannelSeenMixin, {
getStatus: function () {
return this.call('mail_service', 'getImStatus', { partnerID: this._directPartnerID });
},
+
+ /**
+ * @param {Object} data
+ * @param {string} data.outOfOfficeMessage
+ * @param {string} data.outOfOfficeDateEnd
+ */
+ updateOutOfOfficeInfo: function (data) {
+ this._outOfOfficeMessage = data.outOfOfficeMessage;
+ this._outOfOfficeDateEnd = data.outOfOfficeDateEnd;
+ this.call('mail_service', 'getMailBus').trigger('updated_out_of_office', {
+ threadID: this.getID(),
+ });
+ }
});
return DMChat;
diff --git a/addons/mail/static/src/js/services/mail_status_manager.js b/addons/mail/static/src/js/services/mail_status_manager.js
index 3addaf65349..6f9b996f231 100644
--- a/addons/mail/static/src/js/services/mail_status_manager.js
+++ b/addons/mail/static/src/js/services/mail_status_manager.js
@@ -54,13 +54,45 @@ MailManager.include({
updateImStatus: function (statusList) {
var updatedIDs = [];
var self = this;
+ var dmChat;
+ var toUpdateOutOfOfficeChatIDs = [];
_.each(statusList, function (status) {
if (self._imStatus[status.id] === status.im_status) {
return;
}
+ if (
+ status.im_status.indexOf('leave') !== -1 ||
+ (
+ self._imStatus[status.id] &&
+ self._imStatus[status.id].indexOf('leave') !== -1
+ )
+ ) {
+ dmChat = self.getDMChatFromPartnerID(status.id);
+ if (dmChat) {
+ toUpdateOutOfOfficeChatIDs.push(dmChat.getID());
+ }
+ }
updatedIDs.push(status.id);
self._imStatus[status.id] = status.im_status;
});
+ if (!_.isEmpty(toUpdateOutOfOfficeChatIDs)) {
+ this._rpc({
+ model: 'mail.channel',
+ method: 'channel_info',
+ args: [toUpdateOutOfOfficeChatIDs],
+ }).then(function (channelsInfo) {
+ _.each(channelsInfo, function (channelInfo) {
+ dmChat = self.getChannel(channelInfo.id);
+ if (!dmChat) {
+ return;
+ }
+ dmChat.updateOutOfOfficeInfo({
+ outOfOfficeMessage: channelInfo.direct_partner[0].out_of_office_message,
+ outOfOfficeDateEnd: channelInfo.direct_partner[0].out_of_office_date_end,
+ });
+ });
+ });
+ }
if (! _.isEmpty(updatedIDs)) {
this._mailBus.trigger('updated_im_status', updatedIDs); // useful for thread window header
this._renderImStatus(updatedIDs);
diff --git a/addons/mail/static/src/js/services/mail_window_manager.js b/addons/mail/static/src/js/services/mail_window_manager.js
index 3f7ce1aed3d..fdb1b667714 100644
--- a/addons/mail/static/src/js/services/mail_window_manager.js
+++ b/addons/mail/static/src/js/services/mail_window_manager.js
@@ -341,6 +341,7 @@ MailManager.include({
.on('is_thread_bottom_visible', this, this._onIsThreadBottomVisible)
.on('unsubscribe_from_channel', this, this._onUnsubscribeFromChannel)
.on('updated_im_status', this, this._onUpdatedImStatus)
+ .on('updated_out_of_office', this, this._onUpdatedOutOfOffice)
.on('update_thread_unread_counter', this, this._onUpdateThreadUnreadCounter);
core.bus.on('resize', this, _.debounce(this._repositionThreadWindows.bind(this), 100));
@@ -692,6 +693,18 @@ MailManager.include({
});
},
/**
+ * @private
+ * @param {Object} data
+ * @param {integer} data.threadID
+ */
+ _onUpdatedOutOfOffice: function (data) {
+ var threadWindow = this._getThreadWindow(data.threadID);
+ if (!threadWindow) {
+ return;
+ }
+ threadWindow.renderOutOfOffice();
+ },
+ /**
* Called when a thread has its unread counter that has changed.
* The unread counter on the thread windows should be updated.
*
diff --git a/addons/mail/static/src/js/thread_windows/thread_window.js b/addons/mail/static/src/js/thread_windows/thread_window.js
index e5496e0bc3c..9f7c1f00bb5 100644
--- a/addons/mail/static/src/js/thread_windows/thread_window.js
+++ b/addons/mail/static/src/js/thread_windows/thread_window.js
@@ -6,6 +6,7 @@ var BasicComposer = require('mail.composer.Basic');
var core = require('web.core');
+var QWeb = core.qweb;
var _t = core._t;
/**
@@ -153,6 +154,23 @@ var ThreadWindow = AbstractThreadWindow.extend({
removePassive: function () {
this._passive = false;
},
+ renderOutOfOffice: function () {
+ var $outOfOffice = this.$('.o_out_of_office');
+ if (!this.getOutOfOfficeInfo() && !this.getOutOfOfficeMessage()) {
+ if ($outOfOffice.length) {
+ $outOfOffice.remove();
+ }
+ return;
+ }
+ var $newOutOfOffice = $(QWeb.render('mail.thread_window.OutOfOffice', {
+ widget: this,
+ }));
+ if ($outOfOffice.length) {
+ $outOfOffice.replaceWith($newOutOfOffice);
+ } else {
+ $newOutOfOffice.insertAfter(this.$('.o_thread_window_header'));
+ }
+ },
/**
* Update this thread window
*
diff --git a/addons/mail/static/src/xml/thread_window.xml b/addons/mail/static/src/xml/thread_window.xml
index 76a130d1ba2..a9e2131cbdb 100644
--- a/addons/mail/static/src/xml/thread_window.xml
+++ b/addons/mail/static/src/xml/thread_window.xml
@@ -6,13 +6,7 @@
-->
<t t-name="mail.ThreadWindow" t-extend="mail.AbstractThreadWindow">
<t t-jquery=".o_thread_window_header" t-operation="after">
- <div class="o_out_of_office" t-if="widget.getOutOfOfficeInfo() or widget.getOutOfOfficeMessage()">
- <div class="o_out_of_office_info" t-if="widget.getOutOfOfficeInfo()" t-esc="widget.getOutOfOfficeInfo()"/>
- <div class="o_out_of_office_text o_text_wrap" t-if="widget.getOutOfOfficeMessage()">
- <t t-esc="widget.getOutOfOfficeMessage()"/>
- <a href="#" class="o_out_of_office_read_more_less_button">Read more</a>
- </div>
- </div>
+ <t t-call="mail.thread_window.OutOfOffice" t-if="widget.getOutOfOfficeInfo() or widget.getOutOfOfficeMessage()"/>
<div t-if="!widget.hasThread()" class="o_thread_search_input">
<span> To: </span>
<input type="text" placeholder="User name"/>
@@ -21,6 +15,17 @@
</t>
<!--
+ @param {mail.ThreadWindow} widget
+ -->
+ <div class="o_out_of_office" t-name="mail.thread_window.OutOfOffice">
+ <div class="o_out_of_office_info" t-if="widget.getOutOfOfficeInfo()" t-esc="widget.getOutOfOfficeInfo()"/>
+ <div class="o_out_of_office_text o_text_wrap" t-if="widget.getOutOfOfficeMessage()">
+ <t t-esc="widget.getOutOfOfficeMessage()"/>
+ <a href="#" class="o_out_of_office_read_more_less_button">Read more</a>
+ </div>
+ </div>
+
+ <!--
@param {string} expandTitle text to display on mouse hover (title attribute)
-->
<t t-extend="mail.AbstractThreadWindow.HeaderContent">
diff --git a/addons/mail/static/tests/thread_window/basic_thread_window_tests.js b/addons/mail/static/tests/thread_window/basic_thread_window_tests.js
index 5a0bc62f880..0445c344649 100644
--- a/addons/mail/static/tests/thread_window/basic_thread_window_tests.js
+++ b/addons/mail/static/tests/thread_window/basic_thread_window_tests.js
@@ -695,6 +695,119 @@ QUnit.test('no out-of-office status in thread window', function (assert) {
parent.destroy();
});
+QUnit.test('auto-update out-of-office info on im_status change', function (assert) {
+ var done = assert.async();
+ assert.expect(5);
+
+ var imStatusDefs = [$.Deferred(), $.Deferred()];
+ var channelInfoDefs = [$.Deferred(), $.Deferred()];
+ var timeoutMock = mailTestUtils.patchMailTimeouts();
+ var step = 0;
+
+ this.data = {
+ 'mail.message': {
+ fields: {},
+ records: [],
+ },
+ initMessaging: {
+ channel_slots: {
+ channel_channel: [{
+ id: 1,
+ name: "DM",
+ channel_type: "chat",
+ message_unread_counter: 0,
+ direct_partner: [{
+ id: 666,
+ name: 'DemoUser1',
+ im_status: 'online',
+ }],
+ }],
+ },
+ },
+ };
+
+ var parent = this.createParent({
+ data: this.data,
+ services: this.services,
+ mockRPC: function (route, args) {
+ if (route === '/longpolling/im_status') {
+ step++;
+ if (step === 1) {
+ imStatusDefs[0].resolve();
+ return $.when([
+ {
+ id: 666,
+ im_status: 'leave',
+ },
+ ]);
+ } else if (step === 2) {
+ imStatusDefs[1].resolve();
+ return $.when([
+ {
+ id: 666,
+ im_status: 'online',
+ },
+ ]);
+ }
+ }
+ if (args.method === 'channel_info') {
+ if (step === 1) {
+ channelInfoDefs[0].resolve();
+ return $.when([{
+ id: 1,
+ direct_partner: [{
+ out_of_office_message: "Leave me alone",
+ out_of_office_date_end: false,
+ }],
+ }]);
+ }
+ else if (step === 2) {
+ channelInfoDefs[1].resolve();
+ return $.when([{
+ id: 1,
+ direct_partner: [{
+ out_of_office_message: false,
+ out_of_office_date_end: false,
+ }],
+ }]);
+ }
+ }
+ return this._super.apply(this, arguments);
+ },
+ });
+
+ // detach channel 1, so that it opens corresponding thread window.
+ parent.call('mail_service', 'getChannel', 1).detach();
+
+ assert.containsNone($, '.o_out_of_office',
+ "should contain no out of office section on chat window initially");
+
+ timeoutMock.addTime(51*1000); // wait for next im status fetch
+
+ $.when(imStatusDefs[0], channelInfoDefs[0]).then(function () {
+ assert.containsOnce($, '.o_out_of_office',
+ "should contain out of office section on chat window");
+ assert.containsOnce($, '.o_out_of_office > .o_out_of_office_text',
+ "should contain out of office text on chat window");
+ assert.ok(
+ $('.o_out_of_office > .o_out_of_office_text')
+ .text()
+ .replace(/\s/g, "")
+ .indexOf("Leavemealone") !== -1,
+ "should contain out of office text on chat window");
+ timeoutMock.addTime(51*1000); // wait for next im status fetch
+
+ $.when(imStatusDefs[1], channelInfoDefs[1]).then(function () {
+ assert.containsNone($, '.o_out_of_office',
+ "should no longer contain out of office section on chat window");
+
+ timeoutMock.runPendingTimeouts();
+ parent.destroy();
+ done();
+ });
+ });
+});
+
});
});
});