Explorar o código

amélioration AutocompleteApiResource

Vincent hai 4 meses
pai
achega
f106632fc7

+ 67 - 17
components/Form/Freemium/Event.vue

@@ -112,6 +112,7 @@
 
         <client-only>
           <UiMapLeaflet
+            :readonly="!newPlace && !editPlace"
             v-model:latitude="entity.latitude"
             v-model:longitude="entity.longitude"
             :streetAddress="entity.streetAddress"
@@ -151,6 +152,27 @@
         </v-col>
       </v-row>
     </LayoutCommonSection>
+
+    <LazyLayoutDialog :show="showAlert" theme="warning">
+      <template #dialogType>{{ $t('important') }}</template>
+      <template #dialogTitle>{{ $t('place_change_everywhere') }}</template>
+      <template #dialogText>
+        <v-card-text class="text">
+          <p>
+            Si vous modifiez les informations de ce lieu et que ce lieu est lié à d'autre événements,
+            alors les changements seront répercutés dans tous vos événements liés.
+          </p>
+        </v-card-text>
+      </template>
+      <template #dialogBtn>
+        <v-btn class="mr-4 submitBtn theme-neutral-strong" @click="closeDialog">
+          {{ $t('cancel') }}
+        </v-btn>
+        <v-btn class="mr-4 submitBtn theme-warning" @click="onEditPlaceConfirm">
+          {{ $t('i_understand') }}
+        </v-btn>
+      </template>
+    </LazyLayoutDialog>
 </template>
 
 <script setup lang="ts">
@@ -180,10 +202,47 @@ const onUpdateDateTimeEnd = (entity, dateTime) =>{
   }
 }
 
+const showAlert: Ref<boolean> = ref(false)
 const newPlace: Ref<boolean> = ref(false)
 const editPlace: Ref<boolean> = ref(false)
 const onAddPlaceClick = function(entity: Event){
   newPlace.value = true
+  entity.place = null
+  resetPlace(entity)
+}
+
+const onEditPlaceClick = function(){
+  showAlert.value = true
+}
+
+const closeDialog = function(){
+  showAlert.value = false
+}
+
+const onEditPlaceConfirm = function(){
+  showAlert.value = false
+  editPlace.value = true
+}
+
+const getPlace = async (entity: Event)=>{
+  if(entity.place){
+    const placeInstance = await em.fetch(Place, entity.place as number)
+    entity.placeName = placeInstance.name
+    entity.streetAddress = placeInstance.streetAddress
+    entity.streetAddressSecond = placeInstance.streetAddressSecond
+    entity.streetAddressThird = placeInstance.streetAddressThird
+    entity.addressCity = placeInstance.addressCity
+    entity.postalCode = placeInstance.postalCode
+    entity.addressCountry = placeInstance.addressCountry
+    entity.latitude = placeInstance.latitude
+    entity.longitude = placeInstance.longitude
+    editPlace.value = false
+  }else{
+    resetPlace(entity)
+  }
+}
+
+const resetPlace = (entity: Event)=>{
   entity.placeName = null
   entity.streetAddress = null
   entity.streetAddressSecond = null
@@ -193,25 +252,16 @@ const onAddPlaceClick = function(entity: Event){
   entity.addressCountry = null
   entity.latitude = null
   entity.longitude = null
-  entity.place = null
-}
-
-const onEditPlaceClick = function(){
-  editPlace.value = true
 }
 
-const getPlace = async (entity: Event)=>{
-  const placeInstance = await em.fetch(Place, entity.place as number)
-  entity.placeName = placeInstance.name
-  entity.streetAddress = placeInstance.streetAddress
-  entity.streetAddressSecond = placeInstance.streetAddressSecond
-  entity.streetAddressThird = placeInstance.streetAddressThird
-  entity.addressCity = placeInstance.addressCity
-  entity.postalCode = placeInstance.postalCode
-  entity.addressCountry = placeInstance.addressCountry
-  entity.latitude = placeInstance.latitude
-  entity.longitude = placeInstance.longitude
-}
+// Nettoyer les données lors du démontage du composant
+onBeforeUnmount(() => {
+  // Nettoyer les références du store si nécessaire
+  if (process.client) {
+    clearNuxtData('/^' + Place.entity + '_/')
+    useRepo(Place).flush()
+  }
+})
 </script>
 
 <style scoped lang="scss">

+ 10 - 0
components/Ui/Input/Autocomplete.vue

@@ -10,6 +10,7 @@ Liste déroulante avec autocompletion, à placer dans un composant `UiForm`
     <v-autocomplete
       v-model:search-input="search"
       :model-value="modelValue"
+      :readonly="readonly"
       autocomplete="search"
       :items="items"
       :label="$t(fieldLabel)"
@@ -35,6 +36,7 @@ Liste déroulante avec autocompletion, à placer dans un composant `UiForm`
       :variant="variant"
       density="compact"
       class="mb-3"
+      :clearable="clearable && !readonly"
       @update:model-value="onUpdate"
       @update:search="emit('update:search', $event)"
       @update:menu="emit('update:menu', $event)"
@@ -246,6 +248,14 @@ const props = defineProps({
     required: false,
     default: 'outlined',
   },
+  /**
+   * Définit si le champ est en lecture seule
+   * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-readonly
+   */
+  clearable: {
+    type: Boolean,
+    required: false,
+  },
 })
 
 const i18n = useI18n()

