useOnlineNotificationActions.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { cloneDeep } from 'lodash-es'
  3. import { useOnlineNotificationDeleteMutation } from '#shared/entities/online-notification/graphql/mutations/delete.api.ts'
  4. import { useOnlineNotificationMarkAllAsSeenMutation } from '#shared/entities/online-notification/graphql/mutations/markAllAsSeen.api.ts'
  5. import { useOnlineNotificationSeenMutation } from '#shared/entities/online-notification/graphql/mutations/seen.api.ts'
  6. import { OnlineNotificationsDocument } from '#shared/entities/online-notification/graphql/queries/onlineNotifications.api.ts'
  7. import type {
  8. OnlineNotification,
  9. OnlineNotificationsQuery,
  10. Scalars,
  11. } from '#shared/graphql/types.ts'
  12. import { getApolloClient } from '#shared/server/apollo/client.ts'
  13. import { MutationHandler } from '#shared/server/apollo/handler/index.ts'
  14. export const useOnlineNotificationActions = () => {
  15. const { cache } = getApolloClient()
  16. const getCacheData = () => {
  17. const queryOptions = {
  18. query: OnlineNotificationsDocument,
  19. }
  20. const existingQueryCache =
  21. cache.readQuery<OnlineNotificationsQuery>(queryOptions)
  22. if (!existingQueryCache?.onlineNotifications) return null
  23. const oldQueryCache = cloneDeep(existingQueryCache)
  24. return { queryOptions, oldQueryCache, existingQueryCache }
  25. }
  26. const removeNotificationCacheUpdate = (id: Scalars['ID']['output']) => {
  27. const data = getCacheData()
  28. if (!data) return
  29. const { queryOptions, oldQueryCache, existingQueryCache } = data
  30. cache.writeQuery({
  31. ...queryOptions,
  32. data: {
  33. onlineNotifications: {
  34. edges: existingQueryCache.onlineNotifications.edges.filter(
  35. (edge) => edge.node.id !== id,
  36. ),
  37. pageInfo: existingQueryCache.onlineNotifications.pageInfo,
  38. },
  39. },
  40. })
  41. return () => {
  42. cache.writeQuery({
  43. ...queryOptions,
  44. data: oldQueryCache,
  45. })
  46. }
  47. }
  48. const updateAllSeenNotificationCache = (ids: Scalars['ID']['output'][]) => {
  49. const data = getCacheData()
  50. if (!data) return
  51. const { queryOptions, oldQueryCache, existingQueryCache } = data
  52. const clonedQueryCache = cloneDeep(existingQueryCache)
  53. ids.forEach((id) =>
  54. clonedQueryCache.onlineNotifications.edges.forEach(({ node }) => {
  55. if (node.id === id) {
  56. node.seen = true
  57. }
  58. }),
  59. )
  60. cache.writeQuery({
  61. ...queryOptions,
  62. data: {
  63. onlineNotifications: {
  64. ...clonedQueryCache.onlineNotifications,
  65. },
  66. },
  67. })
  68. return () => {
  69. cache.writeQuery({
  70. ...queryOptions,
  71. data: oldQueryCache,
  72. })
  73. }
  74. }
  75. const updateSeenNotificationCache = (id: Scalars['ID']['output']) => {
  76. const data = getCacheData()
  77. if (!data) return
  78. const { queryOptions, oldQueryCache, existingQueryCache } = data
  79. const clonedQueryCache = cloneDeep(existingQueryCache)
  80. clonedQueryCache.onlineNotifications.edges.forEach(({ node }) => {
  81. if ((node.metaObject as OnlineNotification['metaObject'])?.id === id) {
  82. node.seen = true
  83. }
  84. })
  85. cache.writeQuery({
  86. ...queryOptions,
  87. data: {
  88. onlineNotifications: {
  89. ...clonedQueryCache.onlineNotifications,
  90. },
  91. },
  92. })
  93. return () => {
  94. cache.writeQuery({
  95. ...queryOptions,
  96. data: oldQueryCache,
  97. })
  98. }
  99. }
  100. const seenNotificationMutation = new MutationHandler(
  101. useOnlineNotificationSeenMutation(),
  102. {
  103. errorNotificationMessage: __(
  104. 'The online notification could not be marked as seen.',
  105. ),
  106. },
  107. )
  108. const seenNotification = async (id: Scalars['ID']['output']) => {
  109. const revertCache = updateSeenNotificationCache(id)
  110. return seenNotificationMutation
  111. .send({ objectId: id })
  112. .catch(() => revertCache)
  113. }
  114. const markAllSeenMutation = new MutationHandler(
  115. useOnlineNotificationMarkAllAsSeenMutation(),
  116. {
  117. errorNotificationMessage: __('Cannot set online notifications as seen'),
  118. },
  119. )
  120. const markAllRead = (ids: Scalars['ID']['output'][]) => {
  121. const revertCache = updateAllSeenNotificationCache(ids)
  122. return markAllSeenMutation
  123. .send({ onlineNotificationIds: ids })
  124. .catch(() => revertCache)
  125. }
  126. const deleteNotificationMutation = new MutationHandler(
  127. useOnlineNotificationDeleteMutation(),
  128. )
  129. const deleteNotification = async (id: Scalars['ID']['output']) => {
  130. const revertCache = removeNotificationCacheUpdate(id)
  131. return deleteNotificationMutation
  132. .send({
  133. onlineNotificationId: id,
  134. })
  135. .catch(() => revertCache)
  136. }
  137. return {
  138. seenNotification,
  139. deleteNotification,
  140. deleteNotificationMutation,
  141. markAllRead,
  142. }
  143. }