TicketLiveUsers.vue 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { computed, toRef } from 'vue'
  4. import CommonUserAvatar from '#shared/components/CommonUserAvatar/CommonUserAvatar.vue'
  5. import { useTicketLiveUsersDisplay } from '#shared/entities/ticket/composables/useTicketLiveUsersDisplay.ts'
  6. import type { TicketLiveAppUser } from '#shared/entities/ticket/types.ts'
  7. import { EnumTaskbarApp } from '#shared/graphql/types.ts'
  8. export interface Props {
  9. liveUserList: TicketLiveAppUser[]
  10. }
  11. const props = defineProps<Props>()
  12. const { liveUsers } = useTicketLiveUsersDisplay(toRef(props, 'liveUserList'))
  13. const LIVE_USER_LIMIT = 9
  14. const visibleLiveUsers = computed(() =>
  15. liveUsers.value.slice(0, LIVE_USER_LIMIT),
  16. )
  17. const liveUsersOverflow = computed(() => {
  18. if (liveUsers.value.length <= LIVE_USER_LIMIT) return
  19. const overflow = liveUsers.value.length - LIVE_USER_LIMIT
  20. if (overflow > 999) return '+999'
  21. return `+${overflow}`
  22. })
  23. const isLiveUserIdle = (liveUser: TicketLiveAppUser) => liveUser.isIdle
  24. const isLiveUserEditing = (liveUser: TicketLiveAppUser) => liveUser.editing
  25. const isLiveUserMobile = (liveUser: TicketLiveAppUser) =>
  26. liveUser.app === EnumTaskbarApp.Mobile
  27. </script>
  28. <template>
  29. <div class="flex items-center gap-2.5">
  30. <div
  31. v-for="liveUser in visibleLiveUsers"
  32. :key="liveUser.user.id"
  33. class="relative"
  34. :class="{
  35. 'opacity-50 grayscale': isLiveUserIdle(liveUser),
  36. }"
  37. >
  38. <CommonUserAvatar :entity="liveUser.user" />
  39. <div
  40. v-if="isLiveUserEditing(liveUser) || isLiveUserMobile(liveUser)"
  41. class="absolute bottom-0 end-0 flex translate-y-1 items-center justify-center rounded-full bg-blue-200 p-[3px] outline outline-1 -outline-offset-1 outline-neutral-100 ltr:translate-x-2 rtl:-translate-x-2 dark:bg-gray-700 dark:outline-gray-900"
  42. >
  43. <CommonIcon
  44. class="text-black dark:text-white"
  45. :label="__('Editing on Mobile')"
  46. size="xs"
  47. :name="
  48. isLiveUserEditing(liveUser) && isLiveUserMobile(liveUser)
  49. ? 'phone-pencil'
  50. : isLiveUserMobile(liveUser)
  51. ? 'mobile'
  52. : 'pencil'
  53. "
  54. />
  55. </div>
  56. </div>
  57. <div
  58. v-if="liveUsersOverflow"
  59. class="flex h-10 w-10 items-center justify-center rounded-full bg-blue-200 text-sm outline outline-1 -outline-offset-1 outline-neutral-100 dark:bg-gray-700 dark:outline-gray-900"
  60. >
  61. {{ liveUsersOverflow }}
  62. </div>
  63. </div>
  64. </template>