mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
feat: nested eml quick view
This commit is contained in:
@@ -41,10 +41,10 @@ export const download_attachment = async (accountId: number, id: string, content
|
||||
saveAs(blob, fileName);
|
||||
};
|
||||
|
||||
export const download_nested_attachment = async (accountId: number, id: string, content_hash: string, nested_content_hash: string) => {
|
||||
export const download_nested_attachment = async (accountId: number, id: string, content_hash: string, nested_content_hash: string, fileName: string) => {
|
||||
const response = await axiosInstance.get(`api/v1/download-nested-attachment/${accountId}/${id}?content_hash=${content_hash}&nested_content_hash=${nested_content_hash}`, { responseType: 'blob' });
|
||||
const blob = new Blob([response.data]);
|
||||
saveAs(blob, nested_content_hash);
|
||||
saveAs(blob, fileName);
|
||||
};
|
||||
export interface AttachmentInfo {
|
||||
/** MIME content type of the attachment (e.g., `image/png`, `application/pdf`). */
|
||||
|
||||
@@ -21,7 +21,7 @@ import React from 'react'
|
||||
import { SortingState } from '@tanstack/react-table'
|
||||
import { AttachmentModel } from '@/api/attachment/api'
|
||||
|
||||
export type AttachmentDialogType = 'mailbox' | 'display' | 'delete' | 'filters' | 'tags' | 'edit-tags' | 'update-tags' | 'restore' | 'delete-mailbox'
|
||||
export type AttachmentDialogType = 'mailbox' | 'display' | 'delete' | 'filters' | 'tags' | 'edit-tags' | 'update-tags' | 'restore' | 'delete-mailbox' | 'nested-eml'
|
||||
|
||||
interface AttachmentContextType {
|
||||
open: AttachmentDialogType | null
|
||||
|
||||
@@ -32,6 +32,7 @@ import { AttachmentModel } from '@/api/attachment/api';
|
||||
import { MailDisplayDrawer } from './mail-display-dialog';
|
||||
import { EnvelopeDeleteDialog } from './delete-dialog';
|
||||
import { RestoreMessageDialog } from './restore-message-dialog';
|
||||
import { NestedEmailDialog } from './nested-email-dialog';
|
||||
|
||||
export default function AttachmentSearch() {
|
||||
const { t } = useTranslation()
|
||||
@@ -147,6 +148,12 @@ export default function AttachmentSearch() {
|
||||
open={open === 'restore'}
|
||||
onOpenChange={() => setOpen('restore')}
|
||||
/>
|
||||
|
||||
<NestedEmailDialog
|
||||
key="nested-eml-attachment-dialog"
|
||||
open={open === 'nested-eml'}
|
||||
onOpenChange={() => setOpen('nested-eml')}
|
||||
/>
|
||||
</AttachmentProvider>
|
||||
</Main>
|
||||
</>
|
||||
|
||||
@@ -165,7 +165,7 @@ export function AttachmentListTable({
|
||||
accessorKey: "name",
|
||||
header: t('attachment.name'),
|
||||
cell: ({ row }) => {
|
||||
const { name, content_type } = row.original;
|
||||
const { name, content_type, is_message } = row.original;
|
||||
const safeName = name ?? "n/a";
|
||||
|
||||
const shortContentType = content_type
|
||||
@@ -179,9 +179,30 @@ export function AttachmentListTable({
|
||||
contentType={content_type ?? ""}
|
||||
className="h-4 w-4 mt-0.5"
|
||||
/>
|
||||
<LongText className='text-xs font-medium max-w-[320px] text-foreground/90'>
|
||||
|
||||
{is_message && <div className="group relative flex items-center w-full min-w-0 h-full px-2 overflow-hidden">
|
||||
<div className="absolute left-0 top-0 bottom-0 w-[2px] bg-primary opacity-0 group-hover:opacity-100 transition-opacity" />
|
||||
|
||||
<div className="text-xs flex flex-wrap gap-x-1 min-w-0 flex-1">
|
||||
<span className="flex items-center">
|
||||
<button
|
||||
type="button"
|
||||
title={t('attachment.viewEmbeddedEmail')}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setCurrentAttachment(row.original);
|
||||
setOpen("nested-eml");
|
||||
}}
|
||||
className="hover:text-primary hover:underline transition-colors truncate"
|
||||
>
|
||||
<LongText>{safeName}</LongText>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>}
|
||||
{!is_message && <LongText className='text-xs font-medium max-w-[320px] text-foreground/90'>
|
||||
{safeName}
|
||||
</LongText>
|
||||
</LongText>}
|
||||
</div>
|
||||
<div className="flex items-center gap-1 ml-6.5 mt-1">
|
||||
<span className="text-[10px] text-muted-foreground font-mono bg-muted px-1 py-0.5 rounded-sm">
|
||||
@@ -278,7 +299,7 @@ export function AttachmentListTable({
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="divide-y divide-border">
|
||||
{Array.from({ length: 8 }).map((_, i) => (
|
||||
{Array.from({ length: 30 }).map((_, i) => (
|
||||
<div key={i} className="flex items-center gap-2 px-2 py-1.5">
|
||||
<Skeleton className="h-3 w-3" />
|
||||
<Skeleton className="h-3 w-3 rounded-full" />
|
||||
|
||||
@@ -27,6 +27,7 @@ import { useQuery } from '@tanstack/react-query';
|
||||
import { Download, Loader, Mail } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getFileConfig } from './mail-message-view';
|
||||
import { useAttachmentContext } from './context';
|
||||
|
||||
const MessageHeader = ({
|
||||
envelope,
|
||||
@@ -35,7 +36,7 @@ const MessageHeader = ({
|
||||
}: {
|
||||
envelope: EmailEnvelope,
|
||||
attachments?: AttachmentInfo[],
|
||||
onDownload: (nested_content_hash: string) => void
|
||||
onDownload: (nested_content_hash: string, fileName: string) => void
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const displayAttachments = attachments || [];
|
||||
@@ -118,7 +119,7 @@ const MessageHeader = ({
|
||||
<Tooltip key={i}>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
onClick={() => onDownload(att.content_hash)}
|
||||
onClick={() => onDownload(att.content_hash, att.filename)}
|
||||
className="group flex items-center gap-2 px-3 py-1.5 bg-slate-50 border border-slate-200 rounded-lg hover:bg-blue-50 hover:border-blue-200 transition-all text-slate-600 hover:text-blue-700"
|
||||
>
|
||||
<span className={`${color} p-0.5 rounded`}>{icon}</span>
|
||||
@@ -144,12 +145,13 @@ const MessageHeader = ({
|
||||
|
||||
|
||||
|
||||
export function NestedEmailDialog({ open, onOpenChange, accountId, envelopeId, fileName, content_hash }: any) {
|
||||
export function NestedEmailDialog({ open, onOpenChange }: any) {
|
||||
const { currentAttachment } = useAttachmentContext()
|
||||
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['nested-message', accountId, envelopeId, content_hash],
|
||||
queryFn: () => load_nested_message(accountId, envelopeId, content_hash),
|
||||
enabled: open && !!content_hash,
|
||||
queryKey: ['nested-message', currentAttachment?.account_id!, currentAttachment?.envelope_id!, currentAttachment?.content_hash!],
|
||||
queryFn: () => load_nested_message(currentAttachment?.account_id!, currentAttachment?.envelope_id!, currentAttachment?.content_hash!),
|
||||
enabled: open && !!currentAttachment,
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -158,7 +160,7 @@ export function NestedEmailDialog({ open, onOpenChange, accountId, envelopeId, f
|
||||
<div className="text-white px-4 py-3 flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Mail className="h-4 w-4 text-blue-400" />
|
||||
<span className="text-sm font-medium truncate max-w-[400px] opacity-90">{fileName}</span>
|
||||
<span className="text-sm font-medium truncate max-w-[400px] opacity-90">{currentAttachment?.name}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -170,7 +172,13 @@ export function NestedEmailDialog({ open, onOpenChange, accountId, envelopeId, f
|
||||
<MessageHeader
|
||||
envelope={data.envelope}
|
||||
attachments={data.attachments}
|
||||
onDownload={(nested_content_hash) => download_nested_attachment(accountId, envelopeId, content_hash, nested_content_hash)}
|
||||
onDownload={(nested_content_hash, fileName) => download_nested_attachment(
|
||||
currentAttachment?.account_id!,
|
||||
currentAttachment?.envelope_id!,
|
||||
currentAttachment?.content_hash!,
|
||||
nested_content_hash,
|
||||
fileName
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="mt-8 pt-8 border-t border-slate-100">
|
||||
|
||||
@@ -325,7 +325,7 @@ export function MailListTable({
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="divide-y divide-border">
|
||||
{Array.from({ length: 8 }).map((_, i) => (
|
||||
{Array.from({ length: 30 }).map((_, i) => (
|
||||
<div key={i} className="flex items-center gap-2 px-2 py-1.5">
|
||||
<Skeleton className="h-3 w-3" />
|
||||
<Skeleton className="h-3 w-3 rounded-full" />
|
||||
|
||||
@@ -35,7 +35,7 @@ const MessageHeader = ({
|
||||
}: {
|
||||
envelope: EmailEnvelope,
|
||||
attachments?: AttachmentInfo[],
|
||||
onDownload: (nested_content_hash: string) => void
|
||||
onDownload: (nested_content_hash: string, fileName: string) => void
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const displayAttachments = attachments || [];
|
||||
@@ -118,7 +118,7 @@ const MessageHeader = ({
|
||||
<Tooltip key={i}>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
onClick={() => onDownload(att.content_hash)}
|
||||
onClick={() => onDownload(att.content_hash, att.filename)}
|
||||
className="group flex items-center gap-2 px-3 py-1.5 bg-slate-50 border border-slate-200 rounded-lg hover:bg-blue-50 hover:border-blue-200 transition-all text-slate-600 hover:text-blue-700"
|
||||
>
|
||||
<span className={`${color} p-0.5 rounded`}>{icon}</span>
|
||||
@@ -170,7 +170,7 @@ export function NestedEmailDialog({ open, onOpenChange, accountId, envelopeId, f
|
||||
<MessageHeader
|
||||
envelope={data.envelope}
|
||||
attachments={data.attachments}
|
||||
onDownload={(nested_content_hash) => download_nested_attachment(accountId, envelopeId, content_hash, nested_content_hash)}
|
||||
onDownload={(nested_content_hash, fileName) => download_nested_attachment(accountId, envelopeId, content_hash, nested_content_hash, fileName)}
|
||||
/>
|
||||
|
||||
<div className="mt-8 pt-8 border-t border-slate-100">
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "إظهار الملفات المكررة",
|
||||
"size": "حجم الملف",
|
||||
"source": "المصدر",
|
||||
"subject": "الموضوع"
|
||||
"subject": "الموضوع",
|
||||
"viewEmbeddedEmail": "عرض البريد الإلكتروني المضمن"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "هل أنت متأكد أنك تريد تسجيل الخروج؟",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "المرفقات",
|
||||
"bcc": "نسخة مخفية",
|
||||
"cc": "نسخة",
|
||||
"clickToDownload": "انقر للتنزيل",
|
||||
"date": "التاريخ",
|
||||
"delete": "حذف",
|
||||
"download": "تحميل",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Vis dubletter",
|
||||
"size": "Filstørrelse",
|
||||
"source": "Kilde",
|
||||
"subject": "Emne"
|
||||
"subject": "Emne",
|
||||
"viewEmbeddedEmail": "Vis indlejret e-mail"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Er du sikker på, du vil logge ud?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Vedhæftninger",
|
||||
"bcc": "Blindkopi",
|
||||
"cc": "Kopi",
|
||||
"clickToDownload": "Klik for at downloade",
|
||||
"date": "Dato",
|
||||
"delete": "Slet",
|
||||
"download": "Download",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Duplikate anzeigen",
|
||||
"size": "Dateigröße",
|
||||
"source": "Quelle",
|
||||
"subject": "Betreff"
|
||||
"subject": "Betreff",
|
||||
"viewEmbeddedEmail": "Eingebettete E-Mail anzeigen"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Sind Sie sicher, dass Sie sich abmelden möchten?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Anhänge",
|
||||
"bcc": "BCC",
|
||||
"cc": "CC",
|
||||
"clickToDownload": "Zum Herunterladen klicken",
|
||||
"date": "Datum",
|
||||
"delete": "Löschen",
|
||||
"download": "Herunterladen",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Show duplicates",
|
||||
"size": "File size",
|
||||
"source": "Source",
|
||||
"subject": "Subject"
|
||||
"subject": "Subject",
|
||||
"viewEmbeddedEmail": "View embedded email"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Are you sure you want to log out?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Attachments",
|
||||
"bcc": "BCC",
|
||||
"cc": "CC",
|
||||
"clickToDownload": "Click to download",
|
||||
"date": "Date",
|
||||
"delete": "Delete",
|
||||
"download": "Download",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Mostrar duplicados",
|
||||
"size": "Tamaño del archivo",
|
||||
"source": "Fuente",
|
||||
"subject": "Asunto"
|
||||
"subject": "Asunto",
|
||||
"viewEmbeddedEmail": "Ver correo electrónico incrustado"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "¿Estás seguro de que quieres cerrar sesión?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Adjuntos",
|
||||
"bcc": "CCO",
|
||||
"cc": "CC",
|
||||
"clickToDownload": "Hacer clic para descargar",
|
||||
"date": "Fecha",
|
||||
"delete": "Eliminar",
|
||||
"download": "Descargar",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Näytä kaksoiskappaleet",
|
||||
"size": "Tiedostokoko",
|
||||
"source": "Lähde",
|
||||
"subject": "Aihe"
|
||||
"subject": "Aihe",
|
||||
"viewEmbeddedEmail": "Näytä upotettu sähköposti"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Oletko varma, että haluat kirjautua ulos?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Liitteet",
|
||||
"bcc": "Piilokopio",
|
||||
"cc": "Kopio",
|
||||
"clickToDownload": "Napsauta ladataksesi",
|
||||
"date": "Päivämäärä",
|
||||
"delete": "Poista",
|
||||
"download": "Lataa",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Afficher les doublons",
|
||||
"size": "Taille du fichier",
|
||||
"source": "Source",
|
||||
"subject": "Objet"
|
||||
"subject": "Objet",
|
||||
"viewEmbeddedEmail": "Voir l'e-mail intégré"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Êtes-vous sûr de vouloir vous déconnecter ?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Pièces jointes",
|
||||
"bcc": "Cci",
|
||||
"cc": "Cc",
|
||||
"clickToDownload": "Cliquer pour télécharger",
|
||||
"date": "Date",
|
||||
"delete": "Supprimer",
|
||||
"download": "Télécharger",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Mostra duplicati",
|
||||
"size": "Dimensione file",
|
||||
"source": "Origine",
|
||||
"subject": "Oggetto"
|
||||
"subject": "Oggetto",
|
||||
"viewEmbeddedEmail": "Visualizza email incorporata"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Sei sicuro di voler uscire?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Allegati",
|
||||
"bcc": "BCC",
|
||||
"cc": "CC",
|
||||
"clickToDownload": "Clicca per scaricare",
|
||||
"date": "Data",
|
||||
"delete": "Elimina",
|
||||
"download": "Scarica",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "重複ファイルを表示",
|
||||
"size": "ファイルサイズ",
|
||||
"source": "ソース",
|
||||
"subject": "件名"
|
||||
"subject": "件名",
|
||||
"viewEmbeddedEmail": "埋め込みメールを表示"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "ログアウトしてもよろしいですか?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "添付ファイル",
|
||||
"bcc": "BCC",
|
||||
"cc": "CC",
|
||||
"clickToDownload": "クリックしてダウンロード",
|
||||
"date": "日付",
|
||||
"delete": "削除",
|
||||
"download": "ダウンロード",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "중복 파일 표시",
|
||||
"size": "파일 크기",
|
||||
"source": "출처",
|
||||
"subject": "제목"
|
||||
"subject": "제목",
|
||||
"viewEmbeddedEmail": "포함된 메일 보기"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "정말로 로그아웃하시겠습니까?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "첨부 파일",
|
||||
"bcc": "숨은 참조",
|
||||
"cc": "참조",
|
||||
"clickToDownload": "클릭하여 다운로드",
|
||||
"date": "날짜",
|
||||
"delete": "삭제",
|
||||
"download": "다운로드",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Duplicaten weergeven",
|
||||
"size": "Bestandsgrootte",
|
||||
"source": "Bron",
|
||||
"subject": "Onderwerp"
|
||||
"subject": "Onderwerp",
|
||||
"viewEmbeddedEmail": "Ingesloten e-mail bekijken"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Weet u zeker dat u wilt uitloggen?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Bijlagen",
|
||||
"bcc": "BCC",
|
||||
"cc": "CC",
|
||||
"clickToDownload": "Klik om te downloaden",
|
||||
"date": "Datum",
|
||||
"delete": "Verwijderen",
|
||||
"download": "Downloaden",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Vis duplikater",
|
||||
"size": "Filstørrelse",
|
||||
"source": "Kilde",
|
||||
"subject": "Emne"
|
||||
"subject": "Emne",
|
||||
"viewEmbeddedEmail": "Vis innebygd e-post"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Er du sikker på at du vil logge ut?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Vedlegg",
|
||||
"bcc": "Blindkopi",
|
||||
"cc": "Kopi",
|
||||
"clickToDownload": "Klikk for å laste ned",
|
||||
"date": "Dato",
|
||||
"delete": "Slett",
|
||||
"download": "Last ned",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Pokaż duplikaty",
|
||||
"size": "Rozmiar pliku",
|
||||
"source": "Źródło",
|
||||
"subject": "Temat"
|
||||
"subject": "Temat",
|
||||
"viewEmbeddedEmail": "Wyświetl osadzony e-mail"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Czy na pewno chcesz się wylogować?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Załączniki",
|
||||
"bcc": "UDW",
|
||||
"cc": "DW",
|
||||
"clickToDownload": "Kliknij, aby pobrać",
|
||||
"date": "Data",
|
||||
"delete": "Usuń",
|
||||
"download": "Pobierz",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Mostrar duplicados",
|
||||
"size": "Tamanho do arquivo",
|
||||
"source": "Origem",
|
||||
"subject": "Assunto"
|
||||
"subject": "Assunto",
|
||||
"viewEmbeddedEmail": "Ver e-mail incorporado"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Tem certeza que deseja sair?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Anexos",
|
||||
"bcc": "BCC",
|
||||
"cc": "CC",
|
||||
"clickToDownload": "Clique para baixar",
|
||||
"date": "Data",
|
||||
"delete": "Excluir",
|
||||
"download": "Baixar",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Показать дубликаты",
|
||||
"size": "Размер файла",
|
||||
"source": "Источник",
|
||||
"subject": "Тема"
|
||||
"subject": "Тема",
|
||||
"viewEmbeddedEmail": "Просмотреть вложенное письмо"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Вы уверены, что хотите выйти?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Вложения",
|
||||
"bcc": "Скрытая",
|
||||
"cc": "Копия",
|
||||
"clickToDownload": "Нажмите, чтобы скачать",
|
||||
"date": "Дата",
|
||||
"delete": "Удалить",
|
||||
"download": "Скачать",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "Visa dubbletter",
|
||||
"size": "Filstorlek",
|
||||
"source": "Källa",
|
||||
"subject": "Ämne"
|
||||
"subject": "Ämne",
|
||||
"viewEmbeddedEmail": "Visa inbäddat e-postmeddelande"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "Är du säker på att du vill logga ut?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "Bilagor",
|
||||
"bcc": "Hemlig kopia",
|
||||
"cc": "Kopia",
|
||||
"clickToDownload": "Klicka för att ladda ner",
|
||||
"date": "Datum",
|
||||
"delete": "Ta bort",
|
||||
"download": "Ladda ner",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "顯示重複檔案",
|
||||
"size": "檔案大小",
|
||||
"source": "來源",
|
||||
"subject": "主旨"
|
||||
"subject": "主旨",
|
||||
"viewEmbeddedEmail": "檢視內嵌郵件"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "確定要登出嗎?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "附件",
|
||||
"bcc": "密件副本 (BCC)",
|
||||
"cc": "副本 (CC)",
|
||||
"clickToDownload": "點擊下載",
|
||||
"date": "日期",
|
||||
"delete": "刪除",
|
||||
"download": "下載",
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
"showDuplicates": "显示重复文件",
|
||||
"size": "文件大小",
|
||||
"source": "来源",
|
||||
"subject": "主题"
|
||||
"subject": "主题",
|
||||
"viewEmbeddedEmail": "查看内嵌邮件"
|
||||
},
|
||||
"auth": {
|
||||
"areYouSureYouWantToLogOut": "您确定要退出登录吗?",
|
||||
@@ -546,6 +547,7 @@
|
||||
"attachments": "附件",
|
||||
"bcc": "密送",
|
||||
"cc": "抄送",
|
||||
"clickToDownload": "点击下载",
|
||||
"date": "日期",
|
||||
"delete": "删除",
|
||||
"download": "下载",
|
||||
|
||||
Reference in New Issue
Block a user