EventCategories.vue 3.8 KB

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