Implement single file download action
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Fri, 10 Aug 2018 10:35:15 +0000 (12:35 +0200)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Fri, 10 Aug 2018 10:35:15 +0000 (12:35 +0200)
Feature #13990

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

.env
src/components/context-menu/context-menu.tsx
src/views-components/context-menu/action-sets/collection-files-item-action-set.ts
src/views-components/context-menu/actions/download-action.tsx [new file with mode: 0644]
src/views-components/context-menu/actions/download-collection-file-action.tsx [new file with mode: 0644]
src/views-components/context-menu/actions/favorite-action.tsx

diff --git a/.env b/.env
index de1444c0bded77d30caae5614f392b9ba6b1fe12..df56fb28a76b3fbd7d61e647a59af98a3b2e7308 100644 (file)
--- a/.env
+++ b/.env
@@ -4,5 +4,5 @@
 
 REACT_APP_ARVADOS_CONFIG_URL=/config.json
 REACT_APP_ARVADOS_API_HOST=qr1hi.arvadosapi.com
-REACT_APP_ARVADOS_KEEP_WEB_HOST=download.qr1hi.arvadosapi.com
+REACT_APP_ARVADOS_KEEP_WEB_HOST=collections.qr1hi.arvadosapi.com
 HTTPS=true
\ No newline at end of file
index 95bbeafb4f23774c4a358b19282a60120375f751..4068251bdc04c82487cbf141fbdea910692496a8 100644 (file)
@@ -36,21 +36,23 @@ export class ContextMenu extends React.PureComponent<ContextMenuProps> {
                 {items.map((group, groupIndex) =>
                     <React.Fragment key={groupIndex}>
                         {group.map((item, actionIndex) =>
-                            <ListItem
-                                button
-                                key={actionIndex}
-                                onClick={() => onItemClick(item)}>
-                                {item.icon &&
-                                    <ListItemIcon>
-                                        <item.icon />
-                                    </ListItemIcon>}
-                                {item.name &&
-                                    <ListItemText>
-                                        {item.name}
-                                    </ListItemText>}
-                                {item.component &&
-                                    <item.component />}
-                            </ListItem>)}
+                            item.component
+                                ? <item.component
+                                    key={actionIndex}
+                                    onClick={() => onItemClick(item)} />
+                                : <ListItem
+                                    button
+                                    key={actionIndex}
+                                    onClick={() => onItemClick(item)}>
+                                    {item.icon &&
+                                        <ListItemIcon>
+                                            <item.icon />
+                                        </ListItemIcon>}
+                                    {item.name &&
+                                        <ListItemText>
+                                            {item.name}
+                                        </ListItemText>}
+                                </ListItem>)}
                         {groupIndex < items.length - 1 && <Divider />}
                     </React.Fragment>)}
             </List>
index e24108f4d88754fa30e22760e2d993cde0ae6b7f..7b03c49ade34658700f9268c4bad3fcd3f966173 100644 (file)
@@ -6,6 +6,7 @@ import { ContextMenuActionSet } from "../context-menu-action-set";
 import { RenameIcon, DownloadIcon, RemoveIcon } from "../../../components/icon/icon";
 import { openRenameFileDialog } from "../../rename-file-dialog/rename-file-dialog";
 import { openFileRemoveDialog } from "../../file-remove-dialog/file-remove-dialog";
+import { DownloadCollectionFileAction } from "../actions/download-collection-file-action";
 
 
 export const collectionFilesItemActionSet: ContextMenuActionSet = [[{
@@ -15,11 +16,8 @@ export const collectionFilesItemActionSet: ContextMenuActionSet = [[{
         dispatch<any>(openRenameFileDialog(resource.name));
     }
 }, {
-    name: "Download",
-    icon: DownloadIcon,
-    execute: (dispatch, resource) => {
-        return;
-    }
+    component: DownloadCollectionFileAction,
+    execute: () => { return; }
 }, {
     name: "Remove",
     icon: RemoveIcon,
diff --git a/src/views-components/context-menu/actions/download-action.tsx b/src/views-components/context-menu/actions/download-action.tsx
new file mode 100644 (file)
index 0000000..1f6979d
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from "react";
+import { ListItemIcon, ListItemText, Button, ListItem } from "@material-ui/core";
+import { DownloadIcon } from "../../../components/icon/icon";
+
+export const DownloadAction = (props: { href?: string, download?: string, onClick?: () => void }) => {
+    const targetProps = props.download ? {} : { target: '_blank' };
+    const downloadProps = props.download ? { download: props.download } : {};
+    return props.href
+        ? <a
+            style={{ textDecoration: 'none' }}
+            href={props.href}
+            onClick={props.onClick}
+            {...targetProps}
+            {...downloadProps}>
+            <ListItem button>
+                <ListItemIcon>
+                    <DownloadIcon />
+                </ListItemIcon>
+                <ListItemText>
+                    Download
+            </ListItemText>
+            </ListItem>
+        </a >
+        : null;
+};
\ No newline at end of file
diff --git a/src/views-components/context-menu/actions/download-collection-file-action.tsx b/src/views-components/context-menu/actions/download-collection-file-action.tsx
new file mode 100644 (file)
index 0000000..460e620
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { connect } from "react-redux";
+import { RootState } from "../../../store/store";
+import { DownloadAction } from "./download-action";
+import { getNodeValue } from "../../../models/tree";
+import { CollectionFileType } from "../../../models/collection-file";
+
+const mapStateToProps = (state: RootState) => {
+    const { resource } = state.contextMenu;
+    if (resource) {
+        const file = getNodeValue(resource.uuid)(state.collectionPanelFiles);
+        if (file) {
+            return {
+                href: file.url,
+                download: file.type === CollectionFileType.DIRECTORY ? undefined : file.name
+            };
+        }
+    }
+    return {};
+};
+
+export const DownloadCollectionFileAction = connect(mapStateToProps)(DownloadAction);
index 55fe8cfdba19efe1c42b088e7ccc87471aaea97f..06e3b5efedf1540804a42afd63c161075d9efe86 100644 (file)
@@ -3,25 +3,28 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from "react";
-import { ListItemIcon, ListItemText } from "@material-ui/core";
+import { ListItemIcon, ListItemText, ListItem } from "@material-ui/core";
 import { AddFavoriteIcon, RemoveFavoriteIcon } from "../../../components/icon/icon";
 import { connect } from "react-redux";
 import { RootState } from "../../../store/store";
 
-const mapStateToProps = (state: RootState) => ({
-    isFavorite: state.contextMenu.resource !== undefined && state.favorites[state.contextMenu.resource.uuid] === true
+const mapStateToProps = (state: RootState, props: { onClick: () => {} }) => ({
+    isFavorite: state.contextMenu.resource !== undefined && state.favorites[state.contextMenu.resource.uuid] === true,
+    onClick: props.onClick
 });
 
-export const ToggleFavoriteAction = connect(mapStateToProps)((props: { isFavorite: boolean }) =>
-    <>
+export const ToggleFavoriteAction = connect(mapStateToProps)((props: { isFavorite: boolean, onClick: () => void }) =>
+    <ListItem
+        button
+        onClick={props.onClick}>
         <ListItemIcon>
             {props.isFavorite
                 ? <RemoveFavoriteIcon />
                 : <AddFavoriteIcon />}
         </ListItemIcon>
-        <ListItemText>
+        <ListItemText style={{ textDecoration: 'none' }}>
             {props.isFavorite
                 ? <>Remove from favorites</>
                 : <>Add to favorites</>}
         </ListItemText>
-    </>);
+    </ListItem >);