entityManager.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import ApiRequestService from "./apiRequestService";
  2. import {AssociativeArray} from "./data";
  3. import {useRepo} from "pinia-orm";
  4. import UrlBuilder from "~/services/utils/urlBuilder";
  5. import ModelNormalizer from "./serializer/normalizer/modelNormalizer";
  6. import HydraDenormalizer from "./serializer/denormalizer/hydraDenormalizer";
  7. import ApiModel from "~/models/ApiModel";
  8. import {useProfileAccessStore} from "~/store/profile/access";
  9. /**
  10. * Entity manager: make operations on the models defined with the Pinia-Orm library
  11. *
  12. * @see https://pinia-orm.codedredd.de/
  13. */
  14. class EntityManager {
  15. private apiRequestService: ApiRequestService;
  16. public constructor(apiRequestService: ApiRequestService) {
  17. this.apiRequestService = apiRequestService
  18. }
  19. public getRepository(model: typeof ApiModel) {
  20. return useRepo(model)
  21. }
  22. private static getEntityModel(entity: ApiModel): typeof ApiModel{
  23. return Object.getPrototypeOf(entity)
  24. }
  25. /**
  26. * Fetch one entity by its id, save it to the store and returns it
  27. *
  28. * @param model Model of the object to fetch
  29. * @param id Id of the object to fetch
  30. * @param forceRefresh Force a new get request to the api ;
  31. * current object in store will be overwritten if it exists
  32. */
  33. public async fetch(model: typeof ApiModel, id: number, forceRefresh: boolean = false) {
  34. const repository = this.getRepository(model)
  35. // If the entity is already in the store and forceRefresh is false, return the object in store
  36. if (!forceRefresh) {
  37. const item = repository.find(id)
  38. if (item && typeof item !== 'undefined') {
  39. return item
  40. }
  41. }
  42. // Else, get the object from the API
  43. const url = UrlBuilder.join('api', model.entity, String(id))
  44. const response = await this.apiRequestService.get(url)
  45. // deserialize the response
  46. const entity = await HydraDenormalizer.denormalize(response)
  47. entity.persisted = true
  48. entity.initialState = structuredClone(entity)
  49. // Save data into the store
  50. repository.save(entity)
  51. return entity
  52. }
  53. public findBy(model: typeof ApiModel, query: AssociativeArray) {
  54. // TODO: implement
  55. }
  56. public fetchAll(model: typeof ApiModel) {
  57. // TODO: implement
  58. }
  59. public async persist(model: typeof ApiModel, entity: ApiModel) {
  60. const data = ModelNormalizer.normalize(entity)
  61. let url = UrlBuilder.join('api', model.entity)
  62. let response = null
  63. if (entity.persisted) {
  64. url = UrlBuilder.join(url, String(entity.id))
  65. response = await this.apiRequestService.put(url, data)
  66. } else {
  67. response = await this.apiRequestService.post(url, data)
  68. }
  69. const fetchedEntity = await HydraDenormalizer.denormalize(response)
  70. fetchedEntity.persisted = true
  71. // Save data into the store
  72. const repository = this.getRepository(model)
  73. repository.save(fetchedEntity)
  74. if (['accesses', 'organizations', 'parameters', 'subdomains'].includes(model.entity)) {
  75. await this.refreshProfile()
  76. }
  77. return fetchedEntity
  78. }
  79. public async delete(model: typeof ApiModel, id: number) {
  80. const repository = this.getRepository(model)
  81. const entity = repository.find(id) as ApiModel
  82. if (!entity || typeof entity === 'undefined') {
  83. throw new Error(model + ' ' + id + ' does not exists in store')
  84. }
  85. // If object has been persisted to the datasource, send a delete request
  86. if (entity.persisted) {
  87. const url = UrlBuilder.join('api', model.entity, String(id))
  88. await this.apiRequestService.delete(url)
  89. }
  90. // update the store
  91. repository.destroy(id)
  92. }
  93. public new(model: typeof ApiModel) {
  94. const repository = this.getRepository(model)
  95. const entity = repository.make()
  96. entity.persisted = false
  97. // Save data into the store
  98. repository.save(entity)
  99. return entity
  100. }
  101. public reset(entity: ApiModel) {
  102. if (entity.initialState === null) {
  103. console.log('object has no initial state - abort')
  104. return
  105. }
  106. entity = entity.initialState as ApiModel
  107. entity.initialState = structuredClone(entity)
  108. const repository = this.getRepository(EntityManager.getEntityModel(entity))
  109. repository.save(entity)
  110. }
  111. public async refreshProfile() {
  112. const response = await this.apiRequestService.get('api/my_profile')
  113. // deserialize the response
  114. const profile = await HydraDenormalizer.denormalize(response)
  115. const profileAccessStore = useProfileAccessStore()
  116. profileAccessStore.setProfile(profile.data)
  117. }
  118. }
  119. export default EntityManager