mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-11-04 11:18:25 +00:00 
			
		
		
		
	Compare commits
	
		
			13 Commits
		
	
	
		
			v3.12.0
			...
			issue357_f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					db65134743 | ||
| 7af4c3434e | |||
| 
						 | 
					a09c8ee8af | ||
| 
						 | 
					a312a9463d | ||
| 
						 | 
					0035128138 | ||
| 
						 | 
					49cb154672 | ||
| 
						 | 
					1a7ec9e396 | ||
| 
						 | 
					fa0b9271c2 | ||
| 
						 | 
					c7b9a1a3fe | ||
| 
						 | 
					f1c61a2387 | ||
| 
						 | 
					8f6a70b240 | ||
| 
						 | 
					40e4bf953f | ||
| 
						 | 
					378f3a16fc | 
@@ -11,7 +11,8 @@ and this project adheres to
 | 
			
		||||
## Unreleased
 | 
			
		||||
 | 
			
		||||
<!-- write down unreleased development here -->
 | 
			
		||||
 | 
			
		||||
* vuejs: add validation on required fields for AddPerson, Address and Location components
 | 
			
		||||
* vuejs: treat 422 validation errors in locations and AddPerson components
 | 
			
		||||
 | 
			
		||||
## Test releases
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ import Location from './components/Location.vue';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
   name: "App",
 | 
			
		||||
    props: ['hasSocialIssues', 'hasLocation', 'hasPerson'],
 | 
			
		||||
   props: ['hasSocialIssues', 'hasLocation', 'hasPerson'],
 | 
			
		||||
   components: {
 | 
			
		||||
      ConcernedGroups,
 | 
			
		||||
      SocialIssuesAcc,
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
                    v-model="location"
 | 
			
		||||
                >
 | 
			
		||||
                </VueMultiselect>
 | 
			
		||||
                <new-location v-bind:locations="locations"></new-location>
 | 
			
		||||
                <new-location v-bind:availableLocations="availableLocations"></new-location>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </teleport>
 | 
			
		||||
 
 | 
			
		||||
@@ -18,15 +18,6 @@
 | 
			
		||||
                </template>
 | 
			
		||||
                <template v-slot:body>
 | 
			
		||||
                    <form>
 | 
			
		||||
                        <div class="form-floating mb-3">
 | 
			
		||||
                            <p v-if="errors.length">
 | 
			
		||||
                                <b>{{ $t('activity.errors') }}</b>
 | 
			
		||||
                                <ul>
 | 
			
		||||
                                    <li v-for="error in errors" :key="error">{{ error }}</li>
 | 
			
		||||
                                </ul>
 | 
			
		||||
                            </p>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <div class="form-floating mb-3">
 | 
			
		||||
                            <select class="form-select form-select-lg" id="type" required v-model="selectType">
 | 
			
		||||
                                <option selected disabled value="">{{ $t('activity.choose_location_type') }}</option>
 | 
			
		||||
@@ -62,6 +53,12 @@
 | 
			
		||||
                            <input class="form-control form-control-lg" id="email" v-model="inputEmail" placeholder />
 | 
			
		||||
                            <label for="email">{{ $t('activity.location_fields.email') }}</label>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <div class="alert alert-warning" v-if="errors.length">
 | 
			
		||||
                            <ul>
 | 
			
		||||
                                <li v-for="(e, i) in errors" :key="i">{{ e }}</li>
 | 
			
		||||
                            </ul>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </form>
 | 
			
		||||
                </template>
 | 
			
		||||
                <template v-slot:footer>
 | 
			
		||||
@@ -81,7 +78,8 @@
 | 
			
		||||
import Modal from 'ChillMainAssets/vuejs/_components/Modal.vue';
 | 
			
		||||
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
 | 
			
		||||
import { mapState } from "vuex";
 | 
			
		||||
import { getLocationTypes, postLocation } from "../../api";
 | 
			
		||||
import { getLocationTypes } from "../../api";
 | 
			
		||||
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    name: "NewLocation",
 | 
			
		||||
@@ -89,7 +87,7 @@ export default {
 | 
			
		||||
        Modal,
 | 
			
		||||
        AddAddress,
 | 
			
		||||
    },
 | 
			
		||||
    props: ['locations'],
 | 
			
		||||
    props: ['availableLocations'],
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            errors: [],
 | 
			
		||||
@@ -223,7 +221,6 @@ export default {
 | 
			
		||||
        },
 | 
			
		||||
        saveNewLocation() {
 | 
			
		||||
            if (this.checkForm()) {
 | 
			
		||||
                console.log('saveNewLocation', this.selected);
 | 
			
		||||
                let body = {
 | 
			
		||||
                    type: 'location',
 | 
			
		||||
                    name: this.selected.name,
 | 
			
		||||
@@ -242,23 +239,28 @@ export default {
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
                postLocation(body)
 | 
			
		||||
                    .then(
 | 
			
		||||
                        location => new Promise(resolve => {
 | 
			
		||||
                            this.locations.push(location);
 | 
			
		||||
                            this.$store.dispatch('updateLocation', location);
 | 
			
		||||
                            resolve();
 | 
			
		||||
                            this.modal.showModal = false;
 | 
			
		||||
                        })
 | 
			
		||||
                    ).catch(
 | 
			
		||||
                        err => {
 | 
			
		||||
                            this.errors.push(err.message);
 | 
			
		||||
 | 
			
		||||
                makeFetch('POST', '/api/1.0/main/location.json', body)
 | 
			
		||||
                    .then(response => {
 | 
			
		||||
                         this.$store.dispatch('addAvailableLocationGroup', {
 | 
			
		||||
                            locationGroup: 'Localisations nouvellement créées',
 | 
			
		||||
                            locations: [response]
 | 
			
		||||
                        });
 | 
			
		||||
                        this.$store.dispatch('updateLocation', response);
 | 
			
		||||
                        this.modal.showModal = false;
 | 
			
		||||
                    })
 | 
			
		||||
                    .catch((error) => {
 | 
			
		||||
                        if (error.name === 'ValidationException') {
 | 
			
		||||
                            for (let v of error.violations) {
 | 
			
		||||
                                this.errors.push(v);
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            this.errors.push('An error occurred');
 | 
			
		||||
                        }
 | 
			
		||||
                    );
 | 
			
		||||
                    })
 | 
			
		||||
            };
 | 
			
		||||
        },
 | 
			
		||||
        submitNewAddress(payload) {
 | 
			
		||||
            console.log('submitNewAddress', payload);
 | 
			
		||||
            this.selected.addressId = payload.addressId;
 | 
			
		||||
            this.addAddress.context.addressId = payload.addressId;
 | 
			
		||||
            this.addAddress.context.edit = true;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,11 @@ const hasLocation = document.querySelector('#location') !== null;
 | 
			
		||||
const hasPerson = document.querySelector('#add-persons') !== null;
 | 
			
		||||
 | 
			
		||||
const app = createApp({
 | 
			
		||||
   template: `<app :hasSocialIssues="hasSocialIssues", :hasLocation="hasLocation", :hasPerson="hasPerson"></app>`,
 | 
			
		||||
   template: `<app
 | 
			
		||||
       :hasSocialIssues="hasSocialIssues"
 | 
			
		||||
       :hasLocation="hasLocation"
 | 
			
		||||
       :hasPerson="hasPerson"
 | 
			
		||||
    ></app>`,
 | 
			
		||||
    data() {
 | 
			
		||||
       return {
 | 
			
		||||
           hasSocialIssues,
 | 
			
		||||
 
 | 
			
		||||
@@ -240,6 +240,9 @@ const store = createStore({
 | 
			
		||||
            });
 | 
			
		||||
            commit("updateActionsSelected", payload);
 | 
			
		||||
        },
 | 
			
		||||
        addAvailableLocationGroup({ commit }, payload) {
 | 
			
		||||
            commit("addAvailableLocationGroup", payload);
 | 
			
		||||
        },
 | 
			
		||||
        addPersonsInvolved({ commit }, payload) {
 | 
			
		||||
            //console.log('### action addPersonsInvolved', payload.result.type);
 | 
			
		||||
            switch (payload.result.type) {
 | 
			
		||||
 
 | 
			
		||||
@@ -418,3 +418,8 @@ span.item-key {
 | 
			
		||||
    background-color: #0000000a;
 | 
			
		||||
    //text-decoration: dotted underline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// increase toast message z-index (above all modals)
 | 
			
		||||
div.v-toast {
 | 
			
		||||
   z-index: 10000!important;
 | 
			
		||||
}
 | 
			
		||||
@@ -85,7 +85,9 @@ const fetchScopes = () => {
 | 
			
		||||
const ValidationException = (response) => {
 | 
			
		||||
    const error = {};
 | 
			
		||||
    error.name = 'ValidationException';
 | 
			
		||||
    error.violations = response.violations.map((violation) => `${violation.title}`);
 | 
			
		||||
    error.violations = response.violations.map((violation) => `${violation.title}: ${violation.propertyPath}`);
 | 
			
		||||
    error.titles = response.violations.map((violation) => violation.title);
 | 
			
		||||
    error.propertyPaths = response.violations.map((violation) => violation.propertyPath);
 | 
			
		||||
 | 
			
		||||
    return error;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -98,6 +98,8 @@
 | 
			
		||||
               v-bind:defaultz="this.defaultz"
 | 
			
		||||
               v-bind:entity="this.entity"
 | 
			
		||||
               v-bind:flag="this.flag"
 | 
			
		||||
               v-bind:errors="this.errors"
 | 
			
		||||
               v-bind:checkErrors="this.checkErrors"
 | 
			
		||||
               @getCities="getCities"
 | 
			
		||||
               @getReferenceAddresses="getReferenceAddresses">
 | 
			
		||||
            </edit-pane>
 | 
			
		||||
@@ -123,6 +125,8 @@
 | 
			
		||||
         v-bind:defaultz="this.defaultz"
 | 
			
		||||
         v-bind:entity="this.entity"
 | 
			
		||||
         v-bind:flag="this.flag"
 | 
			
		||||
         v-bind:errors="this.errors"
 | 
			
		||||
         v-bind:checkErrors="this.checkErrors"
 | 
			
		||||
         v-bind:insideModal="false"
 | 
			
		||||
         @getCities="getCities"
 | 
			
		||||
         @getReferenceAddresses="getReferenceAddresses">
 | 
			
		||||
@@ -256,8 +260,10 @@ export default {
 | 
			
		||||
            editPane: false,
 | 
			
		||||
            datePane: false,
 | 
			
		||||
            loading: false,
 | 
			
		||||
            success: false
 | 
			
		||||
            success: false,
 | 
			
		||||
            dirty: false
 | 
			
		||||
         },
 | 
			
		||||
         errors: [],
 | 
			
		||||
         defaultz: {
 | 
			
		||||
            button: {
 | 
			
		||||
               text: { create: 'add_an_address_title', edit: 'edit_address' },
 | 
			
		||||
@@ -529,6 +535,23 @@ export default {
 | 
			
		||||
         });
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      checkErrors() {
 | 
			
		||||
         this.errors = [];
 | 
			
		||||
         if (this.flag.dirty) {
 | 
			
		||||
            if (this.entity.selected.country === null) {
 | 
			
		||||
               this.errors.push("Un pays doit être sélectionné.");
 | 
			
		||||
            }
 | 
			
		||||
            if (Object.keys(this.entity.selected.city).length === 0) {
 | 
			
		||||
               this.errors.push("Une ville doit être sélectionnée.");
 | 
			
		||||
            }
 | 
			
		||||
            if (!this.entity.selected.isNoAddress) {
 | 
			
		||||
               if (this.entity.selected.address.street === null || this.entity.selected.address.streetNumber === null) {
 | 
			
		||||
                  this.errors.push("Une adresse doit être sélectionnée.");
 | 
			
		||||
               }
 | 
			
		||||
            }
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      /*
 | 
			
		||||
      *   Make form ready for new changes
 | 
			
		||||
      */
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
         @search-change="listenInputSearch"
 | 
			
		||||
         ref="addressSelector"
 | 
			
		||||
         @select="selectAddress"
 | 
			
		||||
         @remove="remove"
 | 
			
		||||
         name="field"
 | 
			
		||||
         track-by="id"
 | 
			
		||||
         label="value"
 | 
			
		||||
@@ -56,7 +57,7 @@ import { searchReferenceAddresses, fetchReferenceAddresses } from '../../api.js'
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'AddressSelection',
 | 
			
		||||
   components: { VueMultiselect },
 | 
			
		||||
   props: ['entity', 'context', 'updateMapCenter'],
 | 
			
		||||
   props: ['entity', 'context', 'updateMapCenter', 'flag', 'checkErrors'],
 | 
			
		||||
   data() {
 | 
			
		||||
      return {
 | 
			
		||||
         value: this.context.edit ? this.entity.address.addressReference : null,
 | 
			
		||||
@@ -109,6 +110,13 @@ export default {
 | 
			
		||||
         this.entity.selected.address.streetNumber = value.streetNumber;
 | 
			
		||||
         this.entity.selected.writeNew.address = false;
 | 
			
		||||
         this.updateMapCenter(value.point);
 | 
			
		||||
         this.flag.dirty = true;
 | 
			
		||||
         this.checkErrors();
 | 
			
		||||
      },
 | 
			
		||||
      remove() {
 | 
			
		||||
         this.flag.dirty = true;
 | 
			
		||||
         this.entity.selected.address = {};
 | 
			
		||||
         this.checkErrors();
 | 
			
		||||
      },
 | 
			
		||||
      listenInputSearch(query) {
 | 
			
		||||
         //console.log('listenInputSearch', query, this.isAddressSelectorOpen);
 | 
			
		||||
@@ -149,6 +157,8 @@ export default {
 | 
			
		||||
            this.entity.selected.address.street = addr.street;
 | 
			
		||||
            this.entity.selected.address.streetNumber = addr.number;
 | 
			
		||||
            this.entity.selected.writeNew.address = true;
 | 
			
		||||
            this.flag.dirty = true;
 | 
			
		||||
            this.checkErrors();
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
      splitAddress(address) {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
         @search-change="listenInputSearch"
 | 
			
		||||
         ref="citySelector"
 | 
			
		||||
         @select="selectCity"
 | 
			
		||||
         @remove="remove"
 | 
			
		||||
         name="field"
 | 
			
		||||
         track-by="id"
 | 
			
		||||
         label="value"
 | 
			
		||||
@@ -55,12 +56,12 @@ import { searchCities, fetchCities } from '../../api.js';
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'CitySelection',
 | 
			
		||||
   components: { VueMultiselect },
 | 
			
		||||
   props: ['entity', 'context', 'focusOnAddress', 'updateMapCenter'],
 | 
			
		||||
   props: ['entity', 'context', 'focusOnAddress', 'updateMapCenter', 'flag', 'checkErrors'],
 | 
			
		||||
   emits: ['getReferenceAddresses'],
 | 
			
		||||
   data() {
 | 
			
		||||
      return {
 | 
			
		||||
         value: this.context.edit ? this.entity.address.postcode : null,
 | 
			
		||||
         isLoading: false
 | 
			
		||||
         isLoading: false,
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   computed: {
 | 
			
		||||
@@ -123,6 +124,13 @@ export default {
 | 
			
		||||
         if (value.center) {
 | 
			
		||||
            this.updateMapCenter(value.center);
 | 
			
		||||
         }
 | 
			
		||||
         this.flag.dirty = true;
 | 
			
		||||
         this.checkErrors();
 | 
			
		||||
      },
 | 
			
		||||
      remove() {
 | 
			
		||||
         this.flag.dirty = true;
 | 
			
		||||
         this.entity.selected.city = {};
 | 
			
		||||
         this.checkErrors();
 | 
			
		||||
      },
 | 
			
		||||
      listenInputSearch(query) {
 | 
			
		||||
         if (query.length > 2) {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,9 @@
 | 
			
		||||
         :select-label="$t('multiselect.select_label')"
 | 
			
		||||
         :deselect-label="$t('multiselect.deselect_label')"
 | 
			
		||||
         :selected-label="$t('multiselect.selected_label')"
 | 
			
		||||
         @select="selectCountry">
 | 
			
		||||
         @select="selectCountry"
 | 
			
		||||
         @remove="remove"
 | 
			
		||||
      >
 | 
			
		||||
      </VueMultiselect>
 | 
			
		||||
   </div>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -23,7 +25,7 @@ import VueMultiselect from 'vue-multiselect';
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'CountrySelection',
 | 
			
		||||
   components: { VueMultiselect },
 | 
			
		||||
   props: ['context', 'entity'],
 | 
			
		||||
   props: ['context', 'entity', 'flag', 'checkErrors'],
 | 
			
		||||
   emits: ['getCities'],
 | 
			
		||||
   data() {
 | 
			
		||||
      return {
 | 
			
		||||
@@ -34,14 +36,13 @@ export default {
 | 
			
		||||
   },
 | 
			
		||||
   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();
 | 
			
		||||
@@ -50,6 +51,7 @@ export default {
 | 
			
		||||
      init() {
 | 
			
		||||
         if (this.value !== undefined) {
 | 
			
		||||
            this.selectCountry(this.value);
 | 
			
		||||
            this.flag.dirty = false;
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
      selectCountryByCode(countryCode) {
 | 
			
		||||
@@ -62,7 +64,13 @@ export default {
 | 
			
		||||
         //console.log('select country', value);
 | 
			
		||||
         this.entity.selected.country = value;
 | 
			
		||||
         this.$emit('getCities', value);
 | 
			
		||||
      }
 | 
			
		||||
         this.checkErrors();
 | 
			
		||||
      },
 | 
			
		||||
      remove() {
 | 
			
		||||
         this.flag.dirty = true;
 | 
			
		||||
         this.entity.selected.country = null;
 | 
			
		||||
         this.checkErrors();
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,12 @@
 | 
			
		||||
         <span class="sr-only">Loading...</span>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div v-if="errors.length" class="alert alert-warning" >
 | 
			
		||||
         <ul>
 | 
			
		||||
            <li v-for="(e, i) in errors" :key="i">{{ e }}</li>
 | 
			
		||||
         </ul>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <h4 class="h3">{{ $t('select_an_address_title') }}</h4>
 | 
			
		||||
      <div class="row my-3">
 | 
			
		||||
         <div class="col-lg-6">
 | 
			
		||||
@@ -25,6 +31,8 @@
 | 
			
		||||
            <country-selection
 | 
			
		||||
               v-bind:context="context"
 | 
			
		||||
               v-bind:entity="entity"
 | 
			
		||||
               v-bind:flag="flag"
 | 
			
		||||
               v-bind:checkErrors="checkErrors"
 | 
			
		||||
               @getCities="$emit('getCities', selected.country)">
 | 
			
		||||
            </country-selection>
 | 
			
		||||
 | 
			
		||||
@@ -33,13 +41,17 @@
 | 
			
		||||
               v-bind:context="context"
 | 
			
		||||
               v-bind:focusOnAddress="focusOnAddress"
 | 
			
		||||
               v-bind:updateMapCenter="updateMapCenter"
 | 
			
		||||
               v-bind:flag="flag"
 | 
			
		||||
               v-bind:checkErrors="checkErrors"
 | 
			
		||||
               @getReferenceAddresses="$emit('getReferenceAddresses', selected.city)">
 | 
			
		||||
            </city-selection>
 | 
			
		||||
 | 
			
		||||
            <address-selection v-if="!isNoAddress"
 | 
			
		||||
               v-bind:entity="entity"
 | 
			
		||||
               v-bind:context="context"
 | 
			
		||||
               v-bind:updateMapCenter="updateMapCenter">
 | 
			
		||||
               v-bind:updateMapCenter="updateMapCenter"
 | 
			
		||||
               v-bind:flag="flag"
 | 
			
		||||
               v-bind:checkErrors="checkErrors">
 | 
			
		||||
            </address-selection>
 | 
			
		||||
 | 
			
		||||
         </div>
 | 
			
		||||
@@ -99,7 +111,9 @@ export default {
 | 
			
		||||
      'flag',
 | 
			
		||||
      'entity',
 | 
			
		||||
      'errorMsg',
 | 
			
		||||
      'insideModal'
 | 
			
		||||
      'insideModal',
 | 
			
		||||
      'errors',
 | 
			
		||||
      'checkErrors',
 | 
			
		||||
   ],
 | 
			
		||||
   emits: ['getCities', 'getReferenceAddresses'],
 | 
			
		||||
   data() {
 | 
			
		||||
@@ -128,7 +142,7 @@ export default {
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.entity.selected.isNoAddress;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
      },
 | 
			
		||||
   },
 | 
			
		||||
   methods: {
 | 
			
		||||
      focusOnAddress() {
 | 
			
		||||
 
 | 
			
		||||
@@ -90,7 +90,7 @@ export default {
 | 
			
		||||
      OnTheFlyThirdparty,
 | 
			
		||||
      OnTheFlyCreate
 | 
			
		||||
   },
 | 
			
		||||
   props: ['type', 'id', 'action', 'buttonText', 'displayBadge', 'parent'],
 | 
			
		||||
   props: ['type', 'id', 'action', 'buttonText', 'displayBadge', 'parent', 'canCloseModal'],
 | 
			
		||||
   emits: ['saveFormOnTheFly'],
 | 
			
		||||
   data() {
 | 
			
		||||
      return {
 | 
			
		||||
@@ -162,7 +162,20 @@ export default {
 | 
			
		||||
         return 'entity-' + this.type + ' badge-' + this.type;
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   watch: {
 | 
			
		||||
      canCloseModal: {
 | 
			
		||||
         handler: function(val, oldVal) {
 | 
			
		||||
            if (val) {
 | 
			
		||||
               this.closeModal();
 | 
			
		||||
            }
 | 
			
		||||
         },
 | 
			
		||||
         deep: true
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   methods: {
 | 
			
		||||
      closeModal() {
 | 
			
		||||
         this.modal.showModal = false;
 | 
			
		||||
      },
 | 
			
		||||
      openModal() {
 | 
			
		||||
         //console.log('## OPEN ON THE FLY MODAL');
 | 
			
		||||
         //console.log('## type:', this.type, ', action:', this.action);
 | 
			
		||||
@@ -200,8 +213,6 @@ export default {
 | 
			
		||||
 | 
			
		||||
         // pass datas to parent
 | 
			
		||||
         this.$emit('saveFormOnTheFly', { type: type, data: data });
 | 
			
		||||
 | 
			
		||||
         this.modal.showModal = false;
 | 
			
		||||
      },
 | 
			
		||||
      buildLocation(id, type) {
 | 
			
		||||
         if (type === 'person') {
 | 
			
		||||
 
 | 
			
		||||
@@ -66,9 +66,10 @@
 | 
			
		||||
               <div class="create-button">
 | 
			
		||||
                  <on-the-fly
 | 
			
		||||
                     v-if="query.length >= 3"
 | 
			
		||||
                     v-bind:buttonText="$t('onthefly.create.button', {q: query})"
 | 
			
		||||
                     :buttonText="$t('onthefly.create.button', {q: query})"
 | 
			
		||||
                     action="create"
 | 
			
		||||
                     @saveFormOnTheFly="saveFormOnTheFly">
 | 
			
		||||
                     @saveFormOnTheFly="saveFormOnTheFly"
 | 
			
		||||
                     :canCloseModal="canCloseOnTheFlyModal">
 | 
			
		||||
                  </on-the-fly>
 | 
			
		||||
               </div>
 | 
			
		||||
 | 
			
		||||
@@ -91,8 +92,7 @@ import Modal from 'ChillMainAssets/vuejs/_components/Modal';
 | 
			
		||||
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
 | 
			
		||||
import PersonSuggestion from './AddPersons/PersonSuggestion';
 | 
			
		||||
import { searchEntities } from 'ChillPersonAssets/vuejs/_api/AddPersons';
 | 
			
		||||
import { postPerson } from "ChillPersonAssets/vuejs/_api/OnTheFly";
 | 
			
		||||
import { postThirdparty } from "ChillThirdPartyAssets/vuejs/_api/OnTheFly";
 | 
			
		||||
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'AddPersons',
 | 
			
		||||
@@ -120,7 +120,8 @@ export default {
 | 
			
		||||
            suggested: [],
 | 
			
		||||
            selected: [],
 | 
			
		||||
            priorSuggestion: {}
 | 
			
		||||
         }
 | 
			
		||||
         },
 | 
			
		||||
         canCloseOnTheFlyModal: false
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   computed: {
 | 
			
		||||
@@ -267,22 +268,36 @@ export default {
 | 
			
		||||
      saveFormOnTheFly({ type, data }) {
 | 
			
		||||
         console.log('saveFormOnTheFly from addPersons, type', type, ', data', data);
 | 
			
		||||
         if (type === 'person') {
 | 
			
		||||
            console.log('type person with', data);
 | 
			
		||||
            postPerson(data)
 | 
			
		||||
               .then(person => new Promise((resolve, reject) => {
 | 
			
		||||
                  console.log('onthefly create: post person', person);
 | 
			
		||||
                  this.newPriorSuggestion(person);
 | 
			
		||||
                  resolve();
 | 
			
		||||
               }));
 | 
			
		||||
            makeFetch('POST', '/api/1.0/person/person.json', data)
 | 
			
		||||
               .then(response => {
 | 
			
		||||
                  this.newPriorSuggestion(response);
 | 
			
		||||
                  this.canCloseOnTheFlyModal = true;
 | 
			
		||||
               })
 | 
			
		||||
               .catch((error) => {
 | 
			
		||||
                  if (error.name === 'ValidationException') {
 | 
			
		||||
                     for (let v of error.violations) {
 | 
			
		||||
                         this.$toast.open({message: v });
 | 
			
		||||
                     }
 | 
			
		||||
                  } else {
 | 
			
		||||
                      this.$toast.open({message: 'An error occurred'});
 | 
			
		||||
                  }
 | 
			
		||||
               })
 | 
			
		||||
         }
 | 
			
		||||
         else if (type === 'thirdparty') {
 | 
			
		||||
            console.log('type thirdparty with', data);
 | 
			
		||||
            postThirdparty(data)
 | 
			
		||||
               .then(thirdparty => new Promise((resolve, reject) => {
 | 
			
		||||
                  console.log('onthefly create: post thirdparty', thirdparty);
 | 
			
		||||
                  this.newPriorSuggestion(thirdparty);
 | 
			
		||||
                  resolve();
 | 
			
		||||
               }));
 | 
			
		||||
            makeFetch('POST', '/api/1.0/thirdparty/thirdparty.json', data)
 | 
			
		||||
               .then(response => {
 | 
			
		||||
                  this.newPriorSuggestion(response);
 | 
			
		||||
                  this.canCloseOnTheFlyModal = true;
 | 
			
		||||
               })
 | 
			
		||||
               .catch((error) => {
 | 
			
		||||
                  if (error.name === 'ValidationException') {
 | 
			
		||||
                     for (let v of error.violations) {
 | 
			
		||||
                         this.$toast.open({message: v });
 | 
			
		||||
                     }
 | 
			
		||||
                  } else {
 | 
			
		||||
                      this.$toast.open({message: 'An error occurred'});
 | 
			
		||||
                  }
 | 
			
		||||
               })
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
 
 | 
			
		||||
@@ -22,24 +22,45 @@
 | 
			
		||||
<div v-else-if="action === 'edit' || action === 'create'">
 | 
			
		||||
 | 
			
		||||
   <div class="form-floating mb-3">
 | 
			
		||||
      <input class="form-control form-control-lg" id="lastname" v-model="lastName" v-bind:placeholder="$t('person.lastname')" />
 | 
			
		||||
      <input
 | 
			
		||||
          class="form-control form-control-lg"
 | 
			
		||||
          id="lastname"
 | 
			
		||||
          v-model="lastName"
 | 
			
		||||
          :placeholder="$t('person.lastname')"
 | 
			
		||||
          @change="checkErrors"
 | 
			
		||||
      />
 | 
			
		||||
      <label for="lastname">{{ $t('person.lastname') }}</label>
 | 
			
		||||
   </div>
 | 
			
		||||
 | 
			
		||||
   <div class="form-floating mb-3">
 | 
			
		||||
      <input class="form-control form-control-lg" id="firstname" v-model="firstName" v-bind:placeholder="$t('person.firstname')" />
 | 
			
		||||
      <input
 | 
			
		||||
          class="form-control form-control-lg"
 | 
			
		||||
          id="firstname"
 | 
			
		||||
          v-model="firstName"
 | 
			
		||||
          :placeholder="$t('person.firstname')"
 | 
			
		||||
          @change="checkErrors"
 | 
			
		||||
      />
 | 
			
		||||
      <label for="firstname">{{ $t('person.firstname') }}</label>
 | 
			
		||||
   </div>
 | 
			
		||||
 | 
			
		||||
   <div v-for="(a) in config.altNames" :key="a.key" class="form-floating mb-3">
 | 
			
		||||
      <input class="form-control form-control-lg" :id="a.key" @input="onAltNameInput" />
 | 
			
		||||
      <input
 | 
			
		||||
          class="form-control form-control-lg"
 | 
			
		||||
          :id="a.key"
 | 
			
		||||
          @input="onAltNameInput"
 | 
			
		||||
      />
 | 
			
		||||
      <label :for="a.key">{{ a.labels.fr }}</label>
 | 
			
		||||
   </div>
 | 
			
		||||
 | 
			
		||||
   <!--  TODO fix placeholder if undefined
 | 
			
		||||
   -->
 | 
			
		||||
   <div class="form-floating mb-3">
 | 
			
		||||
      <select class="form-select form-select-lg" id="gender" v-model="gender">
 | 
			
		||||
      <select
 | 
			
		||||
         class="form-select form-select-lg"
 | 
			
		||||
         id="gender"
 | 
			
		||||
         v-model="gender"
 | 
			
		||||
         @change="checkErrors"
 | 
			
		||||
         >
 | 
			
		||||
         <option selected disabled >{{ $t('person.gender.placeholder') }}</option>
 | 
			
		||||
         <option value="woman">{{ $t('person.gender.woman') }}</option>
 | 
			
		||||
         <option value="man">{{ $t('person.gender.man') }}</option>
 | 
			
		||||
@@ -62,8 +83,8 @@
 | 
			
		||||
      <span class="input-group-text" id="phonenumber"><i class="fa fa-fw fa-phone"></i></span>
 | 
			
		||||
      <input class="form-control form-control-lg"
 | 
			
		||||
         v-model="phonenumber"
 | 
			
		||||
         v-bind:placeholder="$t('person.phonenumber')"
 | 
			
		||||
         v-bind:aria-label="$t('person.phonenumber')"
 | 
			
		||||
         :placeholder="$t('person.phonenumber')"
 | 
			
		||||
         :aria-label="$t('person.phonenumber')"
 | 
			
		||||
         aria-describedby="phonenumber" />
 | 
			
		||||
   </div>
 | 
			
		||||
 | 
			
		||||
@@ -71,8 +92,8 @@
 | 
			
		||||
      <span class="input-group-text" id="mobilenumber"><i class="fa fa-fw fa-mobile"></i></span>
 | 
			
		||||
      <input class="form-control form-control-lg"
 | 
			
		||||
         v-model="mobilenumber"
 | 
			
		||||
         v-bind:placeholder="$t('person.mobilenumber')"
 | 
			
		||||
         v-bind:aria-label="$t('person.mobilenumber')"
 | 
			
		||||
         :placeholder="$t('person.mobilenumber')"
 | 
			
		||||
         :aria-label="$t('person.mobilenumber')"
 | 
			
		||||
         aria-describedby="mobilenumber" />
 | 
			
		||||
   </div>
 | 
			
		||||
 | 
			
		||||
@@ -80,11 +101,17 @@
 | 
			
		||||
      <span class="input-group-text" id="email"><i class="fa fa-fw fa-at"></i></span>
 | 
			
		||||
      <input class="form-control form-control-lg"
 | 
			
		||||
         v-model="email"
 | 
			
		||||
         v-bind:placeholder="$t('person.email')"
 | 
			
		||||
         v-bind:aria-label="$t('person.email')"
 | 
			
		||||
         :placeholder="$t('person.email')"
 | 
			
		||||
         :aria-label="$t('person.email')"
 | 
			
		||||
         aria-describedby="email" />
 | 
			
		||||
   </div>
 | 
			
		||||
 | 
			
		||||
   <div class="alert alert-warning" v-if="errors.length">
 | 
			
		||||
     <ul>
 | 
			
		||||
       <li v-for="(e, i) in errors" :key="i">{{ e }}</li>
 | 
			
		||||
     </ul>
 | 
			
		||||
   </div>
 | 
			
		||||
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
@@ -108,6 +135,7 @@ export default {
 | 
			
		||||
         config: {
 | 
			
		||||
            altNames: []
 | 
			
		||||
         },
 | 
			
		||||
         errors: []
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   computed: {
 | 
			
		||||
@@ -183,6 +211,18 @@ export default {
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   methods: {
 | 
			
		||||
      checkErrors(e) {
 | 
			
		||||
         this.errors = [];
 | 
			
		||||
         if (!this.person.lastName) {
 | 
			
		||||
             this.errors.push("Le nom ne doit pas être vide.");
 | 
			
		||||
         }
 | 
			
		||||
         if (!this.person.firstName) {
 | 
			
		||||
             this.errors.push("Le prénom ne doit pas être vide.");
 | 
			
		||||
         }
 | 
			
		||||
         if (!this.person.gender) {
 | 
			
		||||
             this.errors.push("Le genre doit être renseigné");
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
      loadData() {
 | 
			
		||||
         getPerson(this.id)
 | 
			
		||||
            .then(person => new Promise((resolve, reject) => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user