Skip to content

Commit 4824050

Browse files
thaisguigonWeiko
authored andcommitted
fix: Links field fixes (#5565)
Related issue: #3607
1 parent af1a719 commit 4824050

File tree

9 files changed

+84
-106
lines changed

9 files changed

+84
-106
lines changed

packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ export const FieldInput = ({
136136
onShiftTab={onShiftTab}
137137
/>
138138
) : isFieldLinks(fieldDefinition) ? (
139-
<LinksFieldInput onCancel={onCancel} onSubmit={onSubmit} />
139+
<LinksFieldInput onCancel={onCancel} />
140140
) : isFieldCurrency(fieldDefinition) ? (
141141
<CurrencyFieldInput
142142
onEnter={onEnter}

packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/LinksFieldInput.tsx

+15-32
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { IconCheck, IconPlus } from 'twenty-ui';
55

66
import { useLinksField } from '@/object-record/record-field/meta-types/hooks/useLinksField';
77
import { LinksFieldMenuItem } from '@/object-record/record-field/meta-types/input/components/LinksFieldMenuItem';
8-
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
98
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
109
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
1110
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
@@ -27,13 +26,9 @@ const StyledDropdownMenu = styled(DropdownMenu)`
2726

2827
export type LinksFieldInputProps = {
2928
onCancel?: () => void;
30-
onSubmit?: FieldInputEvent;
3129
};
3230

33-
export const LinksFieldInput = ({
34-
onCancel,
35-
onSubmit,
36-
}: LinksFieldInputProps) => {
31+
export const LinksFieldInput = ({ onCancel }: LinksFieldInputProps) => {
3732
const { persistLinksField, hotkeyScope, fieldValue } = useLinksField();
3833

3934
const containerRef = useRef<HTMLDivElement>(null);
@@ -99,7 +94,6 @@ export const LinksFieldInput = ({
9994
) {
10095
setIsInputDisplayed(false);
10196
setInputValue('');
102-
onCancel?.();
10397
return;
10498
}
10599

@@ -109,14 +103,11 @@ export const LinksFieldInput = ({
109103
: toSpliced(links, linkToEditIndex, 1, linkValue);
110104
const [nextPrimaryLink, ...nextSecondaryLinks] = nextLinks;
111105

112-
onSubmit?.(() =>
113-
persistLinksField({
114-
primaryLinkUrl: nextPrimaryLink.url ?? '',
115-
primaryLinkLabel: nextPrimaryLink.label ?? '',
116-
secondaryLinks: nextSecondaryLinks,
117-
}),
118-
);
119-
106+
persistLinksField({
107+
primaryLinkUrl: nextPrimaryLink.url ?? '',
108+
primaryLinkLabel: nextPrimaryLink.label ?? '',
109+
secondaryLinks: nextSecondaryLinks,
110+
});
120111
setIsInputDisplayed(false);
121112
setInputValue('');
122113
};
@@ -125,26 +116,18 @@ export const LinksFieldInput = ({
125116
const nextLinks = moveArrayItem(links, { fromIndex: index, toIndex: 0 });
126117
const [nextPrimaryLink, ...nextSecondaryLinks] = nextLinks;
127118

128-
onSubmit?.(() =>
129-
persistLinksField({
130-
primaryLinkUrl: nextPrimaryLink.url ?? '',
131-
primaryLinkLabel: nextPrimaryLink.label ?? '',
132-
secondaryLinks: nextSecondaryLinks,
133-
}),
134-
);
119+
persistLinksField({
120+
primaryLinkUrl: nextPrimaryLink.url ?? '',
121+
primaryLinkLabel: nextPrimaryLink.label ?? '',
122+
secondaryLinks: nextSecondaryLinks,
123+
});
135124
};
136125

137126
const handleDeleteLink = (index: number) => {
138-
onSubmit?.(() =>
139-
persistLinksField({
140-
...fieldValue,
141-
secondaryLinks: toSpliced(
142-
fieldValue.secondaryLinks ?? [],
143-
index - 1,
144-
1,
145-
),
146-
}),
147-
);
127+
persistLinksField({
128+
...fieldValue,
129+
secondaryLinks: toSpliced(fieldValue.secondaryLinks ?? [], index - 1, 1),
130+
});
148131
};
149132

150133
return (

packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/LinksFieldMenuItem.tsx

+31-20
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect } from 'react';
1+
import { useEffect, useState } from 'react';
22
import styled from '@emotion/styled';
33
import {
44
IconBookmark,
@@ -40,8 +40,12 @@ export const LinksFieldMenuItem = ({
4040
onDelete,
4141
url,
4242
}: LinksFieldMenuItemProps) => {
43+
const [isHovered, setIsHovered] = useState(false);
4344
const { isDropdownOpen, closeDropdown } = useDropdown(dropdownId);
4445

46+
const handleMouseEnter = () => setIsHovered(true);
47+
const handleMouseLeave = () => setIsHovered(false);
48+
4549
// Make sure dropdown closes on unmount.
4650
useEffect(() => {
4751
if (isDropdownOpen) {
@@ -51,13 +55,14 @@ export const LinksFieldMenuItem = ({
5155

5256
return (
5357
<MenuItem
58+
onMouseEnter={handleMouseEnter}
59+
onMouseLeave={handleMouseLeave}
5460
text={<LinkDisplay value={{ label, url }} />}
5561
isIconDisplayedOnHoverOnly={!isPrimary && !isDropdownOpen}
5662
iconButtons={[
5763
{
58-
Wrapper: isPrimary
59-
? undefined
60-
: ({ iconButton }) => (
64+
Wrapper: isHovered
65+
? ({ iconButton }) => (
6166
<Dropdown
6267
dropdownId={dropdownId}
6368
dropdownHotkeyScope={{
@@ -69,31 +74,37 @@ export const LinksFieldMenuItem = ({
6974
clickableComponent={iconButton}
7075
dropdownComponents={
7176
<DropdownMenuItemsContainer>
72-
<MenuItem
73-
LeftIcon={IconBookmarkPlus}
74-
text="Set as Primary"
75-
onClick={onSetAsPrimary}
76-
/>
77+
{!isPrimary && (
78+
<MenuItem
79+
LeftIcon={IconBookmarkPlus}
80+
text="Set as Primary"
81+
onClick={onSetAsPrimary}
82+
/>
83+
)}
7784
<MenuItem
7885
LeftIcon={IconPencil}
7986
text="Edit"
8087
onClick={onEdit}
8188
/>
82-
<MenuItem
83-
accent="danger"
84-
LeftIcon={IconTrash}
85-
text="Delete"
86-
onClick={onDelete}
87-
/>
89+
{!isPrimary && (
90+
<MenuItem
91+
accent="danger"
92+
LeftIcon={IconTrash}
93+
text="Delete"
94+
onClick={onDelete}
95+
/>
96+
)}
8897
</DropdownMenuItemsContainer>
8998
}
9099
/>
91-
),
92-
Icon: isPrimary
93-
? (StyledIconBookmark as IconComponent)
94-
: IconDotsVertical,
100+
)
101+
: undefined,
102+
Icon:
103+
isPrimary && !isHovered
104+
? (StyledIconBookmark as IconComponent)
105+
: IconDotsVertical,
95106
accent: 'tertiary',
96-
onClick: isPrimary ? undefined : () => {},
107+
onClick: isHovered ? () => {} : undefined,
97108
},
98109
]}
99110
/>

packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiSelectFieldInput.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { useRef, useState } from 'react';
22
import styled from '@emotion/styled';
33

44
import { useMultiSelectField } from '@/object-record/record-field/meta-types/hooks/useMultiSelectField';
5-
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
65
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
76
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
87
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
@@ -18,7 +17,6 @@ const StyledRelationPickerContainer = styled.div`
1817
`;
1918

2019
export type MultiSelectFieldInputProps = {
21-
onSubmit?: FieldInputEvent;
2220
onCancel?: () => void;
2321
};
2422

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { MouseEvent } from 'react';
2-
import styled from '@emotion/styled';
32

43
import { FieldLinkValue } from '@/object-record/record-field/types/FieldMetadata';
54
import { RoundedLink } from '@/ui/navigation/link/components/RoundedLink';
@@ -11,15 +10,6 @@ import { checkUrlType } from '~/utils/checkUrlType';
1110
import { getAbsoluteUrl } from '~/utils/url/getAbsoluteUrl';
1211
import { getUrlHostName } from '~/utils/url/getUrlHostName';
1312

14-
import { EllipsisDisplay } from './EllipsisDisplay';
15-
16-
const StyledRawLink = styled(RoundedLink)`
17-
a {
18-
font-size: ${({ theme }) => theme.font.size.md};
19-
white-space: nowrap;
20-
}
21-
`;
22-
2313
type LinkDisplayProps = {
2414
value?: FieldLinkValue;
2515
};
@@ -35,18 +25,15 @@ export const LinkDisplay = ({ value }: LinkDisplayProps) => {
3525

3626
if (type === LinkType.LinkedIn || type === LinkType.Twitter) {
3727
return (
38-
<EllipsisDisplay>
39-
<SocialLink href={absoluteUrl} onClick={handleClick} type={type}>
40-
{displayedValue}
41-
</SocialLink>
42-
</EllipsisDisplay>
28+
<SocialLink href={absoluteUrl} onClick={handleClick} type={type}>
29+
{displayedValue}
30+
</SocialLink>
4331
);
4432
}
33+
4534
return (
46-
<EllipsisDisplay>
47-
<StyledRawLink href={absoluteUrl} onClick={handleClick}>
48-
{displayedValue}
49-
</StyledRawLink>
50-
</EllipsisDisplay>
35+
<RoundedLink href={absoluteUrl} onClick={handleClick}>
36+
{displayedValue}
37+
</RoundedLink>
5138
);
5239
};

packages/twenty-front/src/modules/ui/navigation/link/components/RoundedLink.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@ type RoundedLinkProps = {
1111
};
1212

1313
const StyledLink = styled(ReactLink)`
14+
font-size: ${({ theme }) => theme.font.size.md};
1415
max-width: 100%;
16+
height: ${({ theme }) => theme.spacing(5)};
1517
`;
1618

1719
const StyledChip = styled(Chip)`
1820
border-color: ${({ theme }) => theme.border.color.strong};
1921
box-sizing: border-box;
20-
padding: ${({ theme }) => theme.spacing(2)};
22+
padding: ${({ theme }) => theme.spacing(0, 2)};
2123
max-width: 100%;
24+
height: ${({ theme }) => theme.spacing(5)};
25+
min-width: 40px;
2226
`;
2327

2428
export const RoundedLink = ({
@@ -39,7 +43,7 @@ export const RoundedLink = ({
3943
<StyledChip
4044
label={`${children}`}
4145
variant={ChipVariant.Rounded}
42-
size={ChipSize.Small}
46+
size={ChipSize.Large}
4347
/>
4448
</StyledLink>
4549
);

packages/twenty-front/src/modules/ui/navigation/link/components/SocialLink.tsx

+2-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as React from 'react';
2-
import styled from '@emotion/styled';
32

43
import { getDisplayValueByUrlType } from '~/utils/getDisplayValueByUrlType';
54

@@ -18,16 +17,6 @@ type SocialLinkProps = {
1817
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
1918
};
2019

21-
const StyledRawLink = styled(RoundedLink)`
22-
overflow: hidden;
23-
24-
a {
25-
overflow: hidden;
26-
text-overflow: ellipsis;
27-
white-space: nowrap;
28-
}
29-
`;
30-
3120
export const SocialLink = ({
3221
children,
3322
href,
@@ -38,8 +27,8 @@ export const SocialLink = ({
3827
getDisplayValueByUrlType({ type: type, href: href }) ?? children;
3928

4029
return (
41-
<StyledRawLink href={href} onClick={onClick}>
30+
<RoundedLink href={href} onClick={onClick}>
4231
{displayValue}
43-
</StyledRawLink>
32+
</RoundedLink>
4433
);
4534
};

packages/twenty-front/src/modules/ui/navigation/menu-item/components/MenuItem.tsx

+14-8
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,30 @@ export type MenuItemIconButton = {
1919
};
2020

2121
export type MenuItemProps = {
22-
LeftIcon?: IconComponent | null;
2322
accent?: MenuItemAccent;
24-
text: ReactNode;
23+
className?: string;
2524
iconButtons?: MenuItemIconButton[];
2625
isIconDisplayedOnHoverOnly?: boolean;
2726
isTooltipOpen?: boolean;
28-
className?: string;
29-
testId?: string;
27+
LeftIcon?: IconComponent | null;
3028
onClick?: (event: MouseEvent<HTMLDivElement>) => void;
29+
onMouseEnter?: (event: MouseEvent<HTMLDivElement>) => void;
30+
onMouseLeave?: (event: MouseEvent<HTMLDivElement>) => void;
31+
testId?: string;
32+
text: ReactNode;
3133
};
3234

3335
export const MenuItem = ({
34-
LeftIcon,
3536
accent = 'default',
36-
text,
37+
className,
3738
iconButtons,
3839
isIconDisplayedOnHoverOnly = true,
39-
className,
40-
testId,
40+
LeftIcon,
4141
onClick,
42+
onMouseEnter,
43+
onMouseLeave,
44+
testId,
45+
text,
4246
}: MenuItemProps) => {
4347
const showIconButtons = Array.isArray(iconButtons) && iconButtons.length > 0;
4448

@@ -57,6 +61,8 @@ export const MenuItem = ({
5761
className={className}
5862
accent={accent}
5963
isIconDisplayedOnHoverOnly={isIconDisplayedOnHoverOnly}
64+
onMouseEnter={onMouseEnter}
65+
onMouseLeave={onMouseLeave}
6066
>
6167
<StyledMenuItemLeftContent>
6268
<MenuItemLeftContent LeftIcon={LeftIcon ?? undefined} text={text} />

packages/twenty-ui/src/display/chip/components/Chip.tsx

+8-8
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,6 @@ const StyledContainer = styled('div', {
8787
}
8888
}}
8989
90-
// Size style overrides
91-
${({ theme, size }) =>
92-
size === ChipSize.Large &&
93-
css`
94-
height: ${theme.spacing(4)};
95-
`}
96-
9790
// Variant style overrides
9891
${({ disabled, theme, variant }) => {
9992
if (variant === ChipVariant.Regular) {
@@ -153,6 +146,13 @@ const StyledLabel = styled.span`
153146
white-space: nowrap;
154147
`;
155148

149+
const StyledOverflowingTextWithTooltip = styled(OverflowingTextWithTooltip)<{
150+
size?: ChipSize;
151+
}>`
152+
height: ${({ theme, size }) =>
153+
size === ChipSize.Large ? theme.spacing(4) : 'auto'};
154+
`;
155+
156156
export const Chip = ({
157157
size = ChipSize.Small,
158158
label,
@@ -183,7 +183,7 @@ export const Chip = ({
183183
>
184184
{leftComponent}
185185
<StyledLabel>
186-
<OverflowingTextWithTooltip text={label} />
186+
<StyledOverflowingTextWithTooltip size={size} text={label} />
187187
</StyledLabel>
188188
{rightComponent}
189189
</StyledContainer>

0 commit comments

Comments
 (0)