Skip to content
This repository has been archived by the owner on Feb 23, 2022. It is now read-only.

Commit

Permalink
Merge pull request #331 from multinet-app/add_downloader_ui
Browse files Browse the repository at this point in the history
Add Downloader UI
  • Loading branch information
jjnesbitt committed Mar 3, 2020
2 parents b1a3f84 + 021d597 commit c7ef021
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 26 deletions.
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"axios": "^0.18.1",
"core-js": "^2.6.5",
"material-design-icons-iconfont": "^5.0.1",
"multinet": "0.8.0",
"multinet": "0.9.0",
"vue": "^2.6.10",
"vue-gtag": "^1.2.1",
"vue-router": "^3.0.2",
Expand Down
171 changes: 171 additions & 0 deletions client/src/components/DownloadDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<template>

<v-dialog
v-model="dialog"
width="400"
v-if="nonZeroSelection"
>
<template v-slot:activator="{ on: dialog }">
<v-tooltip left>
<template v-slot:activator="{ on: tooltip }">
<v-scroll-x-transition>
<v-btn
icon
small
text
@click="dialog.click"
v-on="tooltip"
>
<v-icon color="primary" size="22px">save_alt</v-icon>
</v-btn>
</v-scroll-x-transition>
</template>
<span>Download selected</span>
</v-tooltip>
</template>

<v-card class="pa-0">
<v-card-title
class="pa-4"
primary-title
>
Download the following {{ selection.length > 1 ? selection.length : '' }} {{downloadType}}{{plural}}?
</v-card-title>

<v-card-text class="pa-0">
<v-list
class="pa-0"
color="grey lighten-5"
dense
>
<template v-for="item in selection">
<v-divider />
<v-list-item :key="item">
<v-list-item-icon>
<v-icon
color="green accent-4"
size="18"
>
check
</v-icon>
</v-list-item-icon>
{{ item }}
</v-list-item>
</template>

</v-list>
</v-card-text>

<v-divider />
<v-progress-linear indeterminate :active="loading" />

<v-card-actions class="px-4 py-3">
<v-spacer />
<v-btn
depressed
color="primary"
@click="execute"
:disabled="disabled"
>
yes
</v-btn>

<v-btn
depressed
@click="dialog = false"
>
cancel
</v-btn>
</v-card-actions>

</v-card>

</v-dialog>

</template>

<script lang="ts">
import Vue, { PropType } from 'vue';
import api from '@/api';
export default Vue.extend({
props: {
selection: {
type: Array as PropType<string[]>,
required: true,
},
workspace: {
type: String as PropType<string>,
required: true,
},
downloadType: {
type: String as PropType<string>,
required: true,
},
},
data() {
return {
dialog: false,
disabled: false,
timeout: undefined as number | undefined,
loading: false,
};
},
computed: {
// This workaround is necessary because of https://github.com/vuejs/vue/issues/10455
plural(this: any) {
return this.selection.length > 1 ? 's' : '';
},
nonZeroSelection(): boolean {
return this.selection.length > 0;
},
downloadEnpoint() {
switch (this.downloadType) {
case 'table':
return api.downloadTable.bind(api);
break;
case 'network':
default:
return api.downloadGraph.bind(api);
break;
}
},
},
methods: {
async execute() {
const {
selection,
workspace,
} = this;
this.loading = true;
for (const name of selection) {
const { data, headers: {'content-type': contentType } } = await this.downloadEnpoint(workspace, name);
const blobData = data instanceof Object ? JSON.stringify(data, null, 2) : data;
const blob = new Blob([blobData], {type: contentType});
const extension = contentType.split('/')[1];
const filename = `${name}.${extension}`;
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
URL.revokeObjectURL(link.href);
}
this.$emit('downloaded');
this.loading = false;
this.dialog = false;
},
},
});
</script>
9 changes: 7 additions & 2 deletions client/src/components/ItemPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@

<v-spacer />

<slot name="downloader"
:selection="selection"
:workspace="workspace"
>
</slot>
<slot name="deleter"
:selection="selection"
:workspace="workspace"
:selection="selection"
:workspace="workspace"
>
</slot>

