PersonalSettingOverviews.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <!-- Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { ref, watch, onActivated } from 'vue'
  4. import { NotificationTypes } from '#shared/components/CommonNotifications/types.ts'
  5. import { useNotifications } from '#shared/components/CommonNotifications/useNotifications.ts'
  6. import { useConfirmation } from '#shared/composables/useConfirmation.ts'
  7. import type {
  8. UserCurrentOverviewListQuery,
  9. UserCurrentOverviewOrderingUpdatesSubscription,
  10. UserCurrentOverviewOrderingUpdatesSubscriptionVariables,
  11. } from '#shared/graphql/types.ts'
  12. import MutationHandler from '#shared/server/apollo/handler/MutationHandler.ts'
  13. import QueryHandler from '#shared/server/apollo/handler/QueryHandler.ts'
  14. import CommonButton from '#desktop/components/CommonButton/CommonButton.vue'
  15. import CommonLoader from '#desktop/components/CommonLoader/CommonLoader.vue'
  16. import LayoutContent from '#desktop/components/layout/LayoutContent.vue'
  17. import { UserCurrentOverviewOrderingUpdatesDocument } from '#desktop/entities/ticket/graphql/subscriptions/userCurrentOverviewOrderingUpdates.api.ts'
  18. import PersonalSettingOverviewOrder, {
  19. type OverviewItem,
  20. } from '../components/PersonalSettingOverviewOrder.vue'
  21. import { useBreadcrumb } from '../composables/useBreadcrumb.ts'
  22. import { useUserCurrentOverviewResetOrderMutation } from '../graphql/mutations/userCurrentOverviewResetOrder.api.ts'
  23. import { useUserCurrentOverviewUpdateOrderMutation } from '../graphql/mutations/userCurrentOverviewUpdateOrder.api.ts'
  24. import { useUserCurrentOverviewListQuery } from '../graphql/queries/userCurrentOverviewList.api.ts'
  25. const { breadcrumbItems } = useBreadcrumb(__('Overviews'))
  26. const overviewList = ref<OverviewItem[]>()
  27. const overviewListQuery = new QueryHandler(
  28. useUserCurrentOverviewListQuery({ ignoreUserConditions: true }),
  29. )
  30. const overviewListQueryLoading = overviewListQuery.loading()
  31. onActivated(() => overviewListQuery.refetch())
  32. overviewListQuery.subscribeToMore<
  33. UserCurrentOverviewOrderingUpdatesSubscriptionVariables,
  34. UserCurrentOverviewOrderingUpdatesSubscription
  35. >({
  36. document: UserCurrentOverviewOrderingUpdatesDocument,
  37. variables: { ignoreUserConditions: true },
  38. updateQuery: (prev, { subscriptionData }) => {
  39. if (!subscriptionData.data?.userCurrentOverviewOrderingUpdates.overviews) {
  40. return null as unknown as UserCurrentOverviewListQuery
  41. }
  42. return {
  43. userCurrentTicketOverviews:
  44. subscriptionData.data.userCurrentOverviewOrderingUpdates.overviews,
  45. }
  46. },
  47. })
  48. watch(overviewListQuery.result(), (newValue) => {
  49. overviewList.value = newValue?.userCurrentTicketOverviews
  50. })
  51. const { notify } = useNotifications()
  52. const updateOverviewList = (newValue: OverviewItem[]) => {
  53. // Update the local order immediately, in order to avoid laggy UX.
  54. overviewList.value = newValue
  55. const overviewUpdateOrderMutation = new MutationHandler(
  56. useUserCurrentOverviewUpdateOrderMutation(),
  57. {
  58. errorNotificationMessage: __(
  59. 'Updating the order of your ticket overviews failed.',
  60. ),
  61. },
  62. )
  63. overviewUpdateOrderMutation
  64. .send({
  65. overviewIds: newValue.map((overview) => overview.id),
  66. })
  67. .then(() => {
  68. notify({
  69. id: 'overview-ordering-success',
  70. type: NotificationTypes.Success,
  71. message: __('The order of your ticket overviews was updated.'),
  72. })
  73. })
  74. }
  75. const { waitForVariantConfirmation } = useConfirmation()
  76. const resetOverviewOrder = () => {
  77. const userCurrentOverviewResetOrderMutation = new MutationHandler(
  78. useUserCurrentOverviewResetOrderMutation(),
  79. {
  80. errorNotificationMessage: __(
  81. 'Resetting the order of your ticket overviews failed.',
  82. ),
  83. },
  84. )
  85. userCurrentOverviewResetOrderMutation.send().then((data) => {
  86. if (data?.userCurrentOverviewResetOrder?.success) {
  87. notify({
  88. id: 'overview-ordering-delete-success',
  89. type: NotificationTypes.Success,
  90. message: __('The order of your ticket overviews was reset.'),
  91. })
  92. if (data.userCurrentOverviewResetOrder.overviews) {
  93. overviewList.value = data.userCurrentOverviewResetOrder.overviews
  94. }
  95. }
  96. })
  97. }
  98. const confirmResetOverviewOrder = async () => {
  99. const confirmed = await waitForVariantConfirmation('confirm')
  100. if (confirmed) resetOverviewOrder()
  101. }
  102. </script>
  103. <template>
  104. <LayoutContent :breadcrumb-items="breadcrumbItems" width="narrow">
  105. <CommonLoader class="mb-3 mt-5" :loading="overviewListQueryLoading">
  106. <div class="mb-4">
  107. <CommonLabel
  108. id="label-ticket-overview-order"
  109. class="!mt-0.5 mb-1 !block"
  110. >{{ $t('Order of ticket overviews') }}
  111. </CommonLabel>
  112. <PersonalSettingOverviewOrder
  113. :model-value="overviewList"
  114. aria-labelledby="label-ticket-overview-order"
  115. @update:model-value="updateOverviewList"
  116. />
  117. <div class="flex flex-col items-end">
  118. <CommonButton
  119. :aria-label="$t('Reset Overview Order')"
  120. class="mt-4"
  121. variant="danger"
  122. size="medium"
  123. @click.stop="confirmResetOverviewOrder"
  124. >
  125. {{ $t('Reset Overview Order') }}
  126. </CommonButton>
  127. </div>
  128. </div>
  129. </CommonLoader>
  130. </LayoutContent>
  131. </template>