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.
|
||||
// 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(() => {
|
||||
if (!email.htmlBody) return '';
|
||||
const sanitized = DOMPurify.sanitize(email.htmlBody, {
|
||||
@@ -66,6 +75,9 @@ export default function EmailDetail({
|
||||
wrapper.querySelectorAll('a').forEach((a) => {
|
||||
a.setAttribute('target', '_blank');
|
||||
a.setAttribute('rel', 'noopener noreferrer');
|
||||
// Corporate-CTA-Styling raus, sonst weiß-auf-weiß nicht sichtbar.
|
||||
a.removeAttribute('style');
|
||||
a.removeAttribute('class');
|
||||
});
|
||||
return wrapper.innerHTML;
|
||||
}, [email.htmlBody]);
|
||||
@@ -197,12 +209,17 @@ export default function EmailDetail({
|
||||
const attachments = parseAttachments(email.attachmentNames);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
{/* Header */}
|
||||
<div className="p-4 border-b border-gray-200 space-y-3">
|
||||
<div className="flex flex-col h-full min-h-0">
|
||||
{/* Header – kompakter Vertical-Rhythm, damit der Body-Bereich bei
|
||||
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 */}
|
||||
<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)'}
|
||||
</h2>
|
||||
<div className="flex items-center gap-2 flex-shrink-0">
|
||||
@@ -291,8 +308,8 @@ export default function EmailDetail({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* From/To/Date */}
|
||||
<div className="text-sm space-y-1">
|
||||
{/* From/To/Date – tighter leading */}
|
||||
<div className="text-sm space-y-0.5">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-gray-500 w-12">Von:</span>
|
||||
<span className="font-medium text-gray-900">
|
||||
|
||||
Reference in New Issue
Block a user