AppDesktop.vue 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <!-- Copyright (C) 2012-2025 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 { initializeDefaultObjectAttributes } from '#shared/entities/object-attributes/composables/useObjectAttributes.ts'
  14. import { useApplicationStore } from '#shared/stores/application.ts'
  15. import { useAuthenticationStore } from '#shared/stores/authentication.ts'
  16. import { useLocaleStore } from '#shared/stores/locale.ts'
  17. import { useSessionStore } from '#shared/stores/session.ts'
  18. import emitter from '#shared/utils/emitter.ts'
  19. import { initializeConfirmationDialog } from '#desktop/components/CommonConfirmationDialog/initializeConfirmationDialog.ts'
  20. import { useTicketOverviewsStore } from '#desktop/entities/ticket/stores/ticketOverviews.ts'
  21. import { useUserCurrentTaskbarTabsStore } from '#desktop/entities/user/current/stores/taskbarTabs.ts'
  22. const router = useRouter()
  23. const authentication = useAuthenticationStore()
  24. const session = useSessionStore()
  25. useMetaTitle().initializeMetaTitle()
  26. const application = useApplicationStore()
  27. onBeforeMount(() => {
  28. application.setLoaded()
  29. })
  30. useAppMaintenanceCheck()
  31. usePushMessages()
  32. // Add a check for authenticated changes (e.g. login/logout in a other
  33. // browser tab or maintenance mode switch).
  34. useAuthenticationChanges()
  35. // We need to trigger a manual translation update for the form related strings.
  36. const formConfig = useFormKitConfig()
  37. useLocaleStore().$subscribe(() => {
  38. formConfig.locale = 'staticLocale'
  39. })
  40. // The handling for invalid sessions. The event will be emitted, when from the server a "NotAuthorized"
  41. // response is received.
  42. emitter.on('sessionInvalid', async () => {
  43. if (authentication.authenticated) {
  44. await authentication.clearAuthentication()
  45. router.replace({
  46. name: 'Login',
  47. query: {
  48. invalidatedSession: '1',
  49. },
  50. })
  51. }
  52. })
  53. initializeConfirmationDialog()
  54. // Initialize the user taskbar tabs store after a valid session is present on
  55. // the app level, so that the query keeps alive.
  56. watch(
  57. () => session.initialized,
  58. (newValue, oldValue) => {
  59. if (!newValue || oldValue) return
  60. useUserCurrentTaskbarTabsStore()
  61. useTicketOverviewsStore()
  62. initializeDefaultObjectAttributes()
  63. },
  64. { immediate: true },
  65. )
  66. onBeforeUnmount(() => {
  67. emitter.off('sessionInvalid')
  68. })
  69. </script>
  70. <template>
  71. <template v-if="application.loaded">
  72. <CommonNotifications />
  73. <Teleport to="body">
  74. <CommonImageViewer />
  75. </Teleport>
  76. <RouterView />
  77. <DynamicInitializer name="dialog" />
  78. <DynamicInitializer name="flyout" />
  79. </template>
  80. </template>