feat: add links to Links field (#5223)

Closes #5115, Closes #5116

<img width="242" alt="image"
src="https://github.com/twentyhq/twenty/assets/3098428/ab78495a-4216-4243-8de3-53720818a09b">

---------

Co-authored-by: Jérémy Magrin <jeremy.magrin@gmail.com>
This commit is contained in:
Thaïs
2024-05-07 15:05:18 +02:00
committed by GitHub
parent 8074aae449
commit b0d1cc9dcb
12 changed files with 306 additions and 146 deletions

View File

@ -8,15 +8,14 @@ import {
SocialLink,
} from '@/ui/navigation/link/components/SocialLink';
import { checkUrlType } from '~/utils/checkUrlType';
import { getAbsoluteUrl } from '~/utils/url/getAbsoluteUrl';
import { getUrlHostName } from '~/utils/url/getUrlHostName';
import { EllipsisDisplay } from './EllipsisDisplay';
const StyledRawLink = styled(RoundedLink)`
overflow: hidden;
a {
overflow: hidden;
text-overflow: ellipsis;
font-size: ${({ theme }) => theme.font.size.md};
white-space: nowrap;
}
`;
@ -30,14 +29,8 @@ export const LinkDisplay = ({ value }: LinkDisplayProps) => {
event.stopPropagation();
};
const absoluteUrl = value?.url
? value.url.startsWith('http')
? value.url
: 'https://' + value.url
: '';
const displayedValue = value?.label || value?.url || '';
const absoluteUrl = getAbsoluteUrl(value?.url || '');
const displayedValue = value?.label || getUrlHostName(absoluteUrl);
const type = checkUrlType(absoluteUrl);
if (type === LinkType.LinkedIn || type === LinkType.Twitter) {

View File

@ -1,14 +1,66 @@
import { MouseEventHandler, useMemo } from 'react';
import styled from '@emotion/styled';
import { FieldLinksValue } from '@/object-record/record-field/types/FieldMetadata';
import { LinkDisplay } from '@/ui/field/display/components/LinkDisplay';
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
import { RoundedLink } from '@/ui/navigation/link/components/RoundedLink';
import {
LinkType,
SocialLink,
} from '@/ui/navigation/link/components/SocialLink';
import { checkUrlType } from '~/utils/checkUrlType';
import { isDefined } from '~/utils/isDefined';
import { getAbsoluteUrl } from '~/utils/url/getAbsoluteUrl';
import { getUrlHostName } from '~/utils/url/getUrlHostName';
const StyledContainer = styled(EllipsisDisplay)`
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
`;
type LinksDisplayProps = {
value?: FieldLinksValue;
};
export const LinksDisplay = ({ value }: LinksDisplayProps) => {
const url = value?.primaryLinkUrl || '';
const label = value?.primaryLinkLabel || getUrlHostName(url);
const links = useMemo(
() =>
[
value?.primaryLinkUrl
? {
url: value.primaryLinkUrl,
label: value.primaryLinkLabel,
}
: null,
...(value?.secondaryLinks ?? []),
]
.filter(isDefined)
.map(({ url, label }) => {
const absoluteUrl = getAbsoluteUrl(url);
return {
url: absoluteUrl,
label: label || getUrlHostName(absoluteUrl),
type: checkUrlType(absoluteUrl),
};
}),
[value?.primaryLinkLabel, value?.primaryLinkUrl, value?.secondaryLinks],
);
return <LinkDisplay value={{ url, label }} />;
const handleClick: MouseEventHandler = (event) => event.stopPropagation();
return (
<StyledContainer>
{links.map(({ url, label, type }, index) =>
type === LinkType.LinkedIn || type === LinkType.Twitter ? (
<SocialLink key={index} href={url} onClick={handleClick} type={type}>
{label}
</SocialLink>
) : (
<RoundedLink key={index} href={url} onClick={handleClick}>
{label}
</RoundedLink>
),
)}
</StyledContainer>
);
};