Bladeren bron

add useEntityFetch and finalize base form script

Olivier Massot 3 jaren geleden
bovenliggende
commit
9c99b34983
5 gewijzigde bestanden met toevoegingen van 98 en 36 verwijderingen
  1. 16 0
      composables/data/useEntityFetch.ts
  2. 1 0
      package.json
  3. 34 31
      pages/poc/[id].vue
  4. 16 5
      pages/poc/index.vue
  5. 31 0
      services/data/entityManager.ts

+ 16 - 0
composables/data/useEntityFetch.ts

@@ -0,0 +1,16 @@
+import {useAsyncData, AsyncData} from "#app";
+import {File} from "~/models/Core/File";
+import {useEntityManager} from "~/composables/data/useEntityManager";
+import ApiResource from "~/models/ApiResource";
+import {Ref} from "@vue/reactivity";
+
+export const useEntityFetch = (model: typeof ApiResource, id: Ref<number>, lazy: boolean = false): AsyncData<ApiResource, ApiResource | true> => {
+    const em = useEntityManager()
+
+    //@ts-ignore
+    return useAsyncData(
+        File.entity + '_' + id.value, // TODO: je me demande si on a besoin de cette clé? (https://v3.nuxtjs.org/api/composables/use-async-data#params)
+        () => em.fetch(File, id.value),
+        { lazy }
+    )
+}

+ 1 - 0
package.json

@@ -52,6 +52,7 @@
     "@casl/vue": "^2.1.3",
     "@fortawesome/fontawesome-free": "^6.2.0",
     "@nuxt/image": "^0.7.1",
+    "@nuxtjs/i18n": "^8.0.0-beta.1",
     "@nuxtjs/i18n-edge": "npm:@nuxtjs/i18n-edge",
     "@pinia-orm/nuxt": "^1.0.18",
     "@pinia/nuxt": "^0.4.0",

+ 34 - 31
pages/poc/[id].vue

@@ -1,65 +1,68 @@
 <template>
   <main>
     <div>
-      <p v-show="pending">Pending...</p>
-      <p>Edit :{{ data }}</p>
-
-      <form @submit.prevent="" @change="onFileChange" class="my-3">
-        <v-text-field v-model="data.name" type="text" />
-
-        <v-select v-model="data.status" :items="['PENDING', 'READY', 'DELETED', 'ERROR']">
-        </v-select>
-
-        <v-btn @click="cancel" class="ma-5">Annuler</v-btn>
-        <v-btn @click="save" class="ma-5">Enregistrer</v-btn>
-        <v-btn @click="deleteAndGoBack" class="ma-5">Supprimer</v-btn>
-        <v-btn @click="refresh" class="ma-5">Refresh</v-btn>
-      </form>
+      <div v-if="pending">
+        Pending...
+      </div>
+      <div v-else>
+        <p>Edit :{{ file }}</p>
+
+        <form @submit.prevent="" @change="onFileChange" class="my-3">
+          <v-text-field v-model="file.name" type="text" />
+
+          <v-select v-model="file.status" :items="['PENDING', 'READY', 'DELETED', 'ERROR']">
+          </v-select>
+
+          <v-btn @click="cancel" class="ma-5">Annuler</v-btn>
+          <v-btn @click="save" class="ma-5">Enregistrer</v-btn>
+          <v-btn @click="deleteAndGoBack" class="ma-5">Supprimer</v-btn>
+          <v-btn @click="refresh" class="ma-5">Refresh</v-btn>
+          <v-btn @click="goBack" class="ma-5">Retour</v-btn>
+        </form>
+      </div>
     </div>
   </main>
 </template>
 
 <script setup lang="ts">
 import {useEntityManager} from "~/composables/data/useEntityManager";
-import {ref, Ref} from "@vue/reactivity";
-import ApiResource from "~/models/ApiResource";
+import {computed, ComputedRef, ref, Ref} from "@vue/reactivity";
 import {File} from "~/models/Core/File";
-import {navigateTo, useAsyncData} from "#app";
+import {navigateTo, useRoute} from "#app";
+import {useEntityFetch} from "~/composables/data/useEntityFetch";
 
 const route = useRoute()
 
 const id: Ref<number> = ref(parseInt(route.params.id as string))
