LayoutTaskbarTabContent.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { computed, onActivated, ref, watch } from 'vue'
  4. import { useRoute } from 'vue-router'
  5. import { EnumTaskbarEntityAccess } from '#shared/graphql/types.ts'
  6. import type { ErrorOptions } from '#shared/router/error.ts'
  7. import { ErrorStatusCodes } from '#shared/types/error.ts'
  8. import CommonError from '#desktop/components/CommonError/CommonError.vue'
  9. import LayoutMain from '#desktop/components/layout/LayoutMain.vue'
  10. import {
  11. initializeCurrentTaskbarTab,
  12. provideCurrentTaskbarTab,
  13. } from '#desktop/entities/user/current/composables/useTaskbarTab.ts'
  14. import { cleanupRouteDialogs } from '../CommonConfirmationDialog/initializeConfirmationDialog.ts'
  15. const { path: currentRoutePath, meta: currentRouteMeta } = useRoute()
  16. // Remember the current taskbar entity key
  17. const currentTaskbarEntityKey = ref(currentRouteMeta.taskbarTabEntityKey)
  18. const {
  19. currentTaskbarTabEntityAccess,
  20. currentTaskbarTabId,
  21. ...currentTaskbarTabData
  22. } = initializeCurrentTaskbarTab(currentTaskbarEntityKey.value)
  23. onActivated(() => {
  24. if (!currentTaskbarEntityKey.value) {
  25. currentTaskbarEntityKey.value = currentRouteMeta.taskbarTabEntityKey
  26. }
  27. })
  28. watch(currentTaskbarTabId, (newCurrentTaskbarTabId) => {
  29. if (!newCurrentTaskbarTabId && currentTaskbarEntityKey) {
  30. currentTaskbarEntityKey.value = undefined
  31. }
  32. })
  33. const showContent = computed(() => {
  34. return !!(currentTaskbarTabId.value && currentTaskbarEntityKey.value)
  35. })
  36. watch(showContent, (newValue, oldValue) => {
  37. if (oldValue && !newValue) {
  38. cleanupRouteDialogs(currentRoutePath)
  39. }
  40. })
  41. // NB: Flag in the route metadata data does not seem to trigger an update all the time.
  42. // Due to this limitation, we need a way to force the re-computation in certain situations.
  43. const pageError = computed(() => {
  44. if (!currentTaskbarEntityKey.value) return null
  45. // Check first for page errors, when the entity access is not undefined.
  46. if (currentTaskbarTabEntityAccess.value === undefined) return undefined
  47. switch (currentTaskbarTabEntityAccess.value) {
  48. case EnumTaskbarEntityAccess.Forbidden:
  49. return {
  50. statusCode: ErrorStatusCodes.Forbidden,
  51. title: __('Forbidden'),
  52. message:
  53. (currentRouteMeta.messageForbidden as string) ??
  54. __('You have insufficient rights to view this object.'),
  55. } as ErrorOptions
  56. case EnumTaskbarEntityAccess.NotFound:
  57. return {
  58. statusCode: ErrorStatusCodes.NotFound,
  59. title: __('Not Found'),
  60. message:
  61. (currentRouteMeta.messageNotFound as string) ??
  62. __(
  63. 'Object with specified ID was not found. Try checking the URL for errors.',
  64. ),
  65. } as ErrorOptions
  66. case EnumTaskbarEntityAccess.Granted:
  67. default:
  68. return null
  69. }
  70. })
  71. provideCurrentTaskbarTab({
  72. currentTaskbarTabId,
  73. currentTaskbarEntityKey: currentTaskbarEntityKey.value,
  74. ...currentTaskbarTabData,
  75. })
  76. </script>
  77. <template>
  78. <LayoutMain
  79. v-if="showContent && pageError"
  80. class="flex grow flex-col items-center justify-center gap-4 bg-blue-50 dark:bg-gray-800"
  81. >
  82. <CommonError :options="pageError" authenticated />
  83. </LayoutMain>
  84. <slot v-else-if="showContent && pageError !== undefined" />
  85. </template>