From 28e7a5d228d77307d0e27669e6a5bb07e343ca63 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 29 Jun 2023 08:58:44 +0530 Subject: [PATCH] fix: CC conditions when the last email is from someone else (#7010) --- app/builders/messages/message_builder.rb | 17 ++++-- app/javascript/dashboard/api/inbox/message.js | 7 +++ .../widgets/conversation/ReplyBox.vue | 59 +++++++++++++++---- .../widgets/conversation/ReplyEmailHead.vue | 34 +++++++++++ .../i18n/locale/en/conversation.json | 1 + app/mailers/conversation_reply_mailer.rb | 14 +++++ .../conversation_reply_mailer_helper.rb | 2 +- 7 files changed, 116 insertions(+), 18 deletions(-) diff --git a/app/builders/messages/message_builder.rb b/app/builders/messages/message_builder.rb index aca06cd04..af312bf2e 100644 --- a/app/builders/messages/message_builder.rb +++ b/app/builders/messages/message_builder.rb @@ -48,17 +48,22 @@ class Messages::MessageBuilder def process_emails return unless @conversation.inbox&.inbox_type == 'Email' - cc_emails = [] - cc_emails = @params[:cc_emails].gsub(/\s+/, '').split(',') if @params[:cc_emails].present? + cc_emails = process_email_string(@params[:cc_emails]) + bcc_emails = process_email_string(@params[:bcc_emails]) + to_emails = process_email_string(@params[:to_emails]) - bcc_emails = [] - bcc_emails = @params[:bcc_emails].gsub(/\s+/, '').split(',') if @params[:bcc_emails].present? - - all_email_addresses = cc_emails + bcc_emails + all_email_addresses = cc_emails + bcc_emails + to_emails validate_email_addresses(all_email_addresses) @message.content_attributes[:cc_emails] = cc_emails @message.content_attributes[:bcc_emails] = bcc_emails + @message.content_attributes[:to_emails] = to_emails + end + + def process_email_string(email_string) + return [] if email_string.blank? + + email_string.gsub(/\s+/, '').split(',') end def validate_email_addresses(all_emails) diff --git a/app/javascript/dashboard/api/inbox/message.js b/app/javascript/dashboard/api/inbox/message.js index 098826ce3..fc77b24f5 100644 --- a/app/javascript/dashboard/api/inbox/message.js +++ b/app/javascript/dashboard/api/inbox/message.js @@ -10,6 +10,7 @@ export const buildCreatePayload = ({ files, ccEmails = '', bccEmails = '', + toEmails = '', templateParams, }) => { let payload; @@ -25,6 +26,9 @@ export const buildCreatePayload = ({ payload.append('echo_id', echoId); payload.append('cc_emails', ccEmails); payload.append('bcc_emails', bccEmails); + if (toEmails) { + payload.append('to_emails', toEmails); + } } else { payload = { content: message, @@ -33,6 +37,7 @@ export const buildCreatePayload = ({ content_attributes: contentAttributes, cc_emails: ccEmails, bcc_emails: bccEmails, + to_emails: toEmails, template_params: templateParams, }; } @@ -53,6 +58,7 @@ class MessageApi extends ApiClient { files, ccEmails = '', bccEmails = '', + toEmails = '', templateParams, }) { return axios({ @@ -66,6 +72,7 @@ class MessageApi extends ApiClient { files, ccEmails, bccEmails, + toEmails, templateParams, }), }); diff --git a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue index bdb107ed8..b682f6f21 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue @@ -35,6 +35,7 @@ v-if="showReplyHead" :cc-emails.sync="ccEmails" :bcc-emails.sync="bccEmails" + :to-emails.sync="toEmails" /> {}, showWhatsAppTemplatesModal: false, updateEditorSelectionWith: '', @@ -528,7 +530,7 @@ export default { this.replyType = REPLY_EDITOR_MODES.NOTE; } - this.setCCEmailFromLastChat(); + this.setCCAndToEmailsFromLastChat(); }, conversationIdByRoute(conversationId, oldConversationId) { if (conversationId !== oldConversationId) { @@ -562,7 +564,7 @@ export default { // working even if input/textarea is focussed. document.addEventListener('paste', this.onPaste); document.addEventListener('keydown', this.handleKeyEvents); - this.setCCEmailFromLastChat(); + this.setCCAndToEmailsFromLastChat(); this.doAutoSaveDraft = debounce( () => { this.saveDraft(this.conversationIdByRoute, this.replyType); @@ -844,6 +846,7 @@ export default { clearEmailField() { this.ccEmails = ''; this.bccEmails = ''; + this.toEmails = ''; }, toggleEmojiPicker() { this.showEmojiPicker = !this.showEmojiPicker; @@ -1054,22 +1057,56 @@ export default { messagePayload.bccEmails = this.bccEmails; } + if (this.toEmails && !this.isOnPrivateNote) { + messagePayload.toEmails = this.toEmails; + } + return messagePayload; }, setCcEmails(value) { this.bccEmails = value.bccEmails; this.ccEmails = value.ccEmails; }, - setCCEmailFromLastChat() { - if (this.lastEmail) { - const { - content_attributes: { email: emailAttributes = {} }, - } = this.lastEmail; - const cc = emailAttributes.cc || []; - const bcc = emailAttributes.bcc || []; - this.ccEmails = cc.join(', '); - this.bccEmails = bcc.join(', '); + 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] || []; + let to = []; + + // 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 + ); + + // Ensure only unique email addresses are in the CC list + bcc = [...new Set(bcc)]; + cc = [...new Set(cc)]; + to = [...new Set(to)]; + + this.ccEmails = cc.join(', '); + this.bccEmails = bcc.join(', '); + this.toEmails = to.join(', '); }, }, }; diff --git a/app/javascript/dashboard/components/widgets/conversation/ReplyEmailHead.vue b/app/javascript/dashboard/components/widgets/conversation/ReplyEmailHead.vue index d5d56be41..fbd1453db 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ReplyEmailHead.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ReplyEmailHead.vue @@ -1,5 +1,21 @@