1 import type { Ref } from 'react';
2 import { forwardRef } from 'react';
4 import { c } from 'ttag';
6 import DropdownActions from '@proton/components/components/dropdown/DropdownActions';
7 import Icon from '@proton/components/components/icon/Icon';
8 import OrderableHandle from '@proton/components/components/orderable/OrderableHandle';
9 import type { ContactEmail, ContactEmailModel } from '@proton/shared/lib/interfaces/contacts';
10 import type { VCardContact, VCardProperty } from '@proton/shared/lib/interfaces/contacts/VCard';
11 import clsx from '@proton/utils/clsx';
13 import ContactGroupDropdown from '../ContactGroupDropdown';
14 import type { ContactGroupEditProps } from '../group/ContactGroupEditModal';
15 import type { ContactGroupLimitReachedProps } from '../modals/ContactGroupLimitReachedModal';
16 import type { ContactImageProps } from '../modals/ContactImageModal';
17 import ContactEditLabel from './ContactEditLabel';
18 import ContactFieldProperty from './fields/ContactFieldProperty';
21 vCardProperty: VCardProperty;
22 vCardContact: VCardContact;
23 onChangeVCard: (vCardProperty: VCardProperty) => void;
24 onRemove: (value: string) => void;
26 isSubmitted?: boolean;
29 labelWidthClassName?: string;
30 filteredTypes?: string[];
31 contactEmail?: ContactEmailModel;
32 onContactEmailChange?: (contactEmail: ContactEmailModel) => void;
33 onUpgrade: () => void;
34 onSelectImage: (props: ContactImageProps) => void;
35 onGroupEdit: (props: ContactGroupEditProps) => void;
36 onLimitReached?: (props: ContactGroupLimitReachedProps) => void;
39 const ContactEditProperty = (
58 ref: Ref<HTMLInputElement>
60 const { field, value } = vCardProperty;
61 const canDelete = !(field === 'photo' && !value);
65 // Delete is always available (except when primary and no image). Primary name has action row disabled.
70 text: <Icon name="trash" className="m-auto" alt={c('Action').t`Delete`} />,
72 if (vCardProperty.uid) {
73 onRemove(vCardProperty.uid);
79 const handleUpdateContactGroups = (changes: { [groupID: string]: boolean }) => {
80 if (contactEmail && onContactEmailChange) {
81 let LabelIDs = [...contactEmail.LabelIDs];
82 Object.entries(changes).forEach(([groupID, checked]) => {
84 LabelIDs.push(groupID);
86 LabelIDs = contactEmail.LabelIDs.filter((id: string) => id !== groupID);
89 onContactEmailChange({ ...contactEmail, LabelIDs, changes: { ...contactEmail.changes, ...changes } });
93 // The data-contact-property-id is used to focus on the element in ContactEditProperties
95 <div className="flex flex-nowrap shrink-0" data-contact-property-id={vCardProperty.uid}>
97 <OrderableHandle key="icon">
98 <div className="cursor-row-resize mr-2 flex shrink-0 mb-4 mt-0.5">
99 <Icon name="text-align-justify" className="mt-2" />
103 <div className="mr-2 flex items-center shrink-0">
104 <Icon name="text-align-justify" className="visibility-hidden" />
107 <div className="contact-modal-field relative flex flex-nowrap flex-column md:flex-row w-full items-stretch md:items-start">
110 'contact-modal-select flex flex-nowrap mb-2 md:mb-4 items-start',
111 labelWidthClassName || 'md:w-3/10',
115 vCardProperty={vCardProperty}
116 onChangeVCard={onChangeVCard}
117 fixedType={fixedType}
118 filteredTypes={filteredTypes}
122 <div className="flex flex-nowrap items-startoupas md:flex-1 shrink-0">
123 <span className="flex-1 mb-4">
124 <ContactFieldProperty
126 vCardProperty={vCardProperty}
127 vCardContact={vCardContact}
128 onChangeVCard={onChangeVCard}
129 isSubmitted={isSubmitted}
130 onSelectImage={onSelectImage}
134 <span className="mb-4 ml-2 flex">
135 {list.length > 0 && (
140 (field === 'photo' ||
147 {field === 'email' && (
148 <ContactGroupDropdown
153 contactEmails={[contactEmail as unknown as ContactEmail]}
154 onDelayedSave={handleUpdateContactGroups}
155 tooltip={c('Title').t`Contact group`}
156 onGroupEdit={onGroupEdit}
157 onLimitReached={onLimitReached}
158 onUpgrade={onUpgrade}
160 <Icon name="users" alt={c('Action').t`Contact group`} />
161 </ContactGroupDropdown>
163 <DropdownActions icon list={list} />
174 export default forwardRef(ContactEditProperty);