Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / applications / drive / src / app / components / sections / Search / Search.tsx
blobad2ff19ed181e712d471a98d2e34ed700b1e8bdf
1 import { useCallback, useMemo, useRef } from 'react';
3 import { c } from 'ttag';
5 import { useActiveBreakpoint } from '@proton/components';
6 import { SHARE_MEMBER_PERMISSIONS } from '@proton/shared/lib/drive/permissions';
8 import useDriveDragMove from '../../../hooks/drive/useDriveDragMove';
9 import useNavigate from '../../../hooks/drive/useNavigate';
10 import type { EncryptedLink, LinkShareUrl, useSearchView } from '../../../store';
11 import { useThumbnailsDownload } from '../../../store';
12 import { SortField } from '../../../store/_views/utils/useSorting';
13 import FileBrowser, { Cells, GridHeader, useItemContextMenu, useSelection } from '../../FileBrowser';
14 import type { BrowserItemId, FileBrowserBaseItem, ListViewHeaderItem } from '../../FileBrowser/interface';
15 import { GridViewItem } from '../FileBrowser/GridViewItemLink';
16 import { LocationCell, ModifiedCell, NameCell, SizeCell } from '../FileBrowser/contentCells';
17 import headerItems from '../FileBrowser/headerCells';
18 import { translateSortField } from '../SortDropdown';
19 import { getSelectedItems } from '../helpers';
20 import { NoSearchResultsView } from './NoSearchResultsView';
21 import { SearchItemContextMenu } from './SearchItemContextMenu';
23 interface SearchItem extends FileBrowserBaseItem {
24     activeRevision?: EncryptedLink['activeRevision'];
25     cachedThumbnailUrl?: string;
26     hasThumbnail: boolean;
27     isFile: boolean;
28     mimeType: string;
29     fileModifyTime: number;
30     name: string;
31     shareUrl?: LinkShareUrl;
32     signatureIssues?: any;
33     size: number;
34     trashed: number | null;
35     parentLinkId: string;
36     rootShareId: string;
37     isShared: boolean;
38     isAdmin: boolean;
41 interface Props {
42     shareId: string;
43     searchView: ReturnType<typeof useSearchView>;
46 const { CheckboxCell, ContextMenuCell } = Cells;
48 const largeScreenCells: React.FC<{ item: SearchItem }>[] = [
49     CheckboxCell,
50     NameCell,
51     LocationCell,
52     ModifiedCell,
53     SizeCell,
54     ContextMenuCell,
56 const smallScreenCells = [CheckboxCell, NameCell, ContextMenuCell];
58 const headerItemsLargeScreen: ListViewHeaderItem[] = [
59     headerItems.checkbox,
60     headerItems.name,
61     headerItems.location,
62     headerItems.modificationDate,
63     headerItems.size,
64     headerItems.placeholder,
67 const headerItemsSmallScreen: ListViewHeaderItem[] = [headerItems.checkbox, headerItems.name, headerItems.placeholder];
69 type SearchSortFields = Extract<SortField, SortField.name | SortField.fileModifyTime | SortField.size>;
70 const SORT_FIELDS: SearchSortFields[] = [SortField.name, SortField.size, SortField.fileModifyTime];
72 export const Search = ({ shareId, searchView }: Props) => {
73     const contextMenuAnchorRef = useRef<HTMLDivElement>(null);
75     const browserItemContextMenu = useItemContextMenu();
76     const thumbnails = useThumbnailsDownload();
77     const { navigateToLink } = useNavigate();
78     const selectionControls = useSelection();
79     const { viewportWidth } = useActiveBreakpoint();
81     const { layout, items, sortParams, setSorting, isLoading } = searchView;
83     const selectedItems = useMemo(
84         () => getSelectedItems(items, selectionControls!.selectedItemIds),
85         [items, selectionControls!.selectedItemIds]
86     );
88     // We consider that search is limited to items you own for now
89     const browserItems: SearchItem[] = items.map((item) => ({ ...item, id: item.linkId, isAdmin: true }));
90     const { getDragMoveControls } = useDriveDragMove(shareId, browserItems, selectionControls!.clearSelections);
92     /* eslint-disable react/display-name */
93     const GridHeaderComponent = useMemo(
94         () =>
95             ({ scrollAreaRef }: { scrollAreaRef: React.RefObject<HTMLDivElement> }) => {
96                 const activeSortingText = translateSortField(sortParams.sortField);
97                 return (
98                     <GridHeader
99                         isLoading={isLoading}
100                         sortFields={SORT_FIELDS}
101                         onSort={setSorting}
102                         sortField={sortParams.sortField}
103                         sortOrder={sortParams.sortOrder}
104                         itemCount={browserItems.length}
105                         scrollAreaRef={scrollAreaRef}
106                         activeSortingText={activeSortingText}
107                     />
108                 );
109             },
110         [sortParams.sortField, sortParams.sortOrder, isLoading]
111     );
113     const handleItemRender = (item: SearchItem) => {
114         if (item.hasThumbnail && item.activeRevision && !item.cachedThumbnailUrl) {
115             thumbnails.addToDownloadQueue(item.rootShareId, item.id, item.activeRevision.id);
116         }
117     };
119     const handleClick = useCallback(
120         (id: BrowserItemId) => {
121             const item = browserItems.find((item) => item.id === id);
123             if (!item) {
124                 return;
125             }
126             document.getSelection()?.removeAllRanges();
127             navigateToLink(shareId, item.linkId, item.isFile);
128         },
129         [navigateToLink, shareId, browserItems]
130     );
132     const Cells = viewportWidth['>=large'] ? largeScreenCells : smallScreenCells;
133     const headerItems = viewportWidth['>=large'] ? headerItemsLargeScreen : headerItemsSmallScreen;
135     if (!items.length && !isLoading) {
136         return <NoSearchResultsView />;
137     }
138     return (
139         <>
140             <SearchItemContextMenu
141                 permissions={SHARE_MEMBER_PERMISSIONS.OWNER} // TODO: Permissions is not supported on search for now
142                 shareId={shareId}
143                 selectedLinks={selectedItems}
144                 anchorRef={contextMenuAnchorRef}
145                 close={browserItemContextMenu.close}
146                 isOpen={browserItemContextMenu.isOpen}
147                 open={browserItemContextMenu.open}
148                 position={browserItemContextMenu.position}
149             />
150             <FileBrowser
151                 // data
152                 caption={c('Title').t`Search results`}
153                 headerItems={headerItems}
154                 items={browserItems}
155                 layout={layout}
156                 loading={isLoading}
157                 sortParams={sortParams}
158                 // components
159                 Cells={Cells}
160                 GridHeaderComponent={GridHeaderComponent}
161                 GridViewItem={GridViewItem}
162                 // handlers
163                 onItemOpen={handleClick}
164                 contextMenuAnchorRef={contextMenuAnchorRef}
165                 onItemContextMenu={browserItemContextMenu.handleContextMenu}
166                 onItemRender={handleItemRender}
167                 onSort={setSorting}
168                 onScroll={browserItemContextMenu.close}
169                 getDragMoveControls={getDragMoveControls}
170             />
171         </>
172     );