[FIX] mail: easily mention followers and employees in chatter
Revision on https://github.com/odoo/odoo/commit/cd34f6de727d5b3858420cff3c9d3c5995c4e75c Resulting of the mail JS refactoring, the list of prefetched suggestions has been changed as follow: - before: list of list of mention suggestions `{Array<Object[]>}` - after: list of mention suggestions `{Object[]}` The change resulted in wrongly thinking that wrapping the list of suggestions in a list was pointless, thus simplifying it as a simple list of mention suggestions. However, because of this change, it has become much harder to mention employees and followers of documents from the chatter: it now always fetches all partner suggestions at all time, whereas before it was suggesting followers, then employees, and finally all partners based on the input of the user. In fact, there was a purpose of using a list of list of prefetched mention suggestions, which is to group suggestions by "priority": followers first, then employees, and all partners as a last resort. This commit re-introduces prefetched mention suggestions as a list of list of partners, so that it re-becomes easier to mention followers and partners of a document from the chatter. Task-ID 1910111
This commit is contained in:
@@ -211,7 +211,8 @@ var BasicComposer = Widget.extend({
|
||||
* displayed to the user. If none of them match, then it will fetch for more
|
||||
* partner suggestions (@see _mentionFetchPartners).
|
||||
*
|
||||
* @param {$.Deferred<Object[]>} prefetchedPartners
|
||||
* @param {$.Deferred<Object[]>} prefetchedPartners list of list of
|
||||
* prefetched partners.
|
||||
*/
|
||||
mentionSetPrefetchedPartners: function (prefetchedPartners) {
|
||||
this._mentionPrefetchedPartners = prefetchedPartners;
|
||||
@@ -302,21 +303,23 @@ var BasicComposer = Widget.extend({
|
||||
*/
|
||||
_mentionFetchPartners: function (search) {
|
||||
var self = this;
|
||||
return $.when(this._mentionPrefetchedPartners).then(function (partners) {
|
||||
return $.when(this._mentionPrefetchedPartners).then(function (prefetchedPartners) {
|
||||
// filter prefetched partners with the given search string
|
||||
var suggestions = [];
|
||||
var limit = self.options.mentionFetchLimit;
|
||||
var searchRegexp = new RegExp(_.str.escapeRegExp(mailUtils.unaccent(search)), 'i');
|
||||
if (limit > 0) {
|
||||
var filteredPartners = _.filter(partners, function (partner) {
|
||||
return partner.email && searchRegexp.test(partner.email) ||
|
||||
partner.name && searchRegexp.test(mailUtils.unaccent(partner.name));
|
||||
});
|
||||
if (filteredPartners.length) {
|
||||
suggestions.push(filteredPartners.slice(0, limit));
|
||||
limit -= filteredPartners.length;
|
||||
_.each(prefetchedPartners, function (partners) {
|
||||
if (limit > 0) {
|
||||
var filteredPartners = _.filter(partners, function (partner) {
|
||||
return partner.email && searchRegexp.test(partner.email) ||
|
||||
partner.name && searchRegexp.test(mailUtils.unaccent(partner.name));
|
||||
});
|
||||
if (filteredPartners.length) {
|
||||
suggestions.push(filteredPartners.slice(0, limit));
|
||||
limit -= filteredPartners.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!suggestions.length && !self.options.mentionPartnersRestricted) {
|
||||
// no result found among prefetched partners, fetch other suggestions
|
||||
suggestions = self._mentionFetchThrottled(
|
||||
|
||||
@@ -179,7 +179,8 @@ var Channel = SearchableThread.extend(ThreadTypingMixin, {
|
||||
/**
|
||||
* Get listeners of a channel
|
||||
*
|
||||
* @returns {$.Promise<Object[]>} resolved with list of channel listeners
|
||||
* @returns {$.Promise<Array<Object[]>>} resolved with list of list of
|
||||
* channel listeners.
|
||||
*/
|
||||
getMentionPartnerSuggestions: function () {
|
||||
var self = this;
|
||||
@@ -193,7 +194,7 @@ var Channel = SearchableThread.extend(ThreadTypingMixin, {
|
||||
})
|
||||
.then(function (members) {
|
||||
self._members = members;
|
||||
return members;
|
||||
return [members];
|
||||
});
|
||||
}
|
||||
return this._membersDef;
|
||||
|
||||
@@ -37,7 +37,8 @@ var Livechat = TwoUserChannel.extend({
|
||||
* display of a user that is typing.
|
||||
*
|
||||
* @override
|
||||
* @returns {$.Promise<Object[]>} resolved with list of livechat members
|
||||
* @returns {$.Promise<Array<Object[]>>} resolved with list of list of
|
||||
* livechat members.
|
||||
*/
|
||||
getMentionPartnerSuggestions: function () {
|
||||
var self = this;
|
||||
@@ -49,7 +50,7 @@ var Livechat = TwoUserChannel.extend({
|
||||
name: self._WEBSITE_USER_NAME,
|
||||
});
|
||||
}
|
||||
return self._members;
|
||||
return [self._members];
|
||||
});
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -111,7 +111,7 @@ var Thread = AbstractThread.extend(ServicesMixin, {
|
||||
* By default, a thread has not listener.
|
||||
*
|
||||
* @abstract
|
||||
* @returns {$.Promise<Object[]>}
|
||||
* @returns {$.Promise<Array<Object[]>>}
|
||||
*/
|
||||
getMentionPartnerSuggestions: function () {
|
||||
return $.when([]);
|
||||
|
||||
@@ -199,7 +199,7 @@ var MailManager = AbstractService.extend({
|
||||
* Get partners as mentions from a chatter
|
||||
* Typically all employees as partner suggestions.
|
||||
*
|
||||
* @returns {Array<Object[]>}
|
||||
* @returns {Array<Array<Object[]>>}
|
||||
*/
|
||||
getMentionPartnerSuggestions: function () {
|
||||
return this._mentionPartnerSuggestions;
|
||||
@@ -1195,8 +1195,8 @@ var MailManager = AbstractService.extend({
|
||||
*
|
||||
* @private
|
||||
* @param {Object} result data from server on mail/init_messaging rpc
|
||||
* @param {Object[]} result.mention_partner_suggestions list of suggestions
|
||||
* with all the employees
|
||||
* @param {Array<Object[]>} result.mention_partner_suggestions list of
|
||||
* suggestions.
|
||||
* @param {integer} result.menu_id the menu ID of discuss app
|
||||
*/
|
||||
_updateInternalStateFromServer: function (result) {
|
||||
|
||||
@@ -2450,6 +2450,124 @@ QUnit.test('chatter: suggested partner auto-follow on message post', function (a
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('chatter: mention prefetched partners (followers & employees)', function (assert) {
|
||||
// Note: employees are in prefeteched partner for mentions in chatter when
|
||||
// the module hr is installed.
|
||||
assert.expect(10);
|
||||
|
||||
var followerSuggestions = [{
|
||||
id: 1,
|
||||
name: 'FollowerUser1',
|
||||
email: 'follower-user1@example.com',
|
||||
}, {
|
||||
id: 2,
|
||||
name: 'FollowerUser2',
|
||||
email: 'follower-user2@example.com',
|
||||
}];
|
||||
|
||||
var nonFollowerSuggestions = [{
|
||||
id: 3,
|
||||
name: 'NonFollowerUser1',
|
||||
email: 'non-follower-user1@example.com',
|
||||
}, {
|
||||
id: 4,
|
||||
name: 'NonFollowerUser2',
|
||||
email: 'non-follower-user2@example.com',
|
||||
}];
|
||||
|
||||
// link followers
|
||||
this.data.partner.records[0].message_follower_ids = [10, 20];
|
||||
|
||||
// prefetched partners
|
||||
this.data.initMessaging = {
|
||||
mention_partner_suggestions: [followerSuggestions.concat(nonFollowerSuggestions)],
|
||||
};
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
arch: '<form string="Partners">' +
|
||||
'<sheet>' +
|
||||
'<field name="foo"/>' +
|
||||
'</sheet>' +
|
||||
'<div class="oe_chatter">' +
|
||||
'<field name="message_follower_ids" widget="mail_followers"/>' +
|
||||
'<field name="message_ids" widget="mail_thread" options="{\'display_log_button\': True}"/>' +
|
||||
'</div>' +
|
||||
'</form>',
|
||||
res_id: 2,
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/mail/read_followers') {
|
||||
return $.when({
|
||||
followers: [{
|
||||
id: 10,
|
||||
name: 'FollowerUser1',
|
||||
email: 'follower-user1@example.com',
|
||||
res_model: 'res.partner',
|
||||
res_id: 1,
|
||||
}, {
|
||||
id: 20,
|
||||
name: 'FollowerUser2',
|
||||
email: 'follower-user2@example.com',
|
||||
res_model: 'res.partner',
|
||||
res_id: 2,
|
||||
}],
|
||||
subtypes: [],
|
||||
});
|
||||
}
|
||||
if (args.method === 'message_get_suggested_recipients') {
|
||||
return $.when({2: []});
|
||||
}
|
||||
if (args.method === 'get_mention_suggestions') {
|
||||
throw new Error('should not fetch partners for mentions');
|
||||
}
|
||||
return this._super(route, args);
|
||||
},
|
||||
session: {},
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.o_followers_count').text(), '2',
|
||||
"should have two followers of this document");
|
||||
assert.strictEqual(form.$('.o_followers_list > .o_partner').text().replace(/\s+/g, ''),
|
||||
'FollowerUser1FollowerUser2',
|
||||
"should have correct follower names");
|
||||
assert.strictEqual(form.$('.o_composer_mention_dropdown').length, 0,
|
||||
"should not show the mention suggestion dropdown");
|
||||
|
||||
form.$('.o_chatter_button_new_message').click();
|
||||
var $input = form.$('.oe_chatter .o_composer_text_field:first()');
|
||||
$input.val('@');
|
||||
// the cursor position must be set for the mention manager to detect that we are mentionning
|
||||
$input[0].selectionStart = 1;
|
||||
$input[0].selectionEnd = 1;
|
||||
$input.trigger('keyup');
|
||||
|
||||
assert.strictEqual(form.$('.o_composer_mention_dropdown').length, 1,
|
||||
"should show the mention suggestion dropdown");
|
||||
|
||||
assert.strictEqual(form.$('.o_mention_proposition').length, 4,
|
||||
"should show 4 mention suggestions");
|
||||
assert.strictEqual(form.$('.o_mention_proposition').eq(0).text().replace(/\s+/g, ''),
|
||||
"FollowerUser1(follower-user1@example.com)",
|
||||
"should display correct 1st mention suggestion");
|
||||
assert.strictEqual(form.$('.o_mention_proposition').eq(1).text().replace(/\s+/g, ''),
|
||||
"FollowerUser2(follower-user2@example.com)",
|
||||
"should display correct 2nd mention suggestion");
|
||||
assert.ok(form.$('.o_mention_proposition').eq(1).next().hasClass('dropdown-divider'),
|
||||
"should have a mention separator after last follower mention suggestion");
|
||||
assert.strictEqual(form.$('.o_mention_proposition').eq(2).text().replace(/\s+/g, ''),
|
||||
"NonFollowerUser1(non-follower-user1@example.com)",
|
||||
"should display correct 3rd mention suggestion");
|
||||
assert.strictEqual(form.$('.o_mention_proposition').eq(3).text().replace(/\s+/g, ''),
|
||||
"NonFollowerUser2(non-follower-user2@example.com)",
|
||||
"should display correct 4th mention suggestion");
|
||||
|
||||
//cleanup
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('FieldMany2ManyTagsEmail', {
|
||||
beforeEach: function () {
|
||||
this.data = {
|
||||
|
||||
Reference in New Issue
Block a user