FavoriteTicketOverviewsEdit.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <!-- Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import CommonSectionMenu from '@mobile/components/CommonSectionMenu/CommonSectionMenu.vue'
  4. import Draggable from 'vuedraggable'
  5. import { useHeader } from '@mobile/composables/useHeader'
  6. import {
  7. NotificationTypes,
  8. useNotifications,
  9. } from '@shared/components/CommonNotifications'
  10. import { computed, ref, watch } from 'vue'
  11. import { storeToRefs } from 'pinia'
  12. import { useTicketsOverviews } from '../stores/ticketOverviews'
  13. import TicketOverviewEditItem from '../components/TicketOverviewEditItem.vue'
  14. const overviewStore = useTicketsOverviews()
  15. const {
  16. overviews,
  17. loading: overviewsLoading,
  18. overviewsByKey,
  19. } = storeToRefs(overviewStore)
  20. // we store local included, so they won't affect home page
  21. const includedIds = ref(new Set(overviewStore.includedIds.values()))
  22. watch(
  23. // when overviews are loaded, updated local included
  24. () => overviewStore.includedIds,
  25. (ids) => {
  26. includedIds.value = ids
  27. },
  28. )
  29. const includedOverviews = computed({
  30. get: () => {
  31. return [...includedIds.value]
  32. .map((id) => overviewsByKey.value[id])
  33. .filter(Boolean)
  34. },
  35. set: (value) => {
  36. includedIds.value = new Set(value.map((overview) => overview.id))
  37. },
  38. })
  39. const { notify } = useNotifications()
  40. useHeader({
  41. title: __('Ticket Overview'),
  42. backTitle: __('Home'),
  43. backUrl: '/',
  44. actionTitle: __('Done'),
  45. onAction() {
  46. if (!includedOverviews.value.length) {
  47. notify({
  48. message: __('Please select at least one ticket overview'),
  49. type: NotificationTypes.Error,
  50. })
  51. return
  52. }
  53. overviewStore.saveOverviews(includedOverviews.value)
  54. notify({
  55. message: __('Ticket Overview settings are saved'),
  56. type: NotificationTypes.Success,
  57. })
  58. },
  59. })
  60. const excludedOverviews = computed(() => {
  61. return overviews.value.filter(
  62. (overview) => !includedIds.value.has(overview.id),
  63. )
  64. })
  65. const removeFromFavorites = (id: string) => {
  66. includedIds.value.delete(id)
  67. }
  68. const addToFavorites = (id: string) => {
  69. includedIds.value.add(id)
  70. }
  71. </script>
  72. <template>
  73. <div class="mx-4 mt-6">
  74. <div v-if="overviewsLoading" class="flex items-center justify-center">
  75. <CommonIcon name="loader" animation="spin" />
  76. </div>
  77. <CommonSectionMenu
  78. v-if="!overviewsLoading"
  79. :header-title="__('Included ticket overviews')"
  80. data-test-id="includedOverviews"
  81. >
  82. <Draggable
  83. v-model="includedOverviews"
  84. :animation="100"
  85. handle=".handler"
  86. item-key="id"
  87. >
  88. <template #item="{ element }">
  89. <TicketOverviewEditItem
  90. action="delete"
  91. :overview="element"
  92. draggable
  93. @action="removeFromFavorites(element.id)"
  94. />
  95. </template>
  96. </Draggable>
  97. <div
  98. v-if="!includedOverviews.length"
  99. class="flex min-h-[54px] items-center"
  100. >
  101. <p>{{ $t('No entries') }}</p>
  102. </div>
  103. </CommonSectionMenu>
  104. <CommonSectionMenu
  105. v-if="!overviewsLoading"
  106. :header-title="__('More ticket overviews')"
  107. data-test-id="excludedOverviews"
  108. >
  109. <TicketOverviewEditItem
  110. v-for="overview of excludedOverviews"
  111. :key="overview.id"
  112. action="add"
  113. :overview="overview"
  114. @action="addToFavorites(overview.id)"
  115. />
  116. <div
  117. v-if="!excludedOverviews.length"
  118. class="flex min-h-[54px] items-center"
  119. >
  120. <p>{{ $t('No entries') }}</p>
  121. </div>
  122. </CommonSectionMenu>
  123. </div>
  124. </template>