feat: support HTML body in vacation responder
This commit is contained in:
@@ -4,9 +4,12 @@ import { useState, useEffect, useCallback } from 'react';
|
|||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { SettingsSection, SettingItem, ToggleSwitch } from './settings-section';
|
import { SettingsSection, SettingItem, ToggleSwitch } from './settings-section';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { RichTextEditor } from '@/components/email/rich-text-editor';
|
||||||
import { useVacationStore } from '@/stores/vacation-store';
|
import { useVacationStore } from '@/stores/vacation-store';
|
||||||
import { useAuthStore } from '@/stores/auth-store';
|
import { useAuthStore } from '@/stores/auth-store';
|
||||||
import { useManagedAccountStore } from '@/stores/managed-account-store';
|
import { useManagedAccountStore } from '@/stores/managed-account-store';
|
||||||
|
import { sanitizeEmailHtml } from '@/lib/email-sanitization';
|
||||||
|
import { htmlToPlainText } from '@/lib/html-to-text';
|
||||||
import { Loader2, AlertTriangle, Eye, EyeOff } from 'lucide-react';
|
import { Loader2, AlertTriangle, Eye, EyeOff } from 'lucide-react';
|
||||||
import { toast } from '@/stores/toast-store';
|
import { toast } from '@/stores/toast-store';
|
||||||
|
|
||||||
@@ -27,6 +30,7 @@ export function VacationSettings() {
|
|||||||
toDate,
|
toDate,
|
||||||
subject,
|
subject,
|
||||||
textBody,
|
textBody,
|
||||||
|
htmlBody,
|
||||||
isLoading,
|
isLoading,
|
||||||
isSaving,
|
isSaving,
|
||||||
error,
|
error,
|
||||||
@@ -40,6 +44,8 @@ export function VacationSettings() {
|
|||||||
const [localToDate, setLocalToDate] = useState(toDate || '');
|
const [localToDate, setLocalToDate] = useState(toDate || '');
|
||||||
const [localSubject, setLocalSubject] = useState(subject);
|
const [localSubject, setLocalSubject] = useState(subject);
|
||||||
const [localTextBody, setLocalTextBody] = useState(textBody);
|
const [localTextBody, setLocalTextBody] = useState(textBody);
|
||||||
|
const [htmlEnabled, setHtmlEnabled] = useState(!!htmlBody);
|
||||||
|
const [localHtmlBody, setLocalHtmlBody] = useState(htmlBody || '');
|
||||||
const [showPreview, setShowPreview] = useState(false);
|
const [showPreview, setShowPreview] = useState(false);
|
||||||
const [validationWarnings, setValidationWarnings] = useState<string[]>([]);
|
const [validationWarnings, setValidationWarnings] = useState<string[]>([]);
|
||||||
|
|
||||||
@@ -55,7 +61,9 @@ export function VacationSettings() {
|
|||||||
setLocalToDate(toDate || '');
|
setLocalToDate(toDate || '');
|
||||||
setLocalSubject(subject);
|
setLocalSubject(subject);
|
||||||
setLocalTextBody(textBody);
|
setLocalTextBody(textBody);
|
||||||
}, [isEnabled, fromDate, toDate, subject, textBody]);
|
setHtmlEnabled(!!htmlBody);
|
||||||
|
setLocalHtmlBody(htmlBody || '');
|
||||||
|
}, [isEnabled, fromDate, toDate, subject, textBody, htmlBody]);
|
||||||
|
|
||||||
const validate = useCallback(() => {
|
const validate = useCallback(() => {
|
||||||
const warnings: string[] = [];
|
const warnings: string[] = [];
|
||||||
@@ -70,13 +78,14 @@ export function VacationSettings() {
|
|||||||
warnings.push(t('warnings.start_in_past'));
|
warnings.push(t('warnings.start_in_past'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localEnabled && !localTextBody.trim()) {
|
const hasHtmlContent = htmlEnabled && !!htmlToPlainText(localHtmlBody).trim();
|
||||||
|
if (localEnabled && !localTextBody.trim() && !hasHtmlContent) {
|
||||||
warnings.push(t('warnings.empty_body'));
|
warnings.push(t('warnings.empty_body'));
|
||||||
}
|
}
|
||||||
|
|
||||||
setValidationWarnings(warnings);
|
setValidationWarnings(warnings);
|
||||||
return warnings;
|
return warnings;
|
||||||
}, [localFromDate, localToDate, localEnabled, localTextBody, t]);
|
}, [localFromDate, localToDate, localEnabled, localTextBody, htmlEnabled, localHtmlBody, t]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
validate();
|
validate();
|
||||||
@@ -87,7 +96,8 @@ export function VacationSettings() {
|
|||||||
(localFromDate || null) !== (fromDate || null) ||
|
(localFromDate || null) !== (fromDate || null) ||
|
||||||
(localToDate || null) !== (toDate || null) ||
|
(localToDate || null) !== (toDate || null) ||
|
||||||
localSubject !== subject ||
|
localSubject !== subject ||
|
||||||
localTextBody !== textBody;
|
localTextBody !== textBody ||
|
||||||
|
(htmlEnabled ? localHtmlBody : '') !== (htmlBody || '');
|
||||||
|
|
||||||
const hasBlockingError = !!(localFromDate && localToDate && new Date(localToDate) <= new Date(localFromDate));
|
const hasBlockingError = !!(localFromDate && localToDate && new Date(localToDate) <= new Date(localFromDate));
|
||||||
|
|
||||||
@@ -96,13 +106,25 @@ export function VacationSettings() {
|
|||||||
validate();
|
validate();
|
||||||
if (hasBlockingError) return;
|
if (hasBlockingError) return;
|
||||||
|
|
||||||
|
const sanitizedHtml =
|
||||||
|
htmlEnabled && htmlToPlainText(localHtmlBody).trim()
|
||||||
|
? sanitizeEmailHtml(localHtmlBody)
|
||||||
|
: null;
|
||||||
|
// Keep a plain-text part as the fallback for clients that don't render
|
||||||
|
// HTML. If the user left it blank, derive it from the HTML body.
|
||||||
|
const textBody =
|
||||||
|
localTextBody.trim() || !sanitizedHtml
|
||||||
|
? localTextBody
|
||||||
|
: htmlToPlainText(sanitizedHtml, { paragraphSpacing: true });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateVacationResponse(client, {
|
await updateVacationResponse(client, {
|
||||||
isEnabled: localEnabled,
|
isEnabled: localEnabled,
|
||||||
fromDate: localFromDate || null,
|
fromDate: localFromDate || null,
|
||||||
toDate: localToDate || null,
|
toDate: localToDate || null,
|
||||||
subject: localSubject,
|
subject: localSubject,
|
||||||
textBody: localTextBody,
|
textBody,
|
||||||
|
htmlBody: sanitizedHtml,
|
||||||
}, managedAccountId ?? undefined);
|
}, managedAccountId ?? undefined);
|
||||||
|
|
||||||
toast.success(tNotifications('vacation_saved'));
|
toast.success(tNotifications('vacation_saved'));
|
||||||
@@ -217,28 +239,66 @@ export function VacationSettings() {
|
|||||||
className="w-full px-3 py-2 text-sm rounded-md bg-muted border border-border text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors duration-150 hover:border-muted-foreground resize-y"
|
className="w-full px-3 py-2 text-sm rounded-md bg-muted border border-border text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors duration-150 hover:border-muted-foreground resize-y"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<SettingItem
|
||||||
|
label={t('message.html_label')}
|
||||||
|
description={t('message.html_description')}
|
||||||
|
>
|
||||||
|
<ToggleSwitch checked={htmlEnabled} onChange={setHtmlEnabled} />
|
||||||
|
</SettingItem>
|
||||||
|
{htmlEnabled && (
|
||||||
|
<div className="pb-3">
|
||||||
|
<div className="rounded-md border border-border overflow-hidden">
|
||||||
|
<RichTextEditor
|
||||||
|
content={localHtmlBody}
|
||||||
|
onChange={setLocalHtmlBody}
|
||||||
|
placeholder={t('message.html_placeholder')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</SettingsSection>
|
</SettingsSection>
|
||||||
|
|
||||||
{localTextBody.trim() && (
|
{(() => {
|
||||||
<SettingsSection title={t('preview.title')}>
|
const showHtmlPreview = htmlEnabled && !!htmlToPlainText(localHtmlBody).trim();
|
||||||
<button
|
if (!localTextBody.trim() && !showHtmlPreview) return null;
|
||||||
type="button"
|
return (
|
||||||
onClick={() => setShowPreview(!showPreview)}
|
<SettingsSection title={t('preview.title')}>
|
||||||
className="flex items-center gap-2 text-sm text-primary hover:underline"
|
<button
|
||||||
>
|
type="button"
|
||||||
{showPreview ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
|
onClick={() => setShowPreview(!showPreview)}
|
||||||
{showPreview ? t('preview.hide') : t('preview.show')}
|
className="flex items-center gap-2 text-sm text-primary hover:underline"
|
||||||
</button>
|
>
|
||||||
{showPreview && (
|
{showPreview ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
|
||||||
<div className="mt-3 p-4 rounded border border-border bg-background">
|
{showPreview ? t('preview.hide') : t('preview.show')}
|
||||||
{localSubject && (
|
</button>
|
||||||
<p className="font-medium text-foreground mb-2">{localSubject}</p>
|
{showPreview && (
|
||||||
)}
|
<div className="mt-3 p-4 rounded border border-border bg-background">
|
||||||
<p className="text-sm text-muted-foreground whitespace-pre-wrap">{localTextBody}</p>
|
{localSubject && (
|
||||||
</div>
|
<p className="font-medium text-foreground mb-2">{localSubject}</p>
|
||||||
)}
|
)}
|
||||||
</SettingsSection>
|
{showHtmlPreview ? (
|
||||||
)}
|
<div
|
||||||
|
className="text-sm text-foreground [&_a]:text-primary [&_a]:underline"
|
||||||
|
// Preview renders into the app's own DOM. Intercept anchor
|
||||||
|
// clicks so following a link doesn't navigate the whole app
|
||||||
|
// away (and lose the unsaved responder), opening a new tab.
|
||||||
|
onClick={(e) => {
|
||||||
|
const anchor = (e.target as HTMLElement).closest('a');
|
||||||
|
if (anchor?.href) {
|
||||||
|
e.preventDefault();
|
||||||
|
window.open(anchor.href, '_blank', 'noopener,noreferrer');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
dangerouslySetInnerHTML={{ __html: sanitizeEmailHtml(localHtmlBody) }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<p className="text-sm text-muted-foreground whitespace-pre-wrap">{localTextBody}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</SettingsSection>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
|
||||||
{validationWarnings.length > 0 && (
|
{validationWarnings.length > 0 && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|||||||
@@ -1539,7 +1539,10 @@
|
|||||||
"subject_placeholder": "خارج المكتب",
|
"subject_placeholder": "خارج المكتب",
|
||||||
"body_label": "نص الرسالة",
|
"body_label": "نص الرسالة",
|
||||||
"body_description": "محتوى الرسالة النصي العادي",
|
"body_description": "محتوى الرسالة النصي العادي",
|
||||||
"body_placeholder": "شكرًا لرسالتك. أنا حاليًا خارج المكتب وسأرد عند عودتي."
|
"body_placeholder": "شكرًا لرسالتك. أنا حاليًا خارج المكتب وسأرد عند عودتي.",
|
||||||
|
"html_label": "رسالة منسّقة (HTML)",
|
||||||
|
"html_description": "أضِف نسخة منسّقة تتضمّن روابط وتنسيقًا. سيرى المستلمون الذين لا يستطيع برنامج بريدهم عرضها النصّ العادي أعلاه.",
|
||||||
|
"html_placeholder": "اكتب ردّ غياب منسّقًا…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "معاينة",
|
"title": "معاينة",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Mimo kancelář",
|
"subject_placeholder": "Mimo kancelář",
|
||||||
"body_label": "Tělo zprávy",
|
"body_label": "Tělo zprávy",
|
||||||
"body_description": "Obsah zprávy v prostém textu",
|
"body_description": "Obsah zprávy v prostém textu",
|
||||||
"body_placeholder": "Děkuji za vaši zprávu. Momentálně jsem mimo kancelář a odpovím po svém návratu."
|
"body_placeholder": "Děkuji za vaši zprávu. Momentálně jsem mimo kancelář a odpovím po svém návratu.",
|
||||||
|
"html_label": "Formátovaná zpráva (HTML)",
|
||||||
|
"html_description": "Přidejte formátovanou verzi s odkazy a stylem. Příjemci, jejichž poštovní klient ji nedokáže zobrazit, uvidí prostý text výše.",
|
||||||
|
"html_placeholder": "Napište formátovanou odpověď o nepřítomnosti…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Náhled",
|
"title": "Náhled",
|
||||||
|
|||||||
@@ -1536,7 +1536,10 @@
|
|||||||
"subject_placeholder": "Fraværende",
|
"subject_placeholder": "Fraværende",
|
||||||
"body_label": "Beskedtekst",
|
"body_label": "Beskedtekst",
|
||||||
"body_description": "Ren tekst-beskedindhold",
|
"body_description": "Ren tekst-beskedindhold",
|
||||||
"body_placeholder": "Tak for din e-mail. Jeg er i øjeblikket fraværende og vil svare, når jeg vender tilbage."
|
"body_placeholder": "Tak for din e-mail. Jeg er i øjeblikket fraværende og vil svare, når jeg vender tilbage.",
|
||||||
|
"html_label": "Formateret besked (HTML)",
|
||||||
|
"html_description": "Tilføj en formateret version med links og styling. Modtagere, hvis mailprogram ikke kan vise den, får den almindelige tekst ovenfor.",
|
||||||
|
"html_placeholder": "Skriv et formateret fraværssvar…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Forhåndsvisning",
|
"title": "Forhåndsvisning",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Abwesenheitsnotiz",
|
"subject_placeholder": "Abwesenheitsnotiz",
|
||||||
"body_label": "Nachrichtentext",
|
"body_label": "Nachrichtentext",
|
||||||
"body_description": "Nur-Text-Nachrichteninhalt",
|
"body_description": "Nur-Text-Nachrichteninhalt",
|
||||||
"body_placeholder": "Vielen Dank für Ihre E-Mail. Ich bin derzeit nicht im Büro und werde nach meiner Rückkehr antworten."
|
"body_placeholder": "Vielen Dank für Ihre E-Mail. Ich bin derzeit nicht im Büro und werde nach meiner Rückkehr antworten.",
|
||||||
|
"html_label": "Formatierte Nachricht (HTML)",
|
||||||
|
"html_description": "Fügen Sie eine formatierte Version mit Links und Gestaltung hinzu. Empfänger, deren E-Mail-Programm sie nicht anzeigen kann, sehen den obigen Klartext.",
|
||||||
|
"html_placeholder": "Formatierte Abwesenheitsantwort schreiben…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Vorschau",
|
"title": "Vorschau",
|
||||||
|
|||||||
@@ -1547,7 +1547,10 @@
|
|||||||
"subject_placeholder": "Out of Office",
|
"subject_placeholder": "Out of Office",
|
||||||
"body_label": "Message Body",
|
"body_label": "Message Body",
|
||||||
"body_description": "Plain text message content",
|
"body_description": "Plain text message content",
|
||||||
"body_placeholder": "Thank you for your email. I am currently out of the office and will respond when I return."
|
"body_placeholder": "Thank you for your email. I am currently out of the office and will respond when I return.",
|
||||||
|
"html_label": "Formatted message (HTML)",
|
||||||
|
"html_description": "Add a rich, formatted version with links and styling. Recipients whose mail client can't display it fall back to the plain text above.",
|
||||||
|
"html_placeholder": "Write a formatted out-of-office reply…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Preview",
|
"title": "Preview",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Fuera de la oficina",
|
"subject_placeholder": "Fuera de la oficina",
|
||||||
"body_label": "Cuerpo del mensaje",
|
"body_label": "Cuerpo del mensaje",
|
||||||
"body_description": "Contenido del mensaje en texto plano",
|
"body_description": "Contenido del mensaje en texto plano",
|
||||||
"body_placeholder": "Gracias por su correo. Actualmente estoy fuera de la oficina y responderé cuando regrese."
|
"body_placeholder": "Gracias por su correo. Actualmente estoy fuera de la oficina y responderé cuando regrese.",
|
||||||
|
"html_label": "Mensaje con formato (HTML)",
|
||||||
|
"html_description": "Añade una versión con formato, enlaces y estilo. Los destinatarios cuyo cliente de correo no pueda mostrarla verán el texto sin formato de arriba.",
|
||||||
|
"html_placeholder": "Escribe una respuesta de ausencia con formato…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Vista previa",
|
"title": "Vista previa",
|
||||||
|
|||||||
@@ -1540,7 +1540,10 @@
|
|||||||
"subject_placeholder": "خارج از دفتر",
|
"subject_placeholder": "خارج از دفتر",
|
||||||
"body_label": "بدنه پیام",
|
"body_label": "بدنه پیام",
|
||||||
"body_description": "محتوای پیام متنی ساده",
|
"body_description": "محتوای پیام متنی ساده",
|
||||||
"body_placeholder": "از ایمیل شما متشکرم. من در حال حاضر خارج از دفتر هستم و پس از بازگشت پاسخ خواهم داد."
|
"body_placeholder": "از ایمیل شما متشکرم. من در حال حاضر خارج از دفتر هستم و پس از بازگشت پاسخ خواهم داد.",
|
||||||
|
"html_label": "پیام قالببندیشده (HTML)",
|
||||||
|
"html_description": "یک نسخهٔ قالببندیشده با پیوند و استایل اضافه کنید. گیرندگانی که برنامهٔ ایمیلشان نمیتواند آن را نمایش دهد، متن سادهٔ بالا را میبینند.",
|
||||||
|
"html_placeholder": "یک پاسخ خودکار قالببندیشده بنویسید…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "پیشنمایش",
|
"title": "پیشنمایش",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Absence du bureau",
|
"subject_placeholder": "Absence du bureau",
|
||||||
"body_label": "Corps du message",
|
"body_label": "Corps du message",
|
||||||
"body_description": "Contenu du message en texte brut",
|
"body_description": "Contenu du message en texte brut",
|
||||||
"body_placeholder": "Merci pour votre email. Je suis actuellement absent du bureau et vous répondrai à mon retour."
|
"body_placeholder": "Merci pour votre email. Je suis actuellement absent du bureau et vous répondrai à mon retour.",
|
||||||
|
"html_label": "Message mis en forme (HTML)",
|
||||||
|
"html_description": "Ajoutez une version mise en forme avec des liens et du style. Les destinataires dont la messagerie ne peut pas l'afficher verront le texte brut ci-dessus.",
|
||||||
|
"html_placeholder": "Rédigez une réponse d'absence mise en forme…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Aperçu",
|
"title": "Aperçu",
|
||||||
|
|||||||
@@ -1503,7 +1503,10 @@
|
|||||||
"subject_placeholder": "מחוץ למשרד",
|
"subject_placeholder": "מחוץ למשרד",
|
||||||
"body_label": "גוף ההודעה",
|
"body_label": "גוף ההודעה",
|
||||||
"body_description": "תוכן הודעת טקסט רגילה",
|
"body_description": "תוכן הודעת טקסט רגילה",
|
||||||
"body_placeholder": "תודה על המייל שלך. אני כרגע מחוץ למשרד ואענה כשאחזור."
|
"body_placeholder": "תודה על המייל שלך. אני כרגע מחוץ למשרד ואענה כשאחזור.",
|
||||||
|
"html_label": "הודעה מעוצבת (HTML)",
|
||||||
|
"html_description": "הוסיפו גרסה מעוצבת עם קישורים וסגנון. נמענים שתוכנת הדוא״ל שלהם אינה יכולה להציג אותה יראו את הטקסט הרגיל שלמעלה.",
|
||||||
|
"html_placeholder": "כתבו תשובת היעדרות מעוצבת…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "תצוגה מקדימה",
|
"title": "תצוגה מקדימה",
|
||||||
|
|||||||
@@ -1536,7 +1536,10 @@
|
|||||||
"subject_placeholder": "Távol vagyok",
|
"subject_placeholder": "Távol vagyok",
|
||||||
"body_label": "Üzenet szövege",
|
"body_label": "Üzenet szövege",
|
||||||
"body_description": "Egyszerű szöveges üzenet tartalma",
|
"body_description": "Egyszerű szöveges üzenet tartalma",
|
||||||
"body_placeholder": "Köszönöm az e-mailed. Jelenleg távol vagyok az irodától, és visszatérésemkor válaszolok."
|
"body_placeholder": "Köszönöm az e-mailed. Jelenleg távol vagyok az irodától, és visszatérésemkor válaszolok.",
|
||||||
|
"html_label": "Formázott üzenet (HTML)",
|
||||||
|
"html_description": "Adjon hozzá egy formázott változatot hivatkozásokkal és stílussal. Azok a címzettek, akiknek a levelezőprogramja nem tudja megjeleníteni, a fenti egyszerű szöveget látják.",
|
||||||
|
"html_placeholder": "Írjon formázott távolléti választ…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Előnézet",
|
"title": "Előnézet",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Fuori ufficio",
|
"subject_placeholder": "Fuori ufficio",
|
||||||
"body_label": "Corpo del messaggio",
|
"body_label": "Corpo del messaggio",
|
||||||
"body_description": "Contenuto del messaggio in testo semplice",
|
"body_description": "Contenuto del messaggio in testo semplice",
|
||||||
"body_placeholder": "Grazie per la tua email. Sono attualmente fuori ufficio e risponderò al mio ritorno."
|
"body_placeholder": "Grazie per la tua email. Sono attualmente fuori ufficio e risponderò al mio ritorno.",
|
||||||
|
"html_label": "Messaggio formattato (HTML)",
|
||||||
|
"html_description": "Aggiungi una versione formattata con link e stile. I destinatari il cui client di posta non può visualizzarla vedranno il testo semplice qui sopra.",
|
||||||
|
"html_placeholder": "Scrivi una risposta di assenza formattata…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Anteprima",
|
"title": "Anteprima",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "不在通知",
|
"subject_placeholder": "不在通知",
|
||||||
"body_label": "メッセージ本文",
|
"body_label": "メッセージ本文",
|
||||||
"body_description": "テキスト形式のメッセージ内容",
|
"body_description": "テキスト形式のメッセージ内容",
|
||||||
"body_placeholder": "メールをいただきありがとうございます。現在不在にしており、戻り次第ご返信いたします。"
|
"body_placeholder": "メールをいただきありがとうございます。現在不在にしており、戻り次第ご返信いたします。",
|
||||||
|
"html_label": "書式付きメッセージ(HTML)",
|
||||||
|
"html_description": "リンクやスタイルを含む書式付きの版を追加します。表示できないメールソフトの受信者には上記のプレーンテキストが表示されます。",
|
||||||
|
"html_placeholder": "書式付きの不在返信を入力…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "プレビュー",
|
"title": "プレビュー",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "부재중 알림",
|
"subject_placeholder": "부재중 알림",
|
||||||
"body_label": "메시지 본문",
|
"body_label": "메시지 본문",
|
||||||
"body_description": "일반 텍스트로 보낼 메시지 내용이에요",
|
"body_description": "일반 텍스트로 보낼 메시지 내용이에요",
|
||||||
"body_placeholder": "메일을 보내주셔서 감사합니다. 현재 자리를 비우고 있어 돌아오는 대로 답변드리겠습니다."
|
"body_placeholder": "메일을 보내주셔서 감사합니다. 현재 자리를 비우고 있어 돌아오는 대로 답변드리겠습니다.",
|
||||||
|
"html_label": "서식 있는 메시지 (HTML)",
|
||||||
|
"html_description": "링크와 스타일이 포함된 서식 있는 버전을 추가합니다. 메일 클라이언트가 이를 표시할 수 없는 수신자에게는 위의 일반 텍스트가 표시됩니다.",
|
||||||
|
"html_placeholder": "서식 있는 부재중 자동 회신 작성…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "미리보기",
|
"title": "미리보기",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Atvaļinājumā / Esmu prom",
|
"subject_placeholder": "Atvaļinājumā / Esmu prom",
|
||||||
"body_label": "Ziņojuma teksts",
|
"body_label": "Ziņojuma teksts",
|
||||||
"body_description": "Ziņojuma saturs parastā tekstā",
|
"body_description": "Ziņojuma saturs parastā tekstā",
|
||||||
"body_placeholder": "Paldies par e-pastu. Pašlaik esmu prombūtnē un atbildēšu, kad atgriezīšos."
|
"body_placeholder": "Paldies par e-pastu. Pašlaik esmu prombūtnē un atbildēšu, kad atgriezīšos.",
|
||||||
|
"html_label": "Formatēts ziņojums (HTML)",
|
||||||
|
"html_description": "Pievienojiet formatētu versiju ar saitēm un noformējumu. Saņēmēji, kuru e-pasta programma to nevar parādīt, redzēs iepriekš redzamo vienkāršo tekstu.",
|
||||||
|
"html_placeholder": "Rakstiet formatētu prombūtnes atbildi…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Priekšskatījums",
|
"title": "Priekšskatījums",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Afwezigheidsbericht",
|
"subject_placeholder": "Afwezigheidsbericht",
|
||||||
"body_label": "Berichttekst",
|
"body_label": "Berichttekst",
|
||||||
"body_description": "Inhoud van het bericht in platte tekst",
|
"body_description": "Inhoud van het bericht in platte tekst",
|
||||||
"body_placeholder": "Bedankt voor je e-mail. Ik ben momenteel niet aanwezig en zal reageren bij terugkomst."
|
"body_placeholder": "Bedankt voor je e-mail. Ik ben momenteel niet aanwezig en zal reageren bij terugkomst.",
|
||||||
|
"html_label": "Opgemaakt bericht (HTML)",
|
||||||
|
"html_description": "Voeg een opgemaakte versie met links en stijl toe. Ontvangers van wie het e-mailprogramma deze niet kan weergeven, zien de platte tekst hierboven.",
|
||||||
|
"html_placeholder": "Schrijf een opgemaakt afwezigheidsantwoord…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Voorbeeld",
|
"title": "Voorbeeld",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Poza biurem",
|
"subject_placeholder": "Poza biurem",
|
||||||
"body_label": "Treść wiadomości",
|
"body_label": "Treść wiadomości",
|
||||||
"body_description": "Treść wiadomości w zwykłym tekście",
|
"body_description": "Treść wiadomości w zwykłym tekście",
|
||||||
"body_placeholder": "Dziękuję za wiadomość. Obecnie jestem poza biurem i odpowiem po powrocie."
|
"body_placeholder": "Dziękuję za wiadomość. Obecnie jestem poza biurem i odpowiem po powrocie.",
|
||||||
|
"html_label": "Wiadomość sformatowana (HTML)",
|
||||||
|
"html_description": "Dodaj sformatowaną wersję z odnośnikami i stylami. Odbiorcy, których program pocztowy nie może jej wyświetlić, zobaczą powyższy zwykły tekst.",
|
||||||
|
"html_placeholder": "Napisz sformatowaną odpowiedź o nieobecności…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Podgląd",
|
"title": "Podgląd",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Fora do escritório",
|
"subject_placeholder": "Fora do escritório",
|
||||||
"body_label": "Corpo da mensagem",
|
"body_label": "Corpo da mensagem",
|
||||||
"body_description": "Conteúdo da mensagem em texto simples",
|
"body_description": "Conteúdo da mensagem em texto simples",
|
||||||
"body_placeholder": "Obrigado pelo seu e-mail. Estou atualmente fora do escritório e responderei quando retornar."
|
"body_placeholder": "Obrigado pelo seu e-mail. Estou atualmente fora do escritório e responderei quando retornar.",
|
||||||
|
"html_label": "Mensagem formatada (HTML)",
|
||||||
|
"html_description": "Adicione uma versão formatada, com links e estilo. Os destinatários cujo cliente de e-mail não a exibir verão o texto simples acima.",
|
||||||
|
"html_placeholder": "Escreva uma resposta de ausência formatada…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Pré-visualização",
|
"title": "Pré-visualização",
|
||||||
|
|||||||
@@ -1540,7 +1540,10 @@
|
|||||||
"subject_placeholder": "Absent de la birou",
|
"subject_placeholder": "Absent de la birou",
|
||||||
"body_label": "Corpul mesajului",
|
"body_label": "Corpul mesajului",
|
||||||
"body_description": "Conținutul mesajelor în text simplu",
|
"body_description": "Conținutul mesajelor în text simplu",
|
||||||
"body_placeholder": "Vă mulțumesc pentru e-mail. În prezent nu mă aflu la birou și vă voi răspunde la întoarcere."
|
"body_placeholder": "Vă mulțumesc pentru e-mail. În prezent nu mă aflu la birou și vă voi răspunde la întoarcere.",
|
||||||
|
"html_label": "Mesaj formatat (HTML)",
|
||||||
|
"html_description": "Adăugați o versiune formatată, cu linkuri și stil. Destinatarii al căror client de e-mail nu o poate afișa vor vedea textul simplu de mai sus.",
|
||||||
|
"html_placeholder": "Scrieți un răspuns de absență formatat…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Previzualizare",
|
"title": "Previzualizare",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Вне офиса",
|
"subject_placeholder": "Вне офиса",
|
||||||
"body_label": "Текст сообщения",
|
"body_label": "Текст сообщения",
|
||||||
"body_description": "Содержимое сообщения в виде обычного текста",
|
"body_description": "Содержимое сообщения в виде обычного текста",
|
||||||
"body_placeholder": "Спасибо за ваше письмо. Я сейчас вне офиса и отвечу, когда вернусь."
|
"body_placeholder": "Спасибо за ваше письмо. Я сейчас вне офиса и отвечу, когда вернусь.",
|
||||||
|
"html_label": "Форматированное сообщение (HTML)",
|
||||||
|
"html_description": "Добавьте форматированную версию со ссылками и оформлением. Получатели, чей почтовый клиент не может её отобразить, увидят обычный текст выше.",
|
||||||
|
"html_placeholder": "Напишите форматированный ответ об отсутствии…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Предпросмотр",
|
"title": "Предпросмотр",
|
||||||
|
|||||||
@@ -1538,7 +1538,10 @@
|
|||||||
"subject_placeholder": "Mimo kancelárie",
|
"subject_placeholder": "Mimo kancelárie",
|
||||||
"body_label": "Telo správy",
|
"body_label": "Telo správy",
|
||||||
"body_description": "Obsah správy v prostom texte",
|
"body_description": "Obsah správy v prostom texte",
|
||||||
"body_placeholder": "Ďakujem za vašu správu. Momentálne som mimo kancelárie a odpoviem po svojom návrate."
|
"body_placeholder": "Ďakujem za vašu správu. Momentálne som mimo kancelárie a odpoviem po svojom návrate.",
|
||||||
|
"html_label": "Formátovaná správa (HTML)",
|
||||||
|
"html_description": "Pridajte formátovanú verziu s odkazmi a štýlom. Príjemcovia, ktorých poštový klient ju nedokáže zobraziť, uvidia obyčajný text vyššie.",
|
||||||
|
"html_placeholder": "Napíšte formátovanú odpoveď o neprítomnosti…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Náhľad",
|
"title": "Náhľad",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Ofis Dışındayım",
|
"subject_placeholder": "Ofis Dışındayım",
|
||||||
"body_label": "İleti Gövdesi",
|
"body_label": "İleti Gövdesi",
|
||||||
"body_description": "Düz metin ileti içeriği",
|
"body_description": "Düz metin ileti içeriği",
|
||||||
"body_placeholder": "E-postanız için teşekkür ederim. Şu anda ofis dışındayım ve döndüğümde yanıt vereceğim."
|
"body_placeholder": "E-postanız için teşekkür ederim. Şu anda ofis dışındayım ve döndüğümde yanıt vereceğim.",
|
||||||
|
"html_label": "Biçimlendirilmiş mesaj (HTML)",
|
||||||
|
"html_description": "Bağlantılar ve stil içeren biçimlendirilmiş bir sürüm ekleyin. E-posta istemcisi bunu görüntüleyemeyen alıcılar yukarıdaki düz metni görür.",
|
||||||
|
"html_placeholder": "Biçimlendirilmiş bir ofis dışı yanıtı yazın…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Önizleme",
|
"title": "Önizleme",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "Поза офісом",
|
"subject_placeholder": "Поза офісом",
|
||||||
"body_label": "Тіло повідомлення",
|
"body_label": "Тіло повідомлення",
|
||||||
"body_description": "Вміст звичайного текстового повідомлення",
|
"body_description": "Вміст звичайного текстового повідомлення",
|
||||||
"body_placeholder": "Дякуємо за ваш електронний лист. Мене зараз немає в офісі, я відповім, коли повернуся."
|
"body_placeholder": "Дякуємо за ваш електронний лист. Мене зараз немає в офісі, я відповім, коли повернуся.",
|
||||||
|
"html_label": "Форматоване повідомлення (HTML)",
|
||||||
|
"html_description": "Додайте форматовану версію з посиланнями та оформленням. Одержувачі, чий поштовий клієнт не може її показати, побачать звичайний текст вище.",
|
||||||
|
"html_placeholder": "Напишіть форматовану відповідь про відсутність…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Попередній перегляд",
|
"title": "Попередній перегляд",
|
||||||
|
|||||||
@@ -1533,7 +1533,10 @@
|
|||||||
"subject_placeholder": "外出办公",
|
"subject_placeholder": "外出办公",
|
||||||
"body_label": "邮件正文",
|
"body_label": "邮件正文",
|
||||||
"body_description": "纯文本邮件内容",
|
"body_description": "纯文本邮件内容",
|
||||||
"body_placeholder": "感谢您的来信。我目前不在办公室,返回后会尽快回复您的邮件。"
|
"body_placeholder": "感谢您的来信。我目前不在办公室,返回后会尽快回复您的邮件。",
|
||||||
|
"html_label": "带格式的消息(HTML)",
|
||||||
|
"html_description": "添加带链接和样式的格式化版本。邮件客户端无法显示时,收件人将看到上面的纯文本。",
|
||||||
|
"html_placeholder": "撰写带格式的外出自动回复…"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "预览",
|
"title": "预览",
|
||||||
|
|||||||
Reference in New Issue
Block a user