diff --git a/packages/twenty-front/src/modules/ui/field/display/components/LinkDisplay.tsx b/packages/twenty-front/src/modules/ui/field/display/components/LinkDisplay.tsx index fb8315319..d360b62e1 100644 --- a/packages/twenty-front/src/modules/ui/field/display/components/LinkDisplay.tsx +++ b/packages/twenty-front/src/modules/ui/field/display/components/LinkDisplay.tsx @@ -7,6 +7,7 @@ import { LinkType, SocialLink, } from '@/ui/navigation/link/components/SocialLink'; +import { checkUrlType } from '~/utils/checkUrlType'; import { EllipsisDisplay } from './EllipsisDisplay'; @@ -24,21 +25,6 @@ type LinkDisplayProps = { value?: FieldLinkValue; }; -const checkUrlType = (url: string) => { - if ( - /^(http|https):\/\/(?:www\.)?linkedin.com(\w+:{0,1}\w*@)?(\S+)(:([0-9])+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/.test( - url, - ) - ) { - return LinkType.LinkedIn; - } - if (url.match(/^((http|https):\/\/)?(?:www\.)?twitter\.com\/(\w+)?/i)) { - return LinkType.Twitter; - } - - return LinkType.Url; -}; - export const LinkDisplay = ({ value }: LinkDisplayProps) => { const handleClick = (event: MouseEvent) => { event.stopPropagation(); diff --git a/packages/twenty-front/src/modules/ui/field/display/components/URLDisplay.tsx b/packages/twenty-front/src/modules/ui/field/display/components/URLDisplay.tsx index b76662c71..858a59e1c 100644 --- a/packages/twenty-front/src/modules/ui/field/display/components/URLDisplay.tsx +++ b/packages/twenty-front/src/modules/ui/field/display/components/URLDisplay.tsx @@ -6,6 +6,7 @@ import { LinkType, SocialLink, } from '@/ui/navigation/link/components/SocialLink'; +import { checkUrlType } from '~/utils/checkUrlType'; import { EllipsisDisplay } from './EllipsisDisplay'; @@ -23,21 +24,6 @@ type URLDisplayProps = { value: string | null; }; -const checkUrlType = (url: string) => { - if ( - /^(http|https):\/\/(?:www\.)?linkedin.com(\w+:{0,1}\w*@)?(\S+)(:([0-9])+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/.test( - url, - ) - ) { - return LinkType.LinkedIn; - } - if (url.match(/^((http|https):\/\/)?(?:www\.)?twitter\.com\/(\w+)?/i)) { - return LinkType.Twitter; - } - - return LinkType.Url; -}; - export const URLDisplay = ({ value }: URLDisplayProps) => { const handleClick = (event: MouseEvent) => { event.stopPropagation(); diff --git a/packages/twenty-front/src/modules/ui/navigation/link/components/SocialLink.tsx b/packages/twenty-front/src/modules/ui/navigation/link/components/SocialLink.tsx index 8233927af..fa859e72a 100644 --- a/packages/twenty-front/src/modules/ui/navigation/link/components/SocialLink.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/link/components/SocialLink.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; import styled from '@emotion/styled'; +import { getDisplayValueByUrlType } from '~/utils/getDisplayValueByUrlType'; + import { RoundedLink } from './RoundedLink'; export enum LinkType { @@ -12,7 +14,7 @@ export enum LinkType { type SocialLinkProps = { href: string; children?: React.ReactNode; - type?: LinkType; + type: LinkType; onClick?: (event: React.MouseEvent) => void; }; @@ -32,29 +34,8 @@ export const SocialLink = ({ onClick, type, }: SocialLinkProps) => { - let displayValue = children; - - if (type === 'linkedin') { - const matches = href.match( - /(?:https?:\/\/)?(?:www.)?linkedin.com\/(?:in|company)\/([-a-zA-Z0-9@:%_+.~#?&//=]*)/, - ); - if (matches && matches[1]) { - displayValue = matches[1]; - } else { - displayValue = 'LinkedIn'; - } - } - - if (type === 'twitter') { - const matches = href.match( - /(?:https?:\/\/)?(?:www.)?twitter.com\/([-a-zA-Z0-9@:%_+.~#?&//=]*)/, - ); - if (matches && matches[1]) { - displayValue = `@${matches[1]}`; - } else { - displayValue = '@twitter'; - } - } + const displayValue = + getDisplayValueByUrlType({ type: type, href: href }) ?? children; return ( diff --git a/packages/twenty-front/src/utils/__tests__/checkUrlType.test.ts b/packages/twenty-front/src/utils/__tests__/checkUrlType.test.ts new file mode 100644 index 000000000..d0ec7c33d --- /dev/null +++ b/packages/twenty-front/src/utils/__tests__/checkUrlType.test.ts @@ -0,0 +1,17 @@ +import { checkUrlType } from '~/utils/checkUrlType'; + +describe('checkUrlType', () => { + it('should return "linkedin", if linkedin url', () => { + expect(checkUrlType('https://www.linkedin.com/in/håkan-fisk')).toBe( + 'linkedin', + ); + }); + + it('should return "twitter", if twitter url', () => { + expect(checkUrlType('https://www.twitter.com/john-doe')).toBe('twitter'); + }); + + it('should return "url", if neither linkedin nor twitter url', () => { + expect(checkUrlType('https://www.example.com')).toBe('url'); + }); +}); diff --git a/packages/twenty-front/src/utils/__tests__/getDisplayValueByUrlType.test.ts b/packages/twenty-front/src/utils/__tests__/getDisplayValueByUrlType.test.ts new file mode 100644 index 000000000..58f447bec --- /dev/null +++ b/packages/twenty-front/src/utils/__tests__/getDisplayValueByUrlType.test.ts @@ -0,0 +1,40 @@ +import { LinkType } from '@/ui/navigation/link/components/SocialLink'; +import { getDisplayValueByUrlType } from '~/utils/getDisplayValueByUrlType'; + +describe('getDisplayValueByUrlType', () => { + it('should return the linkedin username from the url', () => { + expect( + getDisplayValueByUrlType({ + type: LinkType.LinkedIn, + href: 'https://www.linkedin.com/in/håkan-fisk', + }), + ).toBe('håkan-fisk'); + expect( + getDisplayValueByUrlType({ + type: LinkType.LinkedIn, + href: 'https://www.linkedin.com/in/Matías', + }), + ).toBe('Matías'); + expect( + getDisplayValueByUrlType({ + type: LinkType.LinkedIn, + href: 'https://www.linkedin.com/in/Mårten', + }), + ).toBe('Mårten'); + expect( + getDisplayValueByUrlType({ + type: LinkType.LinkedIn, + href: 'https://www.linkedin.com/in/Sörvik', + }), + ).toBe('Sörvik'); + }); + + it('should return the twitter username from the url', () => { + expect( + getDisplayValueByUrlType({ + type: LinkType.Twitter, + href: 'https://www.twitter.com/john-doe', + }), + ).toBe('@john-doe'); + }); +}); diff --git a/packages/twenty-front/src/utils/checkUrlType.ts b/packages/twenty-front/src/utils/checkUrlType.ts new file mode 100644 index 000000000..25a39d179 --- /dev/null +++ b/packages/twenty-front/src/utils/checkUrlType.ts @@ -0,0 +1,16 @@ +import { LinkType } from '@/ui/navigation/link/components/SocialLink'; + +export const checkUrlType = (url: string) => { + if ( + /^(http|https):\/\/(?:www\.)?linkedin.com(\w+:{0,1}\w*@)?(\S+)(:([0-9])+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/.test( + url, + ) + ) { + return LinkType.LinkedIn; + } + if (url.match(/^((http|https):\/\/)?(?:www\.)?twitter\.com\/(\w+)?/i)) { + return LinkType.Twitter; + } + + return LinkType.Url; +}; diff --git a/packages/twenty-front/src/utils/getDisplayValueByUrlType.ts b/packages/twenty-front/src/utils/getDisplayValueByUrlType.ts new file mode 100644 index 000000000..80183962c --- /dev/null +++ b/packages/twenty-front/src/utils/getDisplayValueByUrlType.ts @@ -0,0 +1,33 @@ +import { LinkType } from '@/ui/navigation/link/components/SocialLink'; + +type getUrlDisplayValueByUrlTypeProps = { + type: LinkType; + href: string; +}; + +export const getDisplayValueByUrlType = ({ + type, + href, +}: getUrlDisplayValueByUrlTypeProps) => { + if (type === 'linkedin') { + const matches = href.match( + /(?:https?:\/\/)?(?:www.)?linkedin.com\/(?:in|company)\/(.*)/, + ); + if (matches && matches[1]) { + return matches[1]; + } else { + return 'LinkedIn'; + } + } + + if (type === 'twitter') { + const matches = href.match( + /(?:https?:\/\/)?(?:www.)?twitter.com\/([-a-zA-Z0-9@:%_+.~#?&//=]*)/, + ); + if (matches && matches[1]) { + return `@${matches[1]}`; + } else { + return '@twitter'; + } + } +};