From 7e932e838f9b9d7dbad306e87a515b622be6bc4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 17 Jan 2022 15:28:49 +0100 Subject: [PATCH] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 9e767fa3e0788d87437c235e51fcdc4f26f75d98 Author: Julien Fastré Date: Mon Jan 17 15:28:02 2022 +0100 traductions commit db6513474377b702cc2258be3e2ba720d007bc11 Author: nobohan Date: Mon Jan 17 12:17:22 2022 +0100 add person: increase z-index of toast and wait for validation before closing modal commit 7af4c3434ef39b27eb51881611338b50a379acc8 Merge: a09c8ee8a 46c6d0e29 Author: Julien Fastré Date: Sun Jan 16 22:51:45 2022 +0100 Merge remote-tracking branch 'origin/master' into issue357_front_end_validation commit a09c8ee8af962021b9d6a402863c8c5671c0e621 Author: nobohan Date: Wed Jan 12 15:47:11 2022 +0100 upd CHANGELOG commit a312a9463d861659f70909bed7d8aa67fef444f2 Author: nobohan Date: Wed Jan 12 15:29:32 2022 +0100 address: display error message if some fields are empty (street & streetnumber) commit 0035128138ddd3d877befae3e489329634555f79 Author: nobohan Date: Wed Jan 12 14:47:43 2022 +0100 address: display error message if some fields are empty commit 49cb15467297bd24c5eb9a0dd7e366ccd7744679 Author: nobohan Date: Tue Jan 11 20:58:00 2022 +0100 address: add field validation (WIP) commit 1a7ec9e39631e00d59fcb3204a157e1583679cda Author: nobohan Date: Tue Jan 11 17:16:43 2022 +0100 Activity: fix vuejs warning commit fa0b9271c2b4963564fdc1e0eda09a12758caa4b Author: nobohan Date: Tue Jan 11 16:13:23 2022 +0100 location: treat 422 error when POSTing new location commit c7b9a1a3fe8891f80699faa2dd277064dce7b0b6 Author: nobohan Date: Tue Jan 11 16:00:29 2022 +0100 location: fix error when creating a new location: a new location could not be added to the availableLocations due to refactoring commit f1c61a2387df7507c79c55e7defe46fbb052df6c Author: nobohan Date: Tue Jan 11 15:20:33 2022 +0100 person: treat 422 error in AddPerson for thirdparty commit 8f6a70b240c286c18e1a102953f243e57b4af97a Author: nobohan Date: Tue Jan 11 11:30:05 2022 +0100 person: add validation for required fields in on-the-fly person commit 40e4bf953fa8e9a04a34e0330562bd25324c5589 Author: nobohan Date: Tue Jan 11 09:34:15 2022 +0100 vuejs: better violations message in 422 error handling commit 378f3a16fc34228334cd44b9e7ca618bc7eb72aa Author: nobohan Date: Mon Jan 10 18:11:02 2022 +0100 person: on-the-fly person: first implementation of makeFetch for posting person --- CHANGELOG.md | 2 + .../Resources/public/vuejs/Activity/App.vue | 2 +- .../vuejs/Activity/components/Location.vue | 2 +- .../components/Location/NewLocation.vue | 52 ++++++++-------- .../Resources/public/vuejs/Activity/index.js | 6 +- .../Resources/public/vuejs/Activity/store.js | 3 + .../Resources/public/chill/chillmain.scss | 5 ++ .../Resources/public/lib/api/apiMethods.js | 4 +- .../vuejs/Address/components/AddAddress.vue | 25 +++++++- .../AddAddress/AddressSelection.vue | 12 +++- .../components/AddAddress/CitySelection.vue | 12 +++- .../AddAddress/CountrySelection.vue | 18 ++++-- .../vuejs/Address/components/EditPane.vue | 20 ++++++- .../vuejs/OnTheFly/components/OnTheFly.vue | 17 +++++- .../ChillPersonBundle/Entity/Person.php | 7 +-- .../public/vuejs/_components/AddPersons.vue | 53 ++++++++++------ .../vuejs/_components/OnTheFly/Person.vue | 60 +++++++++++++++---- .../translations/validators.fr.yml | 3 + 18 files changed, 226 insertions(+), 77 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 568224874..233c1f51b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to * [main] Add mainLocation field to User entity and add it in user form type * [course list in person context] show full username/label for ref * [accompanying period work] remove the possibility to generate document from an accompanying period work +* vuejs: add validation on required fields for AddPerson, Address and Location components +* vuejs: treat 422 validation errors in locations and AddPerson components ## Test releases diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/App.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/App.vue index 2fb9d022d..4809a5fae 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/App.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/App.vue @@ -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, diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index b8249ccc5..91c5db839 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -24,7 +24,7 @@ v-model="location" > - + diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue index 35bf9a065..c9a1c233c 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue @@ -18,15 +18,6 @@ @@ -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(); + }, } }; diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue index af1263b43..486d28e73 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue @@ -7,6 +7,12 @@ Loading... +
+
    +
  • {{ e }}
  • +