+ 12 - 5
components/Ui/Input/Autocomplete/ApiResources.vue

@@ -21,6 +21,8 @@ Champs autocomplete dédié à la recherche des Accesses d'une structure
       prepend-inner-icon="fas fa-magnifying-glass"
       :return-object="false"
       :variant="variant"
+      :readonly="readonly"
+      :clearable="true"
       :class="pending || pageStore.loading ? 'hide-selection' : ''"
       @update:model-value="onUpdateModelValue"
       @update:search="onUpdateSearch"
@@ -167,7 +169,6 @@ const item = (searchItem: any): ListItem => {
       : `(${i18n.t('missing_value')})`,
   }
 }
-
 const queryActive = new Query(
   new OrderBy(props.listLabel, ORDER_BY_DIRECTION.ASC),
   new PageFilter(ref(1), ref(20)),
@@ -213,15 +214,14 @@ const items: ComputedRef<Array<ListItem>> = computed(() => {
     return []
   }
 
-  const activeItems: ListItem[] =
-    collectionActive.value.items.map(item)
+  const activeItems: ListItem[] = collectionActive.value.items.map(item)
+
   const searchedItems: ListItem[] = collectionSearch.value.items
     .map(item)
     .filter(
       (item) =>
         !collectionActive.value!.items.find((other) => other[props.listValue] === item[props.listValue]),
     )
-
   return activeItems.concat(searchedItems)
 })
 
@@ -246,8 +246,15 @@ const emit = defineEmits(['update:model-value'])
  * @param event
  */
 const onUpdateSearch = (event: string) => {
+  let search = true
+  if(searchFilter.value === null){
+    search = false
+  }
+
   searchFilter.value = event
-  refreshDebounced()
+  if(search){
+    refreshDebounced()
+  }
 }
 
 const onUpdateModelValue = (event: Array<number>) => {

+ 9 - 3
components/Ui/MapLeaflet.client.vue

@@ -20,13 +20,14 @@
       <LMarker
         :lat-lng="position"
         @update:latLng="onPositionUpdate($event)"
-        draggable />
+        :draggable="!readonly"
+         />
     </LMap>
 
     <v-btn
       prepend-icon="fas fa-location-dot"
       class="mt-3"
-      v-if="searchButton"
+      v-if="searchButton && !readonly"
       @click="search()"
     >
       {{$t('search_gps_button')}}
@@ -93,7 +94,12 @@ const props = defineProps({
     type: Boolean,
     required: false,
     default: false
-  }
+  },
+  readonly: {
+    type: Boolean,
+    required: false,
+    default: false,
+  },
 })
 
 const {apiRequestService, pending} = useAp2iRequestService()

+ 2 - 0
i18n/lang/fr/general.json

@@ -1,4 +1,6 @@
 {
+  "i_understand": "Je comprends",
+  "place_change_everywhere": "Les changements apportés seront appliqués aux autres événements",
   "event_categories_choices": "Choisissez à quelles catégories appartient votre événement",
   "search": "Rechercher",
   "others": "autres",

+ 1 - 1
services/data/Filters/SearchFilter.ts

@@ -32,7 +32,7 @@ export default class SearchFilter extends AbstractFilter implements ApiFilter {
   }
 
   protected search(value: string, filterValue: Ref<string | null>): boolean {
-    if (filterValue.value === null) {
+    if (filterValue.value === null || filterValue.value === '') {
       return false
     }