feat: edit link in Links field (#5447)

Closes #5376
This commit is contained in:
Thaïs
2024-05-22 10:42:08 +02:00
committed by GitHub
parent 47a6146dd0
commit e2b48e2c4e
2 changed files with 58 additions and 11 deletions

View File

@ -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';
@ -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;
@ -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?.(() =>
@ -85,6 +116,9 @@ export const LinksFieldInput = ({
secondaryLinks: nextSecondaryLinks,
}),
);
setIsInputDisplayed(false);
setInputValue('');
};
const handleSetPrimaryLink = (index: number) => {
@ -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}
@ -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"
/>

View File

@ -5,6 +5,7 @@ import {
IconBookmarkPlus,
IconComponent,
IconDotsVertical,
IconPencil,
IconTrash,
} from 'twenty-ui';
@ -18,8 +19,9 @@ type LinksFieldMenuItemProps = {
dropdownId: string;
isPrimary?: boolean;
label: string;
onSetAsPrimary: () => void;
onDelete: () => void;
onEdit?: () => void;
onSetAsPrimary?: () => void;
onDelete?: () => void;
url: string;
};
@ -33,6 +35,7 @@ export const LinksFieldMenuItem = ({
dropdownId,
isPrimary,
label,
onEdit,
onSetAsPrimary,
onDelete,
url,
@ -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}