E-Mail-Detail: Links sichtbar + Header kompakter
Bug 1 (Header gestaucht): kompakteres Vertical-Spacing im Header (px-4 pt-3 pb-2 statt p-4, space-y-2 statt -3), Subject auf max 2 Zeilen begrenzt mit vollem Titel im tooltip. min-h-0 auf der Flex-Container, damit der Body tatsächlich flex-1 claimt. Bug 2 (Link unsichtbar): Corporate-CTAs stylen ihre Buttons gerne mit inline style="color:white;background:green"; der zugehörige <style>-Block wird von DOMPurify entfernt, das inline-style am <a> überlebt aber – Ergebnis: weißer Link auf weißem CRM-Hintergrund, unsichtbar. Fix: von <a>-Tags werden style und class gestrippt, dann greift Browser- Default (blau/violett + unterstrichen) wieder. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -54,6 +54,15 @@ export default function EmailDetail({
|
|||||||
|
|
||||||
// Email-Body sanitizen + alle <a>-Links auf neuen Tab umstellen.
|
// Email-Body sanitizen + alle <a>-Links auf neuen Tab umstellen.
|
||||||
// rel="noopener noreferrer" verhindert window.opener-Tab-Hijacking.
|
// rel="noopener noreferrer" verhindert window.opener-Tab-Hijacking.
|
||||||
|
//
|
||||||
|
// 2026-07-17: Zusätzlich werden von <a>-Tags inline `style` und `class`
|
||||||
|
// gestrippt. Grund: Corporate-Emails (Grünwelt/Vodafone/Klarmobil …)
|
||||||
|
// stylen ihre CTA-Buttons oft mit `style="color:white;background:green"`.
|
||||||
|
// Der zugehörige `<style>`-Block wird von DOMPurify entfernt (=> FORBID_TAGS),
|
||||||
|
// aber inline-styles am `<a>` selbst überleben – Ergebnis: weißer Link
|
||||||
|
// auf weißem CRM-Hintergrund, unsichtbar (User-Bug 2026-07-17). Wir
|
||||||
|
// fahren die Links auf Browser-Default runter, dann rendert der Link
|
||||||
|
// wieder als blau/violett + unterstrichen.
|
||||||
const safeHtmlBody = useMemo(() => {
|
const safeHtmlBody = useMemo(() => {
|
||||||
if (!email.htmlBody) return '';
|
if (!email.htmlBody) return '';
|
||||||
const sanitized = DOMPurify.sanitize(email.htmlBody, {
|
const sanitized = DOMPurify.sanitize(email.htmlBody, {
|
||||||
@@ -66,6 +75,9 @@ export default function EmailDetail({
|
|||||||
wrapper.querySelectorAll('a').forEach((a) => {
|
wrapper.querySelectorAll('a').forEach((a) => {
|
||||||
a.setAttribute('target', '_blank');
|
a.setAttribute('target', '_blank');
|
||||||
a.setAttribute('rel', 'noopener noreferrer');
|
a.setAttribute('rel', 'noopener noreferrer');
|
||||||
|
// Corporate-CTA-Styling raus, sonst weiß-auf-weiß nicht sichtbar.
|
||||||
|
a.removeAttribute('style');
|
||||||
|
a.removeAttribute('class');
|
||||||
});
|
});
|
||||||
return wrapper.innerHTML;
|
return wrapper.innerHTML;
|
||||||
}, [email.htmlBody]);
|
}, [email.htmlBody]);
|
||||||
@@ -197,12 +209,17 @@ export default function EmailDetail({
|
|||||||
const attachments = parseAttachments(email.attachmentNames);
|
const attachments = parseAttachments(email.attachmentNames);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full min-h-0">
|
||||||
{/* Header */}
|
{/* Header – kompakter Vertical-Rhythm, damit der Body-Bereich bei
|
||||||
<div className="p-4 border-b border-gray-200 space-y-3">
|
langen Betreffen nicht auf 100px zusammengestaucht wird. Subject
|
||||||
|
wird auf max 2 Zeilen begrenzt (mit vollem Titel im tooltip). */}
|
||||||
|
<div className="px-4 pt-3 pb-2 border-b border-gray-200 space-y-2 flex-shrink-0">
|
||||||
{/* Subject & Actions */}
|
{/* Subject & Actions */}
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="flex items-start justify-between gap-4">
|
||||||
<h2 className="text-lg font-semibold text-gray-900">
|
<h2
|
||||||
|
className="text-lg font-semibold text-gray-900 line-clamp-2 leading-snug"
|
||||||
|
title={email.subject || undefined}
|
||||||
|
>
|
||||||
{email.subject || '(Kein Betreff)'}
|
{email.subject || '(Kein Betreff)'}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="flex items-center gap-2 flex-shrink-0">
|
<div className="flex items-center gap-2 flex-shrink-0">
|
||||||
@@ -291,8 +308,8 @@ export default function EmailDetail({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* From/To/Date */}
|
{/* From/To/Date – tighter leading */}
|
||||||
<div className="text-sm space-y-1">
|
<div className="text-sm space-y-0.5">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-gray-500 w-12">Von:</span>
|
<span className="text-gray-500 w-12">Von:</span>
|
||||||
<span className="font-medium text-gray-900">
|
<span className="font-medium text-gray-900">
|
||||||
|
|||||||
Reference in New Issue
Block a user