EventCategories.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <template>
  2. <UiInputTreeSelect
  3. :model-value="modelValue"
  4. :items="hierarchicalItems"
  5. :label="$t(label)"
  6. v-bind="$attrs"
  7. :loading="status === FETCHING_STATUS.PENDING"
  8. :max-visible-chips="6"
  9. @update:model-value="$emit('update:modelValue', $event)"
  10. />
  11. </template>
  12. <script setup lang="ts">
  13. import { computed, onBeforeUnmount, type PropType } from 'vue'
  14. import { useEntityFetch } from '~/composables/data/useEntityFetch'
  15. import EventCategory from '~/models/Core/EventCategory'
  16. import { FETCHING_STATUS } from '~/types/enum/data'
  17. const props = defineProps({
  18. modelValue: {
  19. type: Array as PropType<string[]>,
  20. required: true,
  21. },
  22. /**
  23. * Label du champ
  24. * Si non défini, c'est le nom de propriété qui est utilisé
  25. */
  26. label: {
  27. type: String,
  28. required: false,
  29. default: null,
  30. },
  31. })
  32. const i18n = useI18n()
  33. const emit = defineEmits(['update:modelValue'])
  34. const { fetchCollection } = useEntityFetch()
  35. const { data: categories, status } = fetchCollection(EventCategory)
  36. // Transform event categories into hierarchical items for TreeSelect
  37. const hierarchicalItems = computed(() => {
  38. if (
  39. !categories.value ||
  40. !categories.value.items ||
  41. categories.value.items.length === 0
  42. ) {
  43. return []
  44. }
  45. const result = []
  46. const familiesMap = new Map()
  47. const subFamiliesMap = new Map()
  48. // First pass: collect all unique families and subfamilies
  49. categories.value.items.forEach((category) => {
  50. if (
  51. !category.famillyLabel ||
  52. !category.subfamillyLabel ||
  53. !category.genderLabel
  54. )
  55. return
  56. // Create unique keys for families and subfamilies
  57. const familyKey = category.famillyLabel
  58. const subfamilyKey = `${category.famillyLabel}-${category.subfamillyLabel}`
  59. // Add family if not already added
  60. if (!familiesMap.has(familyKey)) {
  61. familiesMap.set(familyKey, {
  62. id: `family-${familyKey}`,
  63. label: i18n.t(category.famillyLabel),
  64. type: 'category',
  65. level: 0,
  66. })
  67. }
  68. // Add subfamily if not already added
  69. if (!subFamiliesMap.has(subfamilyKey)) {
  70. subFamiliesMap.set(subfamilyKey, {
  71. id: `subfamily-${subfamilyKey}`,
  72. label: i18n.t(category.subfamillyLabel),
  73. type: 'subcategory',
  74. parentId: `family-${familyKey}`,
  75. level: 1,
  76. })
  77. }
  78. })
  79. // Convert families map to array and sort alphabetically by label
  80. const sortedFamilies = Array.from(familiesMap.values()).sort((a, b) =>
  81. a.label.localeCompare(b.label),
  82. )
  83. // Add sorted families to result
  84. sortedFamilies.forEach((family) => {
  85. result.push(family)
  86. })
  87. // Convert subfamilies map to array and sort alphabetically by label
  88. const sortedSubfamilies = Array.from(subFamiliesMap.values()).sort((a, b) =>
  89. a.label.localeCompare(b.label),
  90. )
  91. // Add sorted subfamilies to result
  92. sortedSubfamilies.forEach((subfamily) => {
  93. result.push(subfamily)
  94. })
  95. // Collect all genders first, then sort and add to result
  96. const genders = []
  97. categories.value.items.forEach((category) => {
  98. if (
  99. !category.famillyLabel ||
  100. !category.subfamillyLabel ||
  101. !category.genderLabel
  102. )
  103. return
  104. const subfamilyKey = `${category.famillyLabel}-${category.subfamillyLabel}`
  105. genders.push({
  106. id: `gender-${category.id}`,
  107. label: i18n.t(category.genderLabel),
  108. value: category.id,
  109. type: 'item',
  110. parentId: `subfamily-${subfamilyKey}`,
  111. level: 2,
  112. })
  113. })
  114. // Sort genders alphabetically by label and add to result
  115. genders
  116. .sort((a, b) => a.label.localeCompare(b.label))
  117. .forEach((gender) => {
  118. result.push(gender)
  119. })
  120. return result
  121. })
  122. // Nettoyer les données lors du démontage du composant
  123. onBeforeUnmount(() => {
  124. // Nettoyer les références du store si nécessaire
  125. if (import.meta.client) {
  126. clearNuxtData('/^' + EventCategory + '_many_/')
  127. useRepo(EventCategory).flush()
  128. }
  129. })
  130. </script>
  131. <style scoped lang="scss">
  132. /* No specific styles needed */
  133. </style>