[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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
@@ -691,6 +692,18 @@ MailManager.include({
|
||||
threadWindow.renderHeader();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @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.
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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"/>
|
||||
@@ -20,6 +14,17 @@
|
||||
</t>
|
||||
</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)
|
||||
-->
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user