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-i18n": "^9.1.6",
|
||||||
"vue-multiselect": "3.0.0-alpha.2",
|
"vue-multiselect": "3.0.0-alpha.2",
|
||||||
"vue-toast-notification": "^3.1.2",
|
"vue-toast-notification": "^3.1.2",
|
||||||
|
"vue-use-leaflet": "^0.1.7",
|
||||||
"vuex": "^4.0.0"
|
"vuex": "^4.0.0"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
|
@@ -7,7 +7,7 @@ import {
|
|||||||
getAddressesAggregated,
|
getAddressesAggregated,
|
||||||
getPostalCodes,
|
getPostalCodes,
|
||||||
} from "ChillMainAssets/vuejs/AddressPicker/driver/local-search";
|
} 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 AddressAggregatedList from "ChillMainAssets/vuejs/AddressPicker/Component/AddressAggregatedList.vue";
|
||||||
import AddressDetailsForm from "ChillMainAssets/vuejs/AddressPicker/Component/AddressDetailsForm.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 abortControllerSearchAddress: null | AbortController = null;
|
||||||
let abortControllerSearchPostalCode: null | AbortController = null;
|
let abortControllerSearchPostalCode: null | AbortController = null;
|
||||||
|
|
||||||
|
const searchResultsClasses = computed(() => ({
|
||||||
|
"mid-size": addressReference !== null,
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
const onSearch = async function (search: string): Promise<void> {
|
const onSearch = async function (search: string): Promise<void> {
|
||||||
performSearchForAddress(search);
|
performSearchForAddress(search);
|
||||||
performSearchForPostalCode(search);
|
performSearchForPostalCode(search);
|
||||||
@@ -104,10 +109,10 @@ const performSearchForPostalCode = async (search: string): Promise<void> => {
|
|||||||
<template>
|
<template>
|
||||||
<search-bar @search="onSearch"></search-bar>
|
<search-bar @search="onSearch"></search-bar>
|
||||||
<div class="address-pick-content">
|
<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>
|
<address-aggregated-list :addresses="addresses" :search-tokens="searchTokens" @pick-position="(id) => onPickPosition(id)"></address-aggregated-list>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="addressReference !== null">
|
<div v-if="addressReference !== null" class="address-details-form">
|
||||||
<address-details-form :address="addressReference"></address-details-form>
|
<address-details-form :address="addressReference"></address-details-form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -118,5 +123,15 @@ const performSearchForPostalCode = async (search: string): Promise<void> => {
|
|||||||
.address-pick-content {
|
.address-pick-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
.search-results {
|
||||||
|
&.mid-size {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.address-details-form {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -12,18 +12,20 @@
|
|||||||
Voir sur
|
Voir sur
|
||||||
<a :href="makeUrlGoogleMap(props.address)" target="_blank"
|
<a :href="makeUrlGoogleMap(props.address)" target="_blank"
|
||||||
>Google Maps</a
|
>Google Maps</a
|
||||||
>
|
> <a
|
||||||
<a :href="makeUrlOsm(props.address)" target="_blank">OSM</a>
|
:href="makeUrlOsm(props.address)" target="_blank"
|
||||||
|
>OSM</a>
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from "vue";
|
import {computed, onMounted, ref} from "vue";
|
||||||
import "leaflet/dist/leaflet.css";
|
import "leaflet/dist/leaflet.css";
|
||||||
import markerIconPng from "leaflet/dist/images/marker-icon.png";
|
import markerIconPng from "leaflet/dist/images/marker-icon.png";
|
||||||
import L, { LatLngExpression, LatLngTuple } from "leaflet";
|
import L, { LatLngExpression, LatLngTuple } from "leaflet";
|
||||||
import {Address, AddressCreation, Point} from "../../../../types";
|
import {Address, AddressCreation, Point} from "../../../../types";
|
||||||
import {buildAddressLines, getAddressPoint} from "ChillMainAssets/vuejs/_components/AddressDetails/helper";
|
import {buildAddressLines, getAddressPoint} from "ChillMainAssets/vuejs/_components/AddressDetails/helper";
|
||||||
|
import {useLeafletDisplayLayer, useLeafletMap, useLeafletMarker, useLeafletTileLayer} from "vue-use-leaflet";
|
||||||
|
|
||||||
const lonLatForLeaflet = (point: Point): LatLngTuple => {
|
const lonLatForLeaflet = (point: Point): LatLngTuple => {
|
||||||
return [point.coordinates[1], point.coordinates[0]];
|
return [point.coordinates[1], point.coordinates[0]];
|
||||||
@@ -35,36 +37,32 @@ export interface MapProps {
|
|||||||
|
|
||||||
const props = defineProps<MapProps>();
|
const props = defineProps<MapProps>();
|
||||||
|
|
||||||
const map_div = ref<HTMLDivElement | null>(null);
|
const markerIcon = L.icon({
|
||||||
let map: L.Map | null = null;
|
iconUrl: markerIconPng,
|
||||||
let marker: L.Marker | null = null;
|
iconAnchor: [12, 41],
|
||||||
|
|
||||||
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 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 makeUrlGoogleMap = (address: Address|AddressCreation): string => {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
|
Reference in New Issue
Block a user