Facebook links: display profile instead of full url (#16414)
Like we do for LinkedIn/Twitter --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
committed by
GitHub
parent
d36d0d49d1
commit
7f50486de5
@@ -1,5 +1,6 @@
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { LinkType, RoundedLink, SocialLink } from 'twenty-ui/navigation';
|
||||
import { checkUrlType } from '~/utils/checkUrlType';
|
||||
|
||||
type LinkDisplayProps = {
|
||||
value: { url: string; label?: string | null };
|
||||
@@ -22,13 +23,13 @@ export const LinkDisplay = ({ value }: LinkDisplayProps) => {
|
||||
? value.label
|
||||
: url?.replace(/^http[s]?:\/\/(?:[w]+\.)?/gm, '').replace(/^[w]+\./gm, '');
|
||||
|
||||
const type = displayedValue.startsWith('linkedin.')
|
||||
? LinkType.LinkedIn
|
||||
: displayedValue.startsWith('twitter.')
|
||||
? LinkType.Twitter
|
||||
: LinkType.Url;
|
||||
const type = checkUrlType(absoluteUrl);
|
||||
|
||||
if (type === LinkType.LinkedIn || type === LinkType.Twitter) {
|
||||
if (
|
||||
type === LinkType.LinkedIn ||
|
||||
type === LinkType.Twitter ||
|
||||
type === LinkType.Facebook
|
||||
) {
|
||||
return <SocialLink href={absoluteUrl} type={type} label={displayedValue} />;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,9 @@ export const LinksDisplay = ({ value, onLinkClick }: LinksDisplayProps) => {
|
||||
return (
|
||||
<ExpandableList>
|
||||
{links.map(({ url, label, type }, index) =>
|
||||
type === LinkType.LinkedIn || type === LinkType.Twitter ? (
|
||||
type === LinkType.LinkedIn ||
|
||||
type === LinkType.Twitter ||
|
||||
type === LinkType.Facebook ? (
|
||||
<SocialLink
|
||||
key={index}
|
||||
href={url}
|
||||
|
||||
@@ -23,7 +23,11 @@ export const URLDisplay = ({ value }: URLDisplayProps) => {
|
||||
|
||||
const type = checkUrlType(absoluteUrl);
|
||||
|
||||
if (type === LinkType.LinkedIn || type === LinkType.Twitter) {
|
||||
if (
|
||||
type === LinkType.LinkedIn ||
|
||||
type === LinkType.Twitter ||
|
||||
type === LinkType.Facebook
|
||||
) {
|
||||
return (
|
||||
<EllipsisDisplay>
|
||||
<SocialLink
|
||||
|
||||
@@ -21,4 +21,8 @@ describe('checkUrlType', () => {
|
||||
it('should return "url", if neither linkedin nor twitter url', () => {
|
||||
expect(checkUrlType('https://www.example.com')).toBe('url');
|
||||
});
|
||||
|
||||
it('should return "facebook", if facebook url', () => {
|
||||
expect(checkUrlType('https://www.facebook.com/john-doe')).toBe('facebook');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { getDisplayValueByUrlType } from '~/utils/getDisplayValueByUrlType';
|
||||
import { LinkType } from 'twenty-ui/navigation';
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
@@ -9,6 +9,9 @@ export const checkUrlType = (url: string) => {
|
||||
if (/^(https?:\/\/)?(www\.)?x\.com\/.+$/.test(url)) {
|
||||
return LinkType.Twitter;
|
||||
}
|
||||
if (/^(https?:\/\/)?(www\.)?facebook\.com\/.+$/.test(url)) {
|
||||
return LinkType.Facebook;
|
||||
}
|
||||
|
||||
return LinkType.Url;
|
||||
};
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type LinkType } from 'twenty-ui/navigation';
|
||||
|
||||
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|school)\/(.*)/,
|
||||
);
|
||||
if (isDefined(matches?.[1])) {
|
||||
return decodeURIComponent(matches?.[1]);
|
||||
} else {
|
||||
return 'LinkedIn';
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'twitter') {
|
||||
const matches = href.match(
|
||||
/(?:https?:\/\/)?(?:www.)?twitter.com\/([-a-zA-Z0-9@:%_+.~#?&//=]*)/,
|
||||
);
|
||||
if (isDefined(matches?.[1])) {
|
||||
return `@${matches?.[1]}`;
|
||||
} else {
|
||||
return '@twitter';
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -7,6 +7,7 @@ export enum LinkType {
|
||||
Url = 'url',
|
||||
LinkedIn = 'linkedin',
|
||||
Twitter = 'twitter',
|
||||
Facebook = 'facebook',
|
||||
}
|
||||
|
||||
type SocialLinkProps = {
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
import { LinkType } from '@ui/navigation/link/components/SocialLink';
|
||||
|
||||
import { getDisplayValueByUrlType } from '../getDisplayValueByUrlType';
|
||||
|
||||
describe('getDisplayValueByUrlType', () => {
|
||||
describe('linkedin', () => {
|
||||
it('should extract username from LinkedIn profile URL', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.LinkedIn,
|
||||
href: 'https://www.linkedin.com/in/johndoe',
|
||||
});
|
||||
expect(result).toBe('johndoe');
|
||||
});
|
||||
|
||||
it('should extract company name from LinkedIn company URL', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.LinkedIn,
|
||||
href: 'https://www.linkedin.com/company/acme-corp',
|
||||
});
|
||||
expect(result).toBe('acme-corp');
|
||||
});
|
||||
|
||||
it('should extract school name from LinkedIn school URL', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.LinkedIn,
|
||||
href: 'https://www.linkedin.com/school/mit',
|
||||
});
|
||||
expect(result).toBe('mit');
|
||||
});
|
||||
|
||||
it('should handle LinkedIn URL without protocol', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.LinkedIn,
|
||||
href: 'linkedin.com/in/johndoe',
|
||||
});
|
||||
expect(result).toBe('johndoe');
|
||||
});
|
||||
|
||||
it('should handle LinkedIn URL without www', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.LinkedIn,
|
||||
href: 'https://linkedin.com/in/johndoe',
|
||||
});
|
||||
expect(result).toBe('johndoe');
|
||||
});
|
||||
|
||||
it('should decode URL-encoded characters in LinkedIn username', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.LinkedIn,
|
||||
href: 'https://www.linkedin.com/in/john%20doe',
|
||||
});
|
||||
expect(result).toBe('john doe');
|
||||
});
|
||||
|
||||
it('should return "LinkedIn" for invalid LinkedIn URLs', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.LinkedIn,
|
||||
href: 'https://www.linkedin.com/feed',
|
||||
});
|
||||
expect(result).toBe('LinkedIn');
|
||||
});
|
||||
});
|
||||
|
||||
describe('twitter', () => {
|
||||
it('should extract username from Twitter URL with @ prefix', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Twitter,
|
||||
href: 'https://www.twitter.com/johndoe',
|
||||
});
|
||||
expect(result).toBe('@johndoe');
|
||||
});
|
||||
|
||||
it('should handle Twitter URL without protocol', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Twitter,
|
||||
href: 'twitter.com/johndoe',
|
||||
});
|
||||
expect(result).toBe('@johndoe');
|
||||
});
|
||||
|
||||
it('should handle Twitter URL without www', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Twitter,
|
||||
href: 'https://twitter.com/johndoe',
|
||||
});
|
||||
expect(result).toBe('@johndoe');
|
||||
});
|
||||
|
||||
it('should return "@twitter" when no username can be extracted', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Twitter,
|
||||
href: 'https://www.twitter.com',
|
||||
});
|
||||
expect(result).toBe('@twitter');
|
||||
});
|
||||
});
|
||||
|
||||
describe('facebook', () => {
|
||||
it('should extract username from Facebook profile URL', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Facebook,
|
||||
href: 'https://www.facebook.com/johndoe',
|
||||
});
|
||||
expect(result).toBe('johndoe');
|
||||
});
|
||||
|
||||
it('should handle Facebook URL without protocol', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Facebook,
|
||||
href: 'facebook.com/johndoe',
|
||||
});
|
||||
expect(result).toBe('johndoe');
|
||||
});
|
||||
|
||||
it('should handle Facebook URL without www', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Facebook,
|
||||
href: 'https://facebook.com/johndoe',
|
||||
});
|
||||
expect(result).toBe('johndoe');
|
||||
});
|
||||
|
||||
it('should decode URL-encoded characters in Facebook username', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Facebook,
|
||||
href: 'https://www.facebook.com/john%20doe',
|
||||
});
|
||||
expect(result).toBe('john doe');
|
||||
});
|
||||
|
||||
it('should return "Facebook" for invalid Facebook URLs', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Facebook,
|
||||
href: 'https://www.facebook.com/',
|
||||
});
|
||||
expect(result).toBe('Facebook');
|
||||
});
|
||||
});
|
||||
|
||||
describe('url type', () => {
|
||||
it('should return undefined for generic url type', () => {
|
||||
const result = getDisplayValueByUrlType({
|
||||
type: LinkType.Url,
|
||||
href: 'https://example.com',
|
||||
});
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -31,4 +31,13 @@ export const getDisplayValueByUrlType = ({
|
||||
return '@twitter';
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'facebook') {
|
||||
const matches = href.match(/(?:https?:\/\/)?(?:www.)?facebook.com\/(.+)/);
|
||||
if (isDefined(matches?.[1])) {
|
||||
return decodeURIComponent(matches?.[1]);
|
||||
} else {
|
||||
return 'Facebook';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user