|
|
@@ -0,0 +1,113 @@
|
|
|
+<!--
|
|
|
+Wrapper to allow an UI element to trigger a file download
|
|
|
+
|
|
|
+The only required property is the File entity to download. It has to be in READY state.
|
|
|
+Trigger the download by calling `scope.download` on the event you like.
|
|
|
+If you want to display a loading animation while the download request is submitted, you can achieve this with `scope.downloading`
|
|
|
+
|
|
|
+Usage (default button) :
|
|
|
+
|
|
|
+ <UiDownloader :file="file"></UiDownloader>
|
|
|
+
|
|
|
+Usage (custom button) :
|
|
|
+
|
|
|
+ <UiDownloader :file="file" v-slot="scope">
|
|
|
+ <v-btn color="primary" :loading="scope.downloading" @click="scope.download">
|
|
|
+ {{ $t('download') }}
|
|
|
+ </v-btn>
|
|
|
+ </UiDownloader>
|
|
|
+-->
|
|
|
+
|
|
|
+<template>
|
|
|
+<!-- <div @download="download(file)">-->
|
|
|
+ <div>
|
|
|
+ <slot :download="download" :downloading="downloading">
|
|
|
+ <v-btn :loading="downloading" :disabled="downloading" @click="download">
|
|
|
+ {{ $t('download') }}
|
|
|
+ </v-btn>
|
|
|
+ </slot>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts">
|
|
|
+
|
|
|
+import {defineComponent, ref, Ref, useContext} from "@nuxtjs/composition-api";
|
|
|
+import {QUERY_TYPE} from "~/types/enums";
|
|
|
+import {DataProviderArgs} from "~/types/interfaces";
|
|
|
+import {File} from "~/models/Core/File";
|
|
|
+import {Bool} from "@vuex-orm/core";
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ props: {
|
|
|
+ file: {
|
|
|
+ type: File,
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ target: {
|
|
|
+ type: String,
|
|
|
+ required: false,
|
|
|
+ default: '_blank'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setup (props) {
|
|
|
+
|
|
|
+ const { $dataProvider } = useContext()
|
|
|
+
|
|
|
+ let { file, target } = props
|
|
|
+ let downloading: Ref<Boolean> = ref(false)
|
|
|
+
|
|
|
+ const download = async () => {
|
|
|
+ if (!file) {
|
|
|
+ console.error("File is not defined yet, impossible to download")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (file.status === 'PENDING') {
|
|
|
+ console.error("File is not ready yet, impossible to download")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (file.status === 'ERROR') {
|
|
|
+ console.error("An error occurred wilie generating the file, impossible to download")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (file.status !== 'READY') {
|
|
|
+ console.error("File status is not correctly defined")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (downloading.value) {
|
|
|
+ console.error("A download request is already being processed")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ downloading.value = true
|
|
|
+
|
|
|
+ const response = await $dataProvider.invoke(
|
|
|
+ {
|
|
|
+ type: QUERY_TYPE.FILE,
|
|
|
+ fileArgs: { fileId: file.id }
|
|
|
+ } as DataProviderArgs
|
|
|
+ )
|
|
|
+
|
|
|
+ downloading.value = false
|
|
|
+
|
|
|
+ const blob = new Blob([response.data], { type: response.data.type })
|
|
|
+
|
|
|
+ const url = window.URL.createObjectURL(blob)
|
|
|
+
|
|
|
+ const link = document.createElement('a')
|
|
|
+ link.href = url
|
|
|
+ link.download = file.name ?? 'document'
|
|
|
+ link.target = target
|
|
|
+ link.click()
|
|
|
+
|
|
|
+ link.remove()
|
|
|
+ window.URL.revokeObjectURL(url)
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ download: () => download(),
|
|
|
+ downloading
|
|
|
+ }
|
|
|
+ }
|
|
|
+})
|
|
|
+</script>
|