[IMP] mail: introduce Persona model for guest and partner

And use it on partner im status.
This will allow displaying the im status of guest without any other change to
components.

Part of task-2883466

Part-of: odoo/odoo#93731
This commit is contained in:
Sébastien Theys
2022-06-17 14:14:33 +02:00
parent e8023a1c89
commit 0e8b1721b5
7 changed files with 95 additions and 24 deletions
@@ -2,13 +2,13 @@
<templates xml:space="preserve">
<t t-inherit="mail.PartnerImStatusIcon" t-inherit-mode="extension">
<xpath expr="//*[@name='root']" position="inside">
<t t-if="partnerImStatusIconView.partner.im_status === 'leave_online'">
<t t-if="partnerImStatusIconView.persona.im_status === 'leave_online'">
<i class="o_PartnerImStatusIcon_icon o-online fa fa-plane fa-stack-1x" title="Online" role="img" aria-label="User is online"/>
</t>
<t t-if="partnerImStatusIconView.partner.im_status === 'leave_away'">
<t t-if="partnerImStatusIconView.persona.im_status === 'leave_away'">
<i class="o_PartnerImStatusIcon_icon o-away fa fa-plane fa-stack-1x text-warning" title="Away" role="img" aria-label="User is away"/>
</t>
<t t-if="partnerImStatusIconView.partner.im_status === 'leave_offline'">
<t t-if="partnerImStatusIconView.persona.im_status === 'leave_offline'">
<i class="o_PartnerImStatusIcon_icon o-offline fa fa-plane fa-stack-1x text-700" title="Out of office" role="img" aria-label="User is out of office"/>
</t>
</xpath>
@@ -28,10 +28,10 @@ export class PartnerImStatusIcon extends Component {
*/
_onClick(ev) {
markEventHandled(ev, 'PartnerImStatusIcon.Click');
if (!this.props.hasOpenChat) {
if (!this.props.hasOpenChat || !this.partnerImStatusIconView.persona.partner) {
return;
}
this.partnerImStatusIconView.partner.openChat();
this.partnerImStatusIconView.persona.partner.openChat();
}
}
@@ -4,11 +4,11 @@
<t t-name="mail.PartnerImStatusIcon" owl="1">
<span class="o_PartnerImStatusIcon d-flex flex-column fa-stack"
t-att-class="{
'o-away': partnerImStatusIconView.partner.im_status === 'away',
'o-bot': messaging.partnerRoot === partnerImStatusIconView.partner,
'o-away': partnerImStatusIconView.persona.im_status === 'away',
'o-bot': messaging.partnerRoot.persona === partnerImStatusIconView.persona,
'o-has-open-chat o_cursor_pointer': props.hasOpenChat,
'o-offline': partnerImStatusIconView.partner.im_status === 'offline',
'o-online': partnerImStatusIconView.partner.im_status === 'online',
'o-offline': partnerImStatusIconView.persona.im_status === 'offline',
'o-online': partnerImStatusIconView.persona.im_status === 'online',
}"
t-attf-class="{{ className }}"
t-on-click="_onClick"
@@ -19,16 +19,16 @@
<i class="o_PartnerImStatusIcon_outerBackground fa fa-circle fa-stack-1x"/>
<i class="o_PartnerImStatusIcon_innerBackground fa fa-circle fa-stack-1x text-white"/>
</t>
<t t-if="partnerImStatusIconView.partner.im_status === 'online'">
<t t-if="partnerImStatusIconView.persona.im_status === 'online'">
<i class="o_PartnerImStatusIcon_icon o-online fa fa-circle fa-stack-1x" title="Online" role="img" aria-label="User is online"/>
</t>
<t t-if="partnerImStatusIconView.partner.im_status === 'away'">
<t t-if="partnerImStatusIconView.persona.im_status === 'away'">
<i class="o_PartnerImStatusIcon_icon o-away fa fa-circle fa-stack-1x text-warning" title="Idle" role="img" aria-label="User is idle"/>
</t>
<t t-if="partnerImStatusIconView.partner.im_status === 'offline'">
<t t-if="partnerImStatusIconView.persona.im_status === 'offline'">
<i class="o_PartnerImStatusIcon_icon o-offline fa fa-circle-o fa-stack-1x text-700" title="Offline" role="img" aria-label="User is offline"/>
</t>
<t t-if="partnerImStatusIconView.partner === messaging.partnerRoot">
<t t-if="partnerImStatusIconView.persona === messaging.partnerRoot.persona">
<i class="o_PartnerImStatusIcon_icon o-bot fa fa-heart fa-stack-1x" title="Bot" role="img" aria-label="User is a bot"/>
</t>
</span>
+8
View File
@@ -2,6 +2,7 @@
import { attr, many, one } from '@mail/model/model_field';
import { registerModel } from '@mail/model/model_core';
import { insertAndReplace } from '@mail/model/model_field_command';
registerModel({
name: 'Guest',
@@ -43,6 +44,13 @@ registerModel({
readonly: true,
}),
name: attr(),
persona: one('Persona', {
default: insertAndReplace(),
inverse: 'guest',
isCausal: true,
readonly: true,
required: true,
}),
rtcSessions: many('RtcSession', {
inverse: 'guest',
}),
+8 -1
View File
@@ -2,7 +2,7 @@
import { registerModel } from '@mail/model/model_core';
import { attr, many, one } from '@mail/model/model_field';
import { clear, insert, link } from '@mail/model/model_field_command';
import { clear, insert, insertAndReplace, link } from '@mail/model/model_field_command';
import { cleanSearchTerm } from '@mail/utils/utils';
registerModel({
@@ -441,6 +441,13 @@ registerModel({
inverse: 'partner',
isCausal: true,
}),
persona: one('Persona', {
default: insertAndReplace(),
inverse: 'partner',
isCausal: true,
readonly: true,
required: true,
}),
rtcSessions: many('RtcSession', {
inverse: 'partner',
}),
@@ -20,27 +20,27 @@ registerModel({
* @private
* @returns {FieldCommand}
*/
_computePartner() {
_computePersona() {
if (this.channelInvitationFormSelectablePartnerViewOwner) {
return replace(this.channelInvitationFormSelectablePartnerViewOwner.partner);
return replace(this.channelInvitationFormSelectablePartnerViewOwner.partner.persona);
}
if (this.channelMemberViewOwner) {
return replace(this.channelMemberViewOwner.channelMember.partner);
return replace(this.channelMemberViewOwner.channelMember.partner.persona);
}
if (this.composerSuggestionViewOwner) {
return replace(this.composerSuggestionViewOwner.partner);
return replace(this.composerSuggestionViewOwner.partner.persona);
}
if (this.messageViewOwner) {
return replace(this.messageViewOwner.message.author);
return replace(this.messageViewOwner.message.author.persona);
}
if (this.notificationRequestViewOwner) {
return replace(this.messaging.partnerRoot);
return replace(this.messaging.partnerRoot.persona);
}
if (this.threadNeedactionPreviewViewOwner) {
return replace(this.threadNeedactionPreviewViewOwner.thread.correspondent);
return replace(this.threadNeedactionPreviewViewOwner.thread.correspondent.persona);
}
if (this.threadPreviewViewOwner) {
return replace(this.threadPreviewViewOwner.thread.correspondent);
return replace(this.threadPreviewViewOwner.thread.correspondent.persona);
}
return clear();
},
@@ -74,8 +74,8 @@ registerModel({
inverse: 'partnerImStatusIconView',
readonly: true,
}),
partner: one('Partner', {
compute: '_computePartner',
persona: one('Persona', {
compute: '_computePersona',
readonly: true,
required: true,
}),
+56
View File
@@ -0,0 +1,56 @@
/** @odoo-module **/
import { registerModel } from '@mail/model/model_core';
import { attr, one } from '@mail/model/model_field';
import { clear } from '@mail/model/model_field_command';
registerModel({
name: 'Persona',
identifyingFields: [['guest', 'partner']],
recordMethods: {
/**
* @private
* @returns {string|FieldCommand}
*/
_computeImStatus() {
if (this.guest) {
return this.guest.im_status || clear();
}
if (this.partner) {
return this.partner.im_status || clear();
}
return clear();
},
/**
* @private
* @returns {string|FieldCommand}
*/
_computeName() {
if (this.guest) {
return this.guest.name || clear();
}
if (this.partner) {
return this.partner.nameOrDisplayName || clear();
}
return clear();
},
},
fields: {
guest: one('Guest', {
inverse: 'persona',
readonly: true,
}),
im_status: attr({
compute: '_computeImStatus',
readonly: true,
}),
name: attr({
compute: '_computeName',
readonly: true,
}),
partner: one('Partner', {
inverse: 'persona',
readonly: true,
}),
},
});