bedc59059451dbf46f896c864ed8ad877083a39a
[arvados-workbench2.git] / src / views-components / context-menu / actions / file-viewer-actions.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from "react";
6 import { ListItemText, ListItem, ListItemIcon, Icon } from "@material-ui/core";
7 import { RootState } from '~/store/store';
8 import { getNodeValue } from '~/models/tree';
9 import { CollectionDirectory, CollectionFile, CollectionFileType } from '~/models/collection-file';
10 import { FileViewerList, FileViewer } from '~/models/file-viewers-config';
11 import { getFileViewers } from '~/store/file-viewers/file-viewers-selectors';
12 import { connect } from 'react-redux';
13
14 interface FileViewerActionProps {
15     fileUrl: string;
16     viewers: FileViewerList;
17 }
18
19 const mapStateToProps = (state: RootState): FileViewerActionProps => {
20     const { resource } = state.contextMenu;
21     if (resource) {
22         const file = getNodeValue(resource.uuid)(state.collectionPanelFiles);
23         if (file) {
24             const fileViewers = getFileViewers(state.properties);
25             return {
26                 fileUrl: file.url,
27                 viewers: fileViewers.filter(enabledViewers(file)),
28             };
29         }
30     }
31     return {
32         fileUrl: '',
33         viewers: [],
34     };
35 };
36
37 const enabledViewers = (file: CollectionFile | CollectionDirectory) =>
38     ({ extensions, collections }: FileViewer) => {
39         if (collections && file.type === CollectionFileType.DIRECTORY) {
40             return true;
41         } else if (extensions) {
42             return extensions.some(extension => file.name.endsWith(extension));
43         } else {
44             return true;
45         }
46     };
47
48 const fillViewerUrl = (fileUrl: string, { url, filePathParam }: FileViewer) => {
49     const viewerUrl = new URL(url);
50     viewerUrl.searchParams.append(filePathParam, fileUrl);
51     return viewerUrl.href;
52 };
53
54 export const FileViewerActions = connect(mapStateToProps)(
55     ({ fileUrl, viewers, onClick }: FileViewerActionProps & { onClick: () => void }) =>
56         <>
57             {viewers.map(viewer =>
58                 <a
59                     key={viewer.name}
60                     style={{ textDecoration: 'none' }}
61                     href={fillViewerUrl(fileUrl, viewer)}
62                     onClick={onClick}
63                     target='_blank'>
64                     <ListItem button>
65                         <ListItemIcon>
66                             <Icon />
67                         </ListItemIcon>
68                         <ListItemText>
69                             {viewer.name}
70                         </ListItemText>
71                     </ListItem>
72                 </a>
73             )}
74         </>);