Skip to content

Commit

Permalink
feat: edit link in Links field (twentyhq#5447)
Browse files Browse the repository at this point in the history
  • Loading branch information
thaisguigon committed May 22, 2024
1 parent 47a6146 commit e2b48e2
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMemo, useRef, useState } from 'react';
import styled from '@emotion/styled';
import { Key } from 'ts-key-enum';
import { IconPlus } from 'twenty-ui';
import { IconCheck, IconPlus } from 'twenty-ui';

import { useLinksField } from '@/object-record/record-field/meta-types/hooks/useLinksField';
import { LinksFieldMenuItem } from '@/object-record/record-field/meta-types/input/components/LinksFieldMenuItem';
Expand All @@ -17,6 +17,7 @@ import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useLis
import { moveArrayItem } from '~/utils/array/moveArrayItem';
import { toSpliced } from '~/utils/array/toSpliced';
import { isDefined } from '~/utils/isDefined';
import { absoluteUrlSchema } from '~/utils/validation-schemas/absoluteUrlSchema';

const StyledDropdownMenu = styled(DropdownMenu)`
left: -1px;
Expand Down Expand Up @@ -68,14 +69,44 @@ export const LinksFieldInput = ({

const [isInputDisplayed, setIsInputDisplayed] = useState(false);
const [inputValue, setInputValue] = useState('');
const [linkToEditIndex, setLinkToEditIndex] = useState(-1);
const isAddingNewLink = linkToEditIndex === -1;

const handleAddLink = () => {
if (!inputValue) return;
const handleAddButtonClick = () => {
setLinkToEditIndex(-1);
setIsInputDisplayed(true);
};

setIsInputDisplayed(false);
setInputValue('');
const handleEditButtonClick = (index: number) => {
setLinkToEditIndex(index);
setInputValue(links[index].url);
setIsInputDisplayed(true);
};

const nextLinks = [...links, { label: '', url: inputValue }];
const urlInputValidation = inputValue
? absoluteUrlSchema.safeParse(inputValue)
: null;

const handleSubmitInput = () => {
if (!urlInputValidation?.success) return;

const validatedInputValue = urlInputValidation.data;

// Don't persist if value hasn't changed.
if (
!isAddingNewLink &&
validatedInputValue === links[linkToEditIndex].url
) {
setIsInputDisplayed(false);
setInputValue('');
onCancel?.();
return;
}

const linkValue = { label: '', url: validatedInputValue };
const nextLinks = isAddingNewLink
? [...links, linkValue]
: toSpliced(links, linkToEditIndex, 1, linkValue);
const [nextPrimaryLink, ...nextSecondaryLinks] = nextLinks;

onSubmit?.(() =>
Expand All @@ -85,6 +116,9 @@ export const LinksFieldInput = ({
secondaryLinks: nextSecondaryLinks,
}),
);

setIsInputDisplayed(false);
setInputValue('');
};

const handleSetPrimaryLink = (index: number) => {
Expand Down Expand Up @@ -124,6 +158,7 @@ export const LinksFieldInput = ({
dropdownId={`${hotkeyScope}-links-${index}`}
isPrimary={index === 0}
label={label}
onEdit={() => handleEditButtonClick(index)}
onSetAsPrimary={() => handleSetPrimaryLink(index)}
onDelete={() => handleDeleteLink(index)}
url={url}
Expand All @@ -140,15 +175,19 @@ export const LinksFieldInput = ({
value={inputValue}
hotkeyScope={hotkeyScope}
onChange={(event) => setInputValue(event.target.value)}
onEnter={handleAddLink}
onEnter={handleSubmitInput}
rightComponent={
<LightIconButton Icon={IconPlus} onClick={handleAddLink} />
<LightIconButton
Icon={isAddingNewLink ? IconPlus : IconCheck}
disabled={!urlInputValidation?.success}
onClick={handleSubmitInput}
/>
}
/>
) : (
<DropdownMenuItemsContainer>
<MenuItem
onClick={() => setIsInputDisplayed(true)}
onClick={handleAddButtonClick}
LeftIcon={IconPlus}
text="Add link"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
IconBookmarkPlus,
IconComponent,
IconDotsVertical,
IconPencil,
IconTrash,
} from 'twenty-ui';

Expand All @@ -18,8 +19,9 @@ type LinksFieldMenuItemProps = {
dropdownId: string;
isPrimary?: boolean;
label: string;
onSetAsPrimary: () => void;
onDelete: () => void;
onEdit?: () => void;
onSetAsPrimary?: () => void;
onDelete?: () => void;
url: string;
};

Expand All @@ -33,6 +35,7 @@ export const LinksFieldMenuItem = ({
dropdownId,
isPrimary,
label,
onEdit,
onSetAsPrimary,
onDelete,
url,
Expand Down Expand Up @@ -71,6 +74,11 @@ export const LinksFieldMenuItem = ({
text="Set as Primary"
onClick={onSetAsPrimary}
/>
<MenuItem
LeftIcon={IconPencil}
text="Edit"
onClick={onEdit}
/>
<MenuItem
accent="danger"
LeftIcon={IconTrash}
Expand Down

0 comments on commit e2b48e2

Please sign in to comment.