useEntityFetch.ts 2.1 KB

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