diff --git a/dbrepo-ui/api/query.service.js b/dbrepo-ui/api/query.service.js index 1e467a567411736b37be0787a67e74b855659983..09db2312e76e49ebf8cdf11f40a2fa2664c4fdb4 100644 --- a/dbrepo-ui/api/query.service.js +++ b/dbrepo-ui/api/query.service.js @@ -117,7 +117,7 @@ class QueryService { exportSubset (id, databaseId, queryId) { return new Promise((resolve, reject) => { - api.put(`/api/container/${id}/database/${databaseId}/query/${queryId}/export`, {}, { headers: { Accept: 'text/csv' } }) + api.get(`/api/container/${id}/database/${databaseId}/query/${queryId}/export`, { headers: { Accept: 'text/csv' } }) .then((response) => { resolve(response.data) }) diff --git a/dbrepo-ui/components/DBToolbar.vue b/dbrepo-ui/components/DBToolbar.vue index d21a911bbbd1d59449bf247dcd5702e349911d1d..e544e3f3570548e986dd5ba07516c28681f49fd5 100644 --- a/dbrepo-ui/components/DBToolbar.vue +++ b/dbrepo-ui/components/DBToolbar.vue @@ -31,6 +31,12 @@ <v-btn v-if="canImportCsv" class="mr-2 mb-1" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/table/import`"> <v-icon left>mdi-cloud-upload</v-icon> Import .csv </v-btn> + <DownloadButton + v-if="database?.identifier" + :pid="database.identifier.id" + class="mr-2 mb-1"> + <v-icon left>mdi-code-tags</v-icon> Identifier .xml + </DownloadButton> <v-btn v-if="canCreateSubset" color="secondary" class="mb-1 white--text" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/query/create`"> <v-icon left>mdi-wrench</v-icon> Create Subset </v-btn> @@ -65,7 +71,10 @@ </template> <script> +import DownloadButton from '@/components/identifier/DownloadButton' + export default { + components: { DownloadButton }, data () { return { tab: null, @@ -117,20 +126,6 @@ export default { return false } return this.database.owner.username === this.user.username - }, - config () { - if (this.token === null) { - return {} - } - return { - headers: { Authorization: `Bearer ${this.token}` } - } - }, - silentConfig () { - return { - headers: this.config.headers, - progress: false - } } } } diff --git a/dbrepo-ui/components/identifier/DownloadButton.vue b/dbrepo-ui/components/identifier/DownloadButton.vue new file mode 100644 index 0000000000000000000000000000000000000000..0ccc07b8afc299d1f1626ddc0ed74e24bd7f49b4 --- /dev/null +++ b/dbrepo-ui/components/identifier/DownloadButton.vue @@ -0,0 +1,78 @@ +<template> + <v-btn + :loading="loading" + v-bind="$attrs" + @click.stop="download"> + <slot /> + </v-btn> +</template> + +<script> + +export default { + props: { + pid: { + type: Number, + default () { + return null + } + }, + contentType: { + type: String, + default () { + return 'text/xml' + } + }, + filename: { + type: String, + default () { + return 'identifier.xml' + } + } + }, + data () { + return { + loading: false + } + }, + computed: { + token () { + return this.$store.state.token + }, + config () { + if (this.token === null) { + return { + headers: { Accept: 'application/json' } + } + } + return { + headers: { Authorization: `Bearer ${this.token}`, Accept: 'application/json' } + } + } + }, + methods: { + async download () { + this.loading = true + try { + const config = this.config + config.headers.Accept = this.contentType + const res = await this.$axios.get(`/api/pid/${this.pid}`, config) + console.debug('export identifier', res) + const url = window.URL.createObjectURL(new Blob([res.data])) + const link = document.createElement('a') + link.href = url + link.setAttribute('download', this.filename) + document.body.appendChild(link) + link.click() + } catch (err) { + console.error('Could not export identifier', err) + this.$toast.error('Could not export identifier') + this.error = true + } + this.loading = false + } + } +} +</script> +<style scoped> +</style> diff --git a/dbrepo-ui/layouts/default.vue b/dbrepo-ui/layouts/default.vue index 3bc83a2315d49e842b46f759774a0a47599b7161..6c32c271c6cb43916edf25eb1338d0321d547d30 100644 --- a/dbrepo-ui/layouts/default.vue +++ b/dbrepo-ui/layouts/default.vue @@ -85,7 +85,7 @@ </template> <v-list> <v-list-item - v-for="locale in availableLocales" + v-for="locale in []" :key="locale.code" :to="switchLocalePath(locale.code)"> <v-list-item-title>{{ locale.name }}</v-list-item-title> diff --git a/dbrepo-ui/locales/de-DE.json b/dbrepo-ui/locales/de-DE.json index dc46ab160a0ea054e0398c438f21a6a7e4d9f0bf..1c9b4783e25a90dce3d1387d43cb9392612de202 100644 --- a/dbrepo-ui/locales/de-DE.json +++ b/dbrepo-ui/locales/de-DE.json @@ -8,7 +8,7 @@ "signup": "Registrieren" }, "databases": { - "recent": "Kürzliche Datenbanken", + "recent": "Neue Datenbanken", "tooltip": { "private": "Privat", "public": "Öffentlich" diff --git a/dbrepo-ui/pages/container/_container_id/database/_database_id/info.vue b/dbrepo-ui/pages/container/_container_id/database/_database_id/info.vue index 63784829417240bc3a69b2264213198044060dff..dd4a71e482aa248464033918fdbec02b6b2f62bc 100644 --- a/dbrepo-ui/pages/container/_container_id/database/_database_id/info.vue +++ b/dbrepo-ui/pages/container/_container_id/database/_database_id/info.vue @@ -245,7 +245,6 @@ export default { loading: false, loadingDelete: false, editDbDialog: false, - metadataLoading: false, items: [ { text: 'Databases', to: '/container', activeClass: '' }, { @@ -386,26 +385,6 @@ export default { this.editDbDialog = false this.editVisibilityDialog = false }, - async download () { - this.metadataLoading = true - try { - const config = this.config - config.headers.Accept = 'text/xml' - const res = await this.$axios.get(`/api/pid/${this.database.identifier.id}`, config) - console.debug('export identifier', res) - const url = window.URL.createObjectURL(new Blob([res.data])) - const link = document.createElement('a') - link.href = url - link.setAttribute('download', 'identifier.xml') - document.body.appendChild(link) - link.click() - } catch (err) { - console.error('Could not export identifier', err) - this.$toast.error('Could not export identifier') - this.error = true - } - this.metadataLoading = false - }, async deleteIdentifier () { if (!this.database.identifier.id) { return diff --git a/dbrepo-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue b/dbrepo-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue index 02bb472500ae4443a906eed98baa2522af925bc6..e7cac6601311c7bf3711b7e26efef2c6333f615e 100644 --- a/dbrepo-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue +++ b/dbrepo-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue @@ -11,71 +11,25 @@ </v-toolbar-title> <v-spacer /> <v-toolbar-title> - <v-btn v-if="!query.is_persisted && canWrite" :loading="loadingSave" class="mb-1 mr-2" @click.stop="save"> + <v-btn v-if="!loadingQuery && !query.is_persisted && canWrite" :loading="loadingSave" class="mb-1" @click.stop="save"> <v-icon left>mdi-content-save-outline</v-icon> Save </v-btn> - <v-btn v-if="query.is_persisted && !query.identifier && canWrite" class="mb-1 mr-2" color="primary" :disabled="!executionUTC" @click.stop="openDialog()"> + <v-btn v-if="query.is_persisted && !query.identifier && canWrite" class="mb-1 ml-2" color="primary" :disabled="!executionUTC" @click.stop="openDialog()"> <v-icon left>mdi-content-save-outline</v-icon> Get PID </v-btn> - <v-btn v-if="result_visibility && !query.identifier && query.result_number" class="mb-1" :loading="downloadLoading" @click.stop="downloadSubset"> + <v-btn v-if="result_visibility && query.result_number" class="mb-1 ml-2" :loading="downloadLoading" @click.stop="downloadSubset"> <v-icon left>mdi-download</v-icon> Data .csv </v-btn> - <v-btn v-if="result_visibility && query.identifier && query.result_number" class="mb-1" :loading="downloadLoading" @click.stop="downloadMetadata('text/csv')"> - <v-icon left>mdi-download</v-icon> Data .csv - </v-btn> - <v-btn - v-if="query.identifier" - color="secondary" - class="ml-2" - :loading="metadataLoading" - @click.stop="downloadMetadata('text/xml')"> - <v-icon left>mdi-code-tags</v-icon> Metadata .xml - </v-btn> + <DownloadButton v-if="query.identifier" :pid="query.identifier.id" class="mb-1 ml-2"> + <v-icon left>mdi-code-tags</v-icon> Identifier .xml + </DownloadButton> </v-toolbar-title> </v-toolbar> - <v-card flat tile> - <v-card-title> - Subset Information - </v-card-title> + <v-card v-if="query && query.identifier" flat tile> + <v-card-title>Identifier</v-card-title> <v-card-text> - <v-alert - v-if="!loadingQuery && !query.is_persisted && canWrite" - border="left" - color="info"> - Query is not yet saved in the query store, <a @click="save">save</a> it to view it later. - </v-alert> <v-list dense> <v-list-item> - <v-list-item-icon> - <v-icon v-if="!database">mdi-database-outline</v-icon> - <v-icon v-if="database" :color="database.is_public ? 'success' : 'error'">mdi-database-outline</v-icon> - </v-list-item-icon> - <v-list-item-content> - <v-list-item-title> - Database Visibility - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="!database" type="text" class="skeleton-small" /> - <span v-if="database">{{ database.is_public ? 'Public' : 'Private' }}</span> - </v-list-item-content> - <v-list-item-title class="mt-2"> - Database Name - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="!database" type="text" class="skeleton-small" /> - <span v-if="database">{{ database.name }}</span> - </v-list-item-content> - <div v-if="database && database.identifier"> - <v-list-item-title class="mt-2"> - Database License - </v-list-item-title> - <v-list-item-content> - <a :href="database.identifier.license.uri">{{ database.identifier.license.identifier }}</a> - </v-list-item-content> - </div> - </v-list-item-content> - </v-list-item> - <v-list-item v-if="query && query.identifier"> <v-list-item-icon> <v-icon>mdi-lock-clock</v-icon> </v-list-item-icon> @@ -140,6 +94,52 @@ <Citation :pid="pid" /> </v-list-item-content> </v-list-item> + </v-list> + </v-card-text> + </v-card> + <v-divider v-if="query && query.identifier" /> + <v-card flat tile> + <v-card-title> + Subset Information + </v-card-title> + <v-card-text> + <v-alert + v-if="!loadingQuery && !query.is_persisted && canWrite" + border="left" + color="info"> + Query is not yet saved in the query store, <a @click="save">save</a> it to view it later. + </v-alert> + <v-list dense> + <v-list-item> + <v-list-item-icon> + <v-icon v-if="!database">mdi-database-outline</v-icon> + <v-icon v-if="database" :color="database.is_public ? 'success' : 'error'">mdi-database-outline</v-icon> + </v-list-item-icon> + <v-list-item-content> + <v-list-item-title> + Database Visibility + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="!database" type="text" class="skeleton-small" /> + <span v-if="database">{{ database.is_public ? 'Public' : 'Private' }}</span> + </v-list-item-content> + <v-list-item-title class="mt-2"> + Database Name + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="!database" type="text" class="skeleton-small" /> + <span v-if="database">{{ database.name }}</span> + </v-list-item-content> + <div v-if="database && database.identifier"> + <v-list-item-title class="mt-2"> + Database License + </v-list-item-title> + <v-list-item-content> + <a :href="database.identifier.license.uri">{{ database.identifier.license.identifier }}</a> + </v-list-item-content> + </div> + </v-list-item-content> + </v-list-item> <v-list-item> <v-list-item-icon> <v-icon>mdi-text-short</v-icon> @@ -202,6 +202,7 @@ </v-list> </v-card-text> </v-card> + <v-divider /> <QueryResults id="query-results" ref="queryResults" @@ -221,6 +222,7 @@ import Persist from '@/components/dialogs/Persist' import Citation from '@/components/identifier/Citation' import Banner from '@/components/identifier/Banner' +import DownloadButton from '@/components/identifier/DownloadButton' import { formatTimestampUTCLabel, formatDateUTC } from '@/utils' import QueryService from '@/api/query.service' @@ -229,7 +231,8 @@ export default { components: { Persist, Citation, - Banner + Banner, + DownloadButton }, data () { return { @@ -262,7 +265,6 @@ export default { loadingDatabase: false, loadingIdentifier: false, loadingQuery: true, - metadataLoading: false, downloadLoading: false, error: false, promises: [] @@ -375,30 +377,6 @@ export default { this.$refs.queryResults.reExecute(this.query.id) this.$refs.queryResults.reExecuteCount(this.query.id) }, - downloadMetadata (mime) { - if (mime === 'text/csv') { - this.downloadLoading = true - } else if (mime === 'text/xml') { - this.metadataLoading = true - } - QueryService.exportMetadata(this.query.identifier.id, mime) - .then((metadata) => { - const url = window.URL.createObjectURL(new Blob([metadata])) - const link = document.createElement('a') - link.href = url - if (mime === 'text/csv') { - link.setAttribute('download', 'subset.csv') - } else if (mime === 'text/xml') { - link.setAttribute('download', 'identifier.xml') - } - document.body.appendChild(link) - link.click() - }) - .finally(() => { - this.downloadLoading = false - this.metadataLoading = false - }) - }, downloadSubset () { this.downloadLoading = true QueryService.exportSubset(this.$route.params.container_id, this.$route.params.database_id, this.$route.params.query_id)