translations.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright (C) 2012-2021 Zammad Foundation, https://zammad-foundation.org/
  2. import { defineStore } from 'pinia'
  3. import type {
  4. SingleValueStore,
  5. TranslationsStoreValue,
  6. } from '@common/types/store'
  7. import { i18n } from '@common/utils/i18n'
  8. import log from '@common/utils/log'
  9. import { useTranslationsQuery } from '@common/graphql/api'
  10. import { QueryHandler } from '@common/server/apollo/handler'
  11. import type {
  12. TranslationsQuery,
  13. TranslationsQueryVariables,
  14. } from '@common/graphql/types'
  15. import { reactive } from 'vue'
  16. import type { ReactiveFunction } from '@common/types/utils'
  17. function localStorageKey(locale: string): string {
  18. return `translationsStoreCache::${locale}`
  19. }
  20. function loadCache(locale: string): TranslationsStoreValue {
  21. const cached = JSON.parse(
  22. window.localStorage.getItem(localStorageKey(locale)) || '{}',
  23. )
  24. log.debug('translations.loadCache()', locale, cached)
  25. return {
  26. cacheKey: cached.cacheKey || '',
  27. translations: cached.translations || {},
  28. }
  29. }
  30. function setCache(locale: string, value: TranslationsStoreValue): void {
  31. const serialized = JSON.stringify(value)
  32. window.localStorage.setItem(localStorageKey(locale), serialized)
  33. log.debug('translations.setCache()', locale, value)
  34. }
  35. const translationsQueryVariables = reactive({})
  36. let translationsQuery: QueryHandler<
  37. TranslationsQuery,
  38. TranslationsQueryVariables
  39. >
  40. const getTranslationsQuery = () => {
  41. if (translationsQuery) return translationsQuery
  42. translationsQuery = new QueryHandler(
  43. useTranslationsQuery(
  44. translationsQueryVariables as ReactiveFunction<TranslationsQueryVariables>,
  45. ),
  46. )
  47. return translationsQuery
  48. }
  49. const useTranslationsStore = defineStore('translations', {
  50. state: (): SingleValueStore<TranslationsStoreValue> => {
  51. return {
  52. value: {
  53. cacheKey: 'CACHE_EMPTY',
  54. translations: {},
  55. },
  56. }
  57. },
  58. actions: {
  59. async load(locale: string): Promise<void> {
  60. log.debug('translations.load()', locale)
  61. const cachedData = loadCache(locale)
  62. Object.assign(translationsQueryVariables, {
  63. cacheKey: cachedData.cacheKey,
  64. locale,
  65. })
  66. const query = getTranslationsQuery()
  67. const result = await query.loadedResult()
  68. if (result?.translations?.isCacheStillValid) {
  69. this.value = cachedData
  70. } else {
  71. this.value = {
  72. cacheKey: result?.translations?.cacheKey || 'CACHE_EMPTY',
  73. translations: result?.translations?.translations,
  74. }
  75. setCache(locale, this.value)
  76. }
  77. log.debug(
  78. 'translations.load() setting new translation map',
  79. locale,
  80. this.value.translations,
  81. )
  82. i18n.setTranslationMap(new Map(Object.entries(this.value.translations)))
  83. },
  84. },
  85. })
  86. export default useTranslationsStore