CommonTranslateRenderer.vue 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { defineProps, computed } from 'vue'
  4. import { i18n } from '#shared/i18n.ts'
  5. import type { PlaceholderRenderType, RenderPlaceholder } from './types.ts'
  6. interface Props {
  7. source: string
  8. placeholders: (string | RenderPlaceholder)[]
  9. }
  10. const typeComponents: Record<PlaceholderRenderType, string> = {
  11. link: 'CommonLink',
  12. datetime: 'CommonDateTime',
  13. label: 'CommonLabel',
  14. badge: 'CommonBadge',
  15. }
  16. const props = defineProps<Props>()
  17. const translatedSourcePieces = computed(() => {
  18. const translatedSource = i18n.t(
  19. props.source,
  20. ...props.placeholders.map((placeholder) => {
  21. return typeof placeholder === 'string' ? placeholder : `%s`
  22. }),
  23. )
  24. const filteredPlaceholders = props.placeholders.filter(
  25. (ph) => typeof ph === 'object',
  26. )
  27. const translatedSourcePieces: (string | RenderPlaceholder)[] = []
  28. const translatedSourceParts = translatedSource.split('%s')
  29. translatedSourceParts.forEach((part, index) => {
  30. // Add the text part to the result
  31. if (part) translatedSourcePieces.push(part)
  32. // Add the corresponding placeholder if available
  33. if (index < translatedSourceParts.length - 1) {
  34. const placeholder = filteredPlaceholders[index]
  35. translatedSourcePieces.push(placeholder)
  36. }
  37. })
  38. return translatedSourcePieces
  39. })
  40. </script>
  41. <template>
  42. <span>
  43. <template v-for="(translatedSourcePiece, index) in translatedSourcePieces">
  44. <template v-if="typeof translatedSourcePiece === 'string'">
  45. {{ translatedSourcePiece }}
  46. </template>
  47. <template v-else>
  48. <component
  49. :is="typeComponents[translatedSourcePiece.type]"
  50. :key="`${translatedSourcePiece.type}-${index}`"
  51. v-bind="translatedSourcePiece.props"
  52. >
  53. <template v-if="translatedSourcePiece.content" #default>
  54. {{ translatedSourcePiece.content }}
  55. </template>
  56. </component>
  57. </template>
  58. </template>
  59. </span>
  60. </template>