| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- <template>
- <div class="map-container">
- <v-skeleton-loader type="image" v-if="pending"></v-skeleton-loader>
- <LMap
- v-show="!pending"
- style="height: 350px"
- :zoom="zoom"
- :center="position"
- :use-global-leaflet="false"
- >
- <LTileLayer
- url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
- attribution="&copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors"
- layer-type="base"
- name="OpenStreetMap"
- />
- <LMarker
- :lat-lng="position"
- @update:latLng="onPositionUpdate($event)"
- :draggable="!readonly"
- />
- </LMap>
- <v-btn
- prepend-icon="fas fa-location-dot"
- class="mt-3"
- v-if="searchButton && !readonly"
- @click="search()"
- >
- {{$t('search_gps_button')}}
- </v-btn>
- <div v-if="!pending && gpsResponses.length > 0">
- <div v-for="(gpsResponse, key) in gpsResponses" class="address_choices" @click="addressChoice(key)">
- {{gpsResponse['displayName']}}
- <v-btn
- prepend-icon="fas fa-map-location"
- @click="addressChoice(key)"
- >Choisir</v-btn>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import 'leaflet/dist/leaflet.css'
- import { LMap, LTileLayer, LMarker } from '@vue-leaflet/vue-leaflet'
- import {type ComputedRef, defineProps, type PropType} from 'vue'
- import {LatLng, type PointTuple} from 'leaflet'
- import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
- import UrlUtils from "~/services/utils/urlUtils";
- import type {AnyJson, CollectionResponsePromise} from "~/types/data";
- import Country from "~/models/Core/Country";
- import {useEntityManager} from "~/composables/data/useEntityManager";
- const props = defineProps({
- latitude: {
- type: Number as PropType<number | null>,
- required: true,
- },
- longitude: {
- type: Number as PropType<number | null>,
- required: true,
- },
- streetAddress:{
- type: String as PropType<string | null>,
- required: false
- },
- streetAddressSecond:{
- type: String as PropType<string | null>,
- required: false
- },
- streetAddressThird:{
- type: String as PropType<string | null>,
- required: false
- },
- postalCode:{
- type: String as PropType<string | null>,
- required: false
- },
- addressCity:{
- type: String as PropType<string | null>,
- required: false
- },
- addressCountryId:{
- type: Number as PropType<number | null>,
- required: false
- },
- searchButton:{
- type: Boolean,
- required: false,
- default: false
- },
- readonly: {
- type: Boolean,
- required: false,
- default: false,
- },
- })
- const {apiRequestService, pending} = useAp2iRequestService()
- const { em } = useEntityManager()
- const position:ComputedRef<PointTuple> = computed(()=>{
- return [props.latitude || 12, props.longitude || 12]
- })
- const zoom = ref(12)
- const emit = defineEmits(['update:latitude', 'update:longitude'])
- const onPositionUpdate = (event: LatLng):void => {
- emit('update:latitude', event.lat)
- emit('update:longitude', event.lng)
- }
- const gpsResponses:Ref<Array<AnyJson>> = ref([])
- const search = async () => {
- gpsResponses.value = []
- const baseUrl = UrlUtils.join('api', 'gps-coordinate-searching')
- const query:AnyJson = {
- 'streetAddress': props.streetAddress,
- 'streetAddressSecond': props.streetAddressSecond,
- 'streetAddressThird': props.streetAddressThird,
- 'cp': props.postalCode,
- 'city': props.addressCity
- }
- if(props.addressCountryId){
- const country:Country = em.find(Country, props.addressCountryId)
- query['country'] = country?.name
- }
- const url = UrlUtils.addQuery(baseUrl, query)
- const responses:CollectionResponsePromise = await apiRequestService.get(url)
- if(responses['member'].length > 0){
- onPositionUpdate(new LatLng(responses['member'][0]['latitude'], responses['member'][0]['longitude']))
- if(responses['member'].length > 1){
- zoom.value = 6
- gpsResponses.value = responses['member']
- }else{
- zoom.value = 12
- }
- }
- }
- const addressChoice = (key:number):void => {
- zoom.value = 12
- onPositionUpdate(new LatLng(gpsResponses.value[key]['latitude'] as number, gpsResponses.value[key]['longitude'] as number))
- }
- </script>
- <style scoped lang="scss">
- .address_choices {
- cursor: pointer;
- width: 60%;
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 0.75rem 1rem;
- border-radius: 0.5rem;
- margin-top: 0.5rem;
- background-color: #f9f9f9;
- transition: background-color 0.2s ease;
- &:hover {
- background-color: #eef3ff;
- }
- .v-btn {
- flex-shrink: 0;
- }
- }
- :deep(.v-skeleton-loader__image) {
- height: 350px;
- }
- :deep(.map_wrap) {
- height: 350px;
- }
- </style>
|