diff --git a/CHANGELOG.md b/CHANGELOG.md index 940d7e05c..233c1f51b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,14 @@ and this project adheres to ## Unreleased - +* [main] Add editableByUser field to locationType entity, adapt the admin template and add this condition in the location-type endpoint (see https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/297) +* [main] Add mainLocation field to User entity and add it in user form type +* rewrite page which allow to select activity +* [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/chill/chillactivity.scss b/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss index 275f67950..8b88f0e78 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss +++ b/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss @@ -9,8 +9,9 @@ div.new-activity-select-type { display: flex; flex-direction: row; flex-wrap: wrap; - justify-content: center; + justify-content: flex-start; gap: 12px; + margin-bottom: 30px; div.bloc { width: 200px; @@ -27,26 +28,26 @@ div.new-activity-select-type { // precise dashboard specific details p.date-label { - display: inline-block; - margin: 0 0.5em 0 0; - font-weight: 700; - font-size: 18pt; + display: inline-block; + margin: 0 0.5em 0 0; + font-weight: 700; + font-size: 18pt; } div.dashboard, h2.badge-title { - ul.list-content { - font-size: 70%; - list-style-type: none; - padding-left: 0; - margin: 0; - li { - margin-bottom: 0.2em; - // exception: change bg color for action badges above dashboard - .bg-light { - background-color: $chill-light-gray !important; - } - } - } + ul.list-content { + font-size: 70%; + list-style-type: none; + padding-left: 0; + margin: 0; + li { + margin-bottom: 0.2em; + // exception: change bg color for action badges above dashboard + .bg-light { + background-color: $chill-light-gray !important; + } + } + } } //// ACTIVITY SHOW AND FORM PAGES 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... +
+ +
+

{{ $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/ChillMainBundle/Resources/views/LocationType/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig index 5402d5e89..22cb6de44 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig @@ -8,6 +8,7 @@ {{ 'Title'|trans }} {{ 'Available for users'|trans }} + {{ 'Editable by users'|trans }} {{ 'Address required'|trans }} {{ 'Contact data'|trans }} {{ 'Active'|trans }} @@ -25,6 +26,13 @@ {%- endif -%} + + {%- if entity.editableByUsers -%} + + {%- else -%} + + {%- endif -%} + {{ entity.addressRequired|trans }} {{ entity.contactData|trans }} diff --git a/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php b/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php index 975a7c9f8..365433ef3 100644 --- a/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php +++ b/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php @@ -58,7 +58,7 @@ class UserNormalizer implements ContextAwareNormalizerInterface, NormalizerAware ); $locationContext = array_merge( $context, - ['docgen:expects' => Location::class, 'groups' => 'dogen:read'] + ['docgen:expects' => Location::class, 'groups' => 'docgen:read'] ); if (null === $user && 'docgen' === $format) { @@ -67,6 +67,7 @@ class UserNormalizer implements ContextAwareNormalizerInterface, NormalizerAware 'main_center' => $this->normalizer->normalize(null, $format, $centerContext), 'main_scope' => $this->normalizer->normalize(null, $format, $scopeContext), 'current_location' => $this->normalizer->normalize(null, $format, $locationContext), + 'main_location' => $this->normalizer->normalize(null, $format, $locationContext), ]); } @@ -84,6 +85,7 @@ class UserNormalizer implements ContextAwareNormalizerInterface, NormalizerAware if ('docgen' === $format) { $data['current_location'] = $this->normalizer->normalize($user->getCurrentLocation(), $format, $locationContext); + $data['main_location'] = $this->normalizer->normalize($user->getMainLocation(), $format, $locationContext); } return $data; diff --git a/src/Bundle/ChillMainBundle/migrations/Version20220112150413.php b/src/Bundle/ChillMainBundle/migrations/Version20220112150413.php new file mode 100644 index 000000000..c38649711 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20220112150413.php @@ -0,0 +1,36 @@ +addSql('ALTER TABLE chill_main_location_type DROP editableByUsers'); + } + + public function getDescription(): string + { + return 'Add editableByUsers field to ChillMain/LocationType'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_main_location_type ADD editableByUsers BOOLEAN DEFAULT TRUE'); + } +} diff --git a/src/Bundle/ChillMainBundle/migrations/Version20220112161136.php b/src/Bundle/ChillMainBundle/migrations/Version20220112161136.php new file mode 100644 index 000000000..89abc11d7 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20220112161136.php @@ -0,0 +1,40 @@ +addSql('ALTER TABLE users DROP CONSTRAINT FK_1483A5E9DB622A42'); + $this->addSql('DROP INDEX IDX_1483A5E9DB622A42'); + $this->addSql('ALTER TABLE users DROP mainLocation_id'); + } + + public function getDescription(): string + { + return 'Add mainLocation to User'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE users ADD mainLocation_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE users ADD CONSTRAINT FK_1483A5E9DB622A42 FOREIGN KEY (mainLocation_id) REFERENCES chill_main_location (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_1483A5E9DB622A42 ON users (mainLocation_id)'); + } +} diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 2e726a48c..af0dc77d7 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -202,6 +202,7 @@ Location: Localisation Location type list: Liste des types de localisation Create a new location type: Créer un nouveau type de localisation Available for users: Disponible aux utilisateurs +Editable by users: Éditable par les utilisateurs Address required: Adresse requise? Contact data: Données de contact? optional: optionnel 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/chill/scss/badge.scss b/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/badge.scss index 46c13d152..e8a98bc80 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/badge.scss +++ b/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/badge.scss @@ -184,5 +184,9 @@ div[class*='activity-'] { background-color: $chill-ll-gray; color: $chill-blue; } + &.bg-confidential { + background-color: $chill-ll-gray; + color: $chill-red; + } } diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue index 97bda5fc5..b5e5d3221 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue @@ -233,18 +233,6 @@
-
- - - -
-

{{ $t('fix_these_errors') }}

+
+ +
+ @@ -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/Resources/views/AccompanyingCourseWork/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig index a38aa913f..96775ca70 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig @@ -96,7 +96,9 @@ 'type': 'accompanying_period', 'id': accompanyingCourse.id } - } %} + } + } + %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list_item.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list_item.html.twig index 79e159596..3c89bf3e3 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list_item.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list_item.html.twig @@ -11,7 +11,7 @@ {{- 'Emergency'|trans|upper -}} {% endif %} {% if period.confidential %} - {{- 'Confidential'|trans|upper -}} + {{- 'Confidential'|trans|upper -}} {% endif %}
@@ -45,7 +45,7 @@ {% if chill_accompanying_periods.fields.user == 'visible' %} {% if period.user %} {{ 'Referrer'|trans }}: - {{ period.user.username|chill_entity_render_box }} + {{ period.user|chill_entity_render_box }} {% else %} {{ 'No accompanying user'|trans }} {% endif %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig index f28115d8d..4b0076078 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig @@ -80,7 +80,14 @@ {% set app = person.findParticipationForPeriod(acp) %}
- +
+ {% if acp.emergency %} + {{- 'Emergency'|trans|upper -}} + {% endif %} + {% if acp.confidential %} + {{- 'Confidential'|trans|upper -}} + {% endif %} +
{% if acp.step == 'DRAFT' %}
{{ 'course.draft'|trans }} diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkContext.php index b47c46b00..514f396c6 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkContext.php @@ -21,10 +21,7 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; -class AccompanyingPeriodWorkContext implements - DocGeneratorContextInterface, - DocGeneratorContextWithAdminFormInterface, - DocGeneratorContextWithPublicFormInterface +class AccompanyingPeriodWorkContext { private NormalizerInterface $normalizer; 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