TicketDetailViewHeader.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { toRef } from 'vue'
  4. import CommonUserAvatar from '#shared/components/CommonUserAvatar/CommonUserAvatar.vue'
  5. import type {
  6. TicketById,
  7. TicketLiveAppUser,
  8. } from '#shared/entities/ticket/types.ts'
  9. import { useSessionStore } from '#shared/stores/session.ts'
  10. import CommonLoader from '#mobile/components/CommonLoader/CommonLoader.vue'
  11. import LayoutHeader from '#mobile/components/layout/LayoutHeader.vue'
  12. import { useDialog } from '#mobile/composables/useDialog.ts'
  13. interface Props {
  14. ticket?: TicketById
  15. liveUserList?: TicketLiveAppUser[]
  16. loadingTicket?: boolean
  17. refetchingTicket: boolean
  18. }
  19. const props = defineProps<Props>()
  20. const session = useSessionStore()
  21. const viewersDialog = useDialog({
  22. name: 'ticket-viewers-dialog',
  23. component: () => import('./TicketViewersDialog.vue'),
  24. })
  25. const actionsDialog = useDialog({
  26. name: 'ticket-header-actions-dialog',
  27. component: () => import('./TicketActionsDialog.vue'),
  28. })
  29. const showViewers = () => {
  30. return viewersDialog.open({
  31. name: viewersDialog.name,
  32. liveUsers: toRef(props, 'liveUserList'),
  33. })
  34. }
  35. const showActions = () => {
  36. if (!props.ticket) return
  37. actionsDialog.open({
  38. name: actionsDialog.name,
  39. ticket: toRef(props, 'ticket'),
  40. })
  41. }
  42. </script>
  43. <template>
  44. <LayoutHeader
  45. class="bg-gray-600/90"
  46. :refetch="refetchingTicket || loadingTicket"
  47. :back-ignore="[`/tickets/${ticket?.internalId}/information`]"
  48. back-url="/"
  49. >
  50. <div
  51. class="flex flex-1 flex-col items-center justify-center text-center text-sm leading-4"
  52. data-test-id="header-content"
  53. >
  54. <div class="font-bold">
  55. {{ ticket && `#${ticket.number}` }}
  56. </div>
  57. <div class="text-gray">
  58. {{
  59. ticket && $t('created %s', i18n.relativeDateTime(ticket.createdAt))
  60. }}
  61. </div>
  62. </div>
  63. <template #after>
  64. <CommonLoader data-test-id="loader-header" :loading="loadingTicket">
  65. <button
  66. v-if="liveUserList?.length"
  67. class="flex ltr:mr-0.5 rtl:ml-0.5"
  68. data-test-id="viewers-counter"
  69. type="button"
  70. :aria-label="$t('Show ticket viewers')"
  71. @click="showViewers()"
  72. >
  73. <CommonUserAvatar
  74. class="z-10"
  75. :entity="liveUserList[0].user"
  76. personal
  77. size="xs"
  78. />
  79. <div
  80. v-if="liveUserList.length - 1"
  81. class="z-0 flex h-6 w-6 select-none items-center justify-center rounded-full bg-white/80 text-xs text-black ltr:-translate-x-2 rtl:translate-x-2"
  82. role="img"
  83. :aria-label="$t('Ticket has %s viewers', liveUserList.length)"
  84. >
  85. +{{ liveUserList.length - 1 }}
  86. </div>
  87. </button>
  88. <button
  89. v-if="session.hasPermission('ticket.agent')"
  90. type="button"
  91. :aria-label="$t('Show ticket actions')"
  92. @click="showActions()"
  93. >
  94. <CommonIcon name="more" size="base" decorative />
  95. </button>
  96. </CommonLoader>
  97. </template>
  98. </LayoutHeader>
  99. </template>