address refactoring: resolve lack of flexibility for many implementations (modal/not, overriding, options, etc. )

address creation/edition is unchanged
many variables are renamed to improve logic and readability
This commit is contained in:
Mathieu Jaumotte 2021-08-02 16:27:11 +02:00
parent 7665181d44
commit 884de5c19e
24 changed files with 894 additions and 713 deletions

View File

@ -43,6 +43,7 @@ ul.record_actions {
display: flex;
padding: 0.8em 1.6em;
border-radius: 0;
z-index: 1000;
}
/// EXCEPTIONS

View File

@ -1,149 +1,58 @@
<template>
<div class="chill-entity entity-address">
<h2 v-if="!edit">{{ $t('create_a_new_address') }}</h2>
<h2 v-else>{{ $t('edit_address') }}</h2>
<show-address
v-if="address"
v-bind:address="address">
</show-address>
<add-address
modalAddTitle="add_an_address_title"
modalEditTitle="edit_an_address_title"
@addNewAddress="addNewAddress">
</add-address>
</div>
<div v-if="!edit" class='person-address__valid'>
<h2>{{ $t('date') }}</h2>
<div class="input-group mb-3">
<span class="input-group-text" id="validFrom"><i class="fa fa-fw fa-calendar"></i></span>
<input type="date" class="form-control form-control-lg" name="validFrom"
v-bind:placeholder="$t('validFrom')"
v-model="validFrom"
aria-describedby="validFrom" />
</div>
<div v-if="errors.length > 0">
{{ errors }}
</div>
<div v-if="loading">
{{ $t('loading') }}
</div>
<div v-if="success">
{{ $t('person_address_creation_success') }}
</div>
</div>
<ul class="record_actions sticky-form-buttons">
<li class="cancel">
<a :href="backUrl" class="btn btn-cancel">{{ $t('back_to_the_list') }}</a>
</li>
<li v-if="!edit">
<button type="submit" class="btn btn-update" @click="addToPerson">
{{ $t('add_an_address_to_person') }}
</button>
</li>
</ul>
<add-address
v-bind:context="context"
v-bind:key="addAddress.key"
v-bind:options="addAddress.options"
@submitAddress="submitAddress"
ref="addAddress">
</add-address>
</template>
<script>
import AddAddress from './components/AddAddress.vue';
import ShowAddress from './components/ShowAddress.vue';
export default {
name: 'App',
name: "App",
components: {
AddAddress,
ShowAddress
AddAddress
},
data() {
return {
edit: window.mode === 'edit',
personId: window.personId,
addressId: window.addressId,
backUrl: `/fr/person/${window.personId}/address/list`, //TODO better way to pass this
validFrom: new Date().toISOString().split('T')[0]
}
},
computed: {
address() {
return this.$store.state.address;
},
errors() {
return this.$store.state.errorMsg;
},
loading() {
return this.$store.state.loading;
},
success() {
return this.$store.state.success;
context: {
edit: window.mode === 'edit',
personId: window.personId,
addressId: window.addressId,
backUrl: `/fr/person/${window.personId}/address/list`, //TODO better way to pass this
validFrom: new Date().toISOString().split('T')[0]
},
addAddress: {
key: 'person',
options: {
/// Options override default
/// First button text if create or edit address (trans chain, see i18n)
//textButton: { create: 'bim', edit: 'bam' },
/// Modal title text if create or edit address (trans chain, see i18n)
//title: { create: 'boum', edit: 'pan' },
/// Display each step in page or Modal
//bindModal: { step1: false, step2: false } //TODO true-false must not be possible
}
}
}
},
methods: {
addNewAddress({ address, modal }) {
console.log('@@@ CLICK button addNewAdress', address);
submitAddress({ submited, flag }) {
console.log('@@@ CLICK button submitAddress');
let newAddress = {
'isNoAddress': address.isNoAddress,
'street': address.isNoAddress ? '' : address.street,
'streetNumber': address.isNoAddress ? '' : address.streetNumber,
'postcode': {'id': address.selected.city.id},
'floor': address.floor,
'corridor': address.corridor,
'steps': address.steps,
'flat': address.flat,
'buildingName': address.buildingName,
'distribution': address.distribution,
'extra': address.extra
};
console.log('address to post:', submited);
console.log('datas by refs: ', this.$refs.addAddress.entity.address.text);
if (address.selected.address.point !== undefined){
newAddress = Object.assign(newAddress, {
'point': address.selected.address.point.coordinates
});
}
if (address.writeNewPostalCode){
let newPostalCode = address.newPostalCode;
newPostalCode = Object.assign(newPostalCode, {
'country': {'id': address.selected.country.id },
});
newAddress = Object.assign(newAddress, {
'newPostalCode': newPostalCode
});
}
if (this.edit){
this.$store.dispatch('updateAddress', {
addressId: this.addressId,
newAddress: newAddress
});
} else {
this.$store.dispatch('addAddress', newAddress);
}
modal.showModal = false;
},
addToPerson() {
this.$store.dispatch('addDateToAddressAndAddressToPerson', {
personId: this.personId,
addressId: this.$store.state.address.address_id,
body: { validFrom: {datetime: `${this.validFrom}T00:00:00+0100`}},
backUrl: this.backUrl
})
},
getEditAddress() {
this.$store.dispatch('getEditAddress', this.addressId);
this.$refs.addAddress.initForm(); // to cast child method
flag.showPane = false;
}
},
mounted() {
if (this.edit) {
this.getEditAddress();
}
},
};
}
}
</script>

View File

