copy to clipboard on MultiItemFieldMenuItem (#13292)
# ISSUE - closes #13089
This commit is contained in:
@ -6,6 +6,7 @@ import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-sta
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
|
||||
import { MultiItemFieldInput } from './MultiItemFieldInput';
|
||||
|
||||
type EmailsFieldInputProps = {
|
||||
@ -18,6 +19,7 @@ export const EmailsFieldInput = ({
|
||||
onClickOutside,
|
||||
}: EmailsFieldInputProps) => {
|
||||
const { persistEmailsField, fieldValue } = useEmailsField();
|
||||
const { copyToClipboard } = useCopyToClipboard();
|
||||
|
||||
const emails = useMemo<string[]>(
|
||||
() =>
|
||||
@ -56,6 +58,10 @@ export const EmailsFieldInput = ({
|
||||
setIsFieldInError(hasError && values.length === 0);
|
||||
};
|
||||
|
||||
const handleCopy = (email: string) => {
|
||||
copyToClipboard(email);
|
||||
};
|
||||
|
||||
return (
|
||||
<MultiItemFieldInput
|
||||
items={emails}
|
||||
@ -80,10 +86,12 @@ export const EmailsFieldInput = ({
|
||||
dropdownId={`emails-${index}`}
|
||||
showPrimaryIcon={getShowPrimaryIcon(index)}
|
||||
showSetAsPrimaryButton={getShowSetAsPrimaryButton(index)}
|
||||
showCopyButton={true}
|
||||
email={email}
|
||||
onEdit={handleEdit}
|
||||
onSetAsPrimary={handleSetPrimary}
|
||||
onDelete={handleDelete}
|
||||
onCopy={handleCopy}
|
||||
/>
|
||||
)}
|
||||
onError={handleError}
|
||||
|
||||
@ -6,9 +6,11 @@ type EmailsFieldMenuItemProps = {
|
||||
onEdit?: () => void;
|
||||
onSetAsPrimary?: () => void;
|
||||
onDelete?: () => void;
|
||||
onCopy?: (email: string) => void;
|
||||
email: string;
|
||||
showPrimaryIcon: boolean;
|
||||
showSetAsPrimaryButton: boolean;
|
||||
showCopyButton: boolean;
|
||||
};
|
||||
|
||||
export const EmailsFieldMenuItem = ({
|
||||
@ -19,6 +21,8 @@ export const EmailsFieldMenuItem = ({
|
||||
email,
|
||||
showPrimaryIcon,
|
||||
showSetAsPrimaryButton,
|
||||
showCopyButton,
|
||||
onCopy,
|
||||
}: EmailsFieldMenuItemProps) => {
|
||||
return (
|
||||
<MultiItemFieldMenuItem
|
||||
@ -30,6 +34,8 @@ export const EmailsFieldMenuItem = ({
|
||||
DisplayComponent={EmailDisplay}
|
||||
showPrimaryIcon={showPrimaryIcon}
|
||||
showSetAsPrimaryButton={showSetAsPrimaryButton}
|
||||
showCopyButton={showCopyButton}
|
||||
onCopy={onCopy}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@ -8,6 +8,7 @@ import React, { useState } from 'react';
|
||||
import {
|
||||
IconBookmark,
|
||||
IconBookmarkPlus,
|
||||
IconCopy,
|
||||
IconPencil,
|
||||
IconTrash,
|
||||
} from 'twenty-ui/display';
|
||||
@ -19,9 +20,11 @@ type MultiItemFieldMenuItemProps<T> = {
|
||||
onEdit?: () => void;
|
||||
onSetAsPrimary?: () => void;
|
||||
onDelete?: () => void;
|
||||
onCopy?: (value: T) => void;
|
||||
DisplayComponent: React.ComponentType<{ value: T }>;
|
||||
showPrimaryIcon: boolean;
|
||||
showSetAsPrimaryButton: boolean;
|
||||
showCopyButton?: boolean;
|
||||
};
|
||||
|
||||
export const MultiItemFieldMenuItem = <T,>({
|
||||
@ -33,6 +36,8 @@ export const MultiItemFieldMenuItem = <T,>({
|
||||
DisplayComponent,
|
||||
showPrimaryIcon,
|
||||
showSetAsPrimaryButton,
|
||||
showCopyButton,
|
||||
onCopy,
|
||||
}: MultiItemFieldMenuItemProps<T>) => {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
@ -71,6 +76,14 @@ export const MultiItemFieldMenuItem = <T,>({
|
||||
onEdit?.();
|
||||
};
|
||||
|
||||
const handleCopyClick = (event: React.MouseEvent<HTMLDivElement>) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
closeDropdown(dropdownId);
|
||||
onCopy?.(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<MenuItemWithOptionDropdown
|
||||
onMouseEnter={handleMouseEnter}
|
||||
@ -100,6 +113,13 @@ export const MultiItemFieldMenuItem = <T,>({
|
||||
text="Delete"
|
||||
onClick={handleDeleteClick}
|
||||
/>
|
||||
{showCopyButton && (
|
||||
<MenuItem
|
||||
LeftIcon={IconCopy}
|
||||
text="Copy"
|
||||
onClick={handleCopyClick}
|
||||
/>
|
||||
)}
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
}
|
||||
|
||||
@ -13,6 +13,8 @@ import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFi
|
||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
import { EmailsFieldInput } from '../EmailsFieldInput';
|
||||
|
||||
const updateRecord = fn();
|
||||
@ -113,6 +115,7 @@ const EmailInputWithContext = ({
|
||||
const meta: Meta<typeof EmailInputWithContext> = {
|
||||
title: 'UI/Input/EmailsFieldInput',
|
||||
component: EmailInputWithContext,
|
||||
decorators: [SnackBarDecorator, I18nFrontDecorator],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
Reference in New Issue
Block a user