From 8e9890465f80f03296790d04e7258ab05d8bc876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Fournier?= Date: Wed, 5 Feb 2025 15:44:18 +0100 Subject: [PATCH] feat: decorate emails in banner view --- .../banners/internalBanners/LicenseBanner.tsx | 8 ++-- .../utils/decorateEmailsAsMarkdown.test.ts | 44 +++++++++++++++++++ .../src/utils/decorateEmailsAsMarkdown.ts | 5 +++ 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 frontend/src/utils/decorateEmailsAsMarkdown.test.ts create mode 100644 frontend/src/utils/decorateEmailsAsMarkdown.ts diff --git a/frontend/src/component/banners/internalBanners/LicenseBanner.tsx b/frontend/src/component/banners/internalBanners/LicenseBanner.tsx index ae56e53acc..3e1831c036 100644 --- a/frontend/src/component/banners/internalBanners/LicenseBanner.tsx +++ b/frontend/src/component/banners/internalBanners/LicenseBanner.tsx @@ -5,6 +5,7 @@ import { } from 'hooks/api/getters/useLicense/useLicense'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import type { BannerVariant } from 'interfaces/banner'; +import { decorateEmailsAsMarkdown } from 'utils/decorateEmailsAsMarkdown'; export const LicenseBanner = () => { const { isEnterprise } = useUiConfig(); @@ -20,9 +21,10 @@ export const LicenseBanner = () => { ) { if (!licenseInfo.isValid) { const banner = { - message: + message: decorateEmailsAsMarkdown( licenseInfo.message || - 'You have an invalid Unleash license.', + 'You have an invalid Unleash license.', + ), variant: 'error' as BannerVariant, sticky: true, }; @@ -31,7 +33,7 @@ export const LicenseBanner = () => { } else { if (!license.loading && !license.error && licenseInfo.message) { const banner = { - message: licenseInfo.message, + message: decorateEmailsAsMarkdown(licenseInfo.message), variant: mapToVariant(licenseInfo.messageType), sticky: true, }; diff --git a/frontend/src/utils/decorateEmailsAsMarkdown.test.ts b/frontend/src/utils/decorateEmailsAsMarkdown.test.ts new file mode 100644 index 0000000000..b04d3f1c16 --- /dev/null +++ b/frontend/src/utils/decorateEmailsAsMarkdown.test.ts @@ -0,0 +1,44 @@ +import { decorateEmailsAsMarkdown } from './decorateEmailsAsMarkdown'; + +describe('decorateEmailsAsMarkdown', () => { + it('decorates a plain email', () => { + const input = + 'Please contact your account representative or contact@mydomain.com. Thanks!'; + const expected = + 'Please contact your account representative or [contact@mydomain.com](contact@mydomain.com). Thanks!'; + expect(decorateEmailsAsMarkdown(input)).toBe(expected); + }); + + it('does not re-decorate an already decorated email', () => { + const input = + 'Reach us at [contact@mydomain.com](contact@mydomain.com)'; + expect(decorateEmailsAsMarkdown(input)).toBe(input); + }); + + it('handles multiple emails in a string', () => { + const input = 'Emails: first@example.com, second@example.com'; + const expected = + 'Emails: [first@example.com](first@example.com), [second@example.com](second@example.com)'; + expect(decorateEmailsAsMarkdown(input)).toBe(expected); + }); + + it('handles multiple emails in a string when some are decorated', () => { + const input = + 'Emails: [first@example.com](first@example.com), second@example.com'; + const expected = + 'Emails: [first@example.com](first@example.com), [second@example.com](second@example.com)'; + expect(decorateEmailsAsMarkdown(input)).toBe(expected); + }); + + it('ignores invalid email patterns', () => { + const input = 'Not an email: test@@example..com'; + expect(decorateEmailsAsMarkdown(input)).toBe(input); + }); + + it('decorates emails adjacent to punctuation', () => { + const input = 'Contact:contact@mydomain.com, for info.'; + const expected = + 'Contact:[contact@mydomain.com](contact@mydomain.com), for info.'; + expect(decorateEmailsAsMarkdown(input)).toBe(expected); + }); +}); diff --git a/frontend/src/utils/decorateEmailsAsMarkdown.ts b/frontend/src/utils/decorateEmailsAsMarkdown.ts new file mode 100644 index 0000000000..43d260ae09 --- /dev/null +++ b/frontend/src/utils/decorateEmailsAsMarkdown.ts @@ -0,0 +1,5 @@ +export function decorateEmailsAsMarkdown(text: string): string { + const emailRegex = + /(? `[${email}](${email})`); +}