PersonalSettingOverviews.vue 5.2 KB

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