AppDesktop.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { onBeforeMount, onBeforeUnmount, watch } from 'vue'
  4. import { useRouter } from 'vue-router'
  5. import CommonImageViewer from '#shared/components/CommonImageViewer/CommonImageViewer.vue'
  6. import CommonNotifications from '#shared/components/CommonNotifications/CommonNotifications.vue'
  7. import DynamicInitializer from '#shared/components/DynamicInitializer/DynamicInitializer.vue'
  8. import useAuthenticationChanges from '#shared/composables/authentication/useAuthenticationUpdates.ts'
  9. import useFormKitConfig from '#shared/composables/form/useFormKitConfig.ts'
  10. import useAppMaintenanceCheck from '#shared/composables/useAppMaintenanceCheck.ts'
  11. import useMetaTitle from '#shared/composables/useMetaTitle.ts'
  12. import usePushMessages from '#shared/composables/usePushMessages.ts'
  13. import { useApplicationStore } from '#shared/stores/application.ts'
  14. import { useAuthenticationStore } from '#shared/stores/authentication.ts'
  15. import { useLocaleStore } from '#shared/stores/locale.ts'
  16. import { useSessionStore } from '#shared/stores/session.ts'
  17. import emitter from '#shared/utils/emitter.ts'
  18. import { initializeConfirmationDialog } from '#desktop/components/CommonConfirmationDialog/initializeConfirmationDialog.ts'
  19. import { useUserCurrentTaskbarTabsStore } from '#desktop/entities/user/current/stores/taskbarTabs.ts'
  20. const router = useRouter()
  21. const authentication = useAuthenticationStore()
  22. const session = useSessionStore()
  23. useMetaTitle().initializeMetaTitle()
  24. const application = useApplicationStore()
  25. onBeforeMount(() => {
  26. application.setLoaded()
  27. })
  28. useAppMaintenanceCheck()
  29. usePushMessages()
  30. // Add a check for authenticated changes (e.g. login/logout in a other
  31. // browser tab or maintenance mode switch).
  32. useAuthenticationChanges()
  33. // We need to trigger a manual translation update for the form related strings.
  34. const formConfig = useFormKitConfig()
  35. useLocaleStore().$subscribe(() => {
  36. formConfig.locale = 'staticLocale'
  37. })
  38. // The handling for invalid sessions. The event will be emitted, when from the server a "NotAuthorized"
  39. // response is received.
  40. emitter.on('sessionInvalid', async () => {
  41. if (authentication.authenticated) {
  42. await authentication.clearAuthentication()
  43. router.replace({
  44. name: 'Login',
  45. query: {
  46. invalidatedSession: '1',
  47. },
  48. })
  49. }
  50. })
  51. initializeConfirmationDialog()
  52. // Initialize the user taskbar tabs store after a valid session is present on
  53. // the app level, so that the query keeps alive.
  54. watch(
  55. () => session.initialized,
  56. (newValue, oldValue) => {
  57. if (!oldValue && newValue) {
  58. useUserCurrentTaskbarTabsStore()
  59. }
  60. },
  61. { immediate: true },
  62. )
  63. const transition = VITE_TEST_MODE
  64. ? undefined
  65. : {
  66. enterActiveClass: 'duration-300 ease-out',
  67. enterFromClass: 'opacity-0 rtl:-translate-x-3/4 ltr:translate-x-3/4',
  68. enterToClass: 'opacity-100 rtl:-translate-x-0 ltr:translate-x-0',
  69. leaveActiveClass: 'duration-200 ease-in',
  70. leaveFromClass: 'opacity-100 rtl:-translate-x-0 ltr:translate-x-0',
  71. leaveToClass: 'opacity-0 rtl:-translate-x-3/4 ltr:translate-x-3/4',
  72. }
  73. onBeforeUnmount(() => {
  74. emitter.off('sessionInvalid')
  75. })
  76. </script>
  77. <template>
  78. <template v-if="application.loaded">
  79. <CommonNotifications />
  80. <Teleport to="body">
  81. <CommonImageViewer />
  82. </Teleport>
  83. <RouterView />
  84. <DynamicInitializer name="dialog" :transition="transition" />
  85. <DynamicInitializer name="flyout" :transition="transition" />
  86. </template>
  87. </template>