fix: preserve newlines and links in calendar event descriptions (#25868)

The event type description is stored as HTML from the rich text editor.
When converting to plain text for calendar events, the HTML tags were
being stripped without preserving the formatting, causing:
- Newlines to be lost (text runs together)
- Links to be broken

This fix:
- Converts <br>, </p>, </div>, </li>, </h1-6> tags to newlines
- Preserves links in readable format: 'text (url)' or just 'url'
- Normalizes multiple newlines to max 2 for cleaner output

Affects all calendar integrations (Google, Outlook, etc.)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Anik Dhabal Babu
2025-12-17 15:02:12 +00:00
committed by GitHub
co-authored by Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent 0986864835
commit 27775e5d03
+30 -1
View File
@@ -112,11 +112,40 @@ export const getAppsStatus = (calEvent: Pick<CalendarEvent, "appsStatus">, t: TF
`;
};
/**
* Converts HTML to plain text while preserving line breaks and links.
* Used for calendar event descriptions that are stored as HTML from the rich text editor.
*/
const htmlToPlainText = (html: string): string => {
return (
html
// Convert links to markdown-style format: [text](url)
.replace(/<a\s+(?:[^>]*?\s+)?href="([^"]*)"[^>]*>([^<]*)<\/a>/gi, (_, url, text) => {
// If link text is the same as URL, just show the URL
if (text === url || !text.trim()) {
return url;
}
return `${text} (${url})`;
})
// Convert block-level elements to newlines
.replace(/<br\s*\/?>/gi, "\n")
.replace(/<\/p>/gi, "\n")
.replace(/<\/div>/gi, "\n")
.replace(/<\/li>/gi, "\n")
.replace(/<\/h[1-6]>/gi, "\n")
// Strip remaining HTML tags
.replace(/<\/?[^>]+(>|$)/g, "")
// Normalize multiple newlines to max 2
.replace(/\n{3,}/g, "\n\n")
.trim()
);
};
export const getDescription = (calEvent: Pick<CalendarEvent, "description">, t: TFunction) => {
if (!calEvent.description) {
return "";
}
const plainText = calEvent.description.replace(/<\/?[^>]+(>|$)/g, "").replace(/_/g, " ");
const plainText = htmlToPlainText(calEvent.description);
return `${t("description")}\n${plainText}`;
};