Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / applications / drive / src / app / components / sections / FileBrowser / GridViewItem.tsx
blobaed732b95e36e4ff0b2746e4c8aa8a111d91d30c
1 import { c } from 'ttag';
3 import { Button } from '@proton/atoms';
4 import { Badge, Checkbox, FileNameDisplay, Icon } from '@proton/components';
5 import clsx from '@proton/utils/clsx';
7 import { stopPropagation } from '../../../utils/stopPropagation';
8 import { useCheckbox, useItemContextMenu, useSelection } from '../../FileBrowser';
9 import { SelectionState } from '../../FileBrowser/hooks/useSelectionControls';
10 import type { DeviceItem } from '../Devices/Devices';
11 import type { DriveItem } from '../Drive/Drive';
12 import type { SharedLinkItem } from '../SharedLinks/SharedLinks';
13 import type { SharedWithMeItem } from '../SharedWithMe/SharedWithMe';
14 import type { TrashItem } from '../Trash/Trash';
16 const GridViewItemBase = ({
17     IconComponent,
18     SignatureIconComponent,
19     item,
20     disableSelection = false,
21 }: {
22     IconComponent: React.ReactNode;
23     SignatureIconComponent?: React.ReactNode;
24     item: DriveItem | TrashItem | SharedLinkItem | DeviceItem | SharedWithMeItem;
25     disableSelection?: boolean;
26 }) => {
27     const selectionControls = useSelection()!;
28     const contextMenuControls = useItemContextMenu();
29     const { handleCheckboxChange, handleCheckboxClick, handleCheckboxWrapperClick } = useCheckbox(item.id);
31     const isContextMenuButtonActive = contextMenuControls.isOpen && selectionControls.selectedItemIds.includes(item.id);
32     return (
33         <>
34             <button
35                 className={clsx(
36                     'flex flex-1 justify-center items-center file-browser-grid-item--container',
37                     item.isInvitation && 'file-browser-grid-item--invitation'
38                 )}
39                 onClick={(e) => {
40                     // Show Accept/Decline context menu if you click on the box
41                     if (item.isInvitation) {
42                         selectionControls?.selectItem(item.id);
43                         contextMenuControls.handleContextMenu(e);
44                     }
45                 }}
46                 onTouchEnd={(e) => {
47                     if (item.isInvitation) {
48                         selectionControls?.selectItem(item.id);
49                         contextMenuControls.handleContextMenuTouch?.(e);
50                     }
51                 }}
52             >
53                 <>
54                     {item.isInvitation && (
55                         <Badge className="absolute top-0 right-0 mt-1 mr-1" type="primary">{c('Badge')
56                             .t`Invited`}</Badge>
57                     )}
58                     {IconComponent}
59                 </>
60             </button>
61             <div
62                 className={clsx([
63                     'flex file-browser-grid-item--select',
64                     selectionControls?.selectionState !== SelectionState.NONE ? null : 'mouse:group-hover:opacity-100',
65                 ])}
66                 onTouchStart={stopPropagation}
67                 onKeyDown={stopPropagation}
68                 onClick={handleCheckboxWrapperClick}
69             >
70                 {!disableSelection ? (
71                     <Checkbox
72                         disabled={item.isLocked}
73                         className="expand-click-area file-browser-grid-item-checkbox"
74                         checked={selectionControls.isSelected(item.id)}
75                         onChange={handleCheckboxChange}
76                         onClick={handleCheckboxClick}
77                     />
78                 ) : null}
79             </div>
80             <div
81                 className={clsx(
82                     'file-browser-grid-item--file-name flex border-top',
83                     item.isInvitation && 'file-browser-grid-item--invitation'
84                 )}
85             >
86                 {SignatureIconComponent ? SignatureIconComponent : null}
87                 <FileNameDisplay text={item.name} className="mx-auto" data-testid="grid-item-name" />
88                 <Button
89                     shape="ghost"
90                     size="small"
91                     icon
92                     className={clsx([
93                         'file-browser-grid-view--options',
94                         isContextMenuButtonActive ? 'file-browser--options-focus' : 'mouse:group-hover:opacity-100',
95                     ])}
96                     onClick={(e) => {
97                         selectionControls?.selectItem(item.id);
98                         contextMenuControls.handleContextMenu(e);
99                     }}
100                     onTouchEnd={(e) => {
101                         selectionControls?.selectItem(item.id);
102                         contextMenuControls.handleContextMenuTouch?.(e);
103                     }}
104                 >
105                     <Icon name="three-dots-vertical" alt={c('Action').t`More options`} />
106                 </Button>
107             </div>
108         </>
109     );
112 export default GridViewItemBase;