mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-26 00:24:59 +00:00
[wip] Refactor AddressDetailsMap to use vue-use-leaflet
and enhance AddressPicker layout with dynamic styling adjustments.
This commit is contained in:
@@ -70,6 +70,7 @@
|
||||
"vue-i18n": "^9.1.6",
|
||||
"vue-multiselect": "3.0.0-alpha.2",
|
||||
"vue-toast-notification": "^3.1.2",
|
||||
"vue-use-leaflet": "^0.1.7",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
|
@@ -7,7 +7,7 @@ import {
|
||||
getAddressesAggregated,
|
||||
getPostalCodes,
|
||||
} from "ChillMainAssets/vuejs/AddressPicker/driver/local-search";
|
||||
import { Ref, ref } from "vue";
|
||||
import {computed, Ref, ref} from "vue";
|
||||
import AddressAggregatedList from "ChillMainAssets/vuejs/AddressPicker/Component/AddressAggregatedList.vue";
|
||||
import AddressDetailsForm from "ChillMainAssets/vuejs/AddressPicker/Component/AddressDetailsForm.vue";
|
||||
|
||||
@@ -27,6 +27,11 @@ const addressReference: Ref<AddressReference|null> = ref(null);
|
||||
let abortControllerSearchAddress: null | AbortController = null;
|
||||
let abortControllerSearchPostalCode: null | AbortController = null;
|
||||
|
||||
const searchResultsClasses = computed(() => ({
|
||||
"mid-size": addressReference !== null,
|
||||
}));
|
||||
|
||||
|
||||
const onSearch = async function (search: string): Promise<void> {
|
||||
performSearchForAddress(search);
|
||||
performSearchForPostalCode(search);
|
||||
@@ -104,10 +109,10 @@ const performSearchForPostalCode = async (search: string): Promise<void> => {
|
||||
<template>
|
||||
<search-bar @search="onSearch"></search-bar>
|
||||
<div class="address-pick-content">
|
||||
<div>
|
||||
<div class="search-results" :class="searchResultsClasses">
|
||||
<address-aggregated-list :addresses="addresses" :search-tokens="searchTokens" @pick-position="(id) => onPickPosition(id)"></address-aggregated-list>
|
||||
</div>
|
||||
<div v-if="addressReference !== null">
|
||||
<div v-if="addressReference !== null" class="address-details-form">
|
||||
<address-details-form :address="addressReference"></address-details-form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -118,5 +123,15 @@ const performSearchForPostalCode = async (search: string): Promise<void> => {
|
||||
.address-pick-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
|
||||
.search-results {
|
||||
&.mid-size {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
.address-details-form {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -12,18 +12,20 @@
|
||||
Voir sur
|
||||
<a :href="makeUrlGoogleMap(props.address)" target="_blank"
|
||||
>Google Maps</a
|
||||
>
|
||||
<a :href="makeUrlOsm(props.address)" target="_blank">OSM</a>
|
||||
> <a
|
||||
:href="makeUrlOsm(props.address)" target="_blank"
|
||||
>OSM</a>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
import markerIconPng from "leaflet/dist/images/marker-icon.png";
|
||||
import L, { LatLngExpression, LatLngTuple } from "leaflet";
|
||||
import {Address, AddressCreation, Point} from "../../../../types";
|
||||
import {buildAddressLines, getAddressPoint} from "ChillMainAssets/vuejs/_components/AddressDetails/helper";
|
||||
import {useLeafletDisplayLayer, useLeafletMap, useLeafletMarker, useLeafletTileLayer} from "vue-use-leaflet";
|
||||
|
||||
const lonLatForLeaflet = (point: Point): LatLngTuple => {
|
||||
return [point.coordinates[1], point.coordinates[0]];
|
||||
@@ -35,36 +37,32 @@ export interface MapProps {
|
||||
|
||||
const props = defineProps<MapProps>();
|
||||
|
||||
const map_div = ref<HTMLDivElement | null>(null);
|
||||
let map: L.Map | null = null;
|
||||
let marker: L.Marker | null = null;
|
||||
|
||||
onMounted(() => {
|
||||
if (map_div.value === null) {
|
||||
// there is no map div when the address does not have any Point
|
||||
return;
|
||||
}
|
||||
|
||||
if (props.address.point !== null) {
|
||||
map = L.map(map_div.value);
|
||||
map.setView(lonLatForLeaflet(props.address.point), 18);
|
||||
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution:
|
||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||
}).addTo(map);
|
||||
|
||||
const markerIcon = L.icon({
|
||||
iconUrl: markerIconPng,
|
||||
iconAnchor: [12, 41],
|
||||
});
|
||||
|
||||
marker = L.marker(lonLatForLeaflet(props.address.point), {
|
||||
icon: markerIcon,
|
||||
});
|
||||
marker.addTo(map);
|
||||
}
|
||||
const markerIcon = L.icon({
|
||||
iconUrl: markerIconPng,
|
||||
iconAnchor: [12, 41],
|
||||
});
|
||||
const latLngMarker = computed((): LatLngExpression => {
|
||||
if (props.address === null || props.address.point === null) {
|
||||
return [0, 0, 0];
|
||||
}
|
||||
|
||||
return [props.address.point.coordinates[1], props.address.point.coordinates[0], 0]
|
||||
});
|
||||
|
||||
const map_div = ref<HTMLDivElement | null>(null);
|
||||
const map = useLeafletMap(map_div, {zoom: 18, center: latLngMarker});
|
||||
const tileLayer = useLeafletTileLayer(
|
||||
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution:
|
||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||
}
|
||||
);
|
||||
useLeafletDisplayLayer(map, tileLayer);
|
||||
|
||||
|
||||
const marker = useLeafletMarker(latLngMarker, {icon: markerIcon});
|
||||
useLeafletDisplayLayer(map, marker);
|
||||
|
||||
|
||||
const makeUrlGoogleMap = (address: Address|AddressCreation): string => {
|
||||
const params = new URLSearchParams();
|
||||
|
Reference in New Issue
Block a user