1
1
import { useMemo , useRef , useState } from 'react' ;
2
2
import styled from '@emotion/styled' ;
3
3
import { Key } from 'ts-key-enum' ;
4
- import { IconPlus } from 'twenty-ui' ;
4
+ import { IconCheck , IconPlus } from 'twenty-ui' ;
5
5
6
6
import { useLinksField } from '@/object-record/record-field/meta-types/hooks/useLinksField' ;
7
7
import { LinksFieldMenuItem } from '@/object-record/record-field/meta-types/input/components/LinksFieldMenuItem' ;
@@ -17,6 +17,7 @@ import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useLis
17
17
import { moveArrayItem } from '~/utils/array/moveArrayItem' ;
18
18
import { toSpliced } from '~/utils/array/toSpliced' ;
19
19
import { isDefined } from '~/utils/isDefined' ;
20
+ import { absoluteUrlSchema } from '~/utils/validation-schemas/absoluteUrlSchema' ;
20
21
21
22
const StyledDropdownMenu = styled ( DropdownMenu ) `
22
23
left: -1px;
@@ -68,14 +69,44 @@ export const LinksFieldInput = ({
68
69
69
70
const [ isInputDisplayed , setIsInputDisplayed ] = useState ( false ) ;
70
71
const [ inputValue , setInputValue ] = useState ( '' ) ;
72
+ const [ linkToEditIndex , setLinkToEditIndex ] = useState ( - 1 ) ;
73
+ const isAddingNewLink = linkToEditIndex === - 1 ;
71
74
72
- const handleAddLink = ( ) => {
73
- if ( ! inputValue ) return ;
75
+ const handleAddButtonClick = ( ) => {
76
+ setLinkToEditIndex ( - 1 ) ;
77
+ setIsInputDisplayed ( true ) ;
78
+ } ;
74
79
75
- setIsInputDisplayed ( false ) ;
76
- setInputValue ( '' ) ;
80
+ const handleEditButtonClick = ( index : number ) => {
81
+ setLinkToEditIndex ( index ) ;
82
+ setInputValue ( links [ index ] . url ) ;
83
+ setIsInputDisplayed ( true ) ;
84
+ } ;
77
85
78
- const nextLinks = [ ...links , { label : '' , url : inputValue } ] ;
86
+ const urlInputValidation = inputValue
87
+ ? absoluteUrlSchema . safeParse ( inputValue )
88
+ : null ;
89
+
90
+ const handleSubmitInput = ( ) => {
91
+ if ( ! urlInputValidation ?. success ) return ;
92
+
93
+ const validatedInputValue = urlInputValidation . data ;
94
+
95
+ // Don't persist if value hasn't changed.
96
+ if (
97
+ ! isAddingNewLink &&
98
+ validatedInputValue === links [ linkToEditIndex ] . url
99
+ ) {
100
+ setIsInputDisplayed ( false ) ;
101
+ setInputValue ( '' ) ;
102
+ onCancel ?.( ) ;
103
+ return ;
104
+ }
105
+
106
+ const linkValue = { label : '' , url : validatedInputValue } ;
107
+ const nextLinks = isAddingNewLink
108
+ ? [ ...links , linkValue ]
109
+ : toSpliced ( links , linkToEditIndex , 1 , linkValue ) ;
79
110
const [ nextPrimaryLink , ...nextSecondaryLinks ] = nextLinks ;
80
111
81
112
onSubmit ?.( ( ) =>
@@ -85,6 +116,9 @@ export const LinksFieldInput = ({
85
116
secondaryLinks : nextSecondaryLinks ,
86
117
} ) ,
87
118
) ;
119
+
120
+ setIsInputDisplayed ( false ) ;
121
+ setInputValue ( '' ) ;
88
122
} ;
89
123
90
124
const handleSetPrimaryLink = ( index : number ) => {
@@ -124,6 +158,7 @@ export const LinksFieldInput = ({
124
158
dropdownId = { `${ hotkeyScope } -links-${ index } ` }
125
159
isPrimary = { index === 0 }
126
160
label = { label }
161
+ onEdit = { ( ) => handleEditButtonClick ( index ) }
127
162
onSetAsPrimary = { ( ) => handleSetPrimaryLink ( index ) }
128
163
onDelete = { ( ) => handleDeleteLink ( index ) }
129
164
url = { url }
@@ -140,15 +175,19 @@ export const LinksFieldInput = ({
140
175
value = { inputValue }
141
176
hotkeyScope = { hotkeyScope }
142
177
onChange = { ( event ) => setInputValue ( event . target . value ) }
143
- onEnter = { handleAddLink }
178
+ onEnter = { handleSubmitInput }
144
179
rightComponent = {
145
- < LightIconButton Icon = { IconPlus } onClick = { handleAddLink } />
180
+ < LightIconButton
181
+ Icon = { isAddingNewLink ? IconPlus : IconCheck }
182
+ disabled = { ! urlInputValidation ?. success }
183
+ onClick = { handleSubmitInput }
184
+ />
146
185
}
147
186
/>
148
187
) : (
149
188
< DropdownMenuItemsContainer >
150
189
< MenuItem
151
- onClick = { ( ) => setIsInputDisplayed ( true ) }
190
+ onClick = { handleAddButtonClick }
152
191
LeftIcon = { IconPlus }
153
192
text = "Add link"
154
193
/>
0 commit comments