Add email reply functionality to thread view
- Add reply button to each email in thread timeline - Pre-fill composer with recipient, subject, and quoted content when replying - Remove readonly constraint from recipient field in composer - Handle reply-to-email event to populate composer with proper reply data
This commit is contained in:
parent
e388779e11
commit
bb2f5d37c8
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
<!-- Email Composer -->
|
||||
<EmailComposer
|
||||
ref="emailComposer"
|
||||
:interest="interest"
|
||||
@sent="onEmailSent"
|
||||
@eoiGenerated="onEoiGenerated"
|
||||
|
|
@ -40,6 +41,7 @@
|
|||
<EmailThreadView
|
||||
ref="threadView"
|
||||
:interest="interest"
|
||||
@reply-to-email="onReplyToEmail"
|
||||
/>
|
||||
</template>
|
||||
</v-card-text>
|
||||
|
|
@ -67,6 +69,7 @@ const emit = defineEmits<Emits>();
|
|||
const isConnected = ref(false);
|
||||
const connectedEmail = ref('');
|
||||
const threadView = ref<InstanceType<typeof EmailThreadView>>();
|
||||
const emailComposer = ref<InstanceType<typeof EmailComposer>>();
|
||||
|
||||
const checkConnection = () => {
|
||||
// Check if we have a session and connected email
|
||||
|
|
@ -100,6 +103,29 @@ const onEoiGenerated = () => {
|
|||
emit('interestUpdated');
|
||||
};
|
||||
|
||||
const onReplyToEmail = (email: any, thread: any) => {
|
||||
// Extract the original sender's email address
|
||||
const replyTo = email.direction === 'received' ? email.from : email.to;
|
||||
const cleanEmail = replyTo.match(/<(.+)>/)?.[1] || replyTo;
|
||||
|
||||
// Prepare reply content with quote
|
||||
const quotedContent = email.body
|
||||
.split('\n')
|
||||
.map((line: string) => `> ${line}`)
|
||||
.join('\n');
|
||||
|
||||
const replyBody = `\n\n\nOn ${new Date(email.timestamp).toLocaleString()}, ${email.from} wrote:\n${quotedContent}`;
|
||||
|
||||
// Pre-fill the composer with reply data
|
||||
if (emailComposer.value) {
|
||||
(emailComposer.value as any).setReplyData({
|
||||
to: cleanEmail,
|
||||
subject: thread.subject.startsWith('Re: ') ? thread.subject : `Re: ${thread.subject}`,
|
||||
body: replyBody
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const disconnect = () => {
|
||||
// Clear session storage
|
||||
sessionStorage.removeItem('emailSessionId');
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
prepend-inner-icon="mdi-email-outline"
|
||||
:rules="[rules.required, rules.email]"
|
||||
:disabled="sending"
|
||||
readonly
|
||||
/>
|
||||
|
||||
<v-text-field
|
||||
|
|
@ -329,4 +328,19 @@ onMounted(() => {
|
|||
localStorage.setItem('emailSignatureConfig', JSON.stringify(newConfig));
|
||||
}, { deep: true });
|
||||
});
|
||||
|
||||
// Method to set reply data
|
||||
const setReplyData = (replyData: { to: string; subject: string; body: string }) => {
|
||||
email.value.to = replyData.to;
|
||||
email.value.subject = replyData.subject;
|
||||
email.value.body = replyData.body;
|
||||
|
||||
// Scroll to the top of the composer
|
||||
form.value?.$el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
};
|
||||
|
||||
// Expose the setReplyData method to parent
|
||||
defineExpose({
|
||||
setReplyData
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -90,6 +90,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
size="small"
|
||||
variant="text"
|
||||
color="primary"
|
||||
prepend-icon="mdi-reply"
|
||||
@click="replyToEmail(email, thread)"
|
||||
>
|
||||
Reply
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-timeline-item>
|
||||
</v-timeline>
|
||||
|
|
@ -129,6 +141,9 @@ interface EmailThread {
|
|||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits<{
|
||||
'reply-to-email': [email: EmailMessage, thread: EmailThread];
|
||||
}>();
|
||||
|
||||
const user = useDirectusUser();
|
||||
const toast = useToast();
|
||||
|
|
@ -237,6 +252,11 @@ const loadEmails = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
// Reply to an email
|
||||
const replyToEmail = (email: EmailMessage, thread: EmailThread) => {
|
||||
emit('reply-to-email', email, thread);
|
||||
};
|
||||
|
||||
// Reload emails when an email is sent
|
||||
const reloadEmails = () => {
|
||||
loadEmails();
|
||||
|
|
|
|||
Loading…
Reference in New Issue