Merge branch 'develop' into fix/next-message-bubbles
This commit is contained in:
@@ -10,6 +10,7 @@ defineProps({
|
||||
iconBgColor: { type: String, default: 'bg-n-alpha-3' },
|
||||
senderTranslationKey: { type: String, required: true },
|
||||
content: { type: String, required: true },
|
||||
title: { type: String, default: '' }, // Title can be any name, description, etc
|
||||
action: {
|
||||
type: Object,
|
||||
required: true,
|
||||
@@ -48,6 +49,9 @@ const senderName = computed(() => {
|
||||
}}
|
||||
</div>
|
||||
<slot>
|
||||
<div v-if="title" class="truncate text-sm text-n-slate-12">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div v-if="content" class="truncate text-sm text-n-slate-11">
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
ExceptionWithMessage,
|
||||
} from 'shared/helpers/CustomErrors';
|
||||
|
||||
const { content, attachments } = useMessageContext();
|
||||
const { attachments } = useMessageContext();
|
||||
|
||||
const $store = useStore();
|
||||
const { t } = useI18n();
|
||||
@@ -24,6 +24,12 @@ const phoneNumber = computed(() => {
|
||||
return attachment.value.fallbackTitle;
|
||||
});
|
||||
|
||||
const contactName = computed(() => {
|
||||
const { meta } = attachment.value ?? {};
|
||||
const { firstName, lastName } = meta ?? {};
|
||||
return `${firstName ?? ''} ${lastName ?? ''}`.trim();
|
||||
});
|
||||
|
||||
const formattedPhoneNumber = computed(() => {
|
||||
return phoneNumber.value.replace(/\s|-|[A-Za-z]/g, '');
|
||||
});
|
||||
@@ -32,13 +38,9 @@ const rawPhoneNumber = computed(() => {
|
||||
return phoneNumber.value.replace(/\D/g, '');
|
||||
});
|
||||
|
||||
const name = computed(() => {
|
||||
return content.value;
|
||||
});
|
||||
|
||||
function getContactObject() {
|
||||
const contactItem = {
|
||||
name: name.value,
|
||||
name: contactName.value,
|
||||
phone_number: `+${rawPhoneNumber.value}`,
|
||||
};
|
||||
return contactItem;
|
||||
@@ -99,6 +101,7 @@ const action = computed(() => ({
|
||||
icon="i-teenyicons-user-circle-solid"
|
||||
icon-bg-color="bg-[#D6409F]"
|
||||
sender-translation-key="CONVERSATION.SHARED_ATTACHMENT.CONTACT"
|
||||
:title="contactName"
|
||||
:content="phoneNumber"
|
||||
:action="formattedPhoneNumber ? action : null"
|
||||
/>
|
||||
|
||||
@@ -57,7 +57,7 @@ useEventListener(document.body, 'mouseup', onMouseUp);
|
||||
useEventListener(document, 'keydown', onKeydown);
|
||||
|
||||
onMounted(() => {
|
||||
if (onClose && typeof onClose === 'function') {
|
||||
if (import.meta.env.DEV && onClose && typeof onClose === 'function') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
"[DEPRECATED] The 'onClose' prop is deprecated. Please use the 'close' event instead."
|
||||
|
||||
@@ -28,10 +28,12 @@ export default {
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// eslint-disable-next-line
|
||||
console.warn(
|
||||
'[DEPRECATED] This component has been deprecated and will be removed soon. Please use v3/components/Form/Button.vue instead'
|
||||
);
|
||||
if (import.meta.env.DEV) {
|
||||
// eslint-disable-next-line
|
||||
console.warn(
|
||||
'[DEPRECATED] This component has been deprecated and will be removed soon. Please use v3/components/Form/Button.vue instead'
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
import WhatsappTemplates from './WhatsappTemplates/Modal.vue';
|
||||
import { MESSAGE_MAX_LENGTH } from 'shared/helpers/MessageTypeHelper';
|
||||
import inboxMixin, { INBOX_FEATURES } from 'shared/mixins/inboxMixin';
|
||||
import { trimContent, debounce } from '@chatwoot/utils';
|
||||
import { trimContent, debounce, getRecipients } from '@chatwoot/utils';
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
import { CONVERSATION_EVENTS } from '../../../helper/AnalyticsHelper/events';
|
||||
import fileUploadMixin from 'dashboard/mixins/fileUploadMixin';
|
||||
@@ -388,7 +388,6 @@ export default {
|
||||
watch: {
|
||||
currentChat(conversation) {
|
||||
const { can_reply: canReply } = conversation;
|
||||
|
||||
this.setCCAndToEmailsFromLastChat();
|
||||
|
||||
if (this.isOnPrivateNote) {
|
||||
@@ -403,6 +402,19 @@ export default {
|
||||
|
||||
this.fetchAndSetReplyTo();
|
||||
},
|
||||
// When moving from one conversation to another, the store may not have the
|
||||
// list of all the messages. A fetch is subsequently made to get the messages.
|
||||
// However, this update does not trigger the `currentChat` watcher.
|
||||
// We can add a deep watcher to it, but then, that would be too broad of a net to cast
|
||||
// And would impact performance too. So we watch the messages directly.
|
||||
// The watcher here is `deep` too, because the messages array is mutated and
|
||||
// not replaced. So, a shallow watcher would not catch the change.
|
||||
'currentChat.messages': {
|
||||
handler() {
|
||||
this.setCCAndToEmailsFromLastChat();
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
conversationIdByRoute(conversationId, oldConversationId) {
|
||||
if (conversationId !== oldConversationId) {
|
||||
this.setToDraft(oldConversationId, this.replyType);
|
||||
@@ -989,45 +1001,20 @@ export default {
|
||||
this.ccEmails = value.ccEmails;
|
||||
},
|
||||
setCCAndToEmailsFromLastChat() {
|
||||
if (!this.lastEmail) return;
|
||||
|
||||
const {
|
||||
content_attributes: { email: emailAttributes = {} },
|
||||
} = this.lastEmail;
|
||||
|
||||
// Retrieve the email of the current conversation's sender
|
||||
const conversationContact = this.currentChat?.meta?.sender?.email || '';
|
||||
let cc = emailAttributes.cc ? [...emailAttributes.cc] : [];
|
||||
let to = [];
|
||||
const { email: inboxEmail, forward_to_email: forwardToEmail } =
|
||||
this.inbox;
|
||||
|
||||
// there might be a situation where the current conversation will include a message from a third person,
|
||||
// and the current conversation contact is in CC.
|
||||
// This is an edge-case, reported here: CW-1511 [ONLY FOR INTERNAL REFERENCE]
|
||||
// So we remove the current conversation contact's email from the CC list if present
|
||||
if (cc.includes(conversationContact)) {
|
||||
cc = cc.filter(email => email !== conversationContact);
|
||||
}
|
||||
|
||||
// If the last incoming message sender is different from the conversation contact, add them to the "to"
|
||||
// and add the conversation contact to the CC
|
||||
if (!emailAttributes.from.includes(conversationContact)) {
|
||||
to.push(...emailAttributes.from);
|
||||
cc.push(conversationContact);
|
||||
}
|
||||
|
||||
// Remove the conversation contact's email from the BCC list if present
|
||||
let bcc = (emailAttributes.bcc || []).filter(
|
||||
email => email !== conversationContact
|
||||
const { cc, bcc, to } = getRecipients(
|
||||
this.lastEmail,
|
||||
conversationContact,
|
||||
inboxEmail,
|
||||
forwardToEmail
|
||||
);
|
||||
|
||||
// Ensure only unique email addresses are in the CC list
|
||||
bcc = [...new Set(bcc)];
|
||||
cc = [...new Set(cc)];
|
||||
to = [...new Set(to)];
|
||||
|
||||
this.toEmails = to.join(', ');
|
||||
this.ccEmails = cc.join(', ');
|
||||
this.bccEmails = bcc.join(', ');
|
||||
this.toEmails = to.join(', ');
|
||||
},
|
||||
fetchAndSetReplyTo() {
|
||||
const replyStorageKey = LOCAL_STORAGE_KEYS.MESSAGE_REPLY_TO;
|
||||
|
||||
@@ -40,10 +40,12 @@ export default {
|
||||
},
|
||||
emits: ['update:modelValue', 'input', 'blur'],
|
||||
mounted() {
|
||||
// eslint-disable-next-line
|
||||
console.warn(
|
||||
'[DEPRECATED] <WootInput> has be deprecated and will be removed soon. Please use v3/components/Form/Input.vue instead'
|
||||
);
|
||||
if (import.meta.env.DEV) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'[DEPRECATED] <WootInput> has be deprecated and will be removed soon. Please use v3/components/Form/Input.vue instead'
|
||||
);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange(e) {
|
||||
|
||||
@@ -152,7 +152,10 @@ export class DashboardAudioNotificationHelper {
|
||||
|
||||
const shouldPlayAudio = [];
|
||||
|
||||
if (audioAlertType.includes(EVENT_TYPES.ASSIGNED)) {
|
||||
if (
|
||||
audioAlertType.includes(EVENT_TYPES.ASSIGNED) ||
|
||||
audioAlertType.includes('mine')
|
||||
) {
|
||||
shouldPlayAudio.push(assignedToMe);
|
||||
}
|
||||
if (audioAlertType.includes(EVENT_TYPES.UNASSIGNED)) {
|
||||
|
||||
@@ -27,18 +27,12 @@ const getters = {
|
||||
const selectedChat = _getters.getSelectedChat;
|
||||
const { messages = [] } = selectedChat;
|
||||
const lastEmail = [...messages].reverse().find(message => {
|
||||
const {
|
||||
content_attributes: contentAttributes = {},
|
||||
message_type: messageType,
|
||||
} = message;
|
||||
const { email = {} } = contentAttributes;
|
||||
const isIncomingOrOutgoing =
|
||||
messageType === MESSAGE_TYPE.OUTGOING ||
|
||||
messageType === MESSAGE_TYPE.INCOMING;
|
||||
if (email.from && isIncomingOrOutgoing) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
const { message_type: messageType } = message;
|
||||
if (message.private) return false;
|
||||
|
||||
return [MESSAGE_TYPE.OUTGOING, MESSAGE_TYPE.INCOMING].includes(
|
||||
messageType
|
||||
);
|
||||
});
|
||||
|
||||
return lastEmail;
|
||||
|
||||
@@ -40,10 +40,12 @@ export default {
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// eslint-disable-next-line
|
||||
console.warn(
|
||||
'[DEPRECATED] This component has been deprecated and will be removed soon. Please use v3/components/Form/Button.vue instead'
|
||||
);
|
||||
if (import.meta.env.DEV) {
|
||||
// eslint-disable-next-line
|
||||
console.warn(
|
||||
'[DEPRECATED] This component has been deprecated and will be removed soon. Please use v3/components/Form/Button.vue instead'
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user