Address selection: add a leaflet map

This commit is contained in:
nobohan 2021-05-10 17:31:22 +02:00
parent fe5745831c
commit 2fe38945d2
7 changed files with 148 additions and 137 deletions

View File

@ -4,7 +4,8 @@ const addressMessages = {
fr: {
add_an_address: 'Ajouter une adresse',
select_country: 'Choisir le pays',
select_city: 'Choisir une localité'
select_city: 'Choisir une localité',
select_address: 'Choisir une adresse'
}
};

View File

@ -0,0 +1,38 @@
import L from 'leaflet';
export const initMap = () => {
let map = L.map('address_map').setView([48.8589, 2.3469], 12);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
L.marker([48.8589, 2.3469]).addTo(map)
.bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
.openPopup();
console.log(map);
return map;
};
export const updateMap = (state) => {
// console.log(state.map.center);
// let map = L.map('address_map').setView(state.map.center, state.map.zoom);
// L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
// attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
// }).addTo(map);
// L.marker(state.map.center).addTo(map)
// .bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
// .openPopup();
// console.log(map);
};

View File

@ -1,12 +1,10 @@
import 'es6-promise/auto';
import { createStore } from 'vuex';
import { getReferenceAddress } from '../api';
//import { searchPersons } from 'ChillPersonAssets/vuejs/_api/AddPersons'
import { initMap, updateMap } from '../map';
const debug = process.env.NODE_ENV !== 'production';
// const id = window.accompanyingCourseId; //tmp TODO
const getDataPromise = getReferenceAddress()
.then(referenceAddresses => new Promise((resolve, reject) => {
@ -23,23 +21,22 @@ const getDataPromise = getReferenceAddress()
{id: 2, name: 'Aisne', code: '85045', country: 'FR'},
{id: 3, name: 'Saint-Gervais', code: '85230', country: 'FR'}
], //TODO fetch postal codes from CHILL API
selectedCountry: {id: 1, name: 'France', countryCode: 'FR'}, // TODO how to specify a default value?
selectedCountry: {id: 1, name: 'France', countryCode: 'FR'}, // TODO is it ok to specify a default value here?
selectedCity: null,
selectedAddress: null,
addressMap: {
//map: initMap(), //-> the map container is not initialised when store is created.
center : [48.8589, 2.3469],
zoom: 12
}
},
getters: {
getCountries: state => state.countries,
getSelectedCountry: state => state.selectedCountry,
getCities: state => {
console.log(state.cities)
console.log(state)
console.log(state.selectedCountry.countryCode)
console.log(state.cities.filter(c => c.country == state.selectedCountry.countryCode))
return state.selectedCountry.countryCode === undefined ?
state.cities :
state.cities.filter(c => c.country == state.selectedCountry.countryCode);
}
,
getReferenceAddresses: state => state.referenceAddresses,
getCities: state => state.selectedCountry.countryCode === undefined ?
state.cities :
state.cities.filter(c => c.country == state.selectedCountry.countryCode),
getReferenceAddresses: state => state.referenceAddresses, //TODO filter as a function of city
},
mutations: {
setSelectedCountry(state, value) {
@ -47,89 +44,23 @@ const getDataPromise = getReferenceAddress()
},
setSelectedCity(state, value) {
state.selectedCity = value;
},
setSelectedAddress(state, value) {
console.log(value)
state.selectedAddress = value;
state.addressMap.center = value.point.coordinates; //TODO is it OK to put this here?
//updateMap(state); //TODO where to listen to map center change?
},
setMapCenter(state, value) {
state.addressMap.center = value;
}
// removeParticipation(state, item) {
// //console.log('mutation: remove item', item.id);
// state.accompanying_course.participations = state.accompanying_course.participations.filter(participation => participation !== item);
// },
// closeParticipation(state, { participation, payload }) {
// console.log('### mutation: close item', { participation, payload });
// // temporaire, le temps que le backend ajoute la enddate
// participation.endDate = { datetime: "2021-05-06T10:49:00+0200" };
// // trouve dans le state le payload et le supprime du state
// state.accompanying_course.participations = state.accompanying_course.participations.filter(participation => participation !== payload);
// // pousse la participation
// state.accompanying_course.participations.push(participation);
// },
// addParticipation(state, { participation, payload }) {
// //console.log('### mutation: add participation', participation);
// state.accompanying_course.participations.push(participation);
// //console.log('count participations from state', state.accompanying_course.participations.length);
// //console.log('avant', state.add_persons.selected);
// state.add_persons.selected = state.add_persons.selected.filter(value => value !== payload);
// //console.log('après', state.add_persons.selected);
// state.add_persons.query = "";
// state.add_persons.suggested = [];
// },
// setQuery(state, query) {
// //console.log('q=', query);
// state.add_persons = Object.assign({}, state.add_persons, query);
// },
// loadSuggestions(state, suggested) {
// state.add_persons.suggested = suggested;
// },
// updateSelected(state, value) {
// state.add_persons.selected = value;
// }
},
actions: {
// removeParticipation({ commit }, payload) {
// commit('removeParticipation', payload);
// },
// closeParticipation({ commit }, payload) {
// console.log('## action: fetch delete participation: payload', payload.person.id);
// postParticipation(id, payload.person.id, 'DELETE')
// .then(participation => new Promise((resolve, reject) => {
// //console.log('payload', payload);
// commit('closeParticipation', { participation, payload });
// resolve();
// }))
// .catch((error) => {
// console.log('error', error);
// state.errorMsg.push(error.message);
// });
// },
// addParticipation({ commit }, payload) {
// console.log('## action: fetch post participation: payload', payload.id);
// postParticipation(id, payload.id, 'POST')
// .then(participation => new Promise((resolve, reject) => {
// commit('addParticipation', { participation, payload });
// resolve();
// }))
// .catch((error) => {
// state.errorMsg.push(error.message);
// });
// },
// setQuery({ commit }, payload) {
// commit('setQuery', payload);
// //console.log('## action: setquery: payload', payload);
// if (payload.query.length >= 3) {
// searchPersons(payload.query)
// .then(suggested => new Promise((resolve, reject) => {
// commit('loadSuggestions', suggested.results);
// resolve();
// }));
// } else {
// commit('loadSuggestions', []);
// }
// },
// updateSelected({ commit }, payload) {
// //console.log('## action: update selected values: payload', payload);
// commit('updateSelected', payload);
// }
}
});
resolve(store);
}));
export { getDataPromise };