-const valid: Ref<boolean> = ref(true)
 
 const em = useEntityManager()
 
-const { data, pending, refresh } =  useAsyncData(
-    'file_' + id.value,
-    () => em.fetch(File, id.value)
-)
-//@ts-ignore
-const file = reactive(data.value) as ApiResource
+const { pending, refresh } = useEntityFetch(File, id)
 
+// Get file from store
+const file: ComputedRef<File> = computed( () => {
+  return em.find(File, id.value)
+})
+
+// Update store when form is changed
 const onFileChange = () => {
-  console.log(file)
-  em.getRepository(File).save(file)
+  em.save(File, file.value)
 }
 
-
 const save = async () => {
-  await em.persist(File, file)
+  await em.persist(File, file.value)
 }
 
 const cancel = async () => {
   if (em.isNewEntity(File, id.value)) {
-    await em.delete(File, file)
+    await em.delete(File, file.value)
   } else {
-    em.reset(File, file)
+    em.reset(File, file.value)
   }
 }
 
 const deleteItem = async () => {
-  await em.delete(File, file)
+  await em.delete(File, file.value)
 }
 
 const goBack = () => {

+ 16 - 5
pages/poc/index.vue

@@ -25,10 +25,13 @@
   import {Ref} from "@vue/reactivity";
   import ApiResource from "~/models/ApiResource";
   import {File} from "~/models/Core/File";
-  import {Pagination} from "~/types/data";
-  import {useReactiveUpdate} from "~/composables/data/useReactiveUpdate";
+  import {Collection, Pagination} from "~/types/data";
+  import {useLazyAsyncData} from "#app";
 
   const em = useEntityManager()
+
+
+
   let files: Array<ApiResource> = reactive([])
   const page: Ref<number> = ref(1)
 
@@ -36,11 +39,19 @@
   let pagination: Pagination = reactive({first: 1, last: 1, next: undefined, previous: undefined})
 
   const fetchAll = async function() {
-    const collection = await em.fetchAll(File, page.value)
+    const { data, pending, refresh } =  useLazyAsyncData(
+        'files',
+        () => em.fetchAll(File, page.value)
+    )
+
+    //@ts-ignore
+    collection = reactive(data.value) as Collection
 
     // On met à jour les arrays sans les remplacer avec useReactiveUpdate pour ne pas perdre la réactivité
-    useReactiveUpdate(files, collection.items)
-    useReactiveUpdate(pagination, collection.pagination)
+    // useReactiveUpdate(files, collection.items)
+    // useReactiveUpdate(pagination, collection.pagination)
+
+
   }
   await fetchAll()
 

+ 31 - 0
services/data/entityManager.ts

@@ -35,6 +35,11 @@ class EntityManager {
         return useRepo(model)
     }
 
+    // noinspection JSMethodCanBeStatic
+    public cast(model: typeof ApiResource, entity: ApiResource): ApiResource {
+        return new model(entity)
+    }
+
     /**
      * Create a new instance of the given model
      *
@@ -59,6 +64,29 @@ class EntityManager {
         return entity
     }
 
+    /**
+     * Save the entity into the store
+     *
+     * @param model
+     * @param entity
+     */
+    public save(model: typeof ApiResource, entity: ApiResource): ApiResource {
+        return this.getRepository(model).save(entity)
+    }
+
+
+    /**
+     * Find the entity into the store
+     *
+     * @param model
+     * @param id
+     */
+    // @ts-ignore
+    public find<T extends ApiResource>(model: typeof T, id: number): T {
+        const repository = this.getRepository(model)
+        return repository.find(id) as T
+    }
+
     /**
      * Fetch an Entity / ApiResource by its id, save it to the store and returns it
      *
@@ -131,6 +159,9 @@ class EntityManager {
     public async persist(model: typeof ApiModel, entity: ApiModel) {
         const repository = this.getRepository(model)
 
+        // Recast in case class definition has been "lost"
+        entity = this.cast(model, entity)
+
         let url = Url.join('api', model.entity)
         let response