useEntityFetch.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import type { AsyncData } from '#app'
  2. import type { ComputedRef, Ref } from 'vue'
  3. import { v4 as uuid4 } from 'uuid'
  4. import { useEntityManager } from '~/composables/data/useEntityManager'
  5. import ApiResource from '~/models/ApiResource'
  6. import type { Collection } from '~/types/data'
  7. import Query from '~/services/data/Query'
  8. interface useEntityFetchReturnType {
  9. fetch: (
  10. model: typeof ApiResource,
  11. id: number,
  12. ) => AsyncData<ApiResource | null, Error | null>
  13. fetchCollection: (
  14. model: typeof ApiResource,
  15. parent?: ApiResource | null,
  16. query?: Query | null,
  17. ) => AsyncData<ComputedRef<Collection> | null, Error | null>
  18. getRef: <T extends ApiResource>(
  19. model: new () => T,
  20. id: Ref<number | null>,
  21. ) => ComputedRef<null | T>
  22. }
  23. // TODO: améliorer le typage des fonctions sur le modèle de getRef
  24. export const useEntityFetch = (
  25. lazy: boolean = false,
  26. ): useEntityFetchReturnType => {
  27. const { em } = useEntityManager()
  28. const fetch = (model: typeof ApiResource, id: number) =>
  29. useAsyncData(
  30. model.entity + '_' + id + '_' + uuid4(),
  31. () => em.fetch(model, id, true),
  32. { lazy },
  33. )
  34. const fetchCollection = (
  35. model: typeof ApiResource,
  36. parent: ApiResource | null = null,
  37. query: Query | null = null,
  38. ) =>
  39. useAsyncData(
  40. model.entity + '_many_' + uuid4(),
  41. () => em.fetchCollection(model, parent, query),
  42. { lazy, deep: false },
  43. )
  44. const getRef = <T extends ApiResource>(
  45. model: new () => T,
  46. id: Ref<number | null>,
  47. ): ComputedRef<T | null> => {
  48. return computed(() => (id.value ? (em.find(model, id.value) as T) : null))
  49. }
  50. return { fetch, fetchCollection, getRef }
  51. }