Browse Source

makes cmf licences downloadable

Olivier Massot 3 years ago
parent
commit
e5e83dbf79

+ 37 - 3
pages/cmf_licence/organization.vue

@@ -25,7 +25,9 @@
           color="primary"
           :loading="pending"
           :disabled="pending"
-          :href="file ? file.url : ''">
+          target="_blank"
+          @click="download"
+        >
           {{ $t('download') }}
         </v-btn>
       </div>
@@ -37,13 +39,14 @@
 import {computed, ComputedRef, defineComponent, Ref, ref, useContext} from "@nuxtjs/composition-api";
 import {QUERY_TYPE} from "~/types/enums";
 import DataPersister from "~/services/data/dataPersister";
-import {DataPersisterArgs} from "~/types/interfaces";
+import {DataPersisterArgs, DataProviderArgs} from "~/types/interfaces";
 import { Context } from "@nuxt/types";
 import {Repository as VuexRepository} from "@vuex-orm/core/dist/src/repository/Repository";
 import {Model, Query} from "@vuex-orm/core";
 import {repositoryHelper} from "~/services/store/repository";
 import {File} from "~/models/Core/File";
 import {queryHelper} from "~/services/store/query";
+import DataProvider from "~/services/data/dataProvider";
 
 export default defineComponent({
   name: 'OrganizationCmfLicence',
@@ -86,10 +89,41 @@ export default defineComponent({
       repositoryHelper.persist(File, response.data)
     }
 
+    const download = async () => {
+
+      if (file.value === null) {
+        return
+      }
+
+      const dataProvider = new DataProvider()
+      dataProvider.initCtx(context as unknown as Context)
+
+      const response = await dataProvider.invoke(
+        {
+          type: QUERY_TYPE.FILE,
+          fileArgs: { fileId: file.value.id }
+        } as DataProviderArgs
+      )
+
+      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.value.name ?? 'unknown'
+      link.target = '_blank'
+      link.click()
+
+      link.remove()
+      window.URL.revokeObjectURL(url)
+    }
+
     return {
       submit,
       pending,
-      file
+      file,
+      download: () => download()
     }
   },
   beforeDestroy() {

+ 23 - 1
services/connection/connection.ts

@@ -1,6 +1,6 @@
 import {NuxtAxiosInstance} from '@nuxtjs/axios'
 import {AxiosRequestConfig, AxiosResponse} from 'axios'
-import {AnyJson, DataPersisterArgs, DataProviderArgs, UrlArgs} from '~/types/interfaces'
+import {AnyJson, DataPersisterArgs, DataProviderArgs, FileArgs, UrlArgs} from '~/types/interfaces'
 import {HTTP_METHOD, QUERY_TYPE} from '~/types/enums'
 import TypesTesting from "~/services/utils/typesTesting";
 
@@ -31,6 +31,9 @@ class Connection {
   public static invoke (method: HTTP_METHOD, url: string, args: UrlArgs): Promise<any> {
     switch (method) {
       case HTTP_METHOD.GET:
+        if (args.type === QUERY_TYPE.FILE) {
+          return Connection.download(url, args.showProgress, args.params)
+        }
         if (args.id) {
           return Connection.getItem(url, args.id, args.showProgress, args.params)
         } else {
@@ -100,6 +103,25 @@ class Connection {
     return Connection.request(config)
   }
 
+  /**
+   * GET dédié au téléchargement de fichiers
+   * @param url
+   * @param {number} id
+   * @param {boolean} showProgress
+   * @param {AnyJson} params
+   * @return {Promise<any>}
+   */
+  public static download (url: string, showProgress: boolean = true, params: AnyJson = {}): Promise<any> {
+    const config: AxiosRequestConfig = {
+      url: `${url}`,
+      method: HTTP_METHOD.GET,
+      progress: showProgress,
+      responseType: 'blob',
+      params: params
+    }
+    return Connection.request(config)
+  }
+
   /**
    * Post : préparation de la config pour la création d'un item
    * @param {string} url

+ 11 - 4
services/connection/urlBuilder.ts

@@ -1,5 +1,5 @@
 import {Model} from '@vuex-orm/core'
-import {ImageArgs, UrlArgs} from '~/types/interfaces'
+import {FileArgs, ImageArgs, UrlArgs} from '~/types/interfaces'
 import {QUERY_TYPE} from '~/types/enums'
 import {repositoryHelper} from '~/services/store/repository'
 import TypesTesting from "~/services/utils/typesTesting";
@@ -42,7 +42,13 @@ class UrlBuilder {
         break;
 
       case QUERY_TYPE.FILE:
-        url = UrlBuilder.getFileUrl(args.baseUrl)
+        if (!TypesTesting.isDataProviderArgs(args)) {
+          throw new Error('*args* is not a dataProviderArgs')
+        }
+        if (!args.fileArgs) {
+          throw new Error('*args* has no fileArgs')
+        }
+        url = UrlBuilder.getFileUrl(args.fileArgs, args.baseUrl)
         break;
 
       default:
@@ -120,11 +126,12 @@ class UrlBuilder {
 
   /**
    * Construction d'une URL qui ira concaténer la base URL avec le Root et l'uri files
+   * @param args
    * @param baseUrl
    * @private
    */
-  private static getFileUrl (baseUrl: string = ''): string {
-    return UrlBuilder.concat(baseUrl, UrlBuilder.ROOT, 'files')
+  private static getFileUrl (args: FileArgs, baseUrl: string = ''): string {
+    return UrlBuilder.concat(baseUrl, UrlBuilder.ROOT, `download/${args.fileId}`)
   }
 
   /**

+ 1 - 0
services/utils/typesTesting.ts

@@ -8,6 +8,7 @@ export default class TypesTesting {
   public static isDataProviderArgs (args: DataProviderArgs|DataPersisterArgs): args is DataProviderArgs {
     return (args as DataProviderArgs).imgArgs !== undefined
         || (args as DataProviderArgs).listArgs !== undefined
+        || (args as DataProviderArgs).fileArgs !== undefined
   }
 
   /**

+ 5 - 0
types/interfaces.d.ts

@@ -182,6 +182,10 @@ interface ImageArgs {
   readonly width: number
 }
 
+interface FileArgs {
+  readonly fileId: number
+}
+
 interface Filter{
   readonly key: string,
   readonly value: string|boolean|number
@@ -196,6 +200,7 @@ interface ListArgs {
 interface DataProviderArgs extends UrlArgs {
   imgArgs?: ImageArgs,
   listArgs?: ListArgs,
+  fileArgs?: FileArgs,
 }
 interface DataPersisterArgs extends UrlArgs {
   data?: AnyJson,