useTicketLiveUserList.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { type Ref, type ComputedRef } from 'vue'
  3. import { ref } from 'vue'
  4. import { useAppName } from '#shared/composables/useAppName.ts'
  5. import { useTicketLiveUserUpdatesSubscription } from '#shared/entities/ticket/graphql/subscriptions/ticketLiveUserUpdates.api.ts'
  6. import type { TicketLiveAppUser } from '#shared/entities/ticket/types.ts'
  7. import { EnumTaskbarApp } from '#shared/graphql/types.ts'
  8. import type { TicketLiveUser } from '#shared/graphql/types.ts'
  9. import { SubscriptionHandler } from '#shared/server/apollo/handler/index.ts'
  10. import { useSessionStore } from '#shared/stores/session.ts'
  11. export const useTicketLiveUserList = (
  12. ticketInternalId: Ref<string>,
  13. isTicketAgent: ComputedRef<boolean>,
  14. app: EnumTaskbarApp,
  15. ) => {
  16. const liveUserList = ref<TicketLiveAppUser[]>([])
  17. const { userId } = useSessionStore()
  18. const appName = useAppName()
  19. const updateLiveUserList = (liveUsers: TicketLiveUser[]) => {
  20. const mappedLiveUsers: TicketLiveAppUser[] = []
  21. liveUsers.forEach((liveUser) => {
  22. let appItems = liveUser.apps.filter((data) => data.editing)
  23. // Skip own live user item, when it's holds only the current app and is not editing on the other one.
  24. if (liveUser.user.id === userId) {
  25. if (appItems.length === 0) return
  26. appItems = appItems.filter((item) => item.name !== appName)
  27. if (appItems.length === 0) return
  28. }
  29. if (appItems.length === 0) {
  30. appItems = liveUser.apps
  31. }
  32. // Sort app items by last interaction.
  33. appItems.sort((a, b) => {
  34. return (
  35. new Date(b.lastInteraction).getTime() -
  36. new Date(a.lastInteraction).getTime()
  37. )
  38. })
  39. mappedLiveUsers.push({
  40. user: liveUser.user,
  41. ...appItems[0],
  42. app: appItems[0].name,
  43. })
  44. })
  45. return mappedLiveUsers
  46. }
  47. const liveUserSubscription = new SubscriptionHandler(
  48. useTicketLiveUserUpdatesSubscription(
  49. () => ({
  50. userId,
  51. key: `Ticket-${ticketInternalId.value}`,
  52. app,
  53. }),
  54. () => ({
  55. // We need to disable the cache here, because otherwise we have the following error, when
  56. // a ticket is open again which is already in the subscription cache:
  57. // "ApolloError: 'get' on proxy: property 'liveUsers' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '[object Array]' but got '[object Array]')"
  58. // At the end a cache for the subscription is not really needed, but we should create an issue on
  59. // apollo client side, when we have a minimal reproduction.
  60. fetchPolicy: 'no-cache',
  61. enabled: isTicketAgent.value,
  62. }),
  63. ),
  64. )
  65. liveUserSubscription.onResult((result) => {
  66. liveUserList.value = updateLiveUserList(
  67. (result.data?.ticketLiveUserUpdates.liveUsers as TicketLiveUser[]) || [],
  68. )
  69. })
  70. return {
  71. liveUserList,
  72. }
  73. }