feat: Support cc and bcc in email replies (#3098)
Co-authored-by: Tejaswini <tejaswini@chatwoot.com> Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
committed by
GitHub
parent
0e0632be22
commit
68e697c379
@@ -8,6 +8,8 @@ export const buildCreatePayload = ({
|
||||
contentAttributes,
|
||||
echoId,
|
||||
file,
|
||||
ccEmails,
|
||||
bccEmails,
|
||||
}) => {
|
||||
let payload;
|
||||
if (file) {
|
||||
@@ -18,12 +20,16 @@ export const buildCreatePayload = ({
|
||||
}
|
||||
payload.append('private', isPrivate);
|
||||
payload.append('echo_id', echoId);
|
||||
payload.append('cc_emails', ccEmails);
|
||||
payload.append('bcc_emails', bccEmails);
|
||||
} else {
|
||||
payload = {
|
||||
content: message,
|
||||
private: isPrivate,
|
||||
echo_id: echoId,
|
||||
content_attributes: contentAttributes,
|
||||
cc_emails: ccEmails,
|
||||
bcc_emails: bccEmails,
|
||||
};
|
||||
}
|
||||
return payload;
|
||||
@@ -41,6 +47,8 @@ class MessageApi extends ApiClient {
|
||||
contentAttributes,
|
||||
echo_id: echoId,
|
||||
file,
|
||||
ccEmails,
|
||||
bccEmails,
|
||||
}) {
|
||||
return axios({
|
||||
method: 'post',
|
||||
@@ -51,6 +59,8 @@ class MessageApi extends ApiClient {
|
||||
contentAttributes,
|
||||
echoId,
|
||||
file,
|
||||
ccEmails,
|
||||
bccEmails,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
<div :class="wrapClass">
|
||||
<div v-tooltip.top-start="sentByMessage" :class="bubbleClass">
|
||||
<bubble-mail-head
|
||||
v-if="isEmailContentType"
|
||||
:email-attributes="contentAttributes.email"
|
||||
:cc="emailHeadAttributes.cc"
|
||||
:bcc="emailHeadAttributes.bcc"
|
||||
:is-incoming="isIncoming"
|
||||
/>
|
||||
<bubble-text
|
||||
@@ -222,6 +223,13 @@ export default {
|
||||
isIncoming() {
|
||||
return this.data.message_type === MESSAGE_TYPE.INCOMING;
|
||||
},
|
||||
emailHeadAttributes() {
|
||||
return {
|
||||
email: this.contentAttributes.email,
|
||||
cc: this.contentAttributes.cc_emails,
|
||||
bcc: this.contentAttributes.bcc_emails
|
||||
}
|
||||
},
|
||||
hasAttachments() {
|
||||
return !!(this.data.attachments && this.data.attachments.length > 0);
|
||||
},
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
v-on-clickaway="hideEmojiPicker"
|
||||
:on-click="emojiOnClick"
|
||||
/>
|
||||
<reply-email-head
|
||||
v-if="showReplyHead"
|
||||
@set-emails="setCcEmails"
|
||||
:clear-mails="clearMails"
|
||||
/>
|
||||
<resizable-text-area
|
||||
v-if="!showRichContentEditor"
|
||||
ref="messageInput"
|
||||
@@ -82,6 +87,7 @@ import CannedResponse from './CannedResponse';
|
||||
import ResizableTextArea from 'shared/components/ResizableTextArea';
|
||||
import AttachmentPreview from 'dashboard/components/widgets/AttachmentsPreview';
|
||||
import ReplyTopPanel from 'dashboard/components/widgets/WootWriter/ReplyTopPanel';
|
||||
import ReplyEmailHead from './ReplyEmailHead';
|
||||
import ReplyBottomPanel from 'dashboard/components/widgets/WootWriter/ReplyBottomPanel';
|
||||
import { REPLY_EDITOR_MODES } from 'dashboard/components/widgets/WootWriter/constants';
|
||||
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
|
||||
@@ -104,6 +110,7 @@ export default {
|
||||
ResizableTextArea,
|
||||
AttachmentPreview,
|
||||
ReplyTopPanel,
|
||||
ReplyEmailHead,
|
||||
ReplyBottomPanel,
|
||||
WootMessageEditor,
|
||||
},
|
||||
@@ -134,6 +141,7 @@ export default {
|
||||
mentionSearchKey: '',
|
||||
hasUserMention: false,
|
||||
hasSlashCommand: false,
|
||||
clearMails: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -270,6 +278,9 @@ export default {
|
||||
}
|
||||
return !this.message.trim().replace(/\n/g, '').length;
|
||||
},
|
||||
showReplyHead(){
|
||||
return this.isAnEmailChannel;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
currentChat(conversation) {
|
||||
@@ -354,6 +365,7 @@ export default {
|
||||
this.showAlert(errorMessage);
|
||||
}
|
||||
this.hideEmojiPicker();
|
||||
this.clearMails = false;
|
||||
}
|
||||
},
|
||||
replaceText(message) {
|
||||
@@ -376,6 +388,7 @@ export default {
|
||||
clearMessage() {
|
||||
this.message = '';
|
||||
this.attachedFiles = [];
|
||||
this.clearMails = true;
|
||||
},
|
||||
toggleEmojiPicker() {
|
||||
this.showEmojiPicker = !this.showEmojiPicker;
|
||||
@@ -452,11 +465,23 @@ export default {
|
||||
messagePayload.file = attachment.resource.file;
|
||||
}
|
||||
|
||||
if(this.ccEmails) {
|
||||
messagePayload.ccEmails = this.ccEmails;
|
||||
}
|
||||
|
||||
if(this.bccEmails) {
|
||||
messagePayload.bccEmails = this.bccEmails;
|
||||
}
|
||||
|
||||
return messagePayload;
|
||||
},
|
||||
setFormatMode(value) {
|
||||
this.updateUISettings({ display_rich_content_editor: value });
|
||||
},
|
||||
setCcEmails(value) {
|
||||
this.bccEmails = value.bccEmails;
|
||||
this.ccEmails = value.ccEmails
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="input-group-wrap">
|
||||
<div class="input-group small" :class="{ error: $v.ccEmails.$error }">
|
||||
<div class="input-group small" :class="{ error: $v.ccEmailsVal.$error }">
|
||||
<label class="input-group-label">
|
||||
{{ $t('CONVERSATION.REPLYBOX.EMAIL_HEAD.CC.LABEL') }}
|
||||
</label>
|
||||
<div class="input-group-field">
|
||||
<woot-input
|
||||
v-model.trim="ccEmails"
|
||||
v-model.trim="$v.ccEmailsVal.$model"
|
||||
type="email"
|
||||
:class="{ error: $v.ccEmails.$error }"
|
||||
:class="{ error: $v.ccEmailsVal.$error }"
|
||||
:placeholder="$t('CONVERSATION.REPLYBOX.EMAIL_HEAD.CC.PLACEHOLDER')"
|
||||
@blur="$v.ccEmails.$touch"
|
||||
@blur="onBlur"
|
||||
/>
|
||||
</div>
|
||||
<woot-button
|
||||
@@ -23,28 +23,28 @@
|
||||
{{ $t('CONVERSATION.REPLYBOX.EMAIL_HEAD.ADD_BCC') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
<span v-if="$v.ccEmails.$error" class="message">
|
||||
<span v-if="$v.ccEmailsVal.$error" class="message">
|
||||
{{ $t('CONVERSATION.REPLYBOX.EMAIL_HEAD.CC.ERROR') }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="showBcc" class="input-group-wrap">
|
||||
<div class="input-group small" :class="{ error: $v.bccEmails.$error }">
|
||||
<div class="input-group small" :class="{ error: $v.bccEmailsVal.$error }">
|
||||
<label class="input-group-label">
|
||||
{{ $t('CONVERSATION.REPLYBOX.EMAIL_HEAD.BCC.LABEL') }}
|
||||
</label>
|
||||
<div class="input-group-field">
|
||||
<woot-input
|
||||
v-model.trim="bccEmails"
|
||||
v-model.trim="$v.bccEmailsVal.$model"
|
||||
type="email"
|
||||
:class="{ error: $v.bccEmails.$error }"
|
||||
:class="{ error: $v.bccEmailsVal.$error }"
|
||||
:placeholder="
|
||||
$t('CONVERSATION.REPLYBOX.EMAIL_HEAD.BCC.PLACEHOLDER')
|
||||
"
|
||||
@blur="$v.bccEmails.$touch"
|
||||
@blur="onBlur"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<span v-if="$v.bccEmails.$error" class="message">
|
||||
<span v-if="$v.bccEmailsVal.$error" class="message">
|
||||
{{ $t('CONVERSATION.REPLYBOX.EMAIL_HEAD.BCC.ERROR') }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -55,27 +55,25 @@
|
||||
import { validEmailsByComma } from './helpers/emailHeadHelper';
|
||||
export default {
|
||||
props: {
|
||||
ccEmails: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
bccEmails: {
|
||||
type: String,
|
||||
default: '',
|
||||
clearMails: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showBcc: false,
|
||||
ccEmailsVal: '',
|
||||
bccEmailsVal: '',
|
||||
};
|
||||
},
|
||||
validations: {
|
||||
ccEmails: {
|
||||
ccEmailsVal: {
|
||||
hasValidEmails(value) {
|
||||
return validEmailsByComma(value);
|
||||
},
|
||||
},
|
||||
bccEmails: {
|
||||
bccEmailsVal: {
|
||||
hasValidEmails(value) {
|
||||
return validEmailsByComma(value);
|
||||
},
|
||||
@@ -85,7 +83,20 @@ export default {
|
||||
handleAddBcc() {
|
||||
this.showBcc = true;
|
||||
},
|
||||
onBlur() {
|
||||
this.$v.$touch();
|
||||
this.$emit("set-emails", { bccEmails: this.bccEmailsVal, ccEmails: this.ccEmailsVal });
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
clearMails: function(value){
|
||||
if(value) {
|
||||
this.ccEmailsVal = '';
|
||||
this.bccEmailsVal = '';
|
||||
this.clearMails = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -36,6 +36,14 @@ export default {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
cc: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
bcc: {
|
||||
type: Array,
|
||||
default: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
toMails() {
|
||||
@@ -43,11 +51,11 @@ export default {
|
||||
return to.join(', ');
|
||||
},
|
||||
ccMails() {
|
||||
const cc = this.emailAttributes.cc || [];
|
||||
const cc = this.emailAttributes.cc || this.cc || [];
|
||||
return cc.join(', ');
|
||||
},
|
||||
bccMails() {
|
||||
const bcc = this.emailAttributes.bcc || [];
|
||||
const bcc = this.emailAttributes.bcc || this.bcc || [];
|
||||
return bcc.join(', ');
|
||||
},
|
||||
subject() {
|
||||
|
||||
Reference in New Issue
Block a user