Browse Source

add simple image upload functionnality

Olivier Massot 2 years ago
parent
commit
e3455860f9
2 changed files with 61 additions and 35 deletions
  1. 39 35
      components/Ui/Input/Image.vue
  2. 22 0
      services/data/imageManager.ts

+ 39 - 35
components/Ui/Input/Image.vue

@@ -79,17 +79,16 @@ Assistant de création d'image
 
 <script setup lang="ts">
 
-import {ref} from "@vue/reactivity";
+import {type Ref, ref} from "@vue/reactivity";
 import File from '~/models/Core/File'
 import type {PropType} from "@vue/runtime-core";
 import {useEntityManager} from "~/composables/data/useEntityManager";
-import type {AnyJson} from "~/types/data";
-import ApiResource from "~/models/ApiResource";
 import {useImageManager} from "~/composables/data/useImageManager";
 import type { Cropper } from 'vue-advanced-cropper'
 import 'vue-advanced-cropper/dist/style.css';
 import {FILE_FOLDER, FILE_STATUS, FILE_TYPE, FILE_VISIBILITY, TYPE_ALERT} from "~/types/enum/enums";
 import {usePageStore} from "~/stores/page";
+import ImageUtils from "~/services/utils/imageUtils";
 
 const props = defineProps({
   /**
@@ -155,7 +154,7 @@ const imageElement: Ref<any> = ref(null)
 /**
  * L'objet File contenant les informations de l'image
  */
-const file: Ref<ApiResource | null> = ref(null)
+const file: Ref<File | null> = ref(null)
 
 /**
  * L'image elle-même
@@ -175,10 +174,12 @@ const showModal = ref(false)
 /**
  * Données d'une nouvelle image uploadée par l'utilisateur
  */
-const uploadedImage: Ref<AnyJson> = ref({
+const uploadedImage: Ref<
+    {id: string | number | null, src: string | null, content: string | null, name: string | null}
+> = ref({
   id: null,
   src: null,
-  file: null,
+  content: null,
   name: null
 })
 
@@ -220,7 +221,7 @@ const openModal = async () => {
 
   if (props.modelValue !== null) {
     // Un objet File existe déjà: on le récupère
-    file.value = await em.fetch(File, props.modelValue)
+    file.value = await em.fetch(File, props.modelValue) as File
     image.value = await imageManager.get(props.modelValue)
 
     if (file.value.config) {
@@ -233,11 +234,11 @@ const openModal = async () => {
 
     uploadedImage.value.name = file.value.name
     uploadedImage.value.id = file.value.id
-    uploadedImage.value.src = image.value
+    uploadedImage.value.src = image.value as string
 
   } else {
     // Nouveau File
-    file.value = em.newInstance(File)
+    file.value = em.newInstance(File) as File
   }
 
   pending.value = false
@@ -247,18 +248,20 @@ const openModal = async () => {
  * Réinitialise l'image sélectionnée
  */
 const reset = () => {
+  if (uploadedImage.value.src !== null) {
+    URL.revokeObjectURL(uploadedImage.value.src)
+  }
   uploadedImage.value.src = null
-  uploadedImage.value.file = null
+  uploadedImage.value.content = null
   uploadedImage.value.name = null
   uploadedImage.value.id = null
-  URL.revokeObjectURL(uploadedImage.value.src)
 }
 
 /**
  * Upload une image depuis le poste client
  * @param event
  */
-const uploadImage = (event: any) => {
+const uploadImage = async (event: any) => {
   const { files } = event.target
 
   if (!files || !files[0]) {
@@ -274,14 +277,14 @@ const uploadImage = (event: any) => {
 
   reset()
 
-  uploadedImage.value.name = files[0].name
-  uploadedImage.value.src = URL.createObjectURL(files[0])
-  uploadedImage.value.file = files[0]
+  uploadedImage.value.name = uploadedFile.name
+  uploadedImage.value.src = URL.createObjectURL(uploadedFile)
+  uploadedImage.value.content = await ImageUtils.blobToBase64(uploadedFile)
 
   coordinates.value.top = 0
   coordinates.value.left = 0
-  coordinates.value.height = uploadedImage.value.height
-  coordinates.value.width = uploadedImage.value.width
+  coordinates.value.height = uploadedFile.height
+  coordinates.value.width = uploadedFile.width
 }
 
 /**
@@ -319,28 +322,29 @@ const saveNewImage = async () => {
   if (!file.value) {
     throw new Error('No File object defined')
   }
-
-  // On créé l'objet File à sauvegarder
-  file.value.name = uploadedImage.value.name
-  file.value.imgFieldName = props.field
-  file.value.visibility = FILE_VISIBILITY.EVERYBODY
-  file.value.folder = FILE_FOLDER.IMAGES
-  file.value.status = FILE_STATUS.READY
-  file.value.type = FILE_TYPE.UPLOADED
-
-  updateFileConfig()
-
-  if (props.ownerId) {
-    // TODO: revoir
-    file.value.ownerId = props.ownerId
+  if (!uploadedImage.value.name) {
+    throw new Error("Missing file's name")
+  }
+  if (!uploadedImage.value.content) {
+    throw new Error("Missing file's content")
   }
 
-  // TODO: A revoir, on doit pouvoir persister l'image aussi
-  const returnedFile = await em.persist(File, file.value)
-  // await imageManager.persist(file.value, uploadedImage.src)
+  const config = JSON.stringify({
+    x: coordinates.value.left,
+    y: coordinates.value.top,
+    height: coordinates.value.height,
+    width: coordinates.value.width
+  })
+
+  const response = await imageManager.upload(
+      uploadedImage.value.name,
+      uploadedImage.value.content,
+      FILE_VISIBILITY.EVERYBODY,
+      config
+  ) as any
 
   //On émet un évent afin de mettre à jour le formulaire de départ
-  emit('update:modelValue', returnedFile.id)
+  emit('update:modelValue', response.fileId)
 }
 
 /**

+ 22 - 0
services/data/imageManager.ts

@@ -1,5 +1,7 @@
 import ApiRequestService from "./apiRequestService";
 import ImageUtils from "~/services/utils/imageUtils";
+import File from '~/models/Core/File'
+import {FILE_FOLDER, FILE_TYPE, FILE_VISIBILITY} from "~/types/enum/enums";
 
 /**
  * Permet le requêtage, l'upload et la manipulation des images via l'API Opentalent
@@ -59,6 +61,26 @@ class ImageManager {
         return await this.toBase64(response)
     }
 
+    public async upload(
+        filename: string,
+        content: string,
+        visibility: string = FILE_VISIBILITY.NOBODY,
+        config: string | null = null
+    ) {
+
+        content = content.replace(/^data:image\/[\w\/]+;base64,/, "");
+
+        const data = JSON.stringify({
+            filename: filename,
+            content: content,
+            type: FILE_TYPE.UPLOADED,
+            visibility: visibility,
+            config: config
+        })
+
+        return this.apiRequestService.post("api/upload", data)
+    }
+
     /**
      * Convert the API response into base64
      * @param data