TicketDetailViewActions.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. defineProps<{
  4. formInvalid: boolean
  5. newRepliesCount: number
  6. newArticlePresent: boolean
  7. canReply: boolean
  8. canSave: boolean
  9. canScrollDown: boolean
  10. hidden: boolean
  11. }>()
  12. const emit = defineEmits<{
  13. reply: []
  14. save: []
  15. }>()
  16. // Turn off transitions in test mode.
  17. const bannerTransitionDuration = VITE_TEST_MODE ? 0 : { enter: 300, leave: 200 }
  18. // Switch to instant scrolling in test mode as it may interfere with subsequent scroll actions in headless mode.
  19. const behavior = VITE_TEST_MODE ? 'instant' : 'smooth'
  20. const scrollDown = () => {
  21. window.scrollTo({ top: document.body.scrollHeight, behavior })
  22. }
  23. </script>
  24. <template>
  25. <Transition
  26. :duration="bannerTransitionDuration"
  27. enter-from-class="translate-y-full"
  28. enter-active-class="translate-y-0"
  29. enter-to-class="-translate-y-1/3"
  30. leave-from-class="-translate-y-1/3"
  31. leave-active-class="translate-y-full"
  32. leave-to-class="translate-y-full"
  33. >
  34. <div
  35. v-if="!hidden"
  36. class="pb-safe-1 fixed bottom-0 z-10 bg-gray-600/90 px-2 text-white backdrop-blur-lg transition ltr:left-0 ltr:right-0 rtl:left-0 rtl:right-0"
  37. >
  38. <div class="relative flex flex-1 items-center gap-2 p-2">
  39. <div class="flex-1">
  40. <Transition
  41. :duration="bannerTransitionDuration"
  42. enter-from-class="rtl:translate-x-20 ltr:-translate-x-20"
  43. enter-to-class="rtl:-translate-x-0 ltr:translate-x-0"
  44. leave-from-class="rtl:-translate-x-0 ltr:translate-x-0"
  45. leave-to-class="rtl:translate-x-20 ltr:-translate-x-20"
  46. >
  47. <button
  48. v-if="canScrollDown"
  49. class="bg-blue relative flex h-8 cursor-pointer items-center rounded-2xl px-2 transition"
  50. :aria-label="
  51. newRepliesCount
  52. ? $t('Scroll down to see %s new replies', newRepliesCount)
  53. : $t('Scroll down')
  54. "
  55. @click="scrollDown"
  56. >
  57. <CommonIcon name="arrow-down" size="small" decorative />
  58. <span
  59. v-if="newRepliesCount"
  60. aria-hidden="true"
  61. data-test-id="new-replies-count"
  62. class="bg-yellow absolute top-0 z-10 h-4 min-w-[1rem] rounded-full px-1 text-center text-xs text-black ltr:ml-4 rtl:mr-4"
  63. >
  64. {{ newRepliesCount }}
  65. </span>
  66. </button>
  67. </Transition>
  68. </div>
  69. <div class="flex gap-2">
  70. <FormKit
  71. v-if="canReply"
  72. variant="secondary"
  73. input-class="flex gap-1 flex justify-center items-center font-semibold text-base px-3 py-1 !text-white formkit-variant-secondary:bg-blue rounded select-none"
  74. type="button"
  75. @click.prevent="emit('reply')"
  76. >
  77. <div>
  78. <CommonIcon name="chat" size="small" decorative />
  79. </div>
  80. <span class="line-clamp-1 break-all">
  81. {{ newArticlePresent ? $t('Edit reply') : $t('Add reply') }}
  82. </span>
  83. </FormKit>
  84. <FormKit
  85. v-if="canSave"
  86. variant="submit"
  87. input-class="font-semibold text-base px-4 py-1 !text-black formkit-variant-primary:bg-yellow rounded select-none"
  88. wrapper-class="flex justify-center items-center"
  89. type="button"
  90. form="form-ticket-edit"
  91. @click.prevent="emit('save')"
  92. >
  93. {{ $t('Save') }}
  94. </FormKit>
  95. <button v-if="formInvalid" @click="emit('save')">
  96. <span
  97. role="status"
  98. :aria-label="$t('Validation failed')"
  99. class="bg-red absolute bottom-7 h-5 w-5 cursor-pointer rounded-full text-center text-xs leading-5 text-black ltr:right-2 rtl:left-2"
  100. >
  101. <CommonIcon
  102. class="mx-auto h-5"
  103. name="close"
  104. size="tiny"
  105. decorative
  106. />
  107. </span>
  108. </button>
  109. </div>
  110. </div>
  111. </div>
  112. </Transition>
  113. </template>