mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
chore: support bulk restore emails
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
import { useRef } from 'react'
|
||||
import { X, Trash2 } from 'lucide-react'
|
||||
import { X, Trash2, Upload } from 'lucide-react'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
@@ -37,7 +37,7 @@ type MailBulkActionsProps = {
|
||||
}
|
||||
|
||||
export function MailBulkActions({ children }: MailBulkActionsProps) {
|
||||
const { selected, setSelected, setOpen, setToDelete } = useSearchContext()
|
||||
const { selected, setSelected, setOpen, setToDelete, setCurrentEnvelope } = useSearchContext()
|
||||
const toolbarRef = useRef<HTMLDivElement>(null)
|
||||
const { t } = useTranslation()
|
||||
|
||||
@@ -60,6 +60,12 @@ export function MailBulkActions({ children }: MailBulkActionsProps) {
|
||||
setOpen('delete')
|
||||
}
|
||||
|
||||
|
||||
const handleRestore = () => {
|
||||
setCurrentEnvelope(undefined);
|
||||
setOpen('restore')
|
||||
}
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent) => {
|
||||
const buttons = toolbarRef.current?.querySelectorAll('button')
|
||||
if (!buttons || buttons.length === 0) return
|
||||
@@ -161,7 +167,26 @@ export function MailBulkActions({ children }: MailBulkActionsProps) {
|
||||
</div>
|
||||
|
||||
<Separator orientation="vertical" className="h-5" />
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={handleRestore}
|
||||
className="gap-1"
|
||||
>
|
||||
<Upload className="h-3.5 w-3.5" />
|
||||
<span className="hidden sm:inline">
|
||||
{t('restore_message.restore_to_imap', 'Restore Mail')}
|
||||
</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
{t('search.bulkActions.restoreDesc')}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Separator orientation="vertical" className="h-5" />
|
||||
{/* Delete */}
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
|
||||
@@ -95,14 +95,6 @@ export default function Search() {
|
||||
>
|
||||
<div className="mx-auto w-full px-4">
|
||||
<div className="flex gap-6">
|
||||
{/* <aside className="hidden lg:block w-64 flex-shrink-0">
|
||||
<div className="rounded-lg border bg-card p-4">
|
||||
<EnvelopeTags
|
||||
selectedTags={selectedTags}
|
||||
onTagToggle={handleTagToggle}
|
||||
/>
|
||||
</div>
|
||||
</aside> */}
|
||||
<div className="flex-1 min-w-0 space-y-4">
|
||||
{isLoading && (
|
||||
<Card>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import { Loader, Download, Trash2, MessageSquareMore, FileText, FileImage, FileVideo, FileArchive, FileSpreadsheet, FileCode, FileIcon, FileAudio } from 'lucide-react';
|
||||
import { Loader, Download, Trash2, MessageSquareMore, FileText, FileImage, FileVideo, FileArchive, FileSpreadsheet, FileCode, FileIcon, FileAudio, Upload } from 'lucide-react';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Separator } from '@/components/ui/separator';
|
||||
@@ -119,7 +119,7 @@ export function MailMessageView({
|
||||
showHeader = true
|
||||
}: MailMessageViewProps) {
|
||||
const { t } = useTranslation()
|
||||
const { setToDelete, setOpen } = useSearchContext();
|
||||
const { setToDelete, setOpen, setSelected } = useSearchContext();
|
||||
|
||||
const [content, setContent] = useState<string | null>(null);
|
||||
const [contentType, setContentType] = useState<'Plain' | 'Html' | null>(null);
|
||||
@@ -280,6 +280,22 @@ export function MailMessageView({
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t('mail.viewThread')}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Separator orientation="vertical" className="h-5" />
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => {
|
||||
setSelected(new Map())
|
||||
setOpen('restore')
|
||||
}}
|
||||
>
|
||||
<Upload className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t('restore_message.restore_to_imap', 'Restore Mail')}</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -25,6 +25,52 @@ import { AxiosError } from 'axios'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ToastAction } from '@/components/ui/toast'
|
||||
import { useSearchContext } from './context'
|
||||
import { EmailEnvelope } from '@/api'
|
||||
|
||||
function MessageSummary({ envelope, t }: { envelope: EmailEnvelope, t: (key: string) => string }) {
|
||||
return (
|
||||
<div className="mt-3 rounded-md border bg-muted/20 p-3 text-sm overflow-hidden">
|
||||
<div className="grid grid-cols-[auto_1fr] gap-x-2 gap-y-1.5">
|
||||
|
||||
<span className="font-medium text-muted-foreground">{t("mail.subject")}:</span>
|
||||
<div className="break-words font-medium">
|
||||
{envelope.subject || <em className="italic opacity-70">(No subject)</em>}
|
||||
</div>
|
||||
|
||||
<span className="font-medium text-muted-foreground">{t("mail.from")}:</span>
|
||||
<div className="break-all text-foreground/90">
|
||||
{envelope.from}
|
||||
</div>
|
||||
|
||||
{envelope.to?.length > 0 && (
|
||||
<>
|
||||
<span className="font-medium text-muted-foreground">{t("mail.to")}:</span>
|
||||
<div className="break-all text-foreground/90">
|
||||
{envelope.to.slice(0, 2).join(", ")}
|
||||
{envelope.to.length > 2 && " …"}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<span className="font-medium text-muted-foreground">{t("mail.date")}:</span>
|
||||
<div className="text-foreground/90">
|
||||
{new Date(envelope.date).toLocaleString()}
|
||||
</div>
|
||||
|
||||
{envelope.mailbox_name && (
|
||||
<>
|
||||
<span className="font-medium text-muted-foreground">{t("search.mailbox")}:</span>
|
||||
<div className="truncate text-foreground/90" title={envelope.mailbox_name}>
|
||||
{envelope.mailbox_name}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface RestoreMessageDialogProps {
|
||||
open: boolean
|
||||
@@ -36,12 +82,26 @@ export function RestoreMessageDialog({
|
||||
onOpenChange
|
||||
}: RestoreMessageDialogProps) {
|
||||
const { t } = useTranslation()
|
||||
const { currentEnvelope } = useSearchContext()
|
||||
const { currentEnvelope, selected } = useSearchContext()
|
||||
|
||||
const accountsWithSelection = Array.from(selected.entries()).filter(([_, ids]) => ids.size > 0);
|
||||
const selectedCount = accountsWithSelection.reduce((sum, [_, set]) => sum + set.size, 0);
|
||||
const accountCount = accountsWithSelection.length;
|
||||
|
||||
const isBulk = selectedCount > 0;
|
||||
|
||||
|
||||
const restoreMutation = useMutation({
|
||||
mutationFn: () =>
|
||||
restore_message(currentEnvelope!.account_id, [currentEnvelope!.id]),
|
||||
mutationFn: async () => {
|
||||
if (isBulk) {
|
||||
const promises = accountsWithSelection.map(([accountId, ids]) =>
|
||||
restore_message(accountId, Array.from(ids))
|
||||
);
|
||||
return Promise.all(promises);
|
||||
} else if (currentEnvelope) {
|
||||
return restore_message(currentEnvelope.account_id, [currentEnvelope.id]);
|
||||
}
|
||||
},
|
||||
onSuccess: handleRestoreSuccess,
|
||||
onError: handleRestoreError,
|
||||
});
|
||||
@@ -90,16 +150,37 @@ export function RestoreMessageDialog({
|
||||
<ConfirmDialog
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
title={t('restore_message.title', 'Restore messages')}
|
||||
desc={t(
|
||||
'restore_message.desc',
|
||||
'This action will append the selected messages from Bichon to their corresponding mailboxes on the IMAP server.'
|
||||
)}
|
||||
title={isBulk ? t('restore_message.bulkTitle', 'Restore multiple messages') : t('restore_message.title', 'Restore message')}
|
||||
desc={<div className="space-y-3">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t(
|
||||
'restore_message.desc',
|
||||
'This action will append the selected messages to their corresponding mailboxes on the IMAP server.'
|
||||
)}
|
||||
</p>
|
||||
|
||||
{isBulk ? (
|
||||
<div className="rounded-md bg-primary/5 border border-primary/20 p-3 text-sm">
|
||||
<div className="flex justify-between items-center text-primary font-medium">
|
||||
<span>{t('restore_message.summary', 'Summary')}</span>
|
||||
<span className="bg-primary/10 px-2 py-0.5 rounded text-xs">
|
||||
{selectedCount} {t('restore_message.messages', 'messages')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-2 text-xs space-y-1 text-muted-foreground">
|
||||
<p>• {t('restore_message.accountsInvolved', 'Accounts involved')}: {accountCount}</p>
|
||||
<p>• {t('restore_message.bulkWarning', 'Messages will be restored to their original folders.')}</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
currentEnvelope && <MessageSummary envelope={currentEnvelope} t={t} />
|
||||
)}
|
||||
</div>}
|
||||
confirmText={t('restore_message.confirm', 'Restore')}
|
||||
handleConfirm={() => restoreMutation.mutate()}
|
||||
className="sm:max-w-sm"
|
||||
isLoading={restoreMutation.isPending}
|
||||
disabled={restoreMutation.isPending}
|
||||
disabled={restoreMutation.isPending || (!isBulk && !currentEnvelope)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { MoreVertical, TagIcon, Trash2 } from 'lucide-react'
|
||||
import { MoreVertical, TagIcon, Trash2, Upload } from 'lucide-react'
|
||||
import { EmailEnvelope } from '@/api'
|
||||
import { useSearchContext } from '../context'
|
||||
|
||||
@@ -37,7 +37,7 @@ interface DataTableRowActionsProps {
|
||||
}
|
||||
|
||||
export function DataTableRowActions({ row }: DataTableRowActionsProps) {
|
||||
const { setOpen, setCurrentEnvelope, setToDelete } = useSearchContext()
|
||||
const { setOpen, setCurrentEnvelope, setSelected, setToDelete } = useSearchContext()
|
||||
const { t } = useTranslation()
|
||||
|
||||
const toggleToDelete = (accountId: number, mailId: number) => {
|
||||
@@ -93,12 +93,13 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) {
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
setCurrentEnvelope(row.original)
|
||||
setSelected(new Map())
|
||||
setOpen("restore")
|
||||
}}
|
||||
>
|
||||
{t('restore_message.restore_to_imap', 'Restore Mail')}
|
||||
<DropdownMenuShortcut>
|
||||
<TagIcon size={16} />
|
||||
<Upload size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
+12
-7
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "تسجيل الخروج"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "استعادة الرسائل",
|
||||
"desc": "سيقوم هذا الإجراء بإعادة رفع الرسائل المختارة من Bichon واستعادتها إلى صناديق البريد المقابلة لها على خادم IMAP.",
|
||||
"title": "استعادة رسالة واحدة",
|
||||
"bulkTitle": "استعادة رسائل متعددة",
|
||||
"bulkWarning": "ملاحظة: سيتم استعادة الرسائل إلى مجلداتها الأصلية.",
|
||||
"accountsInvolved": "الحسابات المعنية",
|
||||
"summary": "تفاصيل الاستعادة",
|
||||
"messages": "رسائل",
|
||||
"desc": "سيقوم هذا الإجراء بإعادة رفع الرسائل المحددة من Bichon واستعادتها إلى صناديق البريد المقابلة لها على خادم IMAP.",
|
||||
"confirm": "تنفيذ الاستعادة",
|
||||
"restore_to_imap": "استعادة البريد",
|
||||
"success": "تمت استعادة الرسائل بنجاح",
|
||||
"successDesc": "تمت استعادة الرسائل المختارة إلى خادم IMAP بنجاح.",
|
||||
"failed": "فشلت استعادة الرسائل",
|
||||
"failedTitle": "فشل الاستعادة"
|
||||
"restore_to_imap": "استعادة الرسالة",
|
||||
"success": "تمت الاستعادة بنجاح",
|
||||
"successDesc": "تمت استعادة الرسائل المحددة بنجاح إلى خادم IMAP.",
|
||||
"failed": "فشلت الاستعادة",
|
||||
"failedTitle": "فشل في الاستعادة"
|
||||
},
|
||||
"time": {
|
||||
"label": "الوقت",
|
||||
|
||||
+13
-8
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Log ud"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Gendan meddelelser",
|
||||
"desc": "Denne handling vil uploade de valgte meddelelser fra Bichon og gendanne dem til deres tilsvarende postkasser på IMAP-serveren.",
|
||||
"confirm": "Gendan",
|
||||
"restore_to_imap": "Gendan e-mail",
|
||||
"success": "Meddelelser gendannet",
|
||||
"successDesc": "De valgte meddelelser er blevet gendannet til IMAP-serveren.",
|
||||
"failed": "Kunne ikke gendanne meddelelser",
|
||||
"failedTitle": "Gendannelse mislykkedes"
|
||||
"title": "Gendan enkelt besked",
|
||||
"bulkTitle": "Gendan flere beskeder",
|
||||
"bulkWarning": "Bemærk: Beskeder vil blive gendannet til deres oprindelige mapper.",
|
||||
"accountsInvolved": "Involverede konti",
|
||||
"summary": "Gendannelsesdetaljer",
|
||||
"messages": "beskeder",
|
||||
"desc": "Denne handling vil gen-uploade valgte beskeder fra Bichon og gendanne dem til deres tilsvarende postkasser på IMAP-serveren.",
|
||||
"confirm": "Udfør gendannelse",
|
||||
"restore_to_imap": "Gendan besked",
|
||||
"success": "Gendannelse gennemført",
|
||||
"successDesc": "De valgte beskeder er blevet gendannet til IMAP-serveren.",
|
||||
"failed": "Gendannelse mislykkedes",
|
||||
"failedTitle": "Fejl ved gendannelse"
|
||||
},
|
||||
"time": {
|
||||
"label": "Tid",
|
||||
|
||||
+10
-5
@@ -1453,11 +1453,16 @@
|
||||
"confirm": "Abmelden"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Nachrichten wiederherstellen",
|
||||
"desc": "Diese Aktion lädt die ausgewählten Nachrichten von Bichon hoch und stellt sie in den entsprechenden Postfächern auf dem IMAP-Server wieder her.",
|
||||
"confirm": "Wiederherstellen",
|
||||
"restore_to_imap": "E-Mail wiederherstellen",
|
||||
"success": "Nachrichten wiederhergestellt",
|
||||
"title": "Einzelne Nachricht wiederherstellen",
|
||||
"bulkTitle": "Mehrere Nachrichten wiederherstellen",
|
||||
"bulkWarning": "Hinweis: Nachrichten werden in ihren ursprünglichen Ordnern wiederhergestellt.",
|
||||
"accountsInvolved": "Beteiligte Konten",
|
||||
"summary": "Details zur Wiederherstellung",
|
||||
"messages": "Nachrichten",
|
||||
"desc": "Diese Aktion lädt die ausgewählten Nachrichten von Bichon erneut hoch und stellt sie in den entsprechenden Postfächern auf dem IMAP-Server wieder her.",
|
||||
"confirm": "Wiederherstellung ausführen",
|
||||
"restore_to_imap": "Nachricht wiederherstellen",
|
||||
"success": "Wiederherstellung erfolgreich",
|
||||
"successDesc": "Die ausgewählten Nachrichten wurden erfolgreich auf dem IMAP-Server wiederhergestellt.",
|
||||
"failed": "Wiederherstellung fehlgeschlagen",
|
||||
"failedTitle": "Fehler bei der Wiederherstellung"
|
||||
|
||||
+11
-6
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Sign out"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Restore Messages",
|
||||
"desc": "This action will append the selected messages from Bichon back to their corresponding mailboxes on the IMAP server.",
|
||||
"confirm": "Restore",
|
||||
"restore_to_imap": "Restore Mail",
|
||||
"title": "Restore Single Message",
|
||||
"bulkTitle": "Bulk Restore Messages",
|
||||
"bulkWarning": "Note: Messages will be restored to their original storage folders.",
|
||||
"accountsInvolved": "Accounts involved",
|
||||
"summary": "Restoration Details",
|
||||
"messages": "messages",
|
||||
"desc": "This action will re-upload selected messages from Bichon and restore them to their corresponding mailboxes on the IMAP server.",
|
||||
"confirm": "Restore Now",
|
||||
"restore_to_imap": "Restore Message",
|
||||
"success": "Messages Restored",
|
||||
"successDesc": "The selected messages have been successfully restored to the IMAP server.",
|
||||
"failed": "Failed to restore messages",
|
||||
"failedTitle": "Restore Failed"
|
||||
"failed": "Restore Failed",
|
||||
"failedTitle": "Failed to Restore"
|
||||
},
|
||||
"time": {
|
||||
"label": "Time",
|
||||
|
||||
+12
-7
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Cerrar sesión"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Restaurar mensajes",
|
||||
"desc": "Esta acción volverá a cargar los mensajes seleccionados de Bichon y los restaurará en sus carpetas correspondientes en el servidor IMAP.",
|
||||
"confirm": "Restaurar",
|
||||
"restore_to_imap": "Restaurar correo",
|
||||
"success": "Mensajes restaurados",
|
||||
"title": "Restaurar mensaje individual",
|
||||
"bulkTitle": "Restaurar múltiples mensajes",
|
||||
"bulkWarning": "Nota: Los mensajes se restaurarán en sus carpetas originales.",
|
||||
"accountsInvolved": "Cuentas involucradas",
|
||||
"summary": "Detalles de restauración",
|
||||
"messages": "mensajes",
|
||||
"desc": "Esta acción volverá a cargar los mensajes seleccionados desde Bichon y los restaurará en sus buzones correspondientes en el servidor IMAP.",
|
||||
"confirm": "Ejecutar restauración",
|
||||
"restore_to_imap": "Restaurar mensaje",
|
||||
"success": "Restauración exitosa",
|
||||
"successDesc": "Los mensajes seleccionados se han restaurado correctamente en el servidor IMAP.",
|
||||
"failed": "Error al restaurar los mensajes",
|
||||
"failedTitle": "Error de restauración"
|
||||
"failed": "Error al restaurar",
|
||||
"failedTitle": "Fallo en la restauración"
|
||||
},
|
||||
"time": {
|
||||
"label": "Tiempo",
|
||||
|
||||
+12
-7
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Kirjaudu ulos"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Palauta viestit",
|
||||
"desc": "Tämä toiminto lataa valitut viestit Bichonista ja palauttaa ne vastaaviin postilaatikoihin IMAP-palvelimella.",
|
||||
"confirm": "Palauta",
|
||||
"restore_to_imap": "Palauta sähköposti",
|
||||
"success": "Viestit palautettu",
|
||||
"title": "Palauta yksittäinen viesti",
|
||||
"bulkTitle": "Palauta useita viestejä",
|
||||
"bulkWarning": "Huomio: Viestit palautetaan niiden alkuperäisiin kansioihin.",
|
||||
"accountsInvolved": "Osalliset tilit",
|
||||
"summary": "Palautuksen tiedot",
|
||||
"messages": "viestiä",
|
||||
"desc": "Tämä toiminto lataa valitut viestit uudelleen Bichonista ja palauttaa ne vastaaviin postilaatikoihin IMAP-palvelimella.",
|
||||
"confirm": "Suorita palautus",
|
||||
"restore_to_imap": "Palauta viesti",
|
||||
"success": "Palautus onnistui",
|
||||
"successDesc": "Valitut viestit on palautettu onnistuneesti IMAP-palvelimelle.",
|
||||
"failed": "Viestien palautus epäonnistui",
|
||||
"failedTitle": "Palautus epäonnistui"
|
||||
"failed": "Palautus epäonnistui",
|
||||
"failedTitle": "Palautusvirhe"
|
||||
},
|
||||
"time": {
|
||||
"label": "Aika",
|
||||
|
||||
+12
-7
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Déconnexion"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Restaurer les messages",
|
||||
"desc": "Cette action téléchargera les messages sélectionnés depuis Bichon et les restaurera dans leurs boîtes aux lettres correspondantes sur le serveur IMAP.",
|
||||
"confirm": "Restaurer",
|
||||
"restore_to_imap": "Restaurer le courrier",
|
||||
"success": "Messages restaurés",
|
||||
"title": "Restaurer un message",
|
||||
"bulkTitle": "Restaurer plusieurs messages",
|
||||
"bulkWarning": "Remarque : les messages seront restaurés dans leurs dossiers d'origine.",
|
||||
"accountsInvolved": "Comptes concernés",
|
||||
"summary": "Détails de la restauration",
|
||||
"messages": "messages",
|
||||
"desc": "Cette action va re-télécharger les messages sélectionnés depuis Bichon et les restaurer dans leurs boîtes aux lettres correspondantes sur le serveur IMAP.",
|
||||
"confirm": "Exécuter la restauration",
|
||||
"restore_to_imap": "Restaurer le message",
|
||||
"success": "Restauration réussie",
|
||||
"successDesc": "Les messages sélectionnés ont été restaurés avec succès sur le serveur IMAP.",
|
||||
"failed": "Échec de la restauration des messages",
|
||||
"failedTitle": "Échec de la restauration"
|
||||
"failed": "Échec de la restauration",
|
||||
"failedTitle": "Erreur de restauration"
|
||||
},
|
||||
"time": {
|
||||
"label": "Temps",
|
||||
|
||||
+12
-7
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Disconnetti"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Ripristina messaggi",
|
||||
"desc": "Questa azione caricherà i messaggi selezionati da Bichon e li ripristinerà nelle rispettive caselle di posta sul server IMAP.",
|
||||
"confirm": "Ripristina",
|
||||
"restore_to_imap": "Ripristina posta",
|
||||
"success": "Messaggi ripristinati",
|
||||
"title": "Ripristina singolo messaggio",
|
||||
"bulkTitle": "Ripristino multiplo messaggi",
|
||||
"bulkWarning": "Nota: i messaggi verranno ripristinati nelle loro cartelle originali.",
|
||||
"accountsInvolved": "Account coinvolti",
|
||||
"summary": "Dettagli ripristino",
|
||||
"messages": "messaggi",
|
||||
"desc": "Questa azione caricherà nuovamente i messaggi selezionati da Bichon e li ripristinerà nelle rispettive caselle di posta sul server IMAP.",
|
||||
"confirm": "Esegui ripristino",
|
||||
"restore_to_imap": "Ripristina messaggio",
|
||||
"success": "Ripristino completato",
|
||||
"successDesc": "I messaggi selezionati sono stati ripristinati con successo sul server IMAP.",
|
||||
"failed": "Impossibile ripristinare i messaggi",
|
||||
"failedTitle": "Ripristino fallito"
|
||||
"failed": "Ripristino fallito",
|
||||
"failedTitle": "Errore di ripristino"
|
||||
},
|
||||
"time": {
|
||||
"label": "Tempo",
|
||||
|
||||
+11
-6
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "サインアウト"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "メッセージを復元",
|
||||
"desc": "この操作により、選択したメッセージをBichonから再アップロードし、IMAPサーバー上の対応するメールボックスに復元します。",
|
||||
"title": "単一メールの復元",
|
||||
"bulkTitle": "複数メールの一括復元",
|
||||
"bulkWarning": "注意:メールは元の保存先フォルダーに復元されます。",
|
||||
"accountsInvolved": "対象アカウント",
|
||||
"summary": "復元の詳細",
|
||||
"messages": "通のメール",
|
||||
"desc": "この操作により、選択されたメールがBichonシステムから再アップロードされ、IMAPサーバー上の対応するメールボックスに復元されます。",
|
||||
"confirm": "復元を実行",
|
||||
"restore_to_imap": "メールを復元",
|
||||
"success": "メッセージを復元しました",
|
||||
"successDesc": "選択したメッセージがIMAPサーバーに正常に復元されました。",
|
||||
"failed": "メッセージの復元に失敗しました",
|
||||
"failedTitle": "復元失敗"
|
||||
"success": "復元成功",
|
||||
"successDesc": "選択されたメールはIMAPサーバーに正常に復元されました。",
|
||||
"failed": "復元失敗",
|
||||
"failedTitle": "復元に失敗しました"
|
||||
},
|
||||
"time": {
|
||||
"label": "時間",
|
||||
|
||||
+10
-5
@@ -1453,13 +1453,18 @@
|
||||
"confirm": "로그아웃"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "메시지 복원",
|
||||
"desc": "이 작업은 선택한 메시지를 Bichon에서 다시 업로드하여 IMAP 서버의 해당 사서함으로 복원합니다.",
|
||||
"title": "개별 메시지 복원",
|
||||
"bulkTitle": "여러 메시지 일괄 복원",
|
||||
"bulkWarning": "참고: 메시지는 원래 저장된 폴더로 복원됩니다.",
|
||||
"accountsInvolved": "관련 계정",
|
||||
"summary": "복원 세부 정보",
|
||||
"messages": "개의 메시지",
|
||||
"desc": "이 작업은 선택한 메시지를 Bichon 시스템에서 다시 업로드하여 IMAP 서버의 해당 사서함으로 복원합니다.",
|
||||
"confirm": "복원 실행",
|
||||
"restore_to_imap": "메일 복원",
|
||||
"success": "메시지 복원 완료",
|
||||
"restore_to_imap": "메시지 복원",
|
||||
"success": "복원 성공",
|
||||
"successDesc": "선택한 메시지가 IMAP 서버로 성공적으로 복원되었습니다.",
|
||||
"failed": "메시지 복원 실패",
|
||||
"failed": "복원 실패",
|
||||
"failedTitle": "복원 실패"
|
||||
},
|
||||
"time": {
|
||||
|
||||
+12
-7
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Uitloggen"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Berichten herstellen",
|
||||
"desc": "Deze actie uploadt de geselecteerde berichten van Bichon en herstelt ze in de bijbehorende mailboxen op de IMAP-server.",
|
||||
"confirm": "Herstellen",
|
||||
"restore_to_imap": "E-mail herstellen",
|
||||
"success": "Berichten hersteld",
|
||||
"title": "Enkel bericht herstellen",
|
||||
"bulkTitle": "Meerdere berichten herstellen",
|
||||
"bulkWarning": "Let op: berichten worden hersteld in hun oorspronkelijke mappen.",
|
||||
"accountsInvolved": "Betrokken accounts",
|
||||
"summary": "Hersteldetails",
|
||||
"messages": "berichten",
|
||||
"desc": "Deze actie zal de geselecteerde berichten opnieuw uploaden vanuit Bichon en ze herstellen in de bijbehorende mailboxen op de IMAP-server.",
|
||||
"confirm": "Herstel uitvoeren",
|
||||
"restore_to_imap": "Bericht herstellen",
|
||||
"success": "Herstel geslaagd",
|
||||
"successDesc": "De geselecteerde berichten zijn succesvol hersteld op de IMAP-server.",
|
||||
"failed": "Herstellen van berichten mislukt",
|
||||
"failedTitle": "Herstel mislukt"
|
||||
"failed": "Herstel mislukt",
|
||||
"failedTitle": "Herstelfout"
|
||||
},
|
||||
"time": {
|
||||
"label": "Tijd",
|
||||
|
||||
+13
-8
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Logg ut"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Gjenopprett meldinger",
|
||||
"desc": "Denne handlingen vil laste opp de valgte meldingene fra Bichon og gjenopprette dem til deres tilsvarende postbokser på IMAP-serveren.",
|
||||
"confirm": "Gjenopprett",
|
||||
"restore_to_imap": "Gjenopprett e-post",
|
||||
"success": "Meldinger gjenopprettet",
|
||||
"successDesc": "De valgte meldingene har blitt gjenopprettet til IMAP-serveren.",
|
||||
"failed": "Kunne ikke gjenopprette meldinger",
|
||||
"failedTitle": "Gjenoppretting mislyktes"
|
||||
"title": "Gjenopprett enkeltmelding",
|
||||
"bulkTitle": "Gjenopprett flere meldinger",
|
||||
"bulkWarning": "Merk: Meldinger vil bli gjenopprettet til sine opprinnelige mapper.",
|
||||
"accountsInvolved": "Involverte kontoer",
|
||||
"summary": "Gjenopprettingsdetaljer",
|
||||
"messages": "meldinger",
|
||||
"desc": "Denne handlingen vil laste opp valgte meldinger fra Bichon på nytt og gjenopprette dem til de tilsvarende postkassene på IMAP-serveren.",
|
||||
"confirm": "Utfør gjenoppretting",
|
||||
"restore_to_imap": "Gjenopprett melding",
|
||||
"success": "Gjenoppretting vellykket",
|
||||
"successDesc": "De valgte meldingene er gjenopprettet til IMAP-serveren.",
|
||||
"failed": "Gjenoppretting mislykkedes",
|
||||
"failedTitle": "Feil ved gjenoppretting"
|
||||
},
|
||||
"time": {
|
||||
"label": "Tid",
|
||||
|
||||
+12
-7
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Wyloguj się"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Przywróć wiadomości",
|
||||
"desc": "Ta operacja prześle wybrane wiadomości z Bichon i przywróci je do odpowiednich skrzynek pocztowych na serwerze IMAP.",
|
||||
"confirm": "Przywróć",
|
||||
"restore_to_imap": "Przywróć pocztę",
|
||||
"success": "Wiadomości przywrócone",
|
||||
"title": "Przywróć pojedynczą wiadomość",
|
||||
"bulkTitle": "Masowe przywracanie wiadomości",
|
||||
"bulkWarning": "Uwaga: Wiadomości zostaną przywrócone do ich oryginalnych folderów.",
|
||||
"accountsInvolved": "Zaangażowane konta",
|
||||
"summary": "Szczegóły przywracania",
|
||||
"messages": "wiadomości",
|
||||
"desc": "Ta operacja spowoduje ponowne przesłanie wybranych wiadomości z systemu Bichon i przywrócenie ich do odpowiednich skrzynek pocztowych na serwerze IMAP.",
|
||||
"confirm": "Wykonaj przywracanie",
|
||||
"restore_to_imap": "Przywróć wiadomość",
|
||||
"success": "Przywracanie zakończone sukcesem",
|
||||
"successDesc": "Wybrane wiadomości zostały pomyślnie przywrócone na serwer IMAP.",
|
||||
"failed": "Nie udało się przywrócić wiadomości",
|
||||
"failedTitle": "Przywracanie nie powiodło się"
|
||||
"failed": "Przywracanie nie powiodło się",
|
||||
"failedTitle": "Błąd przywracania"
|
||||
},
|
||||
"time": {
|
||||
"label": "Czas",
|
||||
|
||||
+12
-7
@@ -1453,13 +1453,18 @@
|
||||
"confirm": "Sair"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Restaurar mensagens",
|
||||
"desc": "Esta ação irá carregar as mensagens selecionadas do Bichon e restaurá-las nas respetivas caixas de correio no servidor IMAP.",
|
||||
"confirm": "Restaurar",
|
||||
"restore_to_imap": "Restaurar e-mail",
|
||||
"success": "Mensagens restauradas",
|
||||
"successDesc": "As mensagens selecionadas foram restauradas com sucesso para o servidor IMAP.",
|
||||
"failed": "Falha ao restaurar mensagens",
|
||||
"title": "Restaurar mensagem individual",
|
||||
"bulkTitle": "Restaurar múltiplas mensagens",
|
||||
"bulkWarning": "Nota: As mensagens serão restauradas nas suas pastas originais.",
|
||||
"accountsInvolved": "Contas envolvidas",
|
||||
"summary": "Detalhes da restauração",
|
||||
"messages": "mensagens",
|
||||
"desc": "Esta ação irá recarregar as mensagens selecionadas do Bichon e restaurá-las nas pastas correspondentes no servidor IMAP.",
|
||||
"confirm": "Executar restauração",
|
||||
"restore_to_imap": "Restaurar mensagem",
|
||||
"success": "Restauração bem-sucedida",
|
||||
"successDesc": "As mensagens selecionadas foram restauradas com sucesso no servidor IMAP.",
|
||||
"failed": "Falha ao restaurar",
|
||||
"failedTitle": "Falha na restauração"
|
||||
},
|
||||
"time": {
|
||||
|
||||
+13
-8
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Выйти"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Восстановить сообщения",
|
||||
"desc": "Это действие загрузит выбранные сообщения из Bichon и восстановит их в соответствующих почтовых ящиках на IMAP-сервере.",
|
||||
"confirm": "Восстановить",
|
||||
"restore_to_imap": "Восстановить почту",
|
||||
"success": "Сообщения восстановлены",
|
||||
"successDesc": "Выбранные сообщения были успешно восстановлены на IMAP-сервере.",
|
||||
"failed": "Не удалось восстановить сообщения",
|
||||
"failedTitle": "Ошибка восстановления"
|
||||
"title": "Восстановить одно сообщение",
|
||||
"bulkTitle": "Массовое восстановление сообщений",
|
||||
"bulkWarning": "Примечание: сообщения будут восстановлены в исходные папки.",
|
||||
"accountsInvolved": "Задействованные аккаунты",
|
||||
"summary": "Детали восстановления",
|
||||
"messages": "сообщений",
|
||||
"desc": "Это действие повторно загрузит выбранные сообщения из Bichon и восстановит их в соответствующих почтовых ящиках на сервере IMAP.",
|
||||
"confirm": "Выполнить восстановление",
|
||||
"restore_to_imap": "Восстановить сообщение",
|
||||
"success": "Восстановление успешно",
|
||||
"successDesc": "Выбранные сообщения были успешно восстановлены на сервере IMAP.",
|
||||
"failed": "Ошибка восстановления",
|
||||
"failedTitle": "Восстановление не удалось"
|
||||
},
|
||||
"time": {
|
||||
"label": "Время",
|
||||
|
||||
+12
-7
@@ -1453,14 +1453,19 @@
|
||||
"confirm": "Logga ut"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "Återställ meddelanden",
|
||||
"desc": "Denna åtgärd kommer att ladda upp de valda meddelandena från Bichon och återställa dem till deras motsvarande brevlådor på IMAP-servern.",
|
||||
"confirm": "Återställ",
|
||||
"restore_to_imap": "Återställ e-post",
|
||||
"success": "Meddelanden återställda",
|
||||
"title": "Återställ enstaka meddelande",
|
||||
"bulkTitle": "Återställ flera meddelanden",
|
||||
"bulkWarning": "Obs: Meddelanden kommer att återställas till sina ursprungliga mappar.",
|
||||
"accountsInvolved": "Inblandade konton",
|
||||
"summary": "Återställningsdetaljer",
|
||||
"messages": "meddelanden",
|
||||
"desc": "Denna åtgärd kommer att ladda upp de valda meddelandena igen från Bichon och återställa dem till deras motsvarande inkorgar på IMAP-servern.",
|
||||
"confirm": "Utför återställning",
|
||||
"restore_to_imap": "Återställ meddelande",
|
||||
"success": "Återställning lyckades",
|
||||
"successDesc": "De valda meddelandena har återställts till IMAP-servern.",
|
||||
"failed": "Misslyckades med att återställa meddelanden",
|
||||
"failedTitle": "Återställning misslyckades"
|
||||
"failed": "Återställning misslyckades",
|
||||
"failedTitle": "Fel vid återställning"
|
||||
},
|
||||
"time": {
|
||||
"label": "Tid",
|
||||
|
||||
@@ -1453,12 +1453,17 @@
|
||||
"confirm": "登出"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "還原郵件",
|
||||
"desc": "此操作將把選定的郵件從 Bichon 系統重新上傳並還原到其在 IMAP 伺服器上對應的信箱中。",
|
||||
"title": "還原單個郵件",
|
||||
"bulkTitle": "批量還原多個郵件",
|
||||
"bulkWarning": "請注意:郵件將被還原至其原始存儲的資料夾中。",
|
||||
"accountsInvolved": "涉及帳戶",
|
||||
"summary": "待還原詳情",
|
||||
"messages": "封郵件",
|
||||
"desc": "此操作將把選定的郵件從 Bichon 系統重新上傳並恢復到其在 IMAP 服務器上對應的郵箱中。",
|
||||
"confirm": "執行還原",
|
||||
"restore_to_imap": "還原郵件",
|
||||
"success": "郵件還原成功",
|
||||
"successDesc": "選定的郵件已成功還原到 IMAP 伺服器。",
|
||||
"successDesc": "選定的郵件已成功恢復到 IMAP 服務器。",
|
||||
"failed": "還原郵件失敗",
|
||||
"failedTitle": "還原失敗"
|
||||
},
|
||||
|
||||
@@ -1453,7 +1453,12 @@
|
||||
"confirm": "退出登录"
|
||||
},
|
||||
"restore_message": {
|
||||
"title": "还原邮件",
|
||||
"title": "还原单个邮件",
|
||||
"bulkTitle": "批量还原多个邮件",
|
||||
"bulkWarning": "请注意:邮件将被还原至其原始存储的文件夹中。",
|
||||
"accountsInvolved": "涉及账户",
|
||||
"summary": "待还原详情",
|
||||
"messages": "封邮件",
|
||||
"desc": "此操作将把选定的邮件从 Bichon 系统重新上传并恢复到其在 IMAP 服务器上对应的邮箱中。",
|
||||
"confirm": "执行还原",
|
||||
"restore_to_imap": "还原邮件",
|
||||
|
||||
Reference in New Issue
Block a user