mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
633 lines
21 KiB
Vue
633 lines
21 KiB
Vue
<template>
|
|
|
|
<!-- step0 -->
|
|
<show-pane v-if="flag.showPane"
|
|
v-bind:context="this.context"
|
|
v-bind:options="this.options"
|
|
v-bind:default="this.default"
|
|
v-bind:entity="this.entity"
|
|
v-bind:flag="this.flag"
|
|
@openEditPane="openEditPane"
|
|
ref="showAddress">
|
|
</show-pane>
|
|
|
|
<!-- step 1 -->
|
|
<teleport to="body" v-if="inModal">
|
|
<modal v-if="flag.suggestPane"
|
|
modalDialogClass="modal-dialog-scrollable modal-xl"
|
|
@close="resetPane">
|
|
|
|
<template v-slot:header>
|
|
<h2 class="modal-title">{{ $t(getTextTitle) }}
|
|
<span v-if="flag.loading" class="loading">
|
|
<i class="fa fa-circle-o-notch fa-spin fa-fw"></i>
|
|
<span class="sr-only">{{ $t('loading') }}</span>
|
|
</span>
|
|
</h2>
|
|
</template>
|
|
|
|
<template v-slot:body>
|
|
<suggest-pane
|
|
v-bind:context="this.context"
|
|
v-bind:options="this.options"
|
|
v-bind:default="this.default"
|
|
v-bind:entity="this.entity"
|
|
v-bind:flag="this.flag"
|
|
ref="suggestAddress">
|
|
</suggest-pane>
|
|
</template>
|
|
|
|
<template v-slot:footer>
|
|
<button @click="openEditPane"
|
|
class="btn btn-update">
|
|
{{ $t('action.edit')}}
|
|
</button>
|
|
<!--
|
|
<button class="btn btn-save">
|
|
{{ $t('action.save')}}
|
|
</button>
|
|
-->
|
|
</template>
|
|
|
|
</modal>
|
|
</teleport>
|
|
<div class="mt-4" v-else>
|
|
<suggest-pane v-if="flag.suggestPane"
|
|
v-bind:context="this.context"
|
|
v-bind:options="this.options"
|
|
v-bind:default="this.default"
|
|
v-bind:entity="this.entity"
|
|
v-bind:flag="this.flag"
|
|
v-bind:insideModal="false"
|
|
@openEditPane="openEditPane"
|
|
ref="suggestAddress">
|
|
</suggest-pane>
|
|
</div>
|
|
|
|
<!-- step 2 -->
|
|
<teleport to="body" v-if="inModal">
|
|
<modal v-if="flag.editPane"
|
|
modalDialogClass="modal-dialog-scrollable modal-xl"
|
|
@close="resetPane">
|
|
|
|
<template v-slot:header>
|
|
<h2 class="modal-title">{{ $t(getTextTitle) }}
|
|
<span v-if="flag.loading" class="loading">
|
|
<i class="fa fa-circle-o-notch fa-spin fa-fw"></i>
|
|
<span class="sr-only">{{ $t('loading') }}</span>
|
|
</span>
|
|
</h2>
|
|
</template>
|
|
|
|
<template v-slot:body>
|
|
<edit-pane
|
|
v-bind:context="this.context"
|
|
v-bind:options="this.options"
|
|
v-bind:default="this.default"
|
|
v-bind:entity="this.entity"
|
|
v-bind:flag="this.flag"
|
|
@getCities="getCities"
|
|
@getReferenceAddresses="getReferenceAddresses">
|
|
</edit-pane>
|
|
</template>
|
|
|
|
<template v-slot:footer>
|
|
<button class="btn btn-cancel change-icon" @click="flag.showPane = true; flag.editPane = false;">
|
|
{{ $t('action.cancel') }}
|
|
</button>
|
|
<button class="btn btn-update"
|
|
@click="closeEditPane">
|
|
{{ $t('action.valid')}}
|
|
</button>
|
|
</template>
|
|
|
|
</modal>
|
|
</teleport>
|
|
<div class="mt-4" v-else>
|
|
<edit-pane v-if="flag.editPane"
|
|
v-bind:context="this.context"
|
|
v-bind:options="this.options"
|
|
v-bind:default="this.default"
|
|
v-bind:entity="this.entity"
|
|
v-bind:flag="this.flag"
|
|
v-bind:insideModal="false"
|
|
@closeEditPane="closeEditPane"
|
|
@getCities="getCities"
|
|
@getReferenceAddresses="getReferenceAddresses">
|
|
</edit-pane>
|
|
</div>
|
|
|
|
<!-- step 3 -->
|
|
<teleport to="body" v-if="inModal">
|
|
<modal v-if="flag.datePane"
|
|
modalDialogClass="modal-dialog-scrollable modal-xl"
|
|
@close="resetPane">
|
|
|
|
<template v-slot:header>
|
|
<h2 class="modal-title">{{ $t(getTextTitle) }}
|
|
<span v-if="flag.loading" class="loading">
|
|
<i class="fa fa-circle-o-notch fa-spin fa-fw"></i>
|
|
<span class="sr-only">{{ $t('loading') }}</span>
|
|
</span>
|
|
</h2>
|
|
</template>
|
|
|
|
<template v-slot:body>
|
|
<date-pane
|
|
v-bind:context="this.context"
|
|
v-bind:options="this.options"
|
|
v-bind:default="this.default"
|
|
v-bind:entity="this.entity"
|
|
v-bind:flag="this.flag"
|
|
ref="dateAddress">
|
|
</date-pane>
|
|
</template>
|
|
|
|
<template v-slot:footer>
|
|
<button @click="openEditPane"
|
|
class="btn btn-update">
|
|
{{ $t('action.edit')}}
|
|
</button>
|
|
<button class="btn btn-save">
|
|
{{ $t('action.save')}}
|
|
</button>
|
|
</template>
|
|
|
|
</modal>
|
|
</teleport>
|
|
<div class="mt-4" v-else>
|
|
<date-pane v-if="flag.datePane"
|
|
v-bind:context="this.context"
|
|
v-bind:options="this.options"
|
|
v-bind:default="this.default"
|
|
v-bind:entity="this.entity"
|
|
v-bind:flag="this.flag"
|
|
v-bind:insideModal="false"
|
|
@openEditPane="openEditPane"
|
|
ref="dateAddress">
|
|
</date-pane>
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<script>
|
|
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
|
|
import { getAddress, fetchCountries, fetchCities, fetchReferenceAddresses, patchAddress, postAddress, postPostalCode } from '../api';
|
|
import { postAddressToPerson, postAddressToHousehold } from "ChillPersonAssets/vuejs/_api/AddAddress.js";
|
|
import ShowPane from './ShowPane.vue';
|
|
import SuggestPane from './SuggestPane.vue';
|
|
import EditPane from './EditPane.vue';
|
|
import DatePane from './DatePane.vue';
|
|
|
|
export default {
|
|
name: "AddAddress",
|
|
props: ['context', 'options', 'addressChangedCallback'],
|
|
components: {
|
|
Modal,
|
|
ShowPane,
|
|
SuggestPane,
|
|
EditPane,
|
|
DatePane
|
|
},
|
|
data() {
|
|
return {
|
|
flag: {
|
|
showPane: true, // begin with showPane
|
|
suggestPane: false,
|
|
editPane: false,
|
|
datePane: false,
|
|
loading: false,
|
|
success: false
|
|
},
|
|
default: {
|
|
button: {
|
|
text: { create: 'add_an_address_title', edit: 'edit_address' },
|
|
type: { create: 'btn-create', edit: 'btn-update'},
|
|
displayText: true
|
|
},
|
|
title: { create: 'add_an_address_title', edit: 'edit_address' },
|
|
openPanesInModal: true,
|
|
stickyActions: false,
|
|
useDate: {
|
|
validFrom: false,
|
|
validTo: false
|
|
}
|
|
},
|
|
entity: {
|
|
address: {}, // <== loaded and returned
|
|
loaded: {
|
|
countries: [],
|
|
cities: [],
|
|
addresses: [],
|
|
},
|
|
selected: { // <== make temporary changes
|
|
isNoAddress: false,
|
|
country: {},
|
|
city: {},
|
|
postcode: {
|
|
code: null,
|
|
name: null
|
|
},
|
|
address: {},
|
|
writeNew: {
|
|
address: false,
|
|
postcode: false
|
|
},
|
|
valid: {
|
|
from: new Date(),
|
|
to: new Date()
|
|
}
|
|
},
|
|
addressMap: {
|
|
// Note: LeafletJs demands [lat, lon]
|
|
// cfr https://macwright.com/lonlat/
|
|
center : [48.8589, 2.3469],
|
|
zoom: 12
|
|
},
|
|
},
|
|
errorMsg: []
|
|
}
|
|
},
|
|
computed: {
|
|
inModal() {
|
|
return (typeof this.options.openPanesInModal !== 'undefined') ?
|
|
this.options.openPanesInModal : this.default.openPanesInModal;
|
|
},
|
|
useDatePane() {
|
|
let vFrom = (typeof this.options.useDate !== 'undefined'
|
|
&& typeof this.options.useDate.validFrom !== 'undefined') ?
|
|
this.options.useDate.validFrom : this.default.useDate.validFrom ;
|
|
let vTo = (typeof this.options.useDate !== 'undefined'
|
|
&& typeof this.options.useDate.validTo !== 'undefined') ?
|
|
this.options.useDate.validTo : this.default.useDate.validTo ;
|
|
return (vFrom || vTo) ? true : false;
|
|
},
|
|
hasSuggestions() {
|
|
// TODO
|
|
//return addressSuggestions.length > 0
|
|
return true;
|
|
},
|
|
getTextTitle() {
|
|
if ( typeof this.options.title !== 'undefined'
|
|
&& ( this.options.title.edit !== null
|
|
|| this.options.title.create !== null
|
|
)) {
|
|
return (this.context.edit) ? this.options.title.edit : this.options.title.create;
|
|
}
|
|
return (this.context.edit) ? this.default.title.edit : this.default.title.create;
|
|
},
|
|
bypassFirstStep() {
|
|
// exception: passing step0 if new address and pane are not in modal
|
|
return !this.context.edit && !this.inModal && this.flag.editPane === false
|
|
}
|
|
},
|
|
mounted() {
|
|
|
|
//console.log('options displayText', this.options.button.displayText);
|
|
//console.log('options bindModal.step1', this.options.bindModal.step1);
|
|
//console.log('options bindModal.step2', this.options.bindModal.step2);
|
|
//console.log('options useDate.validFrom', this.options.useDate.validFrom);
|
|
//console.log('options useDate.validTo', this.options.useDate.validTo);
|
|
console.log('useDatePane', this.useDatePane);
|
|
|
|
//console.log('Mounted now !');
|
|
this.openShowPane();
|
|
|
|
},
|
|
methods: {
|
|
|
|
/*
|
|
* Opening and closing Panes when interacting with buttons
|
|
*/
|
|
openShowPane() {
|
|
if (this.context.edit) {
|
|
console.log('getInitialAddress');
|
|
this.getInitialAddress(this.context.addressId);
|
|
}
|
|
if (this.bypassFirstStep) {
|
|
this.closeShowPane();
|
|
this.openEditPane();
|
|
} else {
|
|
this.flag.showPane = true;
|
|
console.log('step0: open the Show Panel');
|
|
}
|
|
},
|
|
closeShowPane() {
|
|
// Show pane can be closed only when openPanesInModal is false
|
|
if (!this.inModal) {
|
|
this.flag.showPane = false;
|
|
console.log('step0: close the Show Panel');
|
|
}
|
|
},
|
|
openSuggestPane() {
|
|
this.flag.suggestPane = true;
|
|
console.log('step1: open the Suggestion Panel');
|
|
},
|
|
closeSuggestPane() {
|
|
this.flag.suggestPane = false;
|
|
console.log('step1: close the Suggestion Panel');
|
|
},
|
|
openEditPane() {
|
|
/*
|
|
if (!this.context.edit && this.hasSuggestions) {
|
|
this.openSuggestPane();
|
|
} else {
|
|
}
|
|
*/
|
|
this.initForm();
|
|
this.getCountries();
|
|
this.flag.editPane = true;
|
|
console.log('step2: open the Edit panel');
|
|
},
|
|
closeEditPane() {
|
|
this.applyChanges();
|
|
this.flag.editPane = false;
|
|
console.log('step2: close the Edit Panel');
|
|
/*
|
|
if (!this.context.edit && this.useDatePane) {
|
|
this.openDatePane();
|
|
} else {
|
|
}
|
|
*/
|
|
this.openShowPane()
|
|
},
|
|
openDatePane() {
|
|
this.flag.datePane = true;
|
|
console.log('step3: open the Date Panel');
|
|
},
|
|
closeDatePane() {
|
|
this.flag.datePane = false;
|
|
console.log('step3: close the Date Panel');
|
|
},
|
|
resetPane() {
|
|
this.flag.suggestPane = false;
|
|
this.flag.editPane = false;
|
|
this.flag.datePane = false;
|
|
this.flag.showPane = true;
|
|
},
|
|
|
|
/*
|
|
* Async Fetch datas
|
|
*/
|
|
getInitialAddress(id) {
|
|
this.flag.loading = true;
|
|
getAddress(id).then(
|
|
address => new Promise((resolve, reject) => {
|
|
this.entity.address = address;
|
|
this.flag.loading = false;
|
|
resolve();
|
|
}))
|
|
.catch((error) => {
|
|
this.errorMsg.push(error.message);
|
|
this.flag.loading = false;
|
|
});
|
|
},
|
|
|
|
getCountries() {
|
|
this.flag.loading = true;
|
|
fetchCountries().then(
|
|
countries => new Promise((resolve, reject) => {
|
|
this.entity.loaded.countries = countries.results;
|
|
this.flag.showPane = false;
|
|
this.flag.editPane = true;
|
|
this.flag.loading = false;
|
|
resolve()
|
|
}))
|
|
.catch((error) => {
|
|
this.errorMsg.push(error.message);
|
|
this.flag.loading = false;
|
|
});
|
|
},
|
|
|
|
getCities(country) {
|
|
this.flag.loading = true;
|
|
fetchCities(country).then(
|
|
cities => new Promise((resolve, reject) => {
|
|
this.entity.loaded.cities = cities.results.filter(c => c.origin !== 3); // filter out user-defined cities
|
|
this.flag.loading = false;
|
|
resolve();
|
|
}))
|
|
.catch((error) => {
|
|
this.errorMsg.push(error.message);
|
|
this.flag.loading = false;
|
|
});
|
|
},
|
|
|
|
getReferenceAddresses(city) {
|
|
this.flag.loading = true;
|
|
fetchReferenceAddresses(city).then(
|
|
addresses => new Promise((resolve, reject) => {
|
|
this.entity.loaded.addresses = addresses.results;
|
|
this.flag.loading = false;
|
|
resolve();
|
|
}))
|
|
.catch((error) => {
|
|
this.errorMsg.push(error.message);
|
|
this.flag.loading = false;
|
|
});
|
|
},
|
|
|
|
/*
|
|
* Make form ready for new changes
|
|
*/
|
|
initForm() {
|
|
console.log('init form');
|
|
|
|
this.entity.loaded.addresses = [];
|
|
this.entity.loaded.cities = [];
|
|
this.entity.loaded.countries = [];
|
|
|
|
this.entity.selected.isNoAddress = (this.context.edit && this.entity.address.text === '') ? true : false;
|
|
|
|
this.entity.selected.country = this.context.edit ? this.entity.address.country : {};
|
|
this.entity.selected.postcode = this.context.edit ? this.entity.address.postcode : {};
|
|
this.entity.selected.city = {};
|
|
|
|
this.entity.selected.address = {};
|
|
this.entity.selected.address.street = this.context.edit ? this.entity.address.street: null;
|
|
this.entity.selected.address.streetNumber = this.context.edit ? this.entity.address.streetNumber: null;
|
|
this.entity.selected.address.floor = this.context.edit ? this.entity.address.floor: null;
|
|
this.entity.selected.address.corridor = this.context.edit ? this.entity.address.corridor: null;
|
|
this.entity.selected.address.steps = this.context.edit ? this.entity.address.steps: null;
|
|
this.entity.selected.address.flat = this.context.edit ? this.entity.address.flat: null;
|
|
this.entity.selected.address.buildingName = this.context.edit ? this.entity.address.buildingName: null;
|
|
this.entity.selected.address.distribution = this.context.edit ? this.entity.address.distribution: null;
|
|
this.entity.selected.address.extra = this.context.edit ? this.entity.address.extra: null;
|
|
|
|
this.entity.selected.writeNew.address = this.context.edit;
|
|
this.entity.selected.writeNew.postcode = this.context.edit;
|
|
},
|
|
|
|
/*
|
|
* When changes are validated (get out step2 edit pane, button valid),
|
|
* apply some transformations before asyncing with backend
|
|
* from entity.selected to entity.address
|
|
*/
|
|
applyChanges()
|
|
{
|
|
let newAddress = {
|
|
'isNoAddress': this.entity.selected.isNoAddress,
|
|
'street': this.entity.selected.isNoAddress ? '' : this.entity.selected.address.street,
|
|
'streetNumber': this.entity.selected.isNoAddress ? '' : this.entity.selected.address.streetNumber,
|
|
'postcode': {'id': this.entity.selected.city.id },
|
|
'floor': this.entity.selected.address.floor,
|
|
'corridor': this.entity.selected.address.corridor,
|
|
'steps': this.entity.selected.address.steps,
|
|
'flat': this.entity.selected.address.flat,
|
|
'buildingName': this.entity.selected.address.buildingName,
|
|
'distribution': this.entity.selected.address.distribution,
|
|
'extra': this.entity.selected.address.extra
|
|
};
|
|
|
|
if (this.entity.selected.address.point !== undefined) {
|
|
newAddress = Object.assign(newAddress, {
|
|
'point': this.entity.selected.address.point.coordinates
|
|
});
|
|
}
|
|
if (this.entity.selected.writeNew.postcode) {
|
|
let newPostcode = this.entity.selected.postcode;
|
|
newPostcode = Object.assign(newPostcode, {
|
|
'country': {'id': this.entity.selected.country.id },
|
|
});
|
|
newAddress = Object.assign(newAddress, {
|
|
'newPostcode': newPostcode
|
|
});
|
|
}
|
|
|
|
if (this.context.edit) {
|
|
this.updateAddress({
|
|
addressId: this.context.addressId,
|
|
newAddress: newAddress
|
|
})
|
|
.then(payload => {
|
|
console.log('payload', payload);
|
|
this.closePaneAndCallbackSubmit(payload);
|
|
}
|
|
);
|
|
|
|
} else {
|
|
this.addNewAddress(newAddress)
|
|
.then(payload => this.closePaneAndCallbackSubmit(payload));
|
|
}
|
|
},
|
|
|
|
/*
|
|
* Async POST transactions,
|
|
* creating new address, and receive backend datas when promise is resolved
|
|
*/
|
|
addNewAddress(payload)
|
|
{
|
|
//console.log('addNewAddress', payload);
|
|
this.flag.loading = true;
|
|
|
|
if ('newPostcode' in payload) {
|
|
|
|
let postcodeBody = payload.newPostcode;
|
|
if (this.context.entity.name === 'person') {
|
|
postcodeBody = Object.assign(postcodeBody, {'origin': 3});
|
|
}
|
|
return postPostalCode(postcodeBody)
|
|
.then(postalCode => {
|
|
payload.postcode = {'id': postalCode.id };
|
|
return this.postNewAddress(payload);
|
|
});
|
|
|
|
} else {
|
|
return this.postNewAddress(payload);
|
|
}
|
|
},
|
|
|
|
postNewAddress(payload) {
|
|
//console.log('postNewAddress', payload);
|
|
return postAddress(payload)
|
|
.then(address => new Promise((resolve, reject) => {
|
|
this.entity.address = address;
|
|
this.flag.loading = false;
|
|
this.flag.success = true;
|
|
resolve({
|
|
entity: this.context.entity.name,
|
|
entityId: this.context.entity.id,
|
|
addressId: this.entity.address.address_id
|
|
}
|
|
);
|
|
}))
|
|
.catch((error) => {
|
|
this.errorMsg.push(error);
|
|
this.flag.loading = false;
|
|
});
|
|
},
|
|
|
|
/*
|
|
* Async PATCH transactions,
|
|
* then update existing address with backend datas when promise is resolved
|
|
*/
|
|
updateAddress(payload)
|
|
{
|
|
this.flag.loading = true;
|
|
|
|
// TODO change the condition because it writes new postal code in edit mode now: !writeNewPostalCode
|
|
|
|
if ('newPostcode' in payload.newAddress) {
|
|
let postcodeBody = payload.newAddress.newPostcode;
|
|
postcodeBody = Object.assign(postcodeBody, {'origin': 3});
|
|
|
|
return postPostalCode(postcodeBody)
|
|
.then(postalCode => {
|
|
console.log('create new postcode', postalCode.id);
|
|
payload.newAddress.postcode = {'id': postalCode.id };
|
|
return this.patchExistingAddress(payload);
|
|
});
|
|
|
|
} else {
|
|
return this.patchExistingAddress(payload);
|
|
}
|
|
},
|
|
|
|
patchExistingAddress(payload) {
|
|
console.log('patchExistingAddress', payload);
|
|
return patchAddress(payload.addressId, payload.newAddress)
|
|
.then(address => new Promise((resolve, reject) => {
|
|
this.entity.address = address;
|
|
this.flag.loading = false;
|
|
this.flag.success = true;
|
|
return resolve({
|
|
entity: this.context.entity.name,
|
|
entityId: this.context.entity.id,
|
|
addressId: this.entity.address.address_id
|
|
});
|
|
})
|
|
)
|
|
.catch((error) => {
|
|
this.errorMsg.push(error);
|
|
this.flag.loading = false;
|
|
});
|
|
},
|
|
|
|
/*
|
|
* Method just add closing pane to the callback method
|
|
* (get out step1 show pane, submit button)
|
|
*/
|
|
closePaneAndCallbackSubmit(payload)
|
|
{
|
|
console.log('close pane and call parent callback method', payload);
|
|
|
|
//this.initForm();
|
|
this.flag.showPane = false;
|
|
|
|
// callback props method from parent
|
|
this.addressChangedCallback(payload);
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
div.entity-address {
|
|
position: relative;
|
|
div.loading {
|
|
position: absolute;
|
|
right: 0; top: -55px;
|
|
}
|
|
}
|
|
</style>
|