+
+

{{ $t('select_an_address_title') }}

@@ -25,6 +31,8 @@ @@ -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)"> + v-bind:updateMapCenter="updateMapCenter" + v-bind:flag="flag" + v-bind:checkErrors="checkErrors">
@@ -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() { diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/OnTheFly/components/OnTheFly.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/OnTheFly/components/OnTheFly.vue index d4342fdee..8c93eec71 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/OnTheFly/components/OnTheFly.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/OnTheFly/components/OnTheFly.vue @@ -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') { diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index 73b83f246..91e430a2f 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -151,7 +151,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI * @var DateTime * * @ORM\Column(type="date", nullable=true) - * @Assert\Date * @Birthdate */ private $birthdate; @@ -259,7 +258,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI * @var string * * @ORM\Column(type="string", length=255) - * @Assert\NotBlank + * @Assert\NotBlank(message="The firstname cannot be empty") * @Assert\Length( * max=255, * ) @@ -282,7 +281,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI * @var string * * @ORM\Column(type="string", length=9, nullable=true) - * @Assert\NotNull + * @Assert\NotNull(message="The gender must be set") */ private $gender; @@ -326,7 +325,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI * @var string * * @ORM\Column(type="string", length=255) - * @Assert\NotBlank + * @Assert\NotBlank(message="The lastname cannot be empty") * @Assert\Length( * max=255, * ) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons.vue index f118671ed..59647e160 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons.vue @@ -66,9 +66,10 @@
+ @saveFormOnTheFly="saveFormOnTheFly" + :canCloseModal="canCloseOnTheFlyModal">
@@ -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'}); + } + }) } } }, diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/OnTheFly/Person.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/OnTheFly/Person.vue index 799e5651b..9543da3bb 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/OnTheFly/Person.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/OnTheFly/Person.vue @@ -22,24 +22,45 @@
- +
- +
- +
- @@ -62,8 +83,8 @@
@@ -71,8 +92,8 @@
@@ -80,11 +101,17 @@
+
+
    +
  • {{ e }}
  • +
+
+ @@ -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) => { diff --git a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml index b421e9f43..96cfd565f 100644 --- a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml @@ -16,6 +16,9 @@ The birthdate must be before %date%: La date de naissance doit être avant le %d 'Invalid phone number: it should begin with the international prefix starting with "+", hold only digits and be smaller than 20 characters. Ex: +33623456789': 'Numéro de téléphone invalide: il doit commencer par le préfixe international précédé de "+", ne comporter que des chiffres et faire moins de 20 caractères. Ex: +33623456789' 'The email is not valid': 'Le courriel n''est pas valide' Two addresses has the same validFrom date: La date de validité est identique à celle d'une autre adresse +The firstname cannot be empty: Le prénom ne peut pas être vide +The lastname cannot be empty: Le nom de famille ne peut pas être vide +The gender must be set: Le genre doit être renseigné #export list You must select at least one element: Vous devez sélectionner au moins un élément