fix(projects): wrap long URLs in email preview (no horizontal scroll)

A long unbreakable token (e.g. the gallery link) overflowed the email
container and forced the admin to side-scroll. The preview HTML prep now
also injects overflow-wrap:break-word so long words/URLs wrap within the
container. break-word only triggers on overflow, so table layout is
unaffected. (Renamed neutralizeLinks → preparePreviewHtml.)
This commit is contained in:
Luca
2026-06-07 00:21:26 +02:00
parent f71243e388
commit 0cc52f3693
@@ -83,14 +83,16 @@ const KIND_ICON: Record<FeedKind, React.ComponentType<{ className?: string }>> =
hours: Clock, hours: Clock,
}; };
/** Neutralise links for a read-only preview: force every anchor to target a /** Prepare the rendered email for a read-only preview:
* new tab so the sandboxed iframe (no allow-popups) blocks the navigation * - `<base target="_blank">` so the sandboxed iframe (no allow-popups) blocks
* entirely. Without this, clicking "Accept"/"Decline" in the preview would * every link, preventing accidental clicks on the live Accept/Decline URLs.
* hit the live action URLs and actually change the quote's state. */ * - `overflow-wrap:break-word` so a long unbreakable token (e.g. the gallery
function neutralizeLinks(html: string): string { * link) wraps inside the container instead of forcing horizontal scroll.
const base = '<base target="_blank">'; * break-word only kicks in on overflow, so it won't disturb table layout. */
if (/<head[^>]*>/i.test(html)) return html.replace(/<head[^>]*>/i, (m) => m + base); function preparePreviewHtml(html: string): string {
return base + html; const inject = '<base target="_blank"><style>*{overflow-wrap:break-word}</style>';
if (/<head[^>]*>/i.test(html)) return html.replace(/<head[^>]*>/i, (m) => m + inject);
return inject + html;
} }
function minutesToHours(min: number): string { function minutesToHours(min: number): string {
@@ -463,7 +465,7 @@ export const ProjectCockpitPage: React.FC = () => {
clicking inside the preview. Scrolling still works. */} clicking inside the preview. Scrolling still works. */}
<iframe <iframe
title="email-preview" title="email-preview"
srcDoc={neutralizeLinks(preview.html)} srcDoc={preparePreviewHtml(preview.html)}
sandbox="" sandbox=""
style={{ colorScheme: 'normal' }} style={{ colorScheme: 'normal' }}
className="w-full h-[60vh] border border-neutral-200 dark:border-neutral-700 rounded" className="w-full h-[60vh] border border-neutral-200 dark:border-neutral-700 rounded"