@ -4,7 +4,7 @@
* @returns {Promise} a promise containing all Country object
*/
const fetchCountries = () => {
console.log('<<< fetching countries');
//console.log('<<< fetching countries');
const url = `/api/1.0/main/country.json?item_per_page=1000`;
return fetch(url)
@ -20,7 +20,7 @@ const fetchCountries = () => {
* @returns {Promise} a promise containing all Postal Code objects filtered with country
*/
const fetchCities = (country) => {
console.log('<<< fetching cities for', country);
//console.log('<<< fetching cities for', country);
const url = `/api/1.0/main/postal-code.json?item_per_page=1000&country=${country.id}`;
return fetch(url)
.then(response => {
@ -35,7 +35,7 @@ const fetchCities = (country) => {
* @returns {Promise} a promise containing all AddressReference objects filtered with postal code
*/
const fetchReferenceAddresses = (postalCode) => {
console.log('<<< fetching references addresses for', postalCode);
//console.log('<<< fetching references addresses for', postalCode);
const url = `/api/1.0/main/address-reference.json?item_per_page=1000&postal_code=${postalCode.id}`;
return fetch(url)
.then(response => {
@ -50,7 +50,7 @@ const fetchReferenceAddresses = (postalCode) => {
* @returns {Promise} a promise containing all AddressReference objects filtered with postal code
*/
const fetchAddresses = () => {
console.log('<<< fetching addresses');
//console.log('<<< fetching addresses');
//TODO deal with huge number of addresses... we should do suggestion...
const url = `/api/1.0/main/address.json?item_per_page=1000`;
return fetch(url)
@ -133,8 +133,8 @@ const postPostalCode = (postalCode) => {
* @body Object - dictionary with changes to post
*/
const postAddressToPerson = (personId, addressId) => {
console.log(personId);
console.log(addressId);
//console.log(personId);
//console.log(addressId);
const body = {
'id': addressId
};
@ -157,7 +157,7 @@ const postAddressToPerson = (personId, addressId) => {
* @returns {Promise} a promise containing a Address object
*/
const getAddress = (id) => {
console.log('<<< get address');
//console.log('<< get address');
const url = `/api/1.0/main/address/${id}.json`;
return fetch(url)
.then(response => {

View File

@ -1,282 +1,473 @@
<template>
<button v-if="!edit"
class="btn btn-create mt-4"
type="button"
name="button"
@click="openModal">
{{ $t(modalAddTitle) }}
</button>
<button v-else
class="btn btn-create mt-4"
type="button"
name="button"
@click="openModal">
{{ $t(modalEditTitle) }}
<button v-if="step1WithModal"
@click="openShowPane"
class="btn btn-create mt-4" type="button" name="button">
{{ $t(getTextButton) }}
</button>
<teleport to="body">
<modal v-if="modal.showModal"
v-bind:modalDialogClass="modal.modalDialogClass"
@close="modal.showModal = false">
<teleport to="body" v-if="step1WithModal">
<modal v-if="flag.showPane"
modalDialogClass="modal-dialog-scrollable modal-xl"
@close="flag.showPane = false">
<template v-slot:header>
<h3 v-if="!edit" class="modal-title">{{ $t(modalAddTitle) }}</h3>
<h3 v-if="edit" class="modal-title">{{ $t(modalEditTitle) }}</h3>
<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">Loading...</span>
</span>
</h2>
</template>
<template v-slot:body>
<div class="address-form">
<h4 class="h3">{{ $t('select_an_address_title') }}
<span v-if="loading">
<i class="fa fa-circle-o-notch fa-spin fa-lg"></i>
</span>
</h4>
<div class="row my-3">
<div class="col-lg-6">
<div class="form-check">
<input type="checkbox"
class="form-check-input"
id="isNoAddress"
v-model="isNoAddress"
v-bind:value="value" />
<label class="form-check-label" for="isNoAddress">
{{ $t('isNoAddress') }}
</label>
</div>
<country-selection
v-bind:address="address"
v-bind:getCities="getCities">
</country-selection>
<city-selection
v-bind:address="address"
v-bind:focusOnAddress="focusOnAddress"
v-bind:getReferenceAddresses="getReferenceAddresses">
</city-selection>
<address-selection
v-if="!isNoAddress"
v-bind:address="address"
v-bind:updateMapCenter="updateMapCenter">
</address-selection>
</div>
<div class="col-lg-6 mt-3 mt-lg-0">
<address-map
v-bind:address="address"
ref="addressMap">
</address-map>
</div>
</div>
<address-more
v-if="!isNoAddress"
v-bind:address="address">
</address-more>
</div>
<show-address
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">
</show-address>
</template>
<template v-slot:footer>
<button class="btn btn-create"
@click.prevent="$emit('addNewAddress', { address, modal })">
{{ $t('action.add')}}
<button @click="openEditPane"
class="btn btn-update">
{{ $t('action.edit')}}
</button>
<button class="btn btn-save"
@click.prevent="$emit('submitAddress', { getSubmited , flag })">
{{ $t('action.save')}}
</button>
</template>
</modal>
</teleport>
<div class="mt-4" v-else>
<show-address 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"
v-bind:insideModal="false" @openEditPane="openEditPane"
@submitAddress="$emit('submitAddress', { getSubmited , flag })">
</show-address>
</div>
<teleport to="body" v-if="step2WithModal">
<modal v-if="flag.editPane"
modalDialogClass="modal-dialog-scrollable modal-xl"
@close="flag.editPane = false">
<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">Loading...</span>
</span>
</h2>
</template>
<template v-slot:body>
<edit-address
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-address>
</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-address 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-address>
</div>
</template>
<script>
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
import { fetchCountries, fetchCities, fetchReferenceAddresses } from '../api'
import CountrySelection from './AddAddress/CountrySelection';
import CitySelection from './AddAddress/CitySelection';
import AddressSelection from './AddAddress/AddressSelection';
import AddressMap from './AddAddress/AddressMap';
import AddressMore from './AddAddress/AddressMore'
import ShowAddress from './ShowAddress.vue';
import EditAddress from './EditAddress.vue';
import {
getAddress,
fetchCountries, fetchCities, fetchReferenceAddresses,
patchAddress, postAddress, postPostalCode, postAddressToPerson
} from '../api'
export default {
name: 'AddAddresses',
name: "AddAddress",
props: ['context', 'options'],
emits: ['submitAddress'],
components: {
Modal,
CountrySelection,
CitySelection,
AddressSelection,
AddressMap,
AddressMore
ShowAddress,
EditAddress,
},
props: [
'modalAddTitle',
'modalEditTitle'
],
emits: ['addNewAddress'],
data() {
return {
edit: window.mode === 'edit',
modal: {
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl"
flag: {
showPane: false,
editPane: false,
loading: false,
success: false
},
loading: false,
address: {
writeNewAddress: false,
writeNewPostalCode: false,
default: {
textButton: { create: 'add_an_address_title', edit: 'edit_address' },
title: { create: 'add_an_address_title', edit: 'edit_address' },
bindModal: {
step1: true,
step2: true,
},
},
entity: {
address: {}, // <== loaded and returned
loaded: {
countries: [],
cities: [],
addresses: [],
},
selected: {
selected: { // <== make temporary changes
isNoAddress: false,
country: {},
city: {},
postcode: {
code: null,
name: null
},
address: {},
},
newPostalCode: {
code: null,
name: null
writeNew: {
address: false,
postcode: false
}
},
addressMap: {
center : [48.8589, 2.3469], // Note: LeafletJs demands [lat, lon] cfr https://macwright.com/lonlat/
// Note: LeafletJs demands [lat, lon]
// cfr https://macwright.com/lonlat/
center : [48.8589, 2.3469],
zoom: 12
},
isNoAddress: false,
street: null,
streetNumber: null,
corridor: null,
steps: null,
floor: null,
flat: null,
buildingName: null,
extra: null,
distribution: null,
},
errorMsg: {},
errorMsg: []
}
},
computed: {
isNoAddress: {
set(value) {
console.log('value', value);
this.address.isNoAddress = value;
},
get() {
return this.address.isNoAddress;
// TODO improve: props options must override data default
step1WithModal() {
return (this.options.bindModal) ? this.options.bindModal.step1 : this.default.bindModal.step1;
},
step2WithModal() {
return (this.options.bindModal) ? this.options.bindModal.step2 : this.default.bindModal.step2;
},
getTextButton() {
if (this.options.textButton) {
return (this.context.edit) ? this.options.textButton.edit : this.options.textButton.create;
}
return (this.context.edit) ? this.default.textButton.edit : this.default.textButton.create;
},
getTextTitle() {
if (this.options.title) {
return (this.context.edit) ? this.options.title.edit : this.options.title.create;
}
return (this.context.edit) ? this.default.title.edit : this.default.title.create;
},
getSubmited() {
return this.entity.address;
}
},
mounted() {
this.getCountries();
if (!this.step1WithModal) {
console.log('Mounted now !');
this.openShowPane();
}
},
methods: {
openModal() {
this.modal.showModal = true;
this.resetAll();
//this.$nextTick(function() {
// this.$refs.search.focus(); // positionner le curseur à l'ouverture de la modale
//})
/*
* Opening and closing Panes when interacting with buttons
*/
openShowPane() {
console.log('open the Show Panel');
if (this.context.addressId) {
this.getInitialAddress(this.context.addressId);
}
this.flag.showPane = true;
},
focusOnCity() {
const citySelector = document.getElementById('citySelector');
citySelector.focus();
openEditPane() {
console.log('open the Edit panel');
this.initForm();
this.getCountries();
},
focusOnAddress() {
const addressSelector = document.getElementById('addressSelector');
addressSelector.focus();
closeEditPane() {
console.log('close the Edit Panel (with validation)');
this.applyChanges();
this.flag.showPane = true;
this.flag.editPane = false;
},
getCountries() {
console.log('getCountries');
this.loading = true;
fetchCountries().then(countries => new Promise((resolve, reject) => {
this.address.loaded.countries = countries.results;
resolve()
this.loading = false;
}))
.catch((error) => {
this.errorMsg.push(error.message);
this.loading = false;
});
},
getCities(country) {
console.log('getCities for', country.name);
this.loading = true;
fetchCities(country).then(cities => new Promise((resolve, reject) => {
this.address.loaded.cities = cities.results.filter(c => c.origin !== 3); // filter out user-defined cities
resolve();
this.loading = false;
/*
* 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.loading = false;
this.flag.loading = false;
});
},
getReferenceAddresses(city) {
this.loading = true;
console.log('getReferenceAddresses for', city.name);
fetchReferenceAddresses(city).then(addresses => new Promise((resolve, reject) => {
console.log('addresses', addresses);
this.address.loaded.addresses = addresses.results;
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();
this.loading = false;
}))
.catch((error) => {
this.errorMsg.push(error.message);
this.loading = false;
}))
.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,
* 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 });
} else {
this.addAddress(newAddress);
}
},
updateMapCenter(point) {
console.log('point', point);
this.address.addressMap.center[0] = point.coordinates[1]; // TODO use reverse()
this.address.addressMap.center[1] = point.coordinates[0];
this.$refs.addressMap.update(); // cast child methods
/*
* Async PATCH transactions,
* then update existing address with backend datas when promise is resolved
*/
updateAddress(payload) {
console.log('updateAddress payload', payload);
// TODO change the condition because it writes new postal code in edit mode now: !writeNewPostalCode
this.flag.loading = true;
if ('newPostcode' in payload.newAddress) {
let postcodeBody = payload.newAddress.newPostcode;
postcodeBody = Object.assign(postcodeBody, {'origin': 3});
postPostalCode(postcodeBody)
.then(postalCode => {
let body = payload.newAddress;
body.postcode = {'id': postalCode.id },
patchAddress(payload.addressId, body)
.then(address => new Promise((resolve, reject) => {
console.log('update address');
this.entity.address = address;
this.flag.loading = false;
resolve();
}))
.catch((error) => {
this.errorMsg.push(error);
this.flag.loading = false;
});
})
} else {
patchAddress(payload.addressId, payload.newAddress)
.then(address => new Promise((resolve, reject) => {
console.log('update address');
this.entity.address = address;
this.flag.loading = false;
resolve();
}))
.catch((error) => {
this.errorMsg.push(error);
this.flag.loading = false;
});
}
},
resetAll() {
console.log('reset all selected');
this.address.loaded.addresses = [];
this.address.selected.address = {};
this.address.loaded.cities = [];
this.address.selected.city = {};
this.address.selected.country = {};
this.address.isNoAddress = this.edit ? this.$store.state.editAddress.isNoAddress: false;;
this.address.street = this.edit ? this.$store.state.editAddress.street: null;
this.address.streetNumber = this.edit ? this.$store.state.editAddress.streetNumber: null;
this.address.floor = this.edit ? this.$store.state.editAddress.floor: null;
this.address.corridor = this.edit ? this.$store.state.editAddress.corridor: null;
this.address.steps = this.edit ? this.$store.state.editAddress.steps: null;
this.address.flat = this.edit ? this.$store.state.editAddress.flat: null;
this.address.buildingName = this.edit ? this.$store.state.editAddress.buildingName: null;
this.address.distribution = this.edit ? this.$store.state.editAddress.distribution: null;
this.address.extra = this.edit ? this.$store.state.editAddress.extra: null;
this.address.writeNewAddress = this.edit;
this.address.writeNewPostalCode = this.edit;
this.address.newPostalCode = this.edit ?
{
code: this.$store.state.editAddress.postcode !== undefined ? this.$store.state.editAddress.postcode.code : null,
name: this.$store.state.editAddress.postcode !== undefined ? this.$store.state.editAddress.postcode.name : null
} : {};
console.log('cities and addresses', this.address.loaded.cities, this.address.loaded.addresses);
/*
* Async POST transactions,
* creating new address, and receive backend datas when promise is resolved
*/
addAddress(payload) {
console.log('addAddress payload', payload);
this.flag.loading = true;
if('newPostcode' in payload){
let postcodeBody = payload.newPostcode;
postcodeBody = Object.assign(postcodeBody, {'origin': 3});
postPostalCode(postcodeBody)
.then(postalCode => {
let body = payload;
body.postcode = {'id': postalCode.id},
postAddress(body)
.then(address => new Promise((resolve, reject) => {
console.log('add address');
this.entity.address = address;
resolve();
this.flag.loading = false;
}))
.catch((error) => {
this.errorMsg.push(error);
this.flag.loading = false;
});
})
} else {
postAddress(payload)
.then(address => new Promise((resolve, reject) => {
console.log('add address');
this.entity.address = address;
resolve();
this.flag.loading = false;
}))
.catch((error) => {
this.errorMsg.push(error);
this.flag.loading = false;
});
}
}
}
}
</script>
<style lang="scss">
div.address-form {
h4.h3 {
font-weight: bold;
}
div#address_map {
height: 400px;
width: 100%;
div.entity-address {
position: relative;
div.loading {
position: absolute;
right: 0; top: -55px;
}
}
</style>

View File

@ -13,16 +13,18 @@ let marker;
export default {
name: 'AddressMap',
props: ['address'],
props: ['entity'],
computed: {
center() {
return this.address.addressMap.center;
return this.entity.selected.addressMap.center;
},
},
methods:{
init() {
map = L.map('address_map').setView([46.67059, -1.42683], 12);
map.scrollWheelZoom.disable();
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);
@ -36,9 +38,9 @@ export default {
},
update() {
console.log('update map with : ', this.address.addressMap.center)
marker.setLatLng(this.address.addressMap.center);
map.setView(this.address.addressMap.center, 15);
//console.log('update map with : ', this.address.addressMap.center)
marker.setLatLng(this.entity.addressMap.center);
map.setView(this.entity.addressMap.center, 15);
}
},
mounted(){

View File

@ -74,69 +74,62 @@
<script>
export default {
name: "AddressMore",
props: ['address'],
props: ['entity'],
computed: {
floor: {
set(value) {
console.log('value', value);
this.address.floor = value;
this.entity.selected.address.floor = value;
},
get() {
return this.address.floor;
return this.entity.selected.address.floor;
}
},
corridor: {
set(value) {
console.log('value', value);
this.address.corridor = value;
this.entity.selected.address.corridor = value;
},
get() {
return this.address.corridor;
return this.entity.selected.address.corridor;
}
},
steps: {
set(value) {
console.log('value', value);
this.address.steps = value;
this.entity.selected.address.steps = value;
},
get() {
return this.address.steps;
return this.entity.selected.address.steps;
}
},
flat: {
set(value) {
console.log('value', value);
this.address.flat = value;
this.entity.selected.address.flat = value;
},
get() {
return this.address.flat;
return this.entity.selected.address.flat;
}
},
buildingName: {
set(value) {
console.log('value', value);
this.address.buildingName = value;
this.entity.selected.address.buildingName = value;
},
get() {
return this.address.buildingName;
return this.entity.selected.address.buildingName;
}
},
extra: {
set(value) {
console.log('value', value);
this.address.extra = value;
this.entity.selected.address.extra = value;
},
get() {
return this.address.extra;
return this.entity.selected.address.extra;
}
},
distribution: {
set(value) {
console.log('value', value);
this.address.distribution = value;
this.entity.selected.address.distribution = value;
},
get() {
return this.address.distribution;
return this.entity.selected.address.distribution;
}
}
}

View File

@ -47,7 +47,7 @@ import VueMultiselect from 'vue-multiselect';
export default {
name: 'AddressSelection',
components: { VueMultiselect },
props: ['address', 'updateMapCenter'],
props: ['entity', 'updateMapCenter'],
data() {
return {
value: null
@ -55,28 +55,28 @@ export default {
},
computed: {
writeNewAddress() {
return this.address.writeNewAddress;
return this.entity.selected.writeNew.address;
},
writeNewPostalCode() {
return this.address.writeNewPostalCode;
return this.entity.selected.writeNew.postCode;
},
addresses() {
return this.address.loaded.addresses;
return this.entity.loaded.addresses;
},
street: {
set(value) {
this.address.street = value;
this.entity.selected.address.street = value;
},
get() {
return this.address.street;
return this.entity.selected.address.street;
}
},
streetNumber: {
set(value) {
this.address.streetNumber = value;
this.entity.selected.address.streetNumber = value;
},
get() {
return this.address.streetNumber;
return this.entity.selected.address.streetNumber;
}
},
},
@ -85,13 +85,13 @@ export default {
return value.streetNumber === undefined ? value.street : `${value.streetNumber}, ${value.street}`
},
selectAddress(value) {
this.address.selected.address = value;
this.address.street = value.street;
this.address.streetNumber = value.streetNumber;
this.entity.selected.address = value;
this.entity.selected.address.street = value.street;
this.entity.selected.address.streetNumber = value.streetNumber;
this.updateMapCenter(value.point);
},
addAddress() {
this.address.writeNewAddress = true;
this.entity.selected.writeNew.address = true;
}
}
};

View File

@ -12,13 +12,13 @@
:placeholder="$t('select_city')"
:taggable="true"
:multiple="false"
@tag="addPostalCode"
@tag="addPostcode"
:tagPlaceholder="$t('create_postal_code')"
:options="cities">
</VueMultiselect>
</div>
<div class="custom-postcode row g-1" v-if="writeNewPostalCode">
<div class="custom-postcode row g-1" v-if="writeNewPostcode">
<div class="col-4">
<div class="form-floating">
<input class="form-control"
@ -28,7 +28,7 @@
v-model="code"/>
<label for="code">{{ $t('postalCode_code') }}</label>
</div>
</div>
</div>
<div class="col-8">
<div class="form-floating">
<input class="form-control"
@ -48,33 +48,34 @@ import VueMultiselect from 'vue-multiselect';
export default {
name: 'CitySelection',
components: { VueMultiselect },
props: ['address', 'getReferenceAddresses', 'focusOnAddress'],
props: ['entity', 'focusOnAddress'],
emits: ['getReferenceAddresses'],
data() {
return {
value: null
}
},
computed: {
writeNewPostalCode() {
return this.address.writeNewPostalCode;
writeNewPostcode() {
return this.entity.selected.writeNew.postcode;
},
cities() {
return this.address.loaded.cities;
return this.entity.loaded.cities;
},
name: {
set(value) {
this.address.newPostalCode.name = value;
this.entity.selected.postcode.name = value;
},
get() {
return this.address.newPostalCode.name;
return this.entity.selected.postcode.name;
}
},
code: {
set(value) {
this.address.newPostalCode.code= value;
this.entity.selected.postcode.code= value;
},
get() {
return this.address.newPostalCode.code;
return this.entity.selected.postcode.code;
}
},
},
@ -83,14 +84,14 @@ export default {
return `${value.code}-${value.name}`
},
selectCity(value) {
this.address.selected.city = value;
this.address.newPostalCode.name = value.name;
this.address.newPostalCode.code = value.code;
this.getReferenceAddresses(value);
this.entity.selected.city = value;
this.entity.selected.postcode.name = value.name;
this.entity.selected.postcode.code = value.code;
this.$emit('getReferenceAddresses', value);
this.focusOnAddress();
},
addPostalCode() {
this.address.writeNewPostalCode = true;
addPostcode() {
this.entity.selected.writeNew.postcode = true;
}
}
};

View File

@ -2,13 +2,13 @@
<div class="my-1">
<label class="col-form-label" for="countrySelect">{{ $t('country') }}</label>
<VueMultiselect
v-model="value"
id="countrySelect"
track-by="id"
label="name"
:custom-label="transName"
:placeholder="$t('select_country')"
:options="countries"
track-by="id"
v-bind:custom-label="transName"
v-bind:placeholder="$t('select_country')"
v-bind:options="sortedCountries"
v-model="value"
@select="selectCountry">
</VueMultiselect>
</div>
@ -20,43 +20,47 @@ import VueMultiselect from 'vue-multiselect';
export default {
name: 'CountrySelection',
components: { VueMultiselect },
props: ['address', 'getCities'],
props: ['context', 'entity'],
emits: ['getCities'],
data() {
return {
edit: window.mode === 'edit',
defaultCountry: this.edit ? this.$store.state.editAddress.country.code : 'FR',
value: this.address.loaded.countries.filter(c => c.countryCode === this.defaultCountry)[0]
value: this.selectCountryByCode(
this.context.edit ? this.entity.selected.country.code : 'FR'
)
}
},
computed: {
sortedCountries() {
console.log('sorted countries');
const countries = this.entity.loaded.countries;
let sortedCountries = [];
sortedCountries.push(...countries.filter(c => c.countryCode === 'FR'))
sortedCountries.push(...countries.filter(c => c.countryCode === 'BE'))
sortedCountries.push(...countries.filter(c => c.countryCode !== 'FR').filter(c => c.countryCode !== 'BE'))
return sortedCountries;
}
},
mounted() {
this.init();
},
methods: {
init() {
this.value = this.edit ?
this.address.loaded.countries.filter(c => c.countryCode === this.$store.state.editAddress.country.code)[0]:
this.address.loaded.countries.filter(c => c.countryCode === 'FR')[0]
if (this.value !== undefined) {
this.selectCountry(this.value);
}
},
selectCountryByCode(countryCode) {
return this.entity.loaded.countries.filter(c => c.countryCode === countryCode)[0];
},
transName ({ name }) {
return name.fr //TODO multilang
},
selectCountry(value) {
this.address.selected.country = value;
this.getCities(value);
},
},
mounted(){
this.init()
},
computed: {
countries() {
const countries = this.address.loaded.countries;
let orderedCountries = [];
orderedCountries.push(...countries.filter(c => c.countryCode === 'FR'))
orderedCountries.push(...countries.filter(c => c.countryCode === 'BE'))
orderedCountries.push(...countries.filter(c => c.countryCode !== 'FR').filter(c => c.countryCode !== 'BE'))
return orderedCountries;
console.log('select country', value);
this.entity.selected.country = value;
this.$emit('getCities', value);
}
}
};
</script>

View File

@ -0,0 +1,160 @@
<template>
<div class="address-form">
<!-- Not display in modal -->
<div v-if="insideModal == false" class="loading">
<i v-if="flag.loading" class="fa fa-circle-o-notch fa-spin fa-2x fa-fw"></i>
<span class="sr-only">Loading...</span>
</div>
<h4 class="h3">{{ $t('select_an_address_title') }}</h4>
<div class="row my-3">
<div class="col-lg-6">
<div class="form-check">
<input type="checkbox"
class="form-check-input"
id="isNoAddress"
v-model="isNoAddress"
v-bind:value="value" />
<label class="form-check-label" for="isNoAddress">
{{ $t('isNoAddress') }}
</label>
</div>
<country-selection
v-bind:context="context"
v-bind:entity="entity"
@getCities="$emit('getCities', selected.country)">
</country-selection>
<city-selection
v-bind:entity="entity"
v-bind:focusOnAddress="focusOnAddress"
@getReferenceAddresses="$emit('getReferenceAddresses', selected.city)">
</city-selection>
<address-selection v-if="!isNoAddress"
v-bind:entity="entity"
v-bind:updateMapCenter="updateMapCenter">
</address-selection>
</div>
<div class="col-lg-6 mt-3 mt-lg-0">
<address-map
v-bind:entity="entity"
ref="addressMap">
</address-map>
</div>
</div>
<address-more v-if="!isNoAddress"
v-bind:entity="entity">
</address-more>
<!-- Not display in modal -->
<ul v-if="insideModal == false"
class="record_actions sticky-form-buttons">
<li class="cancel">
<a class="btn btn-cancel" v-bind:href="context.backUrl">
{{ $t('back_to_the_list') }}
</a>
</li>
<li>
<a class="btn btn-cancel change-icon" @click="flag.showPane = true; flag.editPane = false;">
{{ $t('action.cancel') }}
</a>
</li>
<li>
<a class="btn btn-update" @click.prevent="$emit('closeEditPane')">
{{ $t('action.valid_and_see')}}
</a>
</li>
</ul>
</div>
</template>
<script>
import CountrySelection from './AddAddress/CountrySelection';
import CitySelection from './AddAddress/CitySelection';
import AddressSelection from './AddAddress/AddressSelection';
import AddressMap from './AddAddress/AddressMap';
import AddressMore from './AddAddress/AddressMore'
export default {
name: "EditAddress",
components: {
CountrySelection,
CitySelection,
AddressSelection,
AddressMap,
AddressMore
},
props: [
'context',
'options',
'default',
'flag',
'entity',
'errorMsg',
'insideModal'
],
emits: ['closeEditPane', 'getCities', 'getReferenceAddresses'],
data() {
return {
value: false
}
},
computed: {
address() {
return this.entity.address;
},
loaded() {
return this.entity.loaded;
},
selected() {
return this.entity.selected;
},
addressMap() {
return this.entity.addressMap;
},
isNoAddress: {
set(value) {
console.log('isNoAddress value', value);
this.entity.selected.isNoAddress = value;
},
get() {
return this.entity.selected.isNoAddress;
}
}
},
methods: {
focusOnAddress() {
const addressSelector = document.getElementById('addressSelector');
addressSelector.focus();
},
updateMapCenter(point) {
//console.log('point', point);
this.addressMap.center[0] = point.coordinates[1]; // TODO use reverse()
this.addressMap.center[1] = point.coordinates[0];
this.$refs.addressMap.update(); // cast child methods
}
}
};
</script>
<style lang="scss">
div.address-form {
h4.h3 {
font-weight: bold;
}
div#address_map {
height: 400px;
width: 100%;
}
}
</style>

View File

@ -1,17 +1,25 @@
<template>
<div class="address multiline">
<p v-if="address.text"
class="street">
{{ address.text }}
</p>
<p v-if="address.postcode"
class="postcode">
{{ address.postcode.name }}
</p>
<p v-if="address.country"
class="country">
{{ address.country.name.fr }}
</p>
<div class="chill-entity entity-address">
<div v-if="insideModal == false" class="loading">
<i v-if="flag.loading" class="fa fa-circle-o-notch fa-spin fa-2x fa-fw"></i>
<span class="sr-only">Loading...</span>
</div>
<div class="address multiline">
<p v-if="address.text"
class="street">
{{ address.text }}
</p>
<p v-if="address.postcode"
class="postcode">
{{ address.postcode.code }} {{ address.postcode.name }}
</p>
<p v-if="address.country"
class="country">
{{ address.country.name.fr }}
</p>
</div>
<div v-if="address.floor">
<span class="floor">
@ -48,17 +56,60 @@
<b>{{ $t('distribution') }}</b>: {{ address.distribution }}
</span>
</div>
</div>
<ul v-if="insideModal == false"
class="record_actions sticky-form-buttons">
<li class="cancel">
<a class="btn btn-cancel" v-bind:href="context.backUrl">
{{ $t('back_to_the_list') }}</a>
</li>
<li>
<a @click.prevent="$emit('openEditPane')"
class="btn btn-update">
{{ $t('action.edit')}}
</a>
</li>
<li>
<a class="btn btn-save"
@click.prevent="$emit('submitAddress', { getSubmited , flag })">
{{ $t('action.save')}}
</a>
</li>
</ul>
</template>
<script>
export default {
name: 'ShowAddress',
props: ['address'],
data() {
return {
props: [
'context',
'options',
'default',
'flag',
'entity',
'errorMsg',
'insideModal'
],
emits: ['openEditPane', 'submitAddress'],
computed: {
address() {
return this.entity.address;
},
loaded() {
return this.entity.loaded;
},
selected() {
return this.entity.selected;
},
addressMap() {
return this.entity.addressMap;
},
getSubmited() {
return this.entity.address;
}
},
}
};
</script>

View File

@ -0,0 +1,42 @@
const addressMessages = {
fr: {
add_an_address_title: 'Créer une adresse',
edit_an_address_title: 'Modifier une adresse',
create_a_new_address: 'Créer une nouvelle adresse',
edit_address: 'Modifier l\'adresse',
select_an_address_title: 'Sélectionner une adresse',
fill_an_address: 'Compléter l\'adresse',
select_country: 'Choisir le pays',
country: 'Pays',
select_city: 'Choisir une localité',
city: 'Localité',
other_city: 'Autre localité',
select_address: 'Choisir une adresse',
address: 'Adresse',
other_address: 'Autre adresse',
create_address: 'Adresse inconnue. Cliquez ici pour créer une nouvelle adresse',
isNoAddress: 'Pas d\'adresse complète',
street: 'Nom de rue',
streetNumber: 'Numéro',
floor: 'Étage',
corridor: 'Couloir',
steps: 'Escalier',
flat: 'Appartement',
buildingName: 'Nom du bâtiment',
extra: 'Complément d\'adresse',
distribution: 'Service particulier de distribution',
create_postal_code: 'Localité inconnue. Cliquez ici pour créer une nouvelle localité',
postalCode_name: 'Nom',
postalCode_code: 'Code postal',
date: 'Date de la nouvelle adresse',
add_an_address_to_person: 'Ajouter l\'adresse à la personne',
validFrom: 'Date de la nouvelle adresse',
back_to_the_list: 'Retour à la liste',
person_address_creation_success: 'La nouvelle adresse de la personne est enregistrée',
loading: 'chargement en cours...'
}
};
export {
addressMessages
};

View File

@ -1,14 +1,13 @@
import { createApp } from 'vue'
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
import { addressMessages } from './js/i18n'
import { store } from './store'
import App from './App.vue';
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
import { addressMessages } from './i18n'
const i18n = _createI18n(addressMessages);
const app = createApp({
template: `<app></app>`,
template: `<app></app>`,
})
.use(store)
.use(i18n)

View File

@ -1,42 +0,0 @@
const addressMessages = {
fr: {
add_an_address_title: 'Créer une adresse',
edit_an_address_title: 'Modifier une adresse',
create_a_new_address: 'Créer une nouvelle adresse',
edit_address: 'Modifier l\'adresse',
select_an_address_title: 'Sélectionner une adresse',
fill_an_address: 'Compléter l\'adresse',
select_country: 'Choisir le pays',
country: 'Pays',
select_city: 'Choisir une localité',
city: 'Localité',
other_city: 'Autre localité',
select_address: 'Choisir une adresse',
address: 'Adresse',
other_address: 'Autre adresse',
create_address: 'Adresse inconnue. Cliquez ici pour créer une nouvelle adresse',
isNoAddress: 'Pas d\'adresse complète',
street: 'Nom de rue',
streetNumber: 'Numéro',
floor: 'Étage',
corridor: 'Couloir',
steps: 'Escalier',
flat: 'Appartement',
buildingName: 'Nom du bâtiment',
extra: 'Complément d\'adresse',
distribution: 'Service particulier de distribution',
create_postal_code: 'Localité inconnue. Cliquez ici pour créer une nouvelle localité',
postalCode_name: 'Nom',
postalCode_code: 'Code postal',
date: 'Date de la nouvelle adresse',
add_an_address_to_person: 'Ajouter l\'adresse à la personne',
validFrom: 'Date de la nouvelle adresse',
back_to_the_list: 'Retour à la liste',
person_address_creation_success: 'La nouvelle adresse de la personne est enregistrée',
loading: 'chargement en cours...'
}
};
export {
addressMessages
};

View File

@ -0,0 +1,14 @@
import 'es6-promise/auto';
import { createStore } from 'vuex';
const debug = process.env.NODE_ENV !== 'production';
const store = createStore({
strict: debug,
state: {},
getters: {},
mutations: {},
actions: {},
});
export { store };

View File

@ -1,158 +0,0 @@
import 'es6-promise/auto';
import { createStore } from 'vuex';
import { patchAddress, postAddress, postPostalCode, postAddressToPerson, getAddress } from '../api'
const debug = process.env.NODE_ENV !== 'production';
const store = createStore({
strict: debug,
state: {
address: {},
editAddress: {}, //TODO or should be address?
person: {},
errorMsg: [],
loading: false,
success: false
},
getters: {
},
mutations: {
catchError(state, error) {
state.errorMsg.push(error);
},
addAddress(state, address) {
console.log('@M addAddress address', address);
state.address = address;
},
updateAddress(state, address) {
console.log('@M updateAddress address', address);
state.address = address;
},
addAddressToPerson(state, person) {
console.log('@M addAddressToPerson person', person);
state.person = person;
},
addDateToAddress(state, validFrom) {
console.log('@M addDateToAddress address.validFrom', validFrom);
state.validFrom = validFrom;
},
getEditAddress(state, address) {
console.log('@M getEditAddress address', address);
state.editAddress = address;
},
setLoading(state, b) {
state.loading = b;
},
setSuccess(state, b) {
state.success = b;
}
},
actions: {
addAddress({ commit }, payload) {
console.log('@A addAddress payload', payload);
commit('setLoading', true);
if('newPostalCode' in payload){
let postalCodeBody = payload.newPostalCode;
postalCodeBody = Object.assign(postalCodeBody, {'origin': 3});
postPostalCode(postalCodeBody)
.then(postalCode => {
let body = payload;
body.postcode = {'id': postalCode.id},
postAddress(body)
.then(address => new Promise((resolve, reject) => {
commit('addAddress', address);
resolve();
commit('setLoading', false);
}))
.catch((error) => {
commit('catchError', error);
commit('setLoading', false);
});
})
} else {
postAddress(payload)
.then(address => new Promise((resolve, reject) => {
commit('addAddress', address);
resolve();
commit('setLoading', false);
}))
.catch((error) => {
commit('catchError', error);
commit('setLoading', false);
});
}
},
addDateToAddressAndAddressToPerson({ commit }, payload) {
console.log('@A addDateToAddressAndAddressToPerson payload', payload);
commit('setLoading', true);
patchAddress(payload.addressId, payload.body)
.then(address => new Promise((resolve, reject) => {
commit('addDateToAddress', address.validFrom);
resolve();
}).then(
postAddressToPerson(payload.personId, payload.addressId)
.then(person => new Promise((resolve, reject) => {
commit('addAddressToPerson', person);
commit('setLoading', false);
commit('setSuccess', true);
window.location.assign(payload.backUrl);
resolve();
}))
.catch((error) => {
commit('catchError', error);
commit('setLoading', false);
})
))
.catch((error) => {
commit('catchError', error);
commit('setLoading', false);
});
},
updateAddress({ commit }, payload) {
console.log('@A updateAddress payload', payload);
if('newPostalCode' in payload.newAddress){ // TODO change the condition because it writes new postal code in edit mode now: !writeNewPostalCode
let postalCodeBody = payload.newAddress.newPostalCode;
postalCodeBody = Object.assign(postalCodeBody, {'origin': 3});
postPostalCode(postalCodeBody)
.then(postalCode => {
let body = payload.newAddress;
body.postcode = {'id': postalCode.id },
patchAddress(payload.addressId, body)
.then(address => new Promise((resolve, reject) => {
commit('updateAddress', address);
resolve();
}))
.catch((error) => {
commit('catchError', error);
});
})
} else {
patchAddress(payload.addressId, payload.newAddress)
.then(address => new Promise((resolve, reject) => {
commit('updateAddress', address);
resolve();
}))
.catch((error) => {
commit('catchError', error);
});
}
},
getEditAddress({ commit }, payload) {
console.log('@A getEditAddress payload', payload);
getAddress(payload).then(address => new Promise((resolve, reject) => {
commit('getEditAddress', address);
resolve();
}))
.catch((error) => {
commit('catchError', error);
});
},
}
});
export { store };

View File

@ -24,16 +24,16 @@
<!-- :: end styles bootstrap :: -->
</div>
</transition>
</template>
</template>
<script>
/*
* This Modal component is a mix between Vue3 modal implementation
* This Modal component is a mix between Vue3 modal implementation
* [+] with 'v-if:showModal' directive:parameter, html scope is added/removed not just shown/hidden
* [+] with slot we can pass content from parent component
* [+] some classes are passed from parent component
* and Bootstrap 4.6 _modal.scss module
* [+] using bootstrap css classes, the modal have a responsive behaviour,
* [+] using bootstrap css classes, the modal have a responsive behaviour,
* [+] modal design can be configured using css classes (size, scroll)
*/
export default {
@ -54,7 +54,7 @@ export default {
background-color: rgba(0, 0, 0, 0.75);
transition: opacity 0.3s ease;
}
.modal-header .close {
.modal-header .close {
border-top-right-radius: 0.3rem;
}
/*
@ -71,7 +71,8 @@ export default {
.modal-leave-active {
opacity: 0;
}
.modal-enter .modal-container,
.modal-enter
.modal-container,
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
@ -80,4 +81,9 @@ export default {
font-size: 1.5rem;
font-weight: bold;
}
div.modal-footer {
button:first-child {
margin-right: auto;
}
}
</style>

View File

@ -32,6 +32,8 @@ const messages = {
remove: "Enlever",
delete: "Supprimer",
save: "Enregistrer",
valid: "Valider",
valid_and_see: "Valider et voir",
add: "Ajouter",
show_modal: "Ouvrir une modale",
ok: "OK",
@ -61,7 +63,7 @@ const messages = {
title: "Création d'un nouvel usager ou d'un tiers professionnel",
person: "un nouvel usager",
thirdparty: "un nouveau tiers professionnel"
},
},
},
}
};

View File

@ -9,6 +9,7 @@
<origin-demand></origin-demand>
<requestor></requestor>
<social-issue></social-issue>
<!--course-location></course-location-->
<referrer></referrer>
<resources></resources>
<comment v-if="accompanyingCourse.step === 'DRAFT'"></comment>
@ -24,7 +25,7 @@ import OriginDemand from './components/OriginDemand.vue';
import PersonsAssociated from './components/PersonsAssociated.vue';
import Requestor from './components/Requestor.vue';
import SocialIssue from './components/SocialIssue.vue';
import CourseLocation from './components/CourseLocation.vue';
//import CourseLocation from './components/CourseLocation.vue';
import Referrer from './components/Referrer.vue';
import Resources from './components/Resources.vue';
import Comment from './components/Comment.vue';
@ -39,7 +40,7 @@ export default {
PersonsAssociated,
Requestor,
SocialIssue,
CourseLocation,
//CourseLocation,
Referrer,
Resources,
Comment,

View File

@ -1,25 +1,24 @@
<template>
<div class='household__address-move'>
<div class='household__address-move__create'>
<div>
<h2 v-if="!edit">{{ $t('create_a_new_address') }}</h2>
<h2 v-else>{{ $t('edit_a_new_address') }}</h2>
<add-address
modalAddTitle="add_an_address_title"
modalEditTitle="edit_an_address_title"
@addNewAddress="addNewAddress">
</add-address>
</div>
<div>
<show-address
v-if="newAddress"
v-bind:address="newAddress">
</show-address>
</div>
</div>
<div v-if="!edit" class='household__address-move__valid'>
<h2>{{ $t('move_date') }}</h2>
<div class='chill-entity entity-address'>
<div class="my-3">
<h2 v-if="!edit">{{ $t('create_a_new_address') }}</h2>
<h2 v-else>{{ $t('edit_address') }}</h2>
<show-address
v-if="newAddress"
v-bind:address="newAddress">
</show-address>
<add-address
modalAddTitle="add_an_address_title"
modalEditTitle="edit_address"
@addNewAddress="addNewAddress">
</add-address>
</div>
<div v-if="!edit" class='address-valid'>
<h2>{{ $t('move_date') }}</h2>
<div class="input-group mb-3">
<span class="input-group-text" id="validFrom"><i class="fa fa-fw fa-calendar"></i></span>
<input type="date" class="form-control form-control-lg" name="validFrom"
@ -27,7 +26,6 @@
v-model="validFrom"
aria-describedby="validFrom" />
</div>
<div v-if="errors.length > 0">
{{ errors }}
</div>
@ -38,26 +36,26 @@
{{ $t('household_address_move_success') }}
</div>
</div>
<div v-if="success && edit">
{{ $t('household_address_edit_success') }}
</div>
<div>
<ul class="record_actions sticky-form-buttons">
<li class="cancel">
<a :href="backUrl" class="btn btn-cancel">{{ $t('back_to_the_list') }}</a>
</li>
<li v-if="!edit">
<button type="submit" class="btn btn-update" @click="addToHousehold">
{{ $t('add_an_address_to_household') }}
</button>
</li>
</ul>
</div>
<ul class="record_actions sticky-form-buttons">
<li class="cancel">
<a :href="backUrl" class="btn btn-cancel">{{ $t('back_to_the_list') }}</a>
</li>
<li v-if="!edit">
<button type="submit" class="btn btn-update" @click="addToHousehold">
{{ $t('add_an_address_to_household') }}
</button>
</li>
</ul>
</div>
</template>
<script>
import AddAddress from 'ChillMainAssets/vuejs/Address/components/AddAddress.vue';
import ShowAddress from 'ChillMainAssets/vuejs/Address/components/ShowAddress.vue';
@ -153,5 +151,10 @@ export default {
}
},
};
</script>
<style lang="scss">
div.entity-address {
border: 1px dashed grey;
}
</style>

View File

@ -18,15 +18,15 @@
{% set activeRouteKey = '' %}
{% block title 'Modify address for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) %}
{% block title 'Edit an address'|trans %}
{% block personcontent %}
<div class="address-new">
{% block content %}
<h1>{{ block('title') }}</h1>
<div id="address"></div>
{% endblock %}
<div class="address-edit">
{% block content %}
<h1>{{ block('title') }}</h1>
<div id="address"></div>
{% endblock %}
</div>
{% endblock %}

View File

@ -18,16 +18,16 @@
{% set activeRouteKey = '' %}
{% block title %}{{ 'New address for %name%'|trans({ '%name%': person.firstName|capitalize ~ ' ' ~ person.lastName } )|capitalize }}{% endblock %}
{% block title %}{{ 'New address'|trans }}{% endblock %}
{% block personcontent %}
<div class="address-new">
{% block content %}
<h1>{{ block('title') }}</h1>
<div id="address"></div>
{% endblock %}
{% block content %}
<h1>{{ block('title') }}</h1>
<div id="address"></div>
{% endblock %}
</div>
{% endblock %}

View File

@ -8,11 +8,11 @@ module.exports = function(encore, entries)
ChillPersonAssets: __dirname + '/Resources/public'
});
encore.addEntry('vue_household_address', __dirname + '/Resources/public/vuejs/HouseholdAddress/index.js');
encore.addEntry('vue_household_members_editor', __dirname + '/Resources/public/vuejs/HouseholdMembersEditor/index.js');
//encore.addEntry('vue_household_address', __dirname + '/Resources/public/vuejs/HouseholdAddress/index.js');
//encore.addEntry('vue_household_members_editor', __dirname + '/Resources/public/vuejs/HouseholdMembersEditor/index.js');
encore.addEntry('vue_accourse', __dirname + '/Resources/public/vuejs/AccompanyingCourse/index.js');
encore.addEntry('vue_accourse_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js');
encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js');
//encore.addEntry('vue_accourse_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js');
//encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js');
encore.addEntry('page_household_edit_metadata', __dirname + '/Resources/public/page/household_edit_metadata/index.js');
encore.addEntry('page_person', __dirname + '/Resources/public/page/person/index.js');

View File

@ -207,8 +207,10 @@ No address given: Pas d'adresse renseignée
The address has been successfully updated: L'adresse a été mise à jour avec succès
Update address for %name%: Mettre à jour une adresse pour %name%
Modify address for %name%: Modifier une adresse pour %name%
Edit an address: Modifier une adresse
Addresses history for %name%: Historique des adresses de %name%
Addresses history: Historique des adresses
New address : Nouvelle adresse
New address for %name% : Nouvelle adresse pour %name%
The new address was created successfully: La nouvelle adresse a été créée
Add an address: Ajouter une adresse