| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- <!--
- Liste déroulante avec autocompletion issue de Ap2i
- @see https://vuetifyjs.com/en/components/autocompletes/#usage
- -->
- <template>
- <main>
- <UiInputAutocomplete
- :v-model="modelValue"
- :field="field"
- :label="label"
- :items="items"
- :is-loading="pending"
- item-title="title"
- item-value="id"
- :multiple="multiple"
- :chips="chips"
- prepend-icon="fas fa-magnifying-glass"
- :return-object="false"
- />
- </main>
- </template>
- <script setup lang="ts">
- import { computed } from 'vue'
- import type { ComputedRef, Ref, PropType } from 'vue'
- import { useEntityFetch } from '~/composables/data/useEntityFetch'
- import type ApiResource from '~/models/ApiResource'
- import type ApiModel from '~/models/ApiModel'
- import type { AnyJson, AssociativeArray } from '~/types/data'
- const props = defineProps({
- /**
- * v-model
- */
- modelValue: {
- type: [String, Number, Object, Array],
- required: false,
- default: null,
- },
- /**
- * Classe de l'ApiModel (ex: Organization, Notification, ...) qui sert de source à la liste
- */
- model: {
- type: Function as any as () => typeof ApiModel,
- required: true,
- },
- /**
- * Filtres à transmettre à la source de données
- */
- query: {
- type: Object as PropType<Ref<AssociativeArray>>,
- required: false,
- default: ref(null),
- },
- /**
- * Fonction qui sera exécutée sur chaque item, et qui doit renvoyer un objet contenant les
- * propriétés 'id' et 'title'
- *
- * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-item-title
- * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-item-value
- */
- transformation: {
- type: Function as PropType<
- (item: ApiResource) => { id: number | string; title: string }
- >,
- required: false,
- default: (item: ApiResource) => item,
- },
- /**
- * Nom de la propriété d'une entité lorsque l'input concerne cette propriété
- * - Utilisé par la validation
- * - Laisser null si le champ ne s'applique pas à une entité
- */
- field: {
- type: String,
- required: false,
- default: null,
- },
- /**
- * Label du champ
- * Si non défini, c'est le nom de propriété qui est utilisé
- */
- label: {
- type: String,
- required: false,
- default: null,
- },
- /**
- * Définit si le champ est en lecture seule
- * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-readonly
- */
- readonly: {
- type: Boolean,
- required: false,
- },
- /**
- * Autorise la sélection multiple
- * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-multiple
- */
- multiple: {
- type: Boolean,
- default: false,
- },
- /**
- * Rends les résultats sous forme de puces
- * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-chips
- */
- chips: {
- type: Boolean,
- default: false,
- },
- // TODO: c'est quoi?
- slotText: {
- type: Array,
- required: false,
- default: null,
- },
- })
- const { fetchCollection } = useEntityFetch()
- const query: ComputedRef<AnyJson> = computed(() => {
- return {
- ...(props.query.value ?? {}),
- ...{ 'groups[]': 'access_people_ref' },
- }
- })
- const { data: collection, pending } = await fetchCollection(
- props.model,
- null,
- query,
- )
- const items: ComputedRef<Array<{ id: number | string; title: string }>> =
- computed(() => {
- if (!pending.value && collection.value && collection.value.items) {
- return collection.value.items.map(props.transformation)
- }
- return []
- })
- </script>
|