Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / components / containers / contacts / merge / table / MergeTableBodyRow.tsx
blob533ca011d0c2c8cc7441f57c1e882124516d441c
1 import type { ComponentProps } from 'react';
2 import { useEffect, useRef, useState } from 'react';
4 import { c } from 'ttag';
6 import { useUserKeys } from '@proton/account/userKeys/hooks';
7 import DropdownActions from '@proton/components/components/dropdown/DropdownActions';
8 import type OrderableTableBody from '@proton/components/components/orderableTable/OrderableTableBody';
9 import OrderableTableRow from '@proton/components/components/orderableTable/OrderableTableRow';
10 import TableRow from '@proton/components/components/table/TableRow';
11 import useActiveBreakpoint from '@proton/components/hooks/useActiveBreakpoint';
12 import { useContact } from '@proton/mail/contacts/contactHooks';
13 import type { ContactFormatted } from '@proton/shared/lib/interfaces/contacts';
14 import isTruthy from '@proton/utils/isTruthy';
16 import useVCardContact from '../../hooks/useVCardContact';
17 import EmailsTableCell from './EmailsTableCell';
18 import NameTableCell from './NameTableCell';
20 interface Props extends Omit<ComponentProps<typeof OrderableTableBody>, 'colSpan'> {
21     index: number;
22     ID: string;
23     Contact: ContactFormatted;
24     highlightedID: string;
25     isChecked: { [ID: string]: boolean };
26     beDeleted: { [ID: string]: boolean };
27     onClickCheckbox: (ID: string) => void;
28     onClickDetails: (ID: string) => void;
29     onToggleDelete: (ID: string) => void;
32 const MergeTableBodyRow = ({
33     index,
34     ID,
35     Contact,
36     highlightedID,
37     isChecked,
38     beDeleted,
39     onClickCheckbox,
40     onClickDetails,
41     onToggleDelete,
42 }: Props) => {
43     const rowRef = useRef<any>(null);
44     const [isIntersecting, setIsIntersecting] = useState(false);
45     const { Name, emails } = Contact;
46     const [userKeysList] = useUserKeys();
47     // Allow to control when we fetch contacts and avoid fetching them when the row is not visible
48     const [contact] = useContact(isIntersecting ? ID : undefined);
49     const { vCardContact } = useVCardContact({ contact, userKeysList });
51     const { viewportWidth } = useActiveBreakpoint();
53     const deleted = beDeleted[ID];
55     useEffect(() => {
56         const observer = new IntersectionObserver(([entry]) => {
57             setIsIntersecting(entry.isIntersecting);
58         });
60         observer.observe(rowRef.current?.node);
62         return () => {
63             observer.disconnect();
64         };
65     }, [setIsIntersecting]);
67     const options = [
68         !deleted && {
69             text: c('Action').t`View`,
70             onClick() {
71                 onClickDetails(ID);
72             },
73         },
74         {
75             text: deleted ? c('Action').t`Unmark for deletion` : c('Action').t`Mark for deletion`,
76             onClick() {
77                 onToggleDelete(ID);
78             },
79         },
80     ].filter(Boolean) as { text: string; onClick: () => void }[];
82     const givenName = vCardContact?.n?.value.givenNames?.join(' ')?.trim() ?? '-';
83     const familyName = vCardContact?.n?.value.familyNames?.join(' ')?.trim() ?? '-';
85     const cells = [
86         <NameTableCell
87             key="displayName"
88             name={Name}
89             contactID={ID}
90             highlightedID={highlightedID}
91             checked={isChecked[ID]}
92             deleted={deleted}
93             greyedOut={deleted}
94             onToggle={onClickCheckbox}
95         />,
96         !(givenName === '-' && viewportWidth['<=medium']) && (
97             <span className="max-w-full inline-block text-ellipsis">{givenName}</span>
98         ),
99         !(familyName === '-' && viewportWidth['<=medium']) && (
100             <span className="max-w-full inline-block text-ellipsis">{familyName}</span>
101         ),
102         <EmailsTableCell
103             key="email"
104             contactID={ID}
105             highlightedID={highlightedID}
106             emails={emails}
107             greyedOut={deleted}
108         />,
109         <DropdownActions key="options" size="small" list={options} data-testid="merge-model:action-button" />,
110     ].filter((cell) => (viewportWidth['<=medium'] ? isTruthy(cell) : true));
112     return deleted ? (
113         <TableRow key={`${ID}`} cells={[null, ...cells]} />
114     ) : (
115         <OrderableTableRow key={`${ID}`} index={index} cells={cells} ref={rowRef} />
116     );
119 export default MergeTableBodyRow;