TicketActionsDialog.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { computed, toRef } from 'vue'
  4. import { useRoute, useRouter } from 'vue-router'
  5. import CommonUserAvatar from '#shared/components/CommonUserAvatar/CommonUserAvatar.vue'
  6. import { useTicketSubscribe } from '#shared/entities/ticket/composables/useTicketSubscribe.ts'
  7. import { useTicketView } from '#shared/entities/ticket/composables/useTicketView.ts'
  8. import type { TicketById } from '#shared/entities/ticket/types.ts'
  9. import { truthy } from '#shared/utils/helpers.ts'
  10. import CommonButtonGroup from '#mobile/components/CommonButtonGroup/CommonButtonGroup.vue'
  11. import CommonDialog from '#mobile/components/CommonDialog/CommonDialog.vue'
  12. import CommonSectionMenu from '#mobile/components/CommonSectionMenu/CommonSectionMenu.vue'
  13. import CommonSectionMenuLink from '#mobile/components/CommonSectionMenu/CommonSectionMenuLink.vue'
  14. import { useDialog, closeDialog } from '#mobile/composables/useDialog.ts'
  15. import { useTicketsMerge } from '../../composable/useTicketsMerge.ts'
  16. // TODO I think the complete dialog should not be available for none agent user (and maybe also for agents without write permission?)
  17. interface Props {
  18. name: string
  19. ticket: TicketById
  20. }
  21. const props = defineProps<Props>()
  22. const route = useRoute()
  23. const router = useRouter()
  24. const ticketReactive = toRef(props, 'ticket')
  25. const { isTicketAgent, isTicketEditable } = useTicketView(ticketReactive)
  26. const { autocompleteRef, gqlQuery, openMergeTicketsDialog } = useTicketsMerge(
  27. ticketReactive,
  28. () => closeDialog(props.name),
  29. )
  30. const {
  31. isSubscribed,
  32. isSubscriptionLoading,
  33. canManageSubscription,
  34. toggleSubscribe,
  35. } = useTicketSubscribe(ticketReactive)
  36. const topButtons = computed(() =>
  37. [
  38. {
  39. label: __('Merge tickets'),
  40. icon: 'merge',
  41. hidden: !isTicketEditable.value || !isTicketAgent.value,
  42. onAction: openMergeTicketsDialog,
  43. },
  44. {
  45. label: isSubscribed.value ? __('Unsubscribe') : __('Subscribe'),
  46. icon: isSubscribed.value
  47. ? 'notification-unsubscribed'
  48. : 'notification-subscribed',
  49. value: 'subscribe',
  50. hidden: !canManageSubscription.value,
  51. selected: isSubscribed.value,
  52. disabled: isSubscriptionLoading.value,
  53. onAction: toggleSubscribe,
  54. },
  55. {
  56. label: __('Ticket info'),
  57. icon: 'info',
  58. onAction() {
  59. const informationRoute = {
  60. name: 'TicketInformationDetails',
  61. params: {
  62. internalId: props.ticket.internalId,
  63. },
  64. }
  65. closeDialog(props.name)
  66. if (route.name !== informationRoute.name) {
  67. router.push(informationRoute)
  68. }
  69. },
  70. },
  71. ].filter(truthy),
  72. )
  73. const changeCustomerDialog = useDialog({
  74. name: 'ticket-change-customer',
  75. component: () =>
  76. import(
  77. '#mobile/pages/ticket/components/TicketDetailView/TicketAction/TicketActionChangeCustomerDialog.vue'
  78. ),
  79. })
  80. const showChangeCustomer = () => {
  81. if (!props.ticket) return
  82. changeCustomerDialog.open({
  83. name: changeCustomerDialog.name,
  84. ticket: ticketReactive,
  85. })
  86. }
  87. </script>
  88. <template>
  89. <CommonDialog :name="name" :label="__('Ticket actions')">
  90. <div class="w-full px-3">
  91. <CommonButtonGroup class="py-6" mode="full" :options="topButtons" />
  92. <FormKit
  93. ref="autocompleteRef"
  94. type="autocomplete"
  95. outer-class="hidden"
  96. :label="__('Find a ticket')"
  97. :gql-query="gqlQuery"
  98. :action-label="__('Confirm merge')"
  99. :additional-query-params="{ exceptTicketInternalId: ticket.internalId }"
  100. :label-empty="__('Start typing to find the ticket to merge into.')"
  101. action-icon="merge"
  102. />
  103. <!-- Postponed
  104. <CommonSectionMenu>
  105. <CommonSectionMenuLink
  106. :label="__('Execute configured macros')"
  107. icon="macros"
  108. icon-bg="bg-green"
  109. />
  110. </CommonSectionMenu> -->
  111. <!-- Postponed
  112. <CommonSectionMenu>
  113. <CommonSectionMenuLink
  114. :label="__('History')"
  115. icon="history"
  116. icon-bg="bg-gray"
  117. />
  118. </CommonSectionMenu> -->
  119. <CommonSectionMenu v-if="isTicketEditable && isTicketAgent">
  120. <CommonSectionMenuLink
  121. :label="__('Change customer')"
  122. @click="showChangeCustomer"
  123. >
  124. <template #icon>
  125. <CommonUserAvatar :entity="ticket.customer" size="small" />
  126. </template>
  127. </CommonSectionMenuLink>
  128. </CommonSectionMenu>
  129. </div>
  130. </CommonDialog>
  131. </template>