useEntityFetch.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. import type {AsyncDataExecuteOptions, AsyncDataRequestStatus} from "#app/composables/asyncData";
  9. interface useEntityFetchReturnType {
  10. fetch: (
  11. model: typeof ApiResource,
  12. id: number,
  13. ) => AsyncData<ApiResource | null, Error | null>
  14. fetchCollection: (
  15. model: typeof ApiResource,
  16. parent?: ApiResource | null,
  17. query?: Query | null,
  18. ) => {
  19. data: ComputedRef<Collection | null>,
  20. pending: Ref<boolean>,
  21. refresh: (opts?: AsyncDataExecuteOptions) => Promise<ComputedRef<Collection> | null>,
  22. error: Ref<Error | null>,
  23. status: Ref<AsyncDataRequestStatus>,
  24. }
  25. getRef: <T extends ApiResource>(
  26. model: new () => T,
  27. id: Ref<number | null>,
  28. ) => ComputedRef<null | T>
  29. }
  30. // TODO: améliorer le typage des fonctions sur le modèle de getRef
  31. export const useEntityFetch = (
  32. lazy: boolean = false,
  33. ): useEntityFetchReturnType => {
  34. const { em } = useEntityManager()
  35. const fetch = (model: typeof ApiResource, id: number) =>
  36. useAsyncData(
  37. model.entity + '_' + id + '_' + uuid4(),
  38. () => em.fetch(model, id, true),
  39. { lazy },
  40. )
  41. const fetchCollection = (
  42. model: typeof ApiResource,
  43. parent: ApiResource | null = null,
  44. query: Query | null = null,
  45. ) => {
  46. const {data, pending, refresh, error, status } = useAsyncData(
  47. model.entity + '_many_' + uuid4(),
  48. () => em.fetchCollection(model, parent, query),
  49. {lazy, deep: true},
  50. )
  51. return {
  52. data: computed(() => data.value !== null ? data.value.value : null),
  53. pending,
  54. refresh,
  55. error,
  56. status
  57. }
  58. }
  59. const getRef = <T extends ApiResource>(
  60. model: new () => T,
  61. id: Ref<number | null>,
  62. ): ComputedRef<T | null> => {
  63. return computed(() => (id.value ? (em.find(model, id.value) as T) : null))
  64. }
  65. return { fetch, fetchCollection, getRef }
  66. }