Expand Down
52 changes: 34 additions & 18 deletions client/src/views/WorkspaceDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,29 @@
:workspace="workspace"
route-type="graph"
icon="timeline"
>
<graph-dialog
:node-tables="nodeTables"
:edge-tables="edgeTables"
:workspace="workspace"
@success="update"
/>
<template v-slot:deleter="deleter">
<delete-graph-dialog
:selection="deleter.selection"
:workspace="deleter.workspace"
@deleted="update"
/>
</template>
>
<graph-dialog
:node-tables="nodeTables"
:edge-tables="edgeTables"
:workspace="workspace"
@success="update"
/>
<template v-slot:deleter="deleter">
<delete-graph-dialog
:selection="deleter.selection"
:workspace="deleter.workspace"
@deleted="update"
/>
</template>
<template v-slot:downloader="downloader">
<download-dialog
:selection="downloader.selection"
:workspace="downloader.workspace"
downloadType="network"
@downloaded="update"
/>
</template>
</item-panel>

</v-card>
</v-flex>
<v-flex
Expand All @@ -125,16 +132,23 @@
<table-dialog
:workspace="workspace"
@success="update"
/>
/>
<template v-slot:deleter="deleter">
<delete-table-dialog
:selection="deleter.selection"
:workspace="deleter.workspace"
@deleted="update"
/>
/>
</template>
<template v-slot:downloader="downloader">
<download-dialog
:selection="downloader.selection"
:workspace="downloader.workspace"
downloadType="table"
@downloaded="update"
/>
</template>
</item-panel>

</v-card>
</v-flex>
</v-layout>
Expand All @@ -151,6 +165,7 @@ import GraphDialog from '@/components/GraphDialog.vue';
import DeleteGraphDialog from '@/components/DeleteGraphDialog.vue';
import TableDialog from '@/components/TableDialog.vue';
import DeleteTableDialog from '@/components/DeleteTableDialog.vue';
import DownloadDialog from '@/components/DownloadDialog.vue';
export default Vue.extend({
name: 'WorkspaceDetail',
Expand All @@ -160,6 +175,7 @@ export default Vue.extend({
DeleteGraphDialog,
TableDialog,
DeleteTableDialog,
DownloadDialog,
},
props: ['workspace', 'title'],
data() {
Expand Down
8 changes: 4 additions & 4 deletions client/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5517,10 +5517,10 @@ multimatch@^2.1.0:
arrify "^1.0.0"
minimatch "^3.0.0"

multinet@0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.8.0.tgz#fcff1df77c8699519e83d49b717fdb356ab7fb91"
integrity sha512-sIx4mu++zKm6xV0gmLcTBTamP+xwp7VTOCjUP5plHIRzaMEfl9twTZbAOBKF8HLz0LK8Mo2ytBPLN0fNnJhOEQ==
multinet@0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.9.0.tgz#ee9737d5c1ab07c8de32eee1cae3203bc9edec7b"
integrity sha512-w0TjW+c84692tYK0DmwjqP+KlbyjtiDWtZXKCQ7w9KhVow5GHJTckh8QWK+opZAMmLHjlQIKjVEgs7FLp7QB0Q==
dependencies:
axios "^0.19.0"

Expand Down
2 changes: 1 addition & 1 deletion multinetjs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "multinet",
"version": "0.8.0",
"version": "0.9.0",
"description": "Multinet client library",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
4 changes: 4 additions & 0 deletions multinetjs/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export class Client {
});
}

public raw_get(path: string, params: {} = {}): Promise<any> {
return this.axios.get(path, { params });
}

public post(path: string, params: {} = {}, headers: {} = {}): Promise<any> {
return new Promise((resolve, reject) => {
this.axios.post(path, params, { headers, })
Expand Down
9 changes: 9 additions & 0 deletions multinetjs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ class MultinetAPI {
});
}

public async downloadTable(workspace: string, table: string): Promise<any> {
return await this.client.raw_get(`/workspaces/${workspace}/tables/${table}/download`);
}

public deleteTable(workspace: string, table: string): Promise<string> {
return this.client.delete(`/workspaces/${workspace}/tables/${table}`);
}
Expand All @@ -163,6 +167,11 @@ class MultinetAPI {
public deleteGraph(workspace: string, graph: string): Promise<string> {
return this.client.delete(`/workspaces/${workspace}/graphs/${graph}`);
}

public async downloadGraph(workspace: string, graph: string): Promise<any> {
return await this.client.raw_get(`/workspaces/${workspace}/graphs/${graph}/download`);
}

}

export function multinetApi(baseURL: string): MultinetAPI {
Expand Down

0 comments on commit c7ef021

Please sign in to comment.