Chatwoot/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue

223 lines
5.6 KiB
Vue

<template>
<div
class="conversation"
:class="{
active: isActiveChat,
'unread-chat': hasUnread,
'has-inbox-name': showInboxName,
}"
@click="cardClick(chat)"
>
<Thumbnail
v-if="!hideThumbnail"
:src="currentContact.thumbnail"
:badge="chatMetadata.channel"
class="columns"
:username="currentContact.name"
:status="currentContact.availability_status"
size="40px"
/>
<div class="conversation--details columns">
<span v-if="showInboxName" v-tooltip.bottom="inboxName" class="label">
<i :class="computedInboxClass" />
{{ inboxName }}
</span>
<h4 class="conversation--user">
{{ currentContact.name }}
</h4>
<p v-if="lastMessageInChat" class="conversation--message">
<i v-if="messageByAgent" class="ion-ios-undo message-from-agent"></i>
<span v-if="lastMessageInChat.content">
{{ parsedLastMessage }}
</span>
<span v-else-if="!lastMessageInChat.attachments">{{ ` ` }}</span>
<span v-else>
<i :class="`small-icon ${this.$t(`${attachmentIconKey}.ICON`)}`"></i>
{{ this.$t(`${attachmentIconKey}.CONTENT`) }}
</span>
</p>
<p v-else class="conversation--message">
<i class="ion-android-alert"></i>
<span>
{{ this.$t(`CHAT_LIST.NO_MESSAGES`) }}
</span>
</p>
<div class="conversation--meta">
<span class="timestamp">
{{ dynamicTime(chat.timestamp) }}
</span>
<span class="unread">{{ unreadCount > 9 ? '9+' : unreadCount }}</span>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { MESSAGE_TYPE } from 'widget/helpers/constants';
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import { getInboxClassByType } from 'dashboard/helper/inbox';
import Thumbnail from '../Thumbnail';
import conversationMixin from '../../../mixins/conversations';
import timeMixin from '../../../mixins/time';
import router from '../../../routes';
import { frontendURL, conversationUrl } from '../../../helper/URLHelper';
export default {
components: {
Thumbnail,
},
mixins: [timeMixin, conversationMixin, messageFormatterMixin],
props: {
activeLabel: {
type: String,
default: '',
},
chat: {
type: Object,
default: () => {},
},
hideInboxName: {
type: Boolean,
default: false,
},
hideThumbnail: {
type: Boolean,
default: false,
},
teamId: {
type: [String, Number],
default: 0,
},
},
computed: {
...mapGetters({
currentChat: 'getSelectedChat',
inboxesList: 'inboxes/getInboxes',
activeInbox: 'getSelectedInbox',
currentUser: 'getCurrentUser',
accountId: 'getCurrentAccountId',
}),
chatMetadata() {
return this.chat.meta;
},
currentContact() {
return this.$store.getters['contacts/getContact'](
this.chatMetadata.sender.id
);
},
attachmentIconKey() {
const lastMessage = this.lastMessageInChat;
const [{ file_type: fileType } = {}] = lastMessage.attachments;
return `CHAT_LIST.ATTACHMENTS.${fileType}`;
},
isActiveChat() {
return this.currentChat.id === this.chat.id;
},
unreadCount() {
return this.unreadMessagesCount(this.chat);
},
hasUnread() {
return this.unreadCount > 0;
},
isInboxNameVisible() {
return !this.activeInbox;
},
lastMessageInChat() {
return this.lastMessage(this.chat);
},
messageByAgent() {
const lastMessage = this.lastMessageInChat;
const { message_type: messageType } = lastMessage;
return messageType === MESSAGE_TYPE.OUTGOING;
},
parsedLastMessage() {
const { content_attributes: contentAttributes } = this.lastMessageInChat;
const { email: { subject } = {} } = contentAttributes || {};
return this.getPlainText(subject || this.lastMessageInChat.content);
},
chatInbox() {
const { inbox_id: inboxId } = this.chat;
const stateInbox = this.$store.getters['inboxes/getInbox'](inboxId);
return stateInbox;
},
computedInboxClass() {
const { phone_number: phoneNumber, channel_type: type } = this.chatInbox;
const classByType = getInboxClassByType(type, phoneNumber);
return classByType;
},
showInboxName() {
return !this.hideInboxName && this.isInboxNameVisible;
},
inboxName() {
const stateInbox = this.chatInbox;
return stateInbox.name || '';
},
},
methods: {
cardClick(chat) {
const { activeInbox } = this;
const path = conversationUrl({
accountId: this.accountId,
activeInbox,
id: chat.id,
label: this.activeLabel,
teamId: this.teamId,
});
router.push({ path: frontendURL(path) });
},
},
};
</script>
<style lang="scss" scoped>
.conversation {
align-items: center;
}
.has-inbox-name {
&::v-deep .user-thumbnail-box {
margin-top: var(--space-normal);
align-items: flex-start;
}
.conversation--meta {
margin-top: var(--space-normal);
}
}
.conversation--details .label {
padding: var(--space-micro) 0 var(--space-micro) 0;
line-height: var(--space-slab);
font-weight: var(--font-weight-medium);
background: none;
color: var(--s-500);
font-size: var(--font-size-mini);
}
.conversation--details {
.conversation--user {
padding-top: var(--space-micro);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 60%;
}
.ion-earth {
font-size: var(--font-size-mini);
}
}
</style>