application.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. import { computed, ref } from 'vue'
  3. import { defineStore } from 'pinia'
  4. import { useNotifications } from '@shared/components/CommonNotifications'
  5. import type { ConfigList } from '@shared/types/store'
  6. import type {
  7. ApplicationConfigQuery,
  8. ApplicationConfigQueryVariables,
  9. } from '@shared/graphql/types'
  10. import { useConfigUpdatesSubscription } from '@shared/graphql/subscriptions/configUpdates.api'
  11. import { useApplicationConfigQuery } from '@shared/graphql/queries/applicationConfig.api'
  12. import {
  13. QueryHandler,
  14. SubscriptionHandler,
  15. } from '@shared/server/apollo/handler'
  16. import testFlags from '@shared/utils/testFlags'
  17. let configUpdatesSubscriptionInitialized = false
  18. let applicationConfigQuery: QueryHandler<
  19. ApplicationConfigQuery,
  20. ApplicationConfigQueryVariables
  21. >
  22. const getApplicationConfigQuery = () => {
  23. if (applicationConfigQuery) return applicationConfigQuery
  24. applicationConfigQuery = new QueryHandler(
  25. useApplicationConfigQuery({ fetchPolicy: 'no-cache' }),
  26. )
  27. return applicationConfigQuery
  28. }
  29. // TODO: consider switching from notification to a modal dialog, and improving the message
  30. const notifications = useNotifications()
  31. export const useApplicationStore = defineStore(
  32. 'application',
  33. () => {
  34. const loaded = ref(false)
  35. const loading = computed(() => !loaded.value)
  36. const setLoaded = (): void => {
  37. const loadingAppElement: Maybe<HTMLElement> =
  38. document.getElementById('loading-app')
  39. if (notifications.hasErrors()) {
  40. loadingAppElement
  41. ?.getElementsByClassName('loading-animation')
  42. .item(0)
  43. ?.classList.add('error')
  44. loadingAppElement
  45. ?.getElementsByClassName('loading-sr-text')
  46. .item(0)
  47. ?.setAttribute('aria-hidden', 'true')
  48. const loadingFailedElement = loadingAppElement
  49. ?.getElementsByClassName('loading-failed')
  50. .item(0)
  51. loadingFailedElement?.classList.add('active')
  52. loadingFailedElement?.setAttribute('aria-hidden', 'false')
  53. return
  54. }
  55. loaded.value = true
  56. if (loadingAppElement) {
  57. loadingAppElement.remove()
  58. }
  59. testFlags.set('applicationLoaded.loaded')
  60. }
  61. const config = ref<ConfigList>({})
  62. const initializeConfigUpdateSubscription = (): void => {
  63. const configUpdatesSubscription = new SubscriptionHandler(
  64. useConfigUpdatesSubscription(),
  65. )
  66. configUpdatesSubscription.onResult((result) => {
  67. const updatedSetting = result.data?.configUpdates.setting
  68. if (updatedSetting) {
  69. config.value[updatedSetting.key] = updatedSetting.value
  70. } else {
  71. testFlags.set('useConfigUpdatesSubscription.subscribed')
  72. }
  73. })
  74. configUpdatesSubscriptionInitialized = true
  75. }
  76. const getConfig = async (): Promise<void> => {
  77. const configQuery = getApplicationConfigQuery()
  78. const result = await configQuery.loadedResult(true)
  79. if (result?.applicationConfig) {
  80. result.applicationConfig.forEach((item) => {
  81. config.value[item.key] = item.value
  82. })
  83. // app/assets/javascripts/app/config.coffee
  84. config.value.api_path = '/api/v1'
  85. }
  86. if (!configUpdatesSubscriptionInitialized) {
  87. initializeConfigUpdateSubscription()
  88. }
  89. }
  90. const resetAndGetConfig = async (): Promise<void> => {
  91. config.value = {}
  92. await getConfig()
  93. }
  94. const hasCustomProductBranding = computed(() =>
  95. Boolean(
  96. config.value.product_logo && config.value.product_logo !== 'logo.svg',
  97. ),
  98. )
  99. return {
  100. loaded,
  101. loading,
  102. setLoaded,
  103. config,
  104. initializeConfigUpdateSubscription,
  105. getConfig,
  106. resetAndGetConfig,
  107. hasCustomProductBranding,
  108. }
  109. },
  110. {
  111. requiresAuth: false,
  112. },
  113. )