Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / applications / drive / src / app / components / FileBrowser / ListView / ListHeader.tsx
blob1b9e013c9e6edeffffa69ef2cecbdac3ebfab1d9
1 import * as React from 'react';
3 import { c, msgid } from 'ttag';
5 import { Checkbox, Icon, Loader, TableHeaderCell, TableRowSticky, Tooltip } from '@proton/components';
6 import { SORT_DIRECTION } from '@proton/shared/lib/constants';
7 import { getNumAccessesTooltipMessage } from '@proton/shared/lib/drive/translations';
8 import clsx from '@proton/utils/clsx';
10 import { stopPropagation } from '../../../utils/stopPropagation';
11 import { SelectionState } from '../hooks/useSelectionControls';
12 import type { SortParams } from '../interface';
13 import { useSelection } from '../state/useSelection';
15 interface Props<T> {
16     scrollAreaRef: React.RefObject<HTMLDivElement>;
17     sortParams?: SortParams<T>;
18     isLoading: boolean;
19     items: any[];
20     onSort?: (params: SortParams<T>) => void;
21     itemCount: number;
22     isMultiSelectionDisabled?: boolean;
25 enum HeaderCellsPresets {
26     Checkbox,
27     Placeholder,
30 const HeaderCell = <T,>({
31     item,
32     isLoading,
33     sortParams,
34     itemCount,
35     onSort,
36     isMultiSelectionDisabled,
37 }: {
38     item: any;
39     isLoading: boolean;
40     itemCount: number;
41     onSort: (key: T) => void;
42     sortParams?: SortParams<T>;
43     isMultiSelectionDisabled?: boolean;
44 }) => {
45     const selection = useSelection();
46     const selectedCount = selection?.selectedItemIds.length;
47     if (item.type === HeaderCellsPresets.Checkbox && selection) {
48         return (
49             <TableHeaderCell className="file-browser-header-checkbox-cell">
50                 <div role="presentation" key="select-all" className="flex pl-2" onClick={stopPropagation}>
51                     <Checkbox
52                         indeterminate={selection.selectionState === SelectionState.SOME}
53                         className="expand-click-area mr-1"
54                         disabled={!itemCount}
55                         checked={selection?.selectionState !== SelectionState.NONE}
56                         onChange={
57                             selection?.selectionState === SelectionState.SOME
58                                 ? selection.clearSelections
59                                 : selection.toggleAllSelected
60                         }
61                         data-testid="checkbox-select-all"
62                     >
63                         {selectedCount && selection?.selectionState !== SelectionState.NONE ? (
64                             <span className="ml-2">
65                                 {c('Info').ngettext(
66                                     msgid`${selectedCount} selected`,
67                                     `${selectedCount} selected`,
68                                     selectedCount
69                                 )}
70                             </span>
71                         ) : null}
72                     </Checkbox>
73                     {selection?.selectionState !== SelectionState.NONE && isLoading ? (
74                         <Loader className="flex shrink-0" />
75                     ) : null}
76                 </div>
77             </TableHeaderCell>
78         );
79     }
81     if (!isMultiSelectionDisabled && selection?.selectionState !== SelectionState.NONE) {
82         return null;
83     }
85     if (item.type === HeaderCellsPresets.Placeholder) {
86         return (
87             <TableHeaderCell
88                 className={clsx(['file-browser-list--icon-column', item.props?.className])}
89                 style={item.props.style}
90             />
91         );
92     }
94     const getSortDirectionForKey = (key: T) => (sortParams?.sortField === key ? sortParams.sortOrder : undefined);
96     return (
97         <TableHeaderCell
98             className={item.props?.className}
99             direction={getSortDirectionForKey(item.type)}
100             onSort={item.sorting ? () => onSort?.(item.type) : undefined}
101             isLoading={isLoading && sortParams?.sortField === item.type}
102             data-testid="sort-by"
103         >
104             {item.getText()}
105             {item.type === 'numAccesses' && (
106                 <Tooltip className="pl-1" title={getNumAccessesTooltipMessage()}>
107                     <Icon name="info-circle" size={3.5} alt={getNumAccessesTooltipMessage()} />
108                 </Tooltip>
109             )}
110         </TableHeaderCell>
111     );
114 const ListHeader = <T,>({
115     scrollAreaRef,
116     items,
117     sortParams,
118     isLoading,
119     itemCount,
120     onSort,
121     isMultiSelectionDisabled,
122 }: Props<T>) => {
123     const handleSort = (key: T) => {
124         if (!sortParams || !onSort) {
125             return;
126         }
128         const direction =
129             sortParams.sortField === key && sortParams.sortOrder === SORT_DIRECTION.ASC
130                 ? SORT_DIRECTION.DESC
131                 : SORT_DIRECTION.ASC;
133         onSort({ sortField: key, sortOrder: direction });
134     };
136     return (
137         <thead onContextMenu={(e) => e.stopPropagation()}>
138             <TableRowSticky scrollAreaRef={scrollAreaRef}>
139                 {items.map((item, index) => (
140                     <HeaderCell
141                         item={item}
142                         isLoading={isLoading}
143                         sortParams={sortParams}
144                         key={index}
145                         itemCount={itemCount}
146                         onSort={handleSort}
147                         isMultiSelectionDisabled={isMultiSelectionDisabled}
148                     />
149                 ))}
150             </TableRowSticky>
151         </thead>
152     );
155 export default ListHeader;