EventCategories.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <template>
  2. <UiInputTreeSelect
  3. :model-value="modelValue"
  4. :items="hierarchicalItems"
  5. v-bind="$attrs"
  6. :loading="pending"
  7. @update:model-value="$emit('update:modelValue', $event)"
  8. />
  9. </template>
  10. <script setup lang="ts">
  11. import { useEntityFetch } from '~/composables/data/useEntityFetch'
  12. import EventCategory from '~/models/Core/EventCategory'
  13. const props = defineProps({
  14. modelValue: {
  15. type: Array as PropType<string[]>,
  16. required: true,
  17. },
  18. })
  19. const i18n = useI18n()
  20. const emit = defineEmits(['update:modelValue'])
  21. const { fetchCollection } = useEntityFetch()
  22. const { data: categories, pending } = fetchCollection(EventCategory)
  23. // Transform event categories into hierarchical items for TreeSelect
  24. const hierarchicalItems = computed(() => {
  25. if (!categories.value || categories.value.length === 0) {
  26. return []
  27. }
  28. const result = []
  29. const familiesMap = new Map()
  30. const subFamiliesMap = new Map()
  31. // First pass: collect all unique families and subfamilies
  32. categories.value.items.forEach((category) => {
  33. if (
  34. !category.famillyLabel ||
  35. !category.subfamillyLabel ||
  36. !category.genderLabel
  37. )
  38. return
  39. // Create unique keys for families and subfamilies
  40. const familyKey = category.famillyLabel
  41. const subfamilyKey = `${category.famillyLabel}-${category.subfamillyLabel}`
  42. // Add family if not already added
  43. if (!familiesMap.has(familyKey)) {
  44. familiesMap.set(familyKey, {
  45. id: `family-${familyKey}`,
  46. label: i18n.t(category.famillyLabel),
  47. type: 'category',
  48. level: 0,
  49. })
  50. }
  51. // Add subfamily if not already added
  52. if (!subFamiliesMap.has(subfamilyKey)) {
  53. subFamiliesMap.set(subfamilyKey, {
  54. id: `subfamily-${subfamilyKey}`,
  55. label: i18n.t(category.subfamillyLabel),
  56. type: 'subcategory',
  57. parentId: `family-${familyKey}`,
  58. level: 1,
  59. })
  60. }
  61. })
  62. // Convert families map to array and sort alphabetically by label
  63. const sortedFamilies = Array.from(familiesMap.values()).sort((a, b) =>
  64. a.label.localeCompare(b.label),
  65. )
  66. // Add sorted families to result
  67. sortedFamilies.forEach((family) => {
  68. result.push(family)
  69. })
  70. // Convert subfamilies map to array and sort alphabetically by label
  71. const sortedSubfamilies = Array.from(subFamiliesMap.values()).sort((a, b) =>
  72. a.label.localeCompare(b.label),
  73. )
  74. // Add sorted subfamilies to result
  75. sortedSubfamilies.forEach((subfamily) => {
  76. result.push(subfamily)
  77. })
  78. // Collect all genders first, then sort and add to result
  79. const genders = []
  80. categories.value.items.forEach((category) => {
  81. if (
  82. !category.famillyLabel ||
  83. !category.subfamillyLabel ||
  84. !category.genderLabel
  85. )
  86. return
  87. const familyKey = category.famillyLabel
  88. const subfamilyKey = `${category.famillyLabel}-${category.subfamillyLabel}`
  89. genders.push({
  90. id: `gender-${category.id}`,
  91. label: i18n.t(category.genderLabel),
  92. value: category.id.toString(),
  93. type: 'item',
  94. parentId: `subfamily-${subfamilyKey}`,
  95. level: 2,
  96. })
  97. })
  98. // Sort genders alphabetically by label and add to result
  99. genders
  100. .sort((a, b) => a.label.localeCompare(b.label))
  101. .forEach((gender) => {
  102. result.push(gender)
  103. })
  104. return result
  105. })
  106. </script>
  107. <style scoped lang="scss">
  108. /* No specific styles needed */
  109. </style>