diff --git a/app/javascript/dashboard/components-next/message/TranslationToggle.vue b/app/javascript/dashboard/components-next/message/TranslationToggle.vue new file mode 100644 index 000000000..19b80dd9f --- /dev/null +++ b/app/javascript/dashboard/components-next/message/TranslationToggle.vue @@ -0,0 +1,24 @@ + + + diff --git a/app/javascript/dashboard/components-next/message/bubbles/Email/Index.vue b/app/javascript/dashboard/components-next/message/bubbles/Email/Index.vue index 7efb1ed53..2e03e97af 100644 --- a/app/javascript/dashboard/components-next/message/bubbles/Email/Index.vue +++ b/app/javascript/dashboard/components-next/message/bubbles/Email/Index.vue @@ -9,9 +9,11 @@ import BaseBubble from 'next/message/bubbles/Base.vue'; import FormattedContent from 'next/message/bubbles/Text/FormattedContent.vue'; import AttachmentChips from 'next/message/chips/AttachmentChips.vue'; import EmailMeta from './EmailMeta.vue'; +import TranslationToggle from 'dashboard/components-next/message/TranslationToggle.vue'; import { useMessageContext } from '../../provider.js'; import { MESSAGE_TYPES } from 'next/message/constants.js'; +import { useTranslations } from 'dashboard/composables/useTranslations'; const { content, contentAttributes, attachments, messageType } = useMessageContext(); @@ -19,35 +21,77 @@ const { content, contentAttributes, attachments, messageType } = const isExpandable = ref(false); const isExpanded = ref(false); const showQuotedMessage = ref(false); +const renderOriginal = ref(false); const contentContainer = useTemplateRef('contentContainer'); onMounted(() => { isExpandable.value = contentContainer.value?.scrollHeight > 400; }); -const isOutgoing = computed(() => { - return messageType.value === MESSAGE_TYPES.OUTGOING; -}); +const isOutgoing = computed(() => messageType.value === MESSAGE_TYPES.OUTGOING); const isIncoming = computed(() => !isOutgoing.value); -const textToShow = computed(() => { +const { hasTranslations, translationContent } = + useTranslations(contentAttributes); + +const originalEmailText = computed(() => { const text = contentAttributes?.value?.email?.textContent?.full ?? content.value; return text?.replace(/\n/g, '
'); }); -// Use TextContent as the default to fullHTML +const originalEmailHtml = computed( + () => + contentAttributes?.value?.email?.htmlContent?.full ?? + originalEmailText.value +); + +const messageContent = computed(() => { + // If translations exist and we're showing translations (not original) + if (hasTranslations.value && !renderOriginal.value) { + return translationContent.value; + } + // Otherwise show original content + return content.value; +}); + +const textToShow = computed(() => { + // If translations exist and we're showing translations (not original) + if (hasTranslations.value && !renderOriginal.value) { + return translationContent.value; + } + // Otherwise show original text + return originalEmailText.value; +}); + const fullHTML = computed(() => { - return contentAttributes?.value?.email?.htmlContent?.full ?? textToShow.value; + // If translations exist and we're showing translations (not original) + if (hasTranslations.value && !renderOriginal.value) { + return translationContent.value; + } + // Otherwise show original HTML + return originalEmailHtml.value; }); -const unquotedHTML = computed(() => { - return EmailQuoteExtractor.extractQuotes(fullHTML.value); +const unquotedHTML = computed(() => + EmailQuoteExtractor.extractQuotes(fullHTML.value) +); + +const hasQuotedMessage = computed(() => + EmailQuoteExtractor.hasQuotes(fullHTML.value) +); + +// Ensure unique keys for when toggling between original and translated views. +// This forces Vue to re-render the component and update content correctly. +const translationKeySuffix = computed(() => { + if (renderOriginal.value) return 'original'; + if (hasTranslations.value) return 'translated'; + return 'original'; }); -const hasQuotedMessage = computed(() => { - return EmailQuoteExtractor.hasQuotes(fullHTML.value); -}); +const handleSeeOriginal = () => { + renderOriginal.value = !renderOriginal.value; +};