View File

@ -29,7 +29,7 @@
<template v-slot:body>
<!--span class="discret">Selection: {{ selected }}</span-->
<div class="results">
<div class="address_form__left">
<!-- <div class="count">
<span>
<a v-if="suggestedCounter > 0" href="#">
@ -48,16 +48,17 @@
<city-selection>
</city-selection>
<address-selection
v-for="item in this.referenceAddresses.slice().reverse()"
v-bind:item="item"
v-bind:key="item.id">
<address-selection>
</address-selection>
<!-- <button v-if="query.length >= 3" class="sc-button bt-create ml-5 mt-2" name="createPerson">
{{ $t('action.create') }} "{{ query }}"
</button> -->
</div>
<div class="address_form__map">
<address-map>
</address-map>
</div>
</template>
<template v-slot:footer>
@ -76,6 +77,8 @@ import Modal from './Modal';
import CountrySelection from './CountrySelection';
import CitySelection from './CitySelection';
import AddressSelection from './AddressSelection';
import AddressMap from './AddressMap';
export default {
name: 'AddAddresses',
@ -84,6 +87,7 @@ export default {
CountrySelection,
CitySelection,
AddressSelection,
AddressMap
},
data() {
return {
@ -94,8 +98,7 @@ export default {
}
},
computed: {
...mapState(['add_addresses']),
referenceAddresses() { return this.$store.getters.getReferenceAddresses; }
...mapState(['add_addresses']), //TODO: is it useful?
// query: {
// set(query) {
// this.$store.dispatch('setQuery', { query });
@ -123,9 +126,9 @@ export default {
methods: {
openModal() {
this.modal.showModal = true;
this.$nextTick(function() {
this.$refs.search.focus();
})
// this.$nextTick(function() {
// this.$refs.search.focus();
// })
},
addAddresses() {
console.log('@@@ CLICK button addAddresses')

View File

@ -0,0 +1,58 @@
<template>
<div class="container">
<div id='address_map' v-bind='init' style='height:400px; width:400px;'></div>
</div>
</template>
<script>
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
let map;
export default {
name: 'AddressMap',
data() {
},//TODO useful?
computed: {
center: {
set(value) {
this.$store.commit('setMapCenter', value);
},
get() {
return this.$store.state.addressMap.center;
}
},
},
// watch: {
// center: get() {
// console.log()
// }
// },
methods:{
init() {
map = L.map('address_map').setView([48.8589, 2.3469], 12);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
L.marker([48.8589, 2.3469]).addTo(map)
.bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
.openPopup();
console.log(map);
},
update() {
console.log(this.$store.state.addressMap.center)
map.setView(this.$store.state.addressMap.center);
//TODO update map view based on the store map centerS
}
},
mounted(){
this.init()
}
}
</script>

View File

@ -1,25 +1,10 @@
<template>
<div class="list-item" :class="{ checked: isChecked }">
<div class="container">
<!--a class="discret" target="_blank" :href="url.show">{{ item.id }}</a-->
<input class=""
type="checkbox"
v-model="selected"
:value="item" />
{{ item.street }}
{{ item.streetNumber }}
</div>
<!-- <div class="right_actions">
<span class="badge badge-pill badge-secondary" :title="item.id">
{{ $t('item.type_person') }}
</span>
<a class="sc-button bt-show" target="_blank" :title="item.id" :href="url.show"></a>
</div> -->
<div class="container">
<select v-model="selected" :placeholder="$t('select_address')">
<option v-for="item in this.addresses" v-bind:item="item" v-bind:key="item.id" v-bind:value="item">
{{ item.street }}, {{ item.streetNumber }}
</option>
</select>
</div>
</template>
@ -27,24 +12,19 @@
export default {
name: 'AddressSelection',
props: ['item'],
props: ['item'], //TODO useful?
data() {
},
},//TODO useful?
computed: {
addresses() { return this.$store.getters.getReferenceAddresses; },
selected: {
set(value) {
this.$store.dispatch('updateSelected', value);
this.$store.commit('setSelectedAddress', value);
},
// get() {
// return this.$store.state.add_persons.selected; //TODO
// }
get() {
return this.$store.state.selectedAddress;
}
},
//selectedAndSuggested() {
// return this.$store.getters.selectedAndSuggested;
//},
// isChecked() {
// return (this.selected.indexOf(this.item) === -1) ? false : true;
// }
}
};
</script>

View File

@ -2,7 +2,7 @@
<div class="container">
<select v-model="selected" :placeholder="$t('select_city')">
<option v-for="item in this.cities" v-bind:item="item" v-bind:key="item.id" v-bind:value="item">
{{ item.name }}
{{ item.code }}-{{ item.name }}
</option>
</select>
</div>