[IMP] mail: display channel invite group restriction
Before this PR, nothing warned the user that the invitation link was restricted to a user group. task-2818094 closes odoo/odoo#88562 Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
committed by
Sébastien Theys
parent
659c61219f
commit
0b1846bb46
@@ -819,6 +819,7 @@ class Channel(models.Model):
|
||||
'public': channel.public,
|
||||
'group_based_subscription': bool(channel.group_ids),
|
||||
'create_uid': channel.create_uid.id,
|
||||
'authorizedGroupFullName': channel.group_public_id.full_name,
|
||||
}
|
||||
# add last message preview (only used in mobile)
|
||||
info['last_message_id'] = channel_last_message_ids.get(channel.id, False)
|
||||
|
||||
+4
-1
@@ -40,7 +40,7 @@
|
||||
</t>
|
||||
<t t-if="channelInvitationForm.thread and channelInvitationForm.thread.invitationLink">
|
||||
<h4 class="mx-3 mt-3 mb-2">Invitation Link</h4>
|
||||
<div class="mx-3 my-2">
|
||||
<div class="mx-3 mt-2 mb-3">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" t-att-value="channelInvitationForm.thread.invitationLink" readonly="" t-on-focus="channelInvitationForm.onFocusInvitationLinkInput" />
|
||||
<div class="input-group-append">
|
||||
@@ -49,6 +49,9 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<t t-if="channelInvitationForm.accessRestrictedToGroupText">
|
||||
<div class="o_ChannelInvitationForm_accessRestrictedToGroup mt-2" t-esc="channelInvitationForm.accessRestrictedToGroupText"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,8 @@ import { attr, many, one } from '@mail/model/model_field';
|
||||
import { clear, insertAndReplace, link, replace, unlink } from '@mail/model/model_field_command';
|
||||
import { cleanSearchTerm } from '@mail/utils/utils';
|
||||
|
||||
import { sprintf } from '@web/core/utils/strings';
|
||||
|
||||
registerModel({
|
||||
name: 'ChannelInvitationForm',
|
||||
identifyingFields: [['chatWindow', 'popoverViewOwner']],
|
||||
@@ -156,6 +158,25 @@ registerModel({
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {string|FieldCommand}
|
||||
*/
|
||||
_computeAccessRestrictedToGroupText() {
|
||||
if (!this.thread) {
|
||||
return clear();
|
||||
}
|
||||
if (
|
||||
!this.thread.authorizedGroupFullName ||
|
||||
this.thread.public !== 'groups'
|
||||
) {
|
||||
return clear();
|
||||
}
|
||||
return sprintf(
|
||||
this.env._t('Access restricted to group "%(groupFullName)s"'),
|
||||
{ 'groupFullName': this.thread.authorizedGroupFullName }
|
||||
);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {string}
|
||||
@@ -211,6 +232,9 @@ registerModel({
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
accessRestrictedToGroupText: attr({
|
||||
compute: '_computeAccessRestrictedToGroupText',
|
||||
}),
|
||||
chatWindow: one('ChatWindow', {
|
||||
inverse: 'channelInvitationForm',
|
||||
readonly: true,
|
||||
|
||||
@@ -41,6 +41,9 @@ registerModel({
|
||||
*/
|
||||
convertData(data) {
|
||||
const data2 = {};
|
||||
if ('authorizedGroupFullName' in data) {
|
||||
data2.authorizedGroupFullName = data.authorizedGroupFullName;
|
||||
}
|
||||
if ('avatarCacheKey' in data) {
|
||||
data2.avatarCacheKey = data.avatarCacheKey;
|
||||
}
|
||||
@@ -1814,6 +1817,7 @@ registerModel({
|
||||
attachments: many('Attachment', {
|
||||
inverse: 'threads',
|
||||
}),
|
||||
authorizedGroupFullName: attr(),
|
||||
/**
|
||||
* Cache key to force a reload of the avatar when avatar is changed.
|
||||
* It only makes sense for channels.
|
||||
|
||||
@@ -789,7 +789,7 @@ MockServer.include({
|
||||
channel_last_seen_partner_ids: [[2, channelMember.id]],
|
||||
},
|
||||
);
|
||||
this.pyEnv['bus.bus']._sendone(this.currentPartner, 'mail.channel/leave', {
|
||||
this.pyEnv['bus.bus']._sendone(this.currentPartner, 'mail.channel/leave', {
|
||||
'id': channel.id,
|
||||
});
|
||||
/**
|
||||
@@ -1004,6 +1004,9 @@ MockServer.include({
|
||||
['model', '=', 'mail.channel'],
|
||||
['res_id', '=', channel.id],
|
||||
]);
|
||||
const [group_public_id] = this.getRecords('res.groups', [
|
||||
['id', '=', channel.group_public_id],
|
||||
]);
|
||||
const lastMessageId = messages.reduce((lastMessageId, message) => {
|
||||
if (!lastMessageId || message.id > lastMessageId) {
|
||||
return message.id;
|
||||
@@ -1019,6 +1022,7 @@ MockServer.include({
|
||||
last_message_id: lastMessageId,
|
||||
members: [...this._mockResPartnerMailPartnerFormat(partnerIds).values()],
|
||||
message_needaction_counter: messageNeedactionCounter,
|
||||
authorizedGroupFullName: group_public_id ? group_public_id.name : false,
|
||||
});
|
||||
if (channel.channel_type === 'channel') {
|
||||
delete res.members;
|
||||
@@ -1065,8 +1069,8 @@ MockServer.include({
|
||||
);
|
||||
}
|
||||
if (!pinned) {
|
||||
this.pyEnv['bus.bus']._sendone(this.currentPartner, 'mail.channel/unpin', {
|
||||
'id': channel.id,
|
||||
this.pyEnv['bus.bus']._sendone(this.currentPartner, 'mail.channel/unpin', {
|
||||
'id': channel.id,
|
||||
});
|
||||
} else {
|
||||
this.pyEnv['bus.bus']._sendone(this.currentPartner, 'mail.channel/legacy_insert', this._mockMailChannelChannelInfo([channel.id])[0]);
|
||||
@@ -1260,9 +1264,9 @@ MockServer.include({
|
||||
},
|
||||
);
|
||||
const channel = this.pyEnv['mail.channel'].searchRead([['id', '=', id]])[0];
|
||||
this.pyEnv['bus.bus']._sendone(channel, 'mail.channel/insert', {
|
||||
'id': id,
|
||||
'avatarCacheKey': channel.avatarCacheKey
|
||||
this.pyEnv['bus.bus']._sendone(channel, 'mail.channel/insert', {
|
||||
'id': id,
|
||||
'avatarCacheKey': channel.avatarCacheKey
|
||||
});
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,7 @@ addModelNamesToFetch([
|
||||
'ir.attachment', 'ir.model', 'ir.model.fields', 'mail.activity', 'mail.activity.type',
|
||||
'mail.channel', 'mail.channel.partner', 'mail.followers', 'mail.message', 'mail.message.subtype',
|
||||
'mail.notification', 'mail.shortcode', 'mail.template', 'mail.tracking.value',
|
||||
'res.company', 'res.country', 'res.partner', 'res.users', 'res.users.settings',
|
||||
'res.company', 'res.country', 'res.partner', 'res.users', 'res.users.settings', 'res.groups'
|
||||
]);
|
||||
|
||||
addFakeModel('res.fake', {
|
||||
|
||||
+37
@@ -123,5 +123,42 @@ QUnit.test('should be able to create a new group chat from an existing chat', as
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test('Invitation form should display channel group restriction', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
const pyEnv = await startServer();
|
||||
const resPartnerId1 = pyEnv['res.partner'].create({
|
||||
email: "testpartner@odoo.com",
|
||||
name: "TestPartner",
|
||||
});
|
||||
pyEnv['res.users'].create({ partner_id: resPartnerId1 });
|
||||
const resGroupId1 = pyEnv['res.groups'].create({
|
||||
name: "testGroup",
|
||||
});
|
||||
const mailChannelId1 = pyEnv['mail.channel'].create({
|
||||
channel_last_seen_partner_ids: [
|
||||
[0, 0, { partner_id: pyEnv.currentPartnerId }],
|
||||
],
|
||||
channel_type: 'channel',
|
||||
public: 'groups',
|
||||
group_public_id: resGroupId1,
|
||||
});
|
||||
const { click, openDiscuss } = await start({
|
||||
discuss: {
|
||||
context: {
|
||||
active_id: mailChannelId1,
|
||||
},
|
||||
},
|
||||
});
|
||||
await openDiscuss();
|
||||
|
||||
await click(`.o_ThreadViewTopbar_inviteButton`);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ChannelInvitationForm_accessRestrictedToGroup',
|
||||
"should display the channel restriction warning"
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,17 +6,18 @@ from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import Command
|
||||
from odoo.tests.common import users, tagged, TransactionCase, warmup
|
||||
from odoo.tools.misc import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestDiscussFullPerformance(TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group_user = self.env.ref('base.group_user')
|
||||
self.users = self.env['res.users'].create([
|
||||
{
|
||||
'email': 'e.e@example.com',
|
||||
'groups_id': [Command.link(self.env.ref('base.group_user').id)],
|
||||
'groups_id': [Command.link(self.group_user.id)],
|
||||
'login': 'emp',
|
||||
'name': 'Ernest Employee',
|
||||
'notification_type': 'inbox',
|
||||
@@ -100,7 +101,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
self.maxDiff = None
|
||||
self.users[0].flush()
|
||||
self.users[0].invalidate_cache()
|
||||
with self.assertQueryCount(emp=82):
|
||||
with self.assertQueryCount(emp=83):
|
||||
init_messaging = self.users[0].with_user(self.users[0])._init_messaging()
|
||||
|
||||
self.assertEqual(init_messaging, {
|
||||
@@ -108,6 +109,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'starred_counter': 1,
|
||||
'channels': [
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': channel_general._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'create_uid': user_root.id,
|
||||
@@ -122,7 +124,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'is_pinned': True,
|
||||
'last_interest_dt': channel_general.channel_last_seen_partner_ids.filtered(lambda p: p.partner_id == self.users[0].partner_id).last_interest_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||
'last_message_id': next(res['message_id'] for res in channel_general._channel_last_message_ids()),
|
||||
'memberCount': len(self.env.ref('base.group_user').users | user_root),
|
||||
'memberCount': len(self.group_user.users | user_root),
|
||||
'message_needaction_counter': 0,
|
||||
'message_unread_counter': 5,
|
||||
'name': 'general',
|
||||
@@ -133,6 +135,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_general.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': channel_channel_public_1._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -158,6 +161,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_channel_public_1.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': channel_channel_public_2._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -183,6 +187,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_channel_public_2.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': channel_channel_group_1._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -208,6 +213,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_channel_group_1.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': channel_channel_group_2._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -233,6 +239,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_channel_group_2.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': channel_channel_private_1._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -258,6 +265,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_channel_private_1.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': channel_channel_private_2._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -283,6 +291,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_channel_private_2.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': channel_group_1._get_avatar_cache_key(),
|
||||
'channel_type': 'group',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -347,6 +356,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_group_1.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': channel_chat_1._get_avatar_cache_key(),
|
||||
'channel_type': 'chat',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -411,6 +421,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_chat_1.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': channel_chat_2._get_avatar_cache_key(),
|
||||
'channel_type': 'chat',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -475,6 +486,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_chat_2.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': channel_chat_3._get_avatar_cache_key(),
|
||||
'channel_type': 'chat',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -539,6 +551,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_chat_3.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': channel_chat_4._get_avatar_cache_key(),
|
||||
'channel_type': 'chat',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -603,6 +616,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_chat_4.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': channel_livechat_1._get_avatar_cache_key(),
|
||||
'channel_type': 'livechat',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -667,6 +681,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'uuid': channel_livechat_1.uuid,
|
||||
},
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': channel_livechat_2._get_avatar_cache_key(),
|
||||
'channel_type': 'livechat',
|
||||
'create_uid': self.env.ref('base.public_user').id,
|
||||
|
||||
Reference in New Issue
Block a user