Browse Source

add cmf_licence/organization page, working in sync mode

Olivier Massot 2 years ago
parent
commit
e055de34fa

+ 14 - 0
composables/data/useFileManager.ts

@@ -0,0 +1,14 @@
+import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
+import FileManager from "~/services/data/fileManager";
+
+let fileManager: FileManager | null = null
+
+export const useFileManager = () => {
+    //Avoid memory leak
+    if (fileManager === null) {
+        const { apiRequestService } = useAp2iRequestService()
+        fileManager = new FileManager(apiRequestService)
+    }
+
+    return { fileManager }
+}

+ 5 - 2
models/Export/LicenceCmfOrganizationER.ts

@@ -7,7 +7,7 @@ import ApiResource from "~/models/ApiResource";
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Export/LicenceCmf/LicenceCmfOrganizationER.php
  */
 export default class LicenceCmfOrganizationER extends ApiResource {
-  static entity = ''
+  static entity = 'export/cmf-licence/organization'
 
   @Uid()
   declare id: number | string | null
@@ -15,9 +15,12 @@ export default class LicenceCmfOrganizationER extends ApiResource {
   @Str(null)
   declare format: string | null
 
-  @Num(0)
+  @Num(null)
   declare requesterId: number | string | null
 
   @Bool(false)
   declare async: boolean
+
+  @Num(null)
+  declare fileId: number | string | null
 }

+ 112 - 0
pages/cmf_licence/organization.vue

@@ -0,0 +1,112 @@
+<template>
+  <div class="d-flex flex-column align-center">
+    <h2 class="ma-4">{{ $t('cmf_structure_licence')}}</h2>
+    <a
+        href="https://www.cmf-musique.org/services/tarifs-preferentiels/"
+        target="_blank"
+    >
+      {{ $t('cmf_licence_details_url')}}
+    </a>
+
+    <v-form
+        ref="form"
+        lazy-validation
+    >
+      <div class="ma-12">
+        <v-btn
+            v-if="!filePending && file === null"
+            @click="submit"
+        >
+          {{ $t('generate') }}
+        </v-btn>
+
+        <v-btn
+            v-else
+            color="primary"
+            :loading="filePending"
+            :disabled="filePending"
+            target="_blank"
+            @click="download"
+        >
+          {{ $t('download') }}
+        </v-btn>
+      </div>
+    </v-form>
+  </div>
+</template>
+
+<script setup lang="ts">
+import File from "~/models/Core/File"
+import {ComputedRef, Ref} from "vue";
+import {useEntityFetch} from "~/composables/data/useEntityFetch";
+import {useSseStore} from "~/stores/sse";
+import {useEntityManager} from "~/composables/data/useEntityManager";
+import LicenceCmfOrganizationER from "~/models/Export/LicenceCmfOrganizationER";
+import {useFileManager} from "~/composables/data/useFileManager";
+
+const { em } = useEntityManager()
+const { fetch } = useEntityFetch()
+const { fileManager } = useFileManager()
+
+const sseStore = useSseStore()
+const async = () => { return sseStore.connected }
+
+const file: Ref<File | null> = ref(null)
+
+const submittingRequest: Ref<boolean> = ref(false)
+
+const filePending: ComputedRef<boolean> = computed(() => {
+  return submittingRequest.value || (file.value !== null && file.value.status === 'PENDING')
+})
+
+const submit = async () => {
+  submittingRequest.value = true
+
+  const exportRequest = em.newInstance(LicenceCmfOrganizationER)
+
+  exportRequest.format = 'pdf'
+
+  if (async()) {
+    exportRequest.async = false
+  } else {
+    console.error('SSE unavailable - File downloaded synchronously')
+  }
+
+  // Send the export request and get the receipt
+  const receipt = await em.persist(LicenceCmfOrganizationER, exportRequest)
+  if (receipt.fileId === null) {
+    throw new Error("Missing file's id, abort")
+  }
+
+  file.value = await em.fetch(File, receipt.fileId as number, true) as File
+
+  submittingRequest.value = false
+}
+
+const download = async () => {
+  if (file.value === null) {
+    console.error("File is not defined yet, impossible to download")
+    return
+  }
+
+  if (filePending.value) {
+    console.error("File is still pending, impossible to download")
+    return
+  }
+
+  const response = await fileManager.download(file.value.id as number)
+
+  const blob = new Blob([response], { type: response.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)
+}
+</script>

+ 11 - 2
services/data/fileManager.ts

@@ -1,4 +1,5 @@
 import ApiRequestService from "./apiRequestService";
+import File from "~/models/Core/File"
 
 class FileManager {
     private apiRequestService: ApiRequestService;
@@ -6,9 +7,17 @@ class FileManager {
     public constructor(apiRequestService: ApiRequestService) {
         this.apiRequestService = apiRequestService
     }
+    public async download(id: number) {
 
-    public fetch() {
-        // TODO: récupérer le contenu de fileNormalizer ici
+        const downloadUrl = `api/download/${id}`
+
+        const response: any = await this.apiRequestService.get(downloadUrl)
+
+        if(!response || response.size === 0) {
+            console.error('Error: file ' + id + ' not found or invalid')
+        }
+
+        return response
     }
 }