[ARVADOS-WORKBENCH2] created: 2.1.0-284-g37f3a8d7

Git user git at public.arvados.org
Mon Apr 12 08:16:08 UTC 2021


        at  37f3a8d7a7ce05a15fbb9219763b46ba1c250976 (commit)


commit 37f3a8d7a7ce05a15fbb9219763b46ba1c250976
Author: Daniel Kutyła <daniel.kutyla at contractors.roche.com>
Date:   Mon Apr 12 10:13:41 2021 +0200

    17415: Created mountainduck bookmark files generator
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła <daniel.kutyla at contractors.roche.com>

diff --git a/cypress.json b/cypress.json
index ebe064ea..47f77ede 100644
--- a/cypress.json
+++ b/cypress.json
@@ -2,5 +2,6 @@
     "baseUrl": "https://localhost:3000/",
     "chromeWebSecurity": false,
     "viewportWidth": 1920,
-    "viewportHeight": 1080
+    "viewportHeight": 1080,
+    "downloadsFolder": "cypress/downloads"
 }
diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js
index 841197ab..f5f44b85 100644
--- a/cypress/integration/collection.spec.js
+++ b/cypress/integration/collection.spec.js
@@ -2,9 +2,12 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
+const path = require('path');
+
 describe('Collection panel tests', function () {
     let activeUser;
     let adminUser;
+    let downloadsFolder;
 
     before(function () {
         // Only set up common users once. These aren't set up as aliases because
@@ -21,6 +24,7 @@ describe('Collection panel tests', function () {
                 activeUser = this.activeUser;
             }
             );
+        downloadsFolder = Cypress.config('downloadsFolder');
     });
 
     beforeEach(function () {
@@ -28,6 +32,28 @@ describe('Collection panel tests', function () {
         cy.clearLocalStorage();
     });
 
+    it.only('allows to download mountain duck config for a collection', () => {
+        cy.createCollection(adminUser.token, {
+            name: `Test collection ${Math.floor(Math.random() * 999999)}`,
+            owner_uuid: activeUser.user.uuid,
+            manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"
+        })
+        .as('testCollection').then(function (testCollection) {
+            cy.loginAs(activeUser);
+            cy.doSearch(`${testCollection.uuid}`);
+
+            cy.get('[data-cy=collection-panel-options-btn]').click();
+            cy.get('[data-cy=context-menu]').contains('Open as network folder or S3 bucket').click();
+            cy.get('[data-cy=download-button').click();
+
+            const filename = path.join(downloadsFolder, `${testCollection.name}.duck`)
+
+            cy.readFile(filename, { timeout: 15000 })
+                .should('have.length.gt', 50)
+                .then(() => cy.task('clearDownload', { filename }));
+        });
+    });
+
     it('uses the property editor with vocabulary terms', function () {
         cy.createCollection(adminUser.token, {
             name: `Test collection ${Math.floor(Math.random() * 999999)}`,
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
index b11d5528..67262bcb 100644
--- a/cypress/plugins/index.js
+++ b/cypress/plugins/index.js
@@ -16,10 +16,29 @@
 // This function is called when a project is opened or re-opened (e.g. due to
 // the project's config changing)
 
+const fs = require('fs');
+const path = require('path');
+
 /**
  * @type {Cypress.PluginConfig}
  */
 module.exports = (on, config) => {
   // `on` is used to hook into various events Cypress emits
   // `config` is the resolved Cypress config
+  on("before:browser:launch", (browser = {}, launchOptions) => {
+    const downloadDirectory = path.join(__dirname, "..", "downloads");
+    if (browser.family === "chromium") {
+     launchOptions.preferences.default["download"] = {
+      default_directory: downloadDirectory
+     };
+    }
+    return launchOptions;
+  });
+
+  on('task', {
+    clearDownload({ filename }) {
+      fs.unlinkSync(filename);
+      return null;
+    }
+  });
 }
diff --git a/src/store/collections/collection-info-actions.ts b/src/store/collections/collection-info-actions.ts
index 29dc6b87..d874c322 100644
--- a/src/store/collections/collection-info-actions.ts
+++ b/src/store/collections/collection-info-actions.ts
@@ -18,6 +18,7 @@ export interface WebDavS3InfoDialogData {
     localCluster: string;
     username: string;
     activeTab: number;
+    collectionName?: string;
     setActiveTab: (event: any, tabNr: number) => void;
 }
 
@@ -34,6 +35,7 @@ export const openWebDavS3InfoDialog = (uuid: string, activeTab?: number) =>
                 localCluster: getState().auth.localCluster,
                 username: getState().auth.user!.username,
                 activeTab: activeTab || 0,
+                collectionName: (getState().collectionPanel.item || {} as any).name,
                 setActiveTab: (event: any, tabNr: number) => dispatch<any>(openWebDavS3InfoDialog(uuid, tabNr)),
                 uuid
             }
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index 018a0ef0..6e5c7c0f 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -9,13 +9,17 @@ import { COLLECTION_WEBDAV_S3_DIALOG_NAME, WebDavS3InfoDialogData } from '~/stor
 import { WithDialogProps } from '~/store/dialog/with-dialog';
 import { compose } from 'redux';
 import { DetailsAttribute } from "~/components/details-attribute/details-attribute";
+import { DownloadIcon } from "~/components/icon/icon";
 
-export type CssRules = 'details';
+export type CssRules = 'details' | 'downloadButton';
 
 const styles: StyleRulesCallback<CssRules> = theme => ({
     details: {
         marginLeft: theme.spacing.unit * 3,
         marginRight: theme.spacing.unit * 3,
+    },
+    downloadButton: {
+        marginTop: theme.spacing.unit * 2,
     }
 });
 
@@ -40,6 +44,46 @@ function TabPanel(props: TabPanelData) {
     );
 }
 
+const mountainduckTemplate = ({
+    uuid, 
+    username,
+    collectionsUrl,
+}: any) => `<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+   <dict>
+      <key>Protocol</key>
+      <string>davs</string>
+      <key>Provider</key>
+      <string>iterate GmbH</string>
+      <key>UUID</key>
+      <string>${uuid}</string>
+      <key>Hostname</key>
+      <string>${collectionsUrl.replace('https://', `davs://${username}@`).replace('*', uuid)}</string>
+      <key>Port</key>
+      <string>443</string>
+      <key>Username</key>
+      <string>${username}</string>
+      <key>Labels</key>
+      <array>
+      </array>
+   </dict>
+</plist>
+`.split(/\r?\n/).join('\n');
+
+const downloadMountainduckFileHandler = (filename: string, text: string) => {
+    const element = document.createElement('a');
+    element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
+    element.setAttribute('download', filename);
+  
+    element.style.display = 'none';
+    document.body.appendChild(element);
+  
+    element.click();
+  
+    document.body.removeChild(element);
+};
+
 export const WebDavS3InfoDialog = compose(
     withDialog(COLLECTION_WEBDAV_S3_DIALOG_NAME),
     withStyles(styles),
@@ -146,6 +190,17 @@ export const WebDavS3InfoDialog = compose(
                         value={props.data.token}
                         copyValue={props.data.token} />
 
+                    <Button
+                        data-cy='download-button'
+                        className={props.classes.downloadButton}
+                        onClick={() => downloadMountainduckFileHandler(`${props.data.collectionName || props.data.uuid}.duck`, mountainduckTemplate(props.data))}
+                        variant='contained'
+                        color='primary'
+                        size='small'>
+                        <DownloadIcon />
+                        Download config
+                    </Button>
+
                     <h3>Gnome</h3>
                     <ol>
                         <li>Open Files</li>

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list