Accesses.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template>
  2. <main>
  3. <UiInputAutocomplete
  4. :model-value="modelValue"
  5. :field="field"
  6. :label="label"
  7. :items="items"
  8. :isLoading="pending"
  9. item-title="title"
  10. item-value="id"
  11. :multiple="multiple"
  12. :chips="chips"
  13. prependIcon="fas fa-magnifying-glass"
  14. :return-object="false"
  15. @update:model-value="onUpdateModelvalue"
  16. @update:search="onUpdateSearch"
  17. />
  18. </main>
  19. </template>
  20. <script setup lang="ts">
  21. import {PropType} from "@vue/runtime-core";
  22. import {computed, ComputedRef, Ref} from "@vue/reactivity";
  23. import {AnyJson, AssociativeArray} from "~/types/data";
  24. import {useEntityFetch} from "~/composables/data/useEntityFetch";
  25. import Access from "~/models/Access/Access";
  26. const props = defineProps({
  27. /**
  28. * v-model
  29. */
  30. modelValue: {
  31. type: [String, Number, Object, Array],
  32. required: false,
  33. default: null
  34. },
  35. /**
  36. * Filtres à transmettre à la source de données
  37. */
  38. filters: {
  39. type: Object as PropType<Ref<AssociativeArray>>,
  40. required: false,
  41. default: ref(null)
  42. },
  43. /**
  44. * Nom de la propriété d'une entité lorsque l'input concerne cette propriété
  45. * - Utilisé par la validation
  46. * - Laisser null si le champ ne s'applique pas à une entité
  47. */
  48. field: {
  49. type: String,
  50. required: false,
  51. default: null
  52. },
  53. /**
  54. * Label du champ
  55. * Si non défini, c'est le nom de propriété qui est utilisé
  56. */
  57. label: {
  58. type: String,
  59. required: false,
  60. default: null
  61. },
  62. /**
  63. * Définit si le champ est en lecture seule
  64. * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-readonly
  65. */
  66. readonly: {
  67. type: Boolean,
  68. required: false
  69. },
  70. /**
  71. * Autorise la sélection multiple
  72. * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-multiple
  73. */
  74. multiple: {
  75. type: Boolean,
  76. default: false
  77. },
  78. /**
  79. * Rends les résultats sous forme de puces
  80. * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-chips
  81. */
  82. chips: {
  83. type: Boolean,
  84. default: false
  85. }
  86. })
  87. const { fetchCollection } = useEntityFetch()
  88. const i18n = useI18n()
  89. const nameFilter = ref(null)
  90. const query: ComputedRef<AnyJson> = computed(() => {
  91. let q = props.filters.value ?? {}
  92. if (nameFilter.value !== null) {
  93. q['fullname'] = nameFilter.value
  94. }
  95. return { ...q, ...{ 'groups[]': 'access_people_ref' } }
  96. })
  97. const { data: collection, pending, refresh } = await fetchCollection(Access, null, query)
  98. const accessToItem = (access: Access): { id: number | string, title: string } => {
  99. return {
  100. id: access.id,
  101. title: access.person ? `${access.person.givenName} ${access.person.name}` : i18n.t('unknown')
  102. }
  103. }
  104. const items: ComputedRef<Array<{ id: number | string, title: string }>> = computed(() => {
  105. if (!pending.value && collection.value && collection.value.items) {
  106. // @ts-ignore
  107. return collection.value.items.map(accessToItem)
  108. }
  109. return []
  110. })
  111. const emit = defineEmits(['update:model-value'])
  112. const onUpdateModelvalue = (event: Array<number>) => {
  113. console.log(event)
  114. emit('update:model-value', event)
  115. }
  116. const onUpdateSearch = (event: string) => {
  117. if (event.length <= 2) {
  118. return
  119. }
  120. refresh()
  121. }
  122. </script>
  123. <style scoped lang="scss">
  124. </style>