mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 14:43:49 +00:00
Merge remote-tracking branch 'origin/master' into fix-person-tests
This commit is contained in:
@@ -13,9 +13,9 @@
|
||||
div#header-accompanying_course-name {
|
||||
background: none repeat scroll 0 0 #718596;
|
||||
color: #FFF;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
|
||||
h1 {
|
||||
margin: 0.4em 0;
|
||||
}
|
||||
span {
|
||||
a {
|
||||
color: white;
|
||||
@@ -39,115 +39,25 @@ div.subheader {
|
||||
height: 130px;
|
||||
}
|
||||
|
||||
//// VUEJS ////
|
||||
|
||||
div.vue-component {
|
||||
padding: 1.5em;
|
||||
margin: 2em 0;
|
||||
border: 2px dashed grey;
|
||||
position: relative;
|
||||
&:before {
|
||||
content: "vuejs component";
|
||||
position: absolute;
|
||||
left: 1.5em;
|
||||
top: -0.9em;
|
||||
background-color: white;
|
||||
color: grey;
|
||||
padding: 0 0.3em;
|
||||
}
|
||||
dd { margin-left: 1em; }
|
||||
}
|
||||
|
||||
//// MODAL ////
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
z-index: 9998;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
display: table;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.modal-header .close { // bootstrap classes, override sc-button 0 radius
|
||||
border-top-right-radius: 0.3rem;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following styles are auto-applied to elements with
|
||||
* transition="modal" when their visibility is toggled
|
||||
* by Vue.js.
|
||||
*
|
||||
* You can easily play with the modal transition by editing
|
||||
* these styles.
|
||||
*/
|
||||
.modal-enter {
|
||||
opacity: 0;
|
||||
}
|
||||
.modal-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
.modal-enter .modal-container,
|
||||
.modal-leave-active .modal-container {
|
||||
-webkit-transform: scale(1.1);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
//// AddPersons modal
|
||||
div.modal-body.up {
|
||||
margin: auto 4em;
|
||||
div.search {
|
||||
position: relative;
|
||||
input {
|
||||
padding: 1.2em 1.5em 1.2em 2.5em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
i {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0.5em;
|
||||
padding: 0.65em 0;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
div.results {
|
||||
div.count {
|
||||
margin: -0.5em 0 0.7em;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
div.list-item {
|
||||
line-height: 26pt;
|
||||
padding: 0.3em 0.8em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
&.checked {
|
||||
background-color: #ececec;
|
||||
border-bottom: 1px dotted #8b8b8b;
|
||||
}
|
||||
div.container {
|
||||
& > input {
|
||||
margin-right: 0.8em;
|
||||
}
|
||||
}
|
||||
div.right_actions {
|
||||
margin: 0 0 0 auto;
|
||||
& > * {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
a.sc-button {
|
||||
border: 1px solid lightgrey;
|
||||
font-size: 70%;
|
||||
padding: 4px;
|
||||
}
|
||||
//// SCRATCH BUTTONS
|
||||
.sc-button {
|
||||
&.disabled {
|
||||
cursor: default;
|
||||
&.bt-remove {
|
||||
background-color: #d9d9d9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// à ranger
|
||||
.discret {
|
||||
color: grey;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
table {
|
||||
ul.record_actions {
|
||||
margin: 0;
|
||||
padding: 0.5em;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
|
||||
<div v-if="address.address">
|
||||
{{ address.address.street }}, {{ address.address.streetNumber }}
|
||||
</div>
|
||||
<div v-if="address.city">
|
||||
{{ address.city.code }} {{ address.city.name }}
|
||||
</div>
|
||||
<div v-if="address.country">
|
||||
{{ address.country.name }}
|
||||
</div>
|
||||
|
||||
<add-address
|
||||
@addNewAddress="addNewAddress">
|
||||
</add-address>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
import AddAddress from '../_components/AddAddress.vue';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
AddAddress
|
||||
},
|
||||
computed: {
|
||||
address() {
|
||||
return this.$store.state.address;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addNewAddress({ address, modal }) {
|
||||
console.log('@@@ CLICK button addNewAdress', address);
|
||||
this.$store.dispatch('addAddress', address.selected);
|
||||
modal.showModal = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -0,0 +1,16 @@
|
||||
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';
|
||||
|
||||
const i18n = _createI18n(addressMessages);
|
||||
|
||||
const app = createApp({
|
||||
template: `<app></app>`,
|
||||
})
|
||||
.use(store)
|
||||
.use(i18n)
|
||||
.component('app', App)
|
||||
.mount('#address');
|
@@ -0,0 +1,22 @@
|
||||
const addressMessages = {
|
||||
fr: {
|
||||
add_an_address: 'Ajouter une adresse',
|
||||
select_an_address: 'Sélectionner une adresse',
|
||||
fill_an_address: 'Compléter l\'adresse',
|
||||
select_country: 'Choisir le pays',
|
||||
select_city: 'Choisir une localité',
|
||||
select_address: 'Choisir une adresse',
|
||||
isNoAddress: 'L\'adresse n\'est pas celle d\'un domicile fixe ?',
|
||||
floor: 'Étage',
|
||||
corridor: 'Couloir',
|
||||
steps: 'Escalier',
|
||||
flat: 'Appartement',
|
||||
buildingName: 'Nom du batiment',
|
||||
extra: 'Complément d\'adresse',
|
||||
distribution: 'Service particulier de distribution'
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
addressMessages
|
||||
};
|
@@ -0,0 +1,43 @@
|
||||
import 'es6-promise/auto';
|
||||
import { createStore } from 'vuex';
|
||||
|
||||
// le fetch POST serait rangé dans la logique du composant qui appelle AddAddress
|
||||
//import { postAddress } from '... api'
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production';
|
||||
|
||||
const store = createStore({
|
||||
strict: debug,
|
||||
state: {
|
||||
address: {},
|
||||
errorMsg: {}
|
||||
},
|
||||
getters: {
|
||||
},
|
||||
mutations: {
|
||||
addAddress(state, address) {
|
||||
console.log('@M addAddress address', address);
|
||||
state.address = address;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
addAddress({ commit }, payload) {
|
||||
console.log('@A addAddress payload', payload);
|
||||
commit('addAddress', payload); // à remplacer par
|
||||
|
||||
// fetch POST qui envoie l'adresse, et récupère la confirmation que c'est ok.
|
||||
// La confirmation est l'adresse elle-même.
|
||||
//
|
||||
// postAddress(payload)
|
||||
// .fetch(address => new Promise((resolve, reject) => {
|
||||
// commit('addAddress', address);
|
||||
// resolve();
|
||||
// }))
|
||||
// .catch((error) => {
|
||||
// state.errorMsg.push(error.message);
|
||||
// });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export { store };
|
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Endpoint countries GET
|
||||
* TODO
|
||||
*/
|
||||
const fetchCountries = () => {
|
||||
console.log('<<< fetching countries');
|
||||
return [
|
||||
{id: 1, name: 'France', countryCode: 'FR'},
|
||||
{id: 2, name: 'Belgium', countryCode: 'BE'}
|
||||
];
|
||||
};
|
||||
|
||||
/*
|
||||
* Endpoint cities GET
|
||||
* TODO
|
||||
*/
|
||||
const fetchCities = (country) => {
|
||||
console.log('<<< fetching cities for', country);
|
||||
return [
|
||||
{id: 1, name: 'Bruxelles', code: '1000', country: 'BE'},
|
||||
{id: 2, name: 'Aisne', code: '85045', country: 'FR'},
|
||||
{id: 3, name: 'Saint-Gervais', code: '85230', country: 'FR'}
|
||||
];
|
||||
};
|
||||
|
||||
/*
|
||||
* Endpoint chill_main_address_reference_api_show
|
||||
* method GET, get AddressReference Object
|
||||
* @returns {Promise} a promise containing all AddressReference object
|
||||
*/
|
||||
const fetchReferenceAddresses = (city) => {
|
||||
console.log('<<< fetching references addresses for', city); // city n'est pas utilisé pour le moment
|
||||
|
||||
const url = `/api/1.0/main/address-reference.json`;
|
||||
return fetch(url)
|
||||
.then(response => {
|
||||
if (response.ok) { return response.json(); }
|
||||
throw Error('Error with request resource response');
|
||||
});
|
||||
};
|
||||
|
||||
export {
|
||||
fetchCountries,
|
||||
fetchCities,
|
||||
fetchReferenceAddresses
|
||||
};
|
@@ -0,0 +1,219 @@
|
||||
<template>
|
||||
<button class="sc-button bt-create centered mt-4" @click="openModal">
|
||||
{{ $t('add_an_address') }}
|
||||
</button>
|
||||
|
||||
<teleport to="body">
|
||||
<modal v-if="modal.showModal"
|
||||
v-bind:modalDialogClass="modal.modalDialogClass"
|
||||
@close="modal.showModal = false">
|
||||
|
||||
<template v-slot:header>
|
||||
<h3 class="modal-title">{{ $t('add_an_address') }}</h3>
|
||||
</template>
|
||||
|
||||
<template v-slot:body>
|
||||
|
||||
<h4>{{ $t('select_an_address') }}</h4>
|
||||
|
||||
<label for="isNoAddress">
|
||||
<input type="checkbox"
|
||||
name="isNoAddress"
|
||||
v-bind:placeholder="$t('isNoAddress')"
|
||||
v-model="isNoAddress"
|
||||
v-bind:value="value"/>
|
||||
{{ $t('isNoAddress') }}
|
||||
</label>
|
||||
|
||||
<country-selection
|
||||
v-bind:address="address"
|
||||
v-bind:getCities="getCities">
|
||||
</country-selection>
|
||||
|
||||
<city-selection
|
||||
v-bind:address="address"
|
||||
v-bind:getReferenceAddresses="getReferenceAddresses">
|
||||
</city-selection>
|
||||
|
||||
<address-selection
|
||||
v-bind:address="address"
|
||||
v-bind:updateMapCenter="updateMapCenter">
|
||||
</address-selection>
|
||||
|
||||
<address-map
|
||||
v-bind:address="address"
|
||||
ref="addressMap">
|
||||
</address-map>
|
||||
|
||||
<address-more
|
||||
v-if="!isNoAddress"
|
||||
v-bind:address="address">
|
||||
</address-more>
|
||||
|
||||
<!--
|
||||
<div class="address_form__fields__isNoAddress"></div>
|
||||
<div class="address_form__select">
|
||||
<div class="address_form__select__header"></div>
|
||||
<div class="address_form__select__left"></div>
|
||||
<div class="address_form__map"></div>
|
||||
</div>
|
||||
<div class="address_form__fields">
|
||||
<div class="address_form__fields__header"></div>
|
||||
<div class="address_form__fields__left"></div>
|
||||
<div class="address_form__fields__right"></div>
|
||||
</div>
|
||||
|
||||
à discuter,
|
||||
mais je pense qu'il est préférable de profiter de l'imbriquation des classes css
|
||||
|
||||
div.address_form {
|
||||
div.select {
|
||||
div.header {}
|
||||
div.left {}
|
||||
div.map {}
|
||||
}
|
||||
}
|
||||
|
||||
-->
|
||||
</template>
|
||||
|
||||
<template v-slot:footer>
|
||||
<button class="sc-button green"
|
||||
@click.prevent="$emit('addNewAddress', { address, modal })">
|
||||
<i class="fa fa-plus fa-fw"></i>{{ $t('action.add')}}
|
||||
</button>
|
||||
</template>
|
||||
|
||||
</modal>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Modal from './Modal';
|
||||
import { fetchCountries, fetchCities, fetchReferenceAddresses } from '../_api/AddAddress'
|
||||
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: 'AddAddresses',
|
||||
components: {
|
||||
Modal,
|
||||
CountrySelection,
|
||||
CitySelection,
|
||||
AddressSelection,
|
||||
AddressMap,
|
||||
AddressMore
|
||||
},
|
||||
props: [
|
||||
],
|
||||
emits: ['addNewAddress'],
|
||||
data() {
|
||||
return {
|
||||
modal: {
|
||||
showModal: false,
|
||||
modalDialogClass: "modal-dialog-scrollable modal-xl"
|
||||
},
|
||||
address: {
|
||||
loaded: {
|
||||
countries: [],
|
||||
cities: [],
|
||||
addresses: [],
|
||||
},
|
||||
selected: {
|
||||
country: {},
|
||||
city: {},
|
||||
address: {},
|
||||
},
|
||||
addressMap: {
|
||||
center : [48.8589, 2.3469], // Note: LeafletJs demands [lat, lon] cfr https://macwright.com/lonlat/
|
||||
zoom: 12
|
||||
},
|
||||
isNoAddress: false,
|
||||
floor: null,
|
||||
corridor: null,
|
||||
steps: null,
|
||||
floor: null,
|
||||
flat: null,
|
||||
buildingName: null,
|
||||
extra: null,
|
||||
distribution: null,
|
||||
},
|
||||
errorMsg: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isNoAddress: {
|
||||
set(value) {
|
||||
console.log('value', value);
|
||||
this.address.isNoAddress = value;
|
||||
},
|
||||
get() {
|
||||
return this.address.isNoAddress;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openModal() {
|
||||
this.modal.showModal = true;
|
||||
this.resetAll();
|
||||
this.getCountries();
|
||||
|
||||
//this.$nextTick(function() {
|
||||
// this.$refs.search.focus(); // positionner le curseur à l'ouverture de la modale
|
||||
//})
|
||||
},
|
||||
getCountries() {
|
||||
console.log('getCountries');
|
||||
this.address.loaded.countries = fetchCountries(); // à remplacer par
|
||||
// fetchCountries().then(countries => new Promise((resolve, reject) => {
|
||||
// this.address.loaded.countries = countries;
|
||||
// resolve()
|
||||
// }))
|
||||
// .catch((error) => {
|
||||
// this.errorMsg.push(error.message);
|
||||
// });
|
||||
},
|
||||
getCities(country) {
|
||||
console.log('getCities for', country.name);
|
||||
this.address.loaded.cities = fetchCities(); // à remplacer par
|
||||
// fetchCities(country).then(cities => new Promise((resolve, reject) => {
|
||||
// this.address.loaded.cities = cities;
|
||||
// resolve()
|
||||
// }))
|
||||
// .catch((error) => {
|
||||
// this.errorMsg.push(error.message);
|
||||
// });
|
||||
},
|
||||
getReferenceAddresses(city) {
|
||||
console.log('getReferenceAddresses for', city.name);
|
||||
fetchReferenceAddresses(city) // il me semble que le paramètre city va limiter le poids des adresses de références reçues
|
||||
.then(addresses => new Promise((resolve, reject) => {
|
||||
console.log('addresses', addresses);
|
||||
this.address.loaded.addresses = addresses.results;
|
||||
resolve();
|
||||
}))
|
||||
.catch((error) => {
|
||||
this.errorMsg.push(error.message);
|
||||
});
|
||||
},
|
||||
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
|
||||
},
|
||||
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 = {};
|
||||
console.log('cities and addresses', this.address.loaded.cities, this.address.loaded.addresses);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div id='address_map' style='height:400px; width:400px;'></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import L from 'leaflet';
|
||||
import markerIconPng from 'leaflet/dist/images/marker-icon.png'
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
|
||||
let map;
|
||||
|
||||
export default {
|
||||
name: 'AddressMap',
|
||||
props: ['address'],
|
||||
computed: {
|
||||
center() {
|
||||
return this.address.addressMap.center;
|
||||
},
|
||||
},
|
||||
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: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
const markerIcon = L.icon({
|
||||
iconUrl: markerIconPng,
|
||||
});
|
||||
|
||||
L.marker([48.8589, 2.3469], {icon: markerIcon}).addTo(map);
|
||||
|
||||
},
|
||||
update() {
|
||||
console.log('update map with : ', this.address.addressMap.center)
|
||||
map.setView(this.address.addressMap.center, 12);
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<div>
|
||||
<h4>{{ $t('fill_an_address') }}</h4>
|
||||
<input
|
||||
type="text"
|
||||
name="floor"
|
||||
:placeholder="$t('floor')"
|
||||
v-model="floor"/>
|
||||
<input
|
||||
type="text"
|
||||
name="corridor"
|
||||
:placeholder="$t('corridor')"
|
||||
v-model="corridor"/>
|
||||
<input
|
||||
type="text"
|
||||
name="steps"
|
||||
:placeholder="$t('steps')"
|
||||
v-model="steps"/>
|
||||
<input
|
||||
type="text"
|
||||
name="flat"
|
||||
:placeholder="$t('flat')"
|
||||
v-model="flat"/>
|
||||
<input
|
||||
type="text"
|
||||
name="buildingName"
|
||||
:placeholder="$t('buildingName')"
|
||||
v-model="buildingName"/>
|
||||
<input
|
||||
type="text"
|
||||
name="extra"
|
||||
:placeholder="$t('extra')"
|
||||
v-model="extra"/>
|
||||
<input
|
||||
type="text"
|
||||
name="distribution"
|
||||
:placeholder="$t('distribution')"
|
||||
v-model="distribution"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AddressMore",
|
||||
props: ['address'],
|
||||
computed: {
|
||||
floor: {
|
||||
set(value) {
|
||||
console.log('value', value);
|
||||
this.address.floor = value;
|
||||
},
|
||||
get() {
|
||||
return this.address.floor;
|
||||
}
|
||||
},
|
||||
corridor: {
|
||||
set(value) {
|
||||
console.log('value', value);
|
||||
this.address.corridor = value;
|
||||
},
|
||||
get() {
|
||||
return this.address.corridor;
|
||||
}
|
||||
},
|
||||
steps: {
|
||||
set(value) {
|
||||
console.log('value', value);
|
||||
this.address.steps = value;
|
||||
},
|
||||
get() {
|
||||
return this.address.steps;
|
||||
}
|
||||
},
|
||||
flat: {
|
||||
set(value) {
|
||||
console.log('value', value);
|
||||
this.address.flat = value;
|
||||
},
|
||||
get() {
|
||||
return this.address.flat;
|
||||
}
|
||||
},
|
||||
buildingName: {
|
||||
set(value) {
|
||||
console.log('value', value);
|
||||
this.address.buildingName = value;
|
||||
},
|
||||
get() {
|
||||
return this.address.buildingName;
|
||||
}
|
||||
},
|
||||
extra: {
|
||||
set(value) {
|
||||
console.log('value', value);
|
||||
this.address.extra = value;
|
||||
},
|
||||
get() {
|
||||
return this.address.extra;
|
||||
}
|
||||
},
|
||||
distribution: {
|
||||
set(value) {
|
||||
console.log('value', value);
|
||||
this.address.distribution = value;
|
||||
},
|
||||
get() {
|
||||
return this.address.distribution;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<select
|
||||
v-model="selected">
|
||||
<option :value="{}" disabled selected>{{ $t('select_address') }}</option>
|
||||
<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>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'AddressSelection',
|
||||
props: ['address', 'updateMapCenter'],
|
||||
computed: {
|
||||
addresses() {
|
||||
return this.address.loaded.addresses;
|
||||
},
|
||||
selected: {
|
||||
set(value) {
|
||||
console.log('selected value', value);
|
||||
this.address.selected.address = value;
|
||||
this.updateMapCenter(value.point);
|
||||
},
|
||||
get() {
|
||||
return this.address.selected.address;
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<select
|
||||
v-model="selected">
|
||||
<option :value="{}" disabled selected>{{ $t('select_city') }}</option>
|
||||
<option
|
||||
v-for="item in this.cities"
|
||||
v-bind:item="item"
|
||||
v-bind:key="item.id"
|
||||
v-bind:value="item">
|
||||
{{ item.code }}-{{ item.name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'CitySelection',
|
||||
props: ['address', 'getReferenceAddresses'],
|
||||
computed: {
|
||||
cities() {
|
||||
return this.address.loaded.cities;
|
||||
},
|
||||
selected: {
|
||||
set(value) {
|
||||
console.log('selected value', value.name);
|
||||
this.address.selected.city = value;
|
||||
this.getReferenceAddresses(value);
|
||||
},
|
||||
get() {
|
||||
return this.address.selected.city;
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<select
|
||||
v-model="selected">
|
||||
<option :value="{}" disabled selected>{{ $t('select_country') }}</option>
|
||||
<option
|
||||
v-for="item in this.countries"
|
||||
v-bind:item="item"
|
||||
v-bind:key="item.id"
|
||||
v-bind:value="item">
|
||||
{{ item.name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'CountrySelection',
|
||||
props: ['address', 'getCities'],
|
||||
computed: {
|
||||
countries() {
|
||||
return this.address.loaded.countries;
|
||||
},
|
||||
selected: {
|
||||
set(value) {
|
||||
console.log('selected value', value.name);
|
||||
this.address.selected.country = value;
|
||||
this.getCities(value);
|
||||
},
|
||||
get() {
|
||||
return this.address.selected.country;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -1,41 +1,40 @@
|
||||
<template>
|
||||
<transition name="modal">
|
||||
<div class="modal-mask">
|
||||
<!-- :: styles bootstrap :: -->
|
||||
<div class="modal-dialog" :class="modalDialogClass">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<slot name="header"></slot>
|
||||
<button class="close sc-button grey" @click="$emit('close')">
|
||||
<i class="fa fa-times" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
<div class="modal-body up" style="overflow-y: unset;">
|
||||
<slot name="body-fixed"></slot>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<slot name="body"></slot>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="sc-button cancel" @click="$emit('close')">{{ $t('action.close') }}</button>
|
||||
<slot name="footer"></slot>
|
||||
<transition name="modal">
|
||||
<div class="modal-mask">
|
||||
<!-- :: styles bootstrap :: -->
|
||||
<div class="modal-dialog" :class="modalDialogClass">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<slot name="header"></slot>
|
||||
<button class="close sc-button grey" @click="$emit('close')">
|
||||
<i class="fa fa-times" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
<div class="body-head">
|
||||
<slot name="body-head"></slot>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<slot name="body"></slot>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="sc-button cancel" @click="$emit('close')">{{ $t('action.close') }}</button>
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- :: end styles bootstrap :: -->
|
||||
</div>
|
||||
<!-- :: end styles bootstrap :: -->
|
||||
</div>
|
||||
</transition>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* 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
|
||||
* - Bootstrap 4.6 _modal.scss module
|
||||
* => using bootstrap css classes, the modal have a responsive behaviour,
|
||||
* => modal design can be configured using css classes (size, scroll)
|
||||
* 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,
|
||||
* [+] modal design can be configured using css classes (size, scroll)
|
||||
*/
|
||||
export default {
|
||||
name: 'Modal',
|
||||
@@ -43,3 +42,39 @@ export default {
|
||||
emits: ['close']
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
z-index: 9998;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
display: table;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.modal-header .close { // bootstrap classes, override sc-button 0 radius
|
||||
border-top-right-radius: 0.3rem;
|
||||
}
|
||||
/*
|
||||
* The following styles are auto-applied to elements with
|
||||
* transition="modal" when their visibility is toggled
|
||||
* by Vue.js.
|
||||
*
|
||||
* You can easily play with the modal transition by editing
|
||||
* these styles.
|
||||
*/
|
||||
.modal-enter {
|
||||
opacity: 0;
|
||||
}
|
||||
.modal-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
.modal-enter .modal-container,
|
||||
.modal-leave-active .modal-container {
|
||||
-webkit-transform: scale(1.1);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
</style>
|
||||
|
@@ -7,11 +7,15 @@ const datetimeFormats = {
|
||||
month: "numeric",
|
||||
day: "numeric"
|
||||
},
|
||||
text: {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
},
|
||||
long: {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
month: "numeric",
|
||||
day: "numeric",
|
||||
weekday: "short",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
hour12: false
|
||||
@@ -33,12 +37,16 @@ const messages = {
|
||||
ok: "OK",
|
||||
cancel: "Annuler",
|
||||
close: "Fermer",
|
||||
next: "Suivant",
|
||||
previous: "Précédent",
|
||||
back: "Retour",
|
||||
check_all: "cocher tout",
|
||||
reset: "réinitialiser"
|
||||
},
|
||||
nav: {
|
||||
next: "Suivant",
|
||||
previous: "Précédent",
|
||||
top: "Haut",
|
||||
bottom: "Bas",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<footer class="footer">
|
||||
<p>{{ 'This program is free software: you can redistribute it and/or modify it under the terms of the <strong>GNU Affero General Public License</strong>'|trans|raw }}
|
||||
<br/> <a href="https://{{ app.request.locale }}.wikibooks.org/wiki/Chill" target="_blank">{{ 'User manual'|trans }}</a></p>
|
||||
</footer>
|
||||
<br/> <a name="bottom" href="https://{{ app.request.locale }}.wikibooks.org/wiki/Chill" target="_blank">{{ 'User manual'|trans }}</a></p>
|
||||
</footer>
|
||||
|
@@ -1 +1 @@
|
||||
<img class="logo" src="{{ asset('build/images/logo-chill-sans-slogan_white.png') }}">
|
||||
<img name="top" class="logo" src="{{ asset('build/images/logo-chill-sans-slogan_white.png') }}">
|
||||
|
Reference in New Issue
Block a user