diff --git a/CHANGELOG.md b/CHANGELOG.md index 44d50012b..db4ff2b37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to ## Unreleased +* [person] suggest entities (person | thirdparty) when creating/editing the accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/119) +* [activity] add custom validation on the Activity class, based on what is required from the ActivityType (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/188) +* [main] translate multiselect messages when selecting/creating address +* [main] set the coordinates of the city when creating a new address OR choosing "pas d'adresse complète" * Use the user.label in accompanying course banner, instead of username; * fix: show validation message when closing accompanying course; * [thirdparty] link from modal to thirdparty detail page fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/228) @@ -23,6 +27,14 @@ and this project adheres to * https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/101 * https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/295 * [activity/calendar] on show page, concerned groups of persons table adapt itself to isVisibles options +* [activity] remove the "plus" button in activity list +* [activity] check ACL on activity list in person context +* [list for accompanying course in person] filter list using ACL +* [validation] toasts are displayed for errors when modifying accompanying course (generalization required). +* [period] only the user can enable confidentiality +* add an endpoint for checking permissions. See https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/232 +* [activity] for a new activity: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties +* [calendar] for a new rdv: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties ## Test releases diff --git a/phpstan-critical.neon b/phpstan-critical.neon index 6147f2022..b214654bf 100644 --- a/phpstan-critical.neon +++ b/phpstan-critical.neon @@ -70,11 +70,6 @@ parameters: count: 1 path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php - - - message: "#^Undefined variable\\: \\$value$#" - count: 1 - path: src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidityValidator.php - - message: "#^Undefined variable\\: \\$choiceSlug$#" count: 1 diff --git a/phpstan-deprecations.neon b/phpstan-deprecations.neon index bf1ec095e..6f9f19956 100644 --- a/phpstan-deprecations.neon +++ b/phpstan-deprecations.neon @@ -1330,14 +1330,6 @@ parameters: count: 1 path: src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php - - - message: - """ - #^Parameter \\$centerResolverDispatcher of method Chill\\\\PersonBundle\\\\Validator\\\\Constraints\\\\Person\\\\PersonHasCenterValidator\\:\\:__construct\\(\\) has typehint with deprecated interface Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\CenterResolverDispatcherInterface\\: - Use CenterResolverManager and its interface CenterResolverManagerInterface$# - """ - count: 1 - path: src/Bundle/ChillPersonBundle/Validator/Constraints/Person/PersonHasCenterValidator.php - message: diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index f4248b5e8..ae7cdfa59 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -105,18 +105,19 @@ final class ActivityController extends AbstractController [$person, $accompanyingPeriod] = $this->getEntity($request); - if ($accompanyingPeriod instanceof AccompanyingPeriod) { - $view = 'ChillActivityBundle:Activity:confirm_deleteAccompanyingCourse.html.twig'; - } elseif ($person instanceof Person) { - $view = 'ChillActivityBundle:Activity:confirm_deletePerson.html.twig'; - } - $activity = $this->activityRepository->find($id); if (!$activity) { throw $this->createNotFoundException('Unable to find Activity entity.'); } + if ($activity->getAccompanyingPeriod() instanceof AccompanyingPeriod) { + $view = 'ChillActivityBundle:Activity:confirm_deleteAccompanyingCourse.html.twig'; + $accompanyingPeriod = $activity->getAccompanyingPeriod(); + } else { + $view = 'ChillActivityBundle:Activity:confirm_deletePerson.html.twig'; + } + // TODO // $this->denyAccessUnlessGranted('CHILL_ACTIVITY_DELETE', $activity); @@ -137,7 +138,7 @@ final class ActivityController extends AbstractController static fn (ActivityReason $ar): int => $ar->getId() ) ->toArray(), - 'type_id' => $activity->getType()->getId(), + 'type_id' => $activity->getActivityType()->getId(), 'duration' => $activity->getDurationTime() ? $activity->getDurationTime()->format('U') : null, 'date' => $activity->getDate()->format('Y-m-d'), 'attendee' => $activity->getAttendee(), @@ -176,25 +177,25 @@ final class ActivityController extends AbstractController [$person, $accompanyingPeriod] = $this->getEntity($request); - if ($accompanyingPeriod instanceof AccompanyingPeriod) { - $view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig'; - } elseif ($person instanceof Person) { - $view = 'ChillActivityBundle:Activity:editPerson.html.twig'; - } - $entity = $this->activityRepository->find($id); if (null === $entity) { throw $this->createNotFoundException('Unable to find Activity entity.'); } + if ($entity->getAccompanyingPeriod() instanceof AccompanyingPeriod) { + $view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig'; + $accompanyingPeriod = $entity->getAccompanyingPeriod(); + } else { + $view = 'ChillActivityBundle:Activity:editPerson.html.twig'; + } // TODO // $this->denyAccessUnlessGranted('CHILL_ACTIVITY_UPDATE', $entity); $form = $this->createForm(ActivityType::class, $entity, [ 'center' => $entity->getCenter(), 'role' => new Role('CHILL_ACTIVITY_UPDATE'), - 'activityType' => $entity->getType(), + 'activityType' => $entity->getActivityType(), 'accompanyingPeriod' => $accompanyingPeriod, ])->handleRequest($request); @@ -327,7 +328,7 @@ final class ActivityController extends AbstractController $entity->setAccompanyingPeriod($accompanyingPeriod); } - $entity->setType($activityType); + $entity->setActivityType($activityType); $entity->setDate(new DateTime('now')); if ($request->query->has('activityData')) { @@ -385,7 +386,7 @@ final class ActivityController extends AbstractController $form = $this->createForm(ActivityType::class, $entity, [ 'center' => $entity->getCenter(), 'role' => new Role('CHILL_ACTIVITY_CREATE'), - 'activityType' => $entity->getType(), + 'activityType' => $entity->getActivityType(), 'accompanyingPeriod' => $accompanyingPeriod, ])->handleRequest($request); @@ -408,7 +409,7 @@ final class ActivityController extends AbstractController $activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']); - $defaultLocationId = $this->getUser()->getCurrentLocation()->getId(); + $defaultLocation = $this->getUser()->getCurrentLocation(); return $this->render($view, [ 'person' => $person, @@ -416,7 +417,7 @@ final class ActivityController extends AbstractController 'entity' => $entity, 'form' => $form->createView(), 'activity_json' => $activity_array, - 'default_location_id' => $defaultLocationId, + 'default_location' => $defaultLocation, ]); } diff --git a/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeController.php b/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeController.php index 140a0b855..81c978bf2 100644 --- a/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeController.php +++ b/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeController.php @@ -23,6 +23,7 @@ class AdminActivityTypeController extends CRUDController protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { /** @var \Doctrine\ORM\QueryBuilder $query */ - return $query->orderBy('e.ordering', 'ASC'); + return $query->orderBy('e.ordering', 'ASC') + ->addOrderBy('e.id', 'ASC'); } } diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 693e2af85..07b88fcae 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -9,6 +9,7 @@ namespace Chill\ActivityBundle\Entity; +use Chill\ActivityBundle\Validator\Constraints as ActivityValidator; use Chill\DocStoreBundle\Entity\Document; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; @@ -41,6 +42,7 @@ use Symfony\Component\Serializer\Annotation\SerializedName; * @DiscriminatorMap(typeProperty="type", mapping={ * "activity": Activity::class * }) + * @ActivityValidator\ActivityValidity */ /* @@ -202,7 +204,9 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer public function addPerson(?Person $person): self { if (null !== $person) { - $this->persons[] = $person; + if (!$this->persons->contains($person)) { + $this->persons[] = $person; + } } return $this; @@ -236,7 +240,9 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer public function addThirdParty(?ThirdParty $thirdParty): self { if (null !== $thirdParty) { - $this->thirdParties[] = $thirdParty; + if (!$this->thirdParties->contains($thirdParty)) { + $this->thirdParties[] = $thirdParty; + } } return $this; @@ -245,7 +251,9 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer public function addUser(?User $user): self { if (null !== $user) { - $this->users[] = $user; + if (!$this->users->contains($user)) { + $this->users[] = $user; + } } return $this; diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php index 0e9b1150a..4cb4250b5 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php @@ -12,6 +12,7 @@ namespace Chill\ActivityBundle\Entity; use Doctrine\ORM\Mapping as ORM; use InvalidArgumentException; use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Validator\Constraints as Assert; /** * Class ActivityType. @@ -29,11 +30,13 @@ class ActivityType public const FIELD_REQUIRED = 2; /** + * @deprecated not in use * @ORM\Column(type="string", nullable=false, options={"default": ""}) */ private string $accompanyingPeriodLabel = ''; /** + * @deprecated not in use * @ORM\Column(type="smallint", nullable=false, options={"default": 1}) */ private int $accompanyingPeriodVisible = self::FIELD_INVISIBLE; @@ -195,16 +198,21 @@ class ActivityType /** * @ORM\Column(type="smallint", nullable=false, options={"default": 1}) + * @Assert\EqualTo(propertyPath="socialIssuesVisible", message="This parameter must be equal to social issue parameter") */ private int $socialActionsVisible = self::FIELD_INVISIBLE; /** * @ORM\Column(type="string", nullable=false, options={"default": ""}) + * + * @deprecated not in use */ private string $socialDataLabel = ''; /** * @ORM\Column(type="smallint", nullable=false, options={"default": 1}) + * + * @deprecated not in use */ private int $socialDataVisible = self::FIELD_INVISIBLE; @@ -260,16 +268,6 @@ class ActivityType */ private int $userVisible = self::FIELD_REQUIRED; - public function getAccompanyingPeriodLabel(): string - { - return $this->accompanyingPeriodLabel; - } - - public function getAccompanyingPeriodVisible(): int - { - return $this->accompanyingPeriodVisible; - } - /** * Get active * return true if the type is active. @@ -446,16 +444,6 @@ class ActivityType return $this->socialActionsVisible; } - public function getSocialDataLabel(): string - { - return $this->socialDataLabel; - } - - public function getSocialDataVisible(): int - { - return $this->socialDataVisible; - } - public function getSocialIssuesLabel(): ?string { return $this->socialIssuesLabel; @@ -537,20 +525,6 @@ class ActivityType return self::FIELD_INVISIBLE !== $this->{$property}; } - public function setAccompanyingPeriodLabel(string $accompanyingPeriodLabel): self - { - $this->accompanyingPeriodLabel = $accompanyingPeriodLabel; - - return $this; - } - - public function setAccompanyingPeriodVisible(int $accompanyingPeriodVisible): self - { - $this->accompanyingPeriodVisible = $accompanyingPeriodVisible; - - return $this; - } - /** * Set active * set to true if the type is active. @@ -768,20 +742,6 @@ class ActivityType return $this; } - public function setSocialDataLabel(string $socialDataLabel): self - { - $this->socialDataLabel = $socialDataLabel; - - return $this; - } - - public function setSocialDataVisible(int $socialDataVisible): self - { - $this->socialDataVisible = $socialDataVisible; - - return $this; - } - public function setSocialIssuesLabel(string $socialIssuesLabel): self { $this->socialIssuesLabel = $socialIssuesLabel; diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php b/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php index 300be5c4c..682d73aaf 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php @@ -56,7 +56,7 @@ class ActivityTypeType extends AbstractType 'persons', 'user', 'date', 'place', 'persons', 'thirdParties', 'durationTime', 'travelTime', 'attendee', 'reasons', 'comment', 'sentReceived', 'documents', - 'emergency', 'accompanyingPeriod', 'socialData', 'users', + 'emergency', 'socialIssues', 'socialActions', 'users', ]; foreach ($fields as $field) { diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/App.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/App.vue index 52454c2f7..2fb9d022d 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/App.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/App.vue @@ -1,7 +1,7 @@ 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 2920e15b2..35bf9a065 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 @@ -214,11 +214,9 @@ export default { return cond; }, getLocationTypesList() { - getLocationTypes().then(response => new Promise(resolve => { - console.log('getLocationTypes', response); - this.locationTypes = response.results.filter(t => t.availableForUsers === true); - resolve(); - })) + getLocationTypes().then(results => { + this.locationTypes = results.filter(t => t.availableForUsers === true); + }) }, openModal() { this.modal.showModal = true; @@ -247,7 +245,6 @@ export default { postLocation(body) .then( location => new Promise(resolve => { - console.log('postLocation', location); this.locations.push(location); this.$store.dispatch('updateLocation', location); resolve(); diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/index.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/index.js index 1408afd37..66657df47 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/index.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/index.js @@ -7,8 +7,19 @@ import App from './App.vue'; const i18n = _createI18n(activityMessages); +const hasSocialIssues = document.querySelector('#social-issues-acc') !== null; +const hasLocation = document.querySelector('#location') !== null; +const hasPerson = document.querySelector('#add-persons') !== null; + const app = createApp({ - template: ``, + template: ``, + data() { + return { + hasSocialIssues, + hasLocation, + hasPerson, + }; + } }) .use(store) .use(i18n) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js index ef9cf3b1f..5b6297553 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js @@ -1,5 +1,6 @@ import 'es6-promise/auto'; import { createStore } from 'vuex'; +import { postLocation } from './api'; const debug = process.env.NODE_ENV !== 'production'; //console.log('window.activity', window.activity); @@ -27,7 +28,6 @@ const store = createStore({ }, getters: { suggestedEntities(state) { - console.log(state.activity); if (typeof state.activity.accompanyingPeriod === "undefined") { return []; } @@ -303,7 +303,33 @@ const store = createStore({ let hiddenLocation = document.getElementById( "chill_activitybundle_activity_location" ); - hiddenLocation.value = value.id; + if (value.onthefly) { + const body = { + "type": "location", + "name": value.name === '__AccompanyingCourseLocation__' ? null : value.name, + "locationType": { + "id": value.locationType.id, + "type": "location-type" + } + }; + if (value.address.id) { + Object.assign(body, { + "address": { + "id": value.address.id + }, + }) + } + postLocation(body) + .then( + location => hiddenLocation.value = location.id + ).catch( + err => { + console.log(err.message); + } + ); + } else { + hiddenLocation.value = value.id; + } commit("updateLocation", value); }, }, diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/edit.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/edit.html.twig index e043b4d53..b3da40e96 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/edit.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/edit.html.twig @@ -28,7 +28,9 @@ {{ form_row(edit_form.socialActions) }} {% endif %} +{%- if edit_form.socialIssues is defined or edit_form.socialIssues is defined -%}
+{% endif %} {%- if edit_form.reasons is defined -%} {{ form_row(edit_form.reasons) }} @@ -46,9 +48,10 @@ {%- if edit_form.users is defined -%} {{ form_widget(edit_form.users) }} {% endif %} + +
{% endif %} -

{{ 'Activity data'|trans }}

diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig index fef381527..7c75f5bf0 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig @@ -3,7 +3,6 @@ {% if activities|length == 0 %}

{{ "There isn't any activities."|trans }} -

{% else %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig index 830fecfb9..158bd0e1b 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig @@ -36,12 +36,14 @@ {% include 'ChillActivityBundle:Activity:list.html.twig' with {'context': 'person'} %} + {% if is_granted('CHILL_ACTIVITY_CREATE', person) %} + {% endif %} {% endblock %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/new.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/new.html.twig index 10afd77a2..62aac6d6c 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/new.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/new.html.twig @@ -29,25 +29,29 @@ {{ form_row(form.socialActions) }} {% endif %} -
+{%- if edit_form.socialIssues is defined or edit_form.socialIssues is defined -%} +
+{% endif %} {%- if form.reasons is defined -%} {{ form_row(form.reasons) }} {% endif %} -

{{ 'Concerned groups'|trans }}

+{%- if edit_form.persons is defined or edit_form.thirdParties is defined or edit_form.users is defined -%} +

{{ 'Concerned groups'|trans }}

-{%- if form.persons is defined -%} - {{ form_widget(form.persons) }} + {%- if form.persons is defined -%} + {{ form_widget(form.persons) }} + {% endif %} + {%- if form.thirdParties is defined -%} + {{ form_widget(form.thirdParties) }} + {% endif %} + {%- if form.users is defined -%} + {{ form_widget(form.users) }} + {% endif %} +
+ {% endif %} {% endif %} -{%- if form.thirdParties is defined -%} - {{ form_widget(form.thirdParties) }} -{% endif %} -{%- if form.users is defined -%} - {{ form_widget(form.users) }} -{% endif %} - -

{{ 'Activity data'|trans }}

diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig index d8f02a37d..505d8c6cb 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig @@ -22,7 +22,7 @@ '{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}'); }); window.activity = {{ activity_json|json_encode|raw }}; - window.default_location_id = {{ default_location_id }}; + {% if default_location is not null %}window.default_location_id = {{ default_location.id }}{% endif %}; {{ encore_entry_script_tags('vue_activity') }} {% endblock %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig index a30034257..a1fc44196 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig @@ -27,7 +27,7 @@
{{ 'Social issues'|trans }}
{% if entity.socialIssues|length == 0 %} -

{{ 'Any social issues'|trans }}

+

{{ 'No social issues associated'|trans }}

{% else %} {% for si in entity.socialIssues %}{{ si|chill_entity_render_box }}{% endfor %} {% endif %} @@ -38,7 +38,7 @@
{{ 'Social actions'|trans }}
{% if entity.socialActions|length == 0 %} -

{{ 'Any social actions'|trans }}

+

{{ 'No social actions associated'|trans }}

{% else %} {% for sa in entity.socialActions %}{{ sa|chill_entity_render_box }}{% endfor %} {% endif %} @@ -67,8 +67,8 @@
{% if entity.location is not null %}

- {{ entity.location.locationType.title|localize_translatable_string }} {{ entity.location.name }} + ({{ entity.location.locationType.title|localize_translatable_string }})

{{ entity.location.address|chill_entity_render_box }} {% else %} diff --git a/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidity.php b/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidity.php new file mode 100644 index 000000000..6164c3c5d --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidity.php @@ -0,0 +1,42 @@ +getActivityType()->getPersonsVisible() === 2 && count($activity->getPersons()) === 0) { + $this->context + ->buildViolation($constraint->noPersonsMessage) + ->addViolation(); + } + + if ($activity->getActivityType()->getUsersVisible() === 2 && count($activity->getUsers()) === 0) { + $this->context + ->buildViolation($constraint->noUsersMessage) + ->addViolation(); + } + + if ($activity->getActivityType()->getThirdPartiesVisible() === 2 && count($activity->getThirdParties()) === 0) { + $this->context + ->buildViolation($constraint->noThirdPartiesMessage) + ->addViolation(); + } + + if ($activity->getActivityType()->getUserVisible() === 2 && null === $activity->getUser()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('user')) + ->addViolation(); + } + + if ($activity->getActivityType()->getDateVisible() === 2 && null === $activity->getDate()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('date')) + ->addViolation(); + } + + if ($activity->getActivityType()->getLocationVisible() === 2 && null === $activity->getLocation()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('location')) + ->addViolation(); + } + + if ($activity->getActivityType()->getDurationTimeVisible() === 2 && null === $activity->getDurationTime()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('duration time')) + ->addViolation(); + } + + if ($activity->getActivityType()->getTravelTimeVisible() === 2 && null === $activity->getTravelTime()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('travel time')) + ->addViolation(); + } + + if ($activity->getActivityType()->getAttendeeVisible() === 2 && null === $activity->getAttendee()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('attendee')) + ->addViolation(); + } + + if ($activity->getActivityType()->getReasonsVisible() === 2 && null === $activity->getReasons()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('reasons')) + ->addViolation(); + } + + if ($activity->getActivityType()->getCommentVisible() === 2 && null === $activity->getComment()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('comment')) + ->addViolation(); + } + + if ($activity->getActivityType()->getSentReceivedVisible() === 2 && null === $activity->getSentReceived()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('sent/received')) + ->addViolation(); + } + + if ($activity->getActivityType()->getDocumentsVisible() === 2 && null === $activity->getDocuments()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('document')) + ->addViolation(); + } + + if ($activity->getActivityType()->getEmergencyVisible() === 2 && null === $activity->getEmergency()) { + $this->context + ->buildViolation($constraint->makeIsRequiredMessage('emergency')) + ->addViolation(); + } + + if ($activity->getActivityType()->getSocialIssuesVisible() === 2 && $activity->getSocialIssues()->count() === 0) { + $this->context + ->buildViolation($constraint->socialIssuesMessage) + ->addViolation(); + } + + if ($activity->getActivityType()->getSocialActionsVisible() === 2 && $activity->getSocialActions()->count() === 0) { + $this->context + ->buildViolation($constraint->socialActionsMessage) + ->addViolation(); + } + } +} diff --git a/src/Bundle/ChillActivityBundle/config/services.yaml b/src/Bundle/ChillActivityBundle/config/services.yaml index 4e93e38be..1ca413f0e 100644 --- a/src/Bundle/ChillActivityBundle/config/services.yaml +++ b/src/Bundle/ChillActivityBundle/config/services.yaml @@ -27,3 +27,8 @@ services: Chill\ActivityBundle\Repository\: resource: '../Repository/' + + Chill\ActivityBundle\Validator\Constraints\: + autowire: true + autoconfigure: true + resource: '../Validator/Constraints/' diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index d0c3ddc6d..098a6f6df 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -43,6 +43,7 @@ Sent: Envoyer Received: Recevoir by: 'Par ' location: Lieu +Reasons: Sujets #forms @@ -139,34 +140,40 @@ ActivityReasonCategory is inactive and won't be proposed: La catégorie est inac # activity type type admin ActivityType list: Types d'activités Create a new activity type: Créer un nouveau type d'activité -Persons visible: Visibilté du champ Personnes +Persons visible: Visibilité du champ Personnes Persons label: Libellé du champ Personnes -User visible: Visibilté du champ Utilisateur +User visible: Visibilité du champ Utilisateur User label: Libellé du champ Utilisateur -Date visible: Visibilté du champ Date +Date visible: Visibilité du champ Date Date label: Libellé du champ Date -Place visible: Visibilté du champ Lieu +Place visible: Visibilité du champ Lieu Place label: Libellé du champ Lieu -Third parties visible: Visibilté du champ Tiers +Third parties visible: Visibilité du champ Tiers Third parties label: Libellé du champ Tiers -Duration time visible: Visibilté du champ Durée +Duration time visible: Visibilité du champ Durée Duration time label: Libellé du champ Durée -Travel time visible: Visibilté du champ Durée de déplacement +Travel time visible: Visibilité du champ Durée de déplacement Travel time label: Libellé du champ Durée de déplacement -Attendee visible: Visibilté du champ Présence de l'usager +Attendee visible: Visibilité du champ Présence de l'usager Attendee label: Libellé du champ Présence de l'usager -Reasons visible: Visibilté du champ Sujet +Reasons visible: Visibilité du champ Sujet Reasons label: Libellé du champ Sujet -Comment visible: Visibilté du champ Commentaire +Comment visible: Visibilité du champ Commentaire Comment label: Libellé du champ Commentaire -Emergency visible: Visibilté du champ Urgent +Emergency visible: Visibilité du champ Urgent Emergency label: Libellé du champ Urgent -Accompanying period visible: Visibilté du champ Période d'accompagnement +Accompanying period visible: Visibilité du champ Période d'accompagnement Accompanying period label: Libellé du champ Période d'accompagnement -Social data visible: Visibilté du champ Données sociales -Social data label: Libellé du champ Données sociales -Users visible: Visibilté du champ Utilisateurs +Social issues visible: Visibilité du champ Problématiques sociales +Social issues label: Libellé du champ Problématiques sociales +Social actions visible: Visibilité du champ Action sociale +Social actions label: Libellé du champ Action sociale +Users visible: Visibilité du champ Utilisateurs Users label: Libellé du champ Utilisateurs +Sent received visible: Visibilité du champ Entrant / Sortant +Sent received label: Libellé du champ Entrant / Sortant +Documents visible: Visibilité du champ Documents +Documents label: Libellé du champ Documents # activity type category admin ActivityTypeCategory list: Liste des catégories des types d'activité diff --git a/src/Bundle/ChillActivityBundle/translations/validators.fr.yml b/src/Bundle/ChillActivityBundle/translations/validators.fr.yml index edda0b67b..072ac55d2 100644 --- a/src/Bundle/ChillActivityBundle/translations/validators.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/validators.fr.yml @@ -1,2 +1,22 @@ The reasons's level should not be empty: Le niveau du sujet ne peut pas être vide At least one reason must be choosen: Au moins un sujet doit être choisi +For this type of activity, you must add at least one person: Pour ce type d'activité, vous devez ajouter au moins un usager +For this type of activity, you must add at least one user: Pour ce type d'activité, vous devez ajouter au moins un utilisateur +For this type of activity, you must add at least one third party: Pour ce type d'activité, vous devez ajouter au moins un tiers +For this type of activity, user is required: Pour ce type d'activité, l'utilisateur est requis +For this type of activity, date is required: Pour ce type d'activité, la date est requise +For this type of activity, location is required: Pour ce type d'activité, la localisation est requise +For this type of activity, attendee is required: Pour ce type d'activité, le champ "Présence de la personne" est requis +For this type of activity, duration time is required: Pour ce type d'activité, la durée est requise +For this type of activity, travel time is required: Pour ce type d'activité, la durée du trajet est requise +For this type of activity, reasons is required: Pour ce type d'activité, le champ "sujet" est requis +For this type of activity, comment is required: Pour ce type d'activité, un commentaire est requis +For this type of activity, sent/received is required: Pour ce type d'activité, le champ Entrant/Sortant est requis +For this type of activity, document is required: Pour ce type d'activité, un document est requis +For this type of activity, emergency is required: Pour ce type d'activité, le champ "Urgent" est requis +For this type of activity, accompanying period is required: Pour ce type d'activité, le parcours d'accompagnement est requis +For this type of activity, you must add at least one social issue: Pour ce type d'activité, vous devez ajouter au moins une problématique sociale +For this type of activity, you must add at least one social action: Pour ce type d'activité, vous devez indiquez au moins une action sociale + +# admin +This parameter must be equal to social issue parameter: Ce paramètre doit être égal au paramètre "Visibilité du champs Problématiques sociales" diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php index 0165142f7..6e6bce842 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php @@ -332,12 +332,12 @@ class CalendarController extends AbstractController $personsId = array_map( static fn (Person $p): int => $p->getId(), - $entity->getPersons() + $entity->getPersons()->toArray() ); $professionalsId = array_map( static fn (ThirdParty $thirdParty): ?int => $thirdParty->getId(), - $entity->getProfessionals() + $entity->getProfessionals()->toArray() ); $durationTime = $entity->getEndDate()->diff($entity->getStartDate()); diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js index 457d31799..edfb7f236 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js @@ -1,5 +1,6 @@ import 'es6-promise/auto'; import { createStore } from 'vuex'; +import { postLocation } from 'ChillActivityAssets/vuejs/Activity/api'; const debug = process.env.NODE_ENV !== 'production'; @@ -33,7 +34,6 @@ const store = createStore({ }, getters: { suggestedEntities(state) { - console.log(state.activity) if (typeof(state.activity.accompanyingPeriod) === 'undefined') { return []; } @@ -189,8 +189,35 @@ const store = createStore({ updateLocation({ commit }, value) { console.log('### action: updateLocation', value); let hiddenLocation = document.getElementById("chill_calendarbundle_calendar_location"); - hiddenLocation.value = value.id; - commit('updateLocation', value); + if (value.onthefly) { + const body = { + "type": "location", + "name": value.name === '__AccompanyingCourseLocation__' ? null : value.name, + "locationType": { + "id": value.locationType.id, + "type": "location-type" + } + }; + if (value.address.id) { + Object.assign(body, { + "address": { + "id": value.address.id + }, + }) + } + postLocation(body) + .then( + location => hiddenLocation.value = location.id + ).catch( + err => { + console.log(err.message); + } + ); + } else { + hiddenLocation.value = value.id; + } + commit("updateLocation", value); + } } diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig index 5dfde6fc3..7c59996d2 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig @@ -41,8 +41,8 @@
{% if entity.location is not null %}

- {{ entity.location.locationType.title|localize_translatable_string }} {{ entity.location.name }} + ({{ entity.location.locationType.title|localize_translatable_string }})

{{ entity.location.address|chill_entity_render_box }} {% else %} diff --git a/src/Bundle/ChillMainBundle/Controller/LocationApiController.php b/src/Bundle/ChillMainBundle/Controller/LocationApiController.php index 52b6f1e81..16fc414d9 100644 --- a/src/Bundle/ChillMainBundle/Controller/LocationApiController.php +++ b/src/Bundle/ChillMainBundle/Controller/LocationApiController.php @@ -10,8 +10,6 @@ namespace Chill\MainBundle\Controller; use Chill\MainBundle\CRUD\Controller\ApiController; -use DateInterval; -use DateTime; use Symfony\Component\HttpFoundation\Request; /** @@ -21,22 +19,11 @@ class LocationApiController extends ApiController { public function customizeQuery(string $action, Request $request, $query): void { - $query->andWhere($query->expr()->orX( - $query->expr()->andX( - $query->expr()->eq('e.createdBy', ':user'), - $query->expr()->gte('e.createdAt', ':dateBefore') - ), + $query->andWhere( $query->expr()->andX( $query->expr()->eq('e.availableForUsers', "'TRUE'"), $query->expr()->eq('e.active', "'TRUE'"), - $query->expr()->isNotNull('e.name'), - $query->expr()->neq('e.name', ':emptyString'), ) - )) - ->setParameters([ - 'user' => $this->getUser(), - 'dateBefore' => (new DateTime())->sub(new DateInterval('P6M')), - 'emptyString' => '', - ]); + ); } } diff --git a/src/Bundle/ChillMainBundle/Controller/PermissionApiController.php b/src/Bundle/ChillMainBundle/Controller/PermissionApiController.php new file mode 100644 index 000000000..3476c4bbe --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/PermissionApiController.php @@ -0,0 +1,80 @@ +denormalizer = $denormalizer; + $this->security = $security; + } + + /** + * @Route("/api/1.0/main/permissions/info.json", methods={"POST"}) + * + * @throws \Symfony\Component\Serializer\Exception\ExceptionInterface + */ + public function getPermissions(Request $request): JsonResponse + { + $this->denyAccessUnlessGranted('ROLE_USER'); + + $data = json_decode($request->getContent(), true); + + if (null === $data) { + throw new BadRequestHttpException(sprintf( + 'Could not decode json received, or data invalid: %s, %s', + json_last_error(), + json_last_error_msg() + )); + } + + if (!array_key_exists('object', $data)) { + throw new BadRequestHttpException('the object key is not present'); + } + + if (!array_key_exists('class', $data)) { + throw new BadRequestHttpException('the class key is not present'); + } + + if (null !== $data['object']) { + $object = $this->denormalizer->denormalize($data['object'], $data['class'], 'json'); + } else { + $object = null; + } + $roles = []; + + foreach (($data['roles'] ?? []) as $role) { + $roles[$role] = $this->security->isGranted($role, $object); + } + + return $this->json( + ['roles' => $roles], + 200, + [], + ); + } +} diff --git a/src/Bundle/ChillMainBundle/Entity/LocationType.php b/src/Bundle/ChillMainBundle/Entity/LocationType.php index 8b171eb0f..b0d91a4f1 100644 --- a/src/Bundle/ChillMainBundle/Entity/LocationType.php +++ b/src/Bundle/ChillMainBundle/Entity/LocationType.php @@ -11,6 +11,7 @@ namespace Chill\MainBundle\Entity; use Chill\MainBundle\Repository\LocationTypeRepository; use Doctrine\ORM\Mapping as ORM; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Serializer\Annotation as Serializer; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; @@ -20,9 +21,14 @@ use Symfony\Component\Serializer\Annotation\DiscriminatorMap; * @DiscriminatorMap(typeProperty="type", mapping={ * "location-type": LocationType::class * }) + * @UniqueEntity({"defaultFor"}) */ class LocationType { + public const DEFAULT_FOR_3PARTY = 'thirdparty'; + + public const DEFAULT_FOR_PERSON = 'person'; + public const STATUS_NEVER = 'never'; public const STATUS_OPTIONAL = 'optional'; @@ -53,6 +59,12 @@ class LocationType */ private string $contactData = self::STATUS_OPTIONAL; + /** + * @ORM\Column(type="string", nullable=true, length=32, unique=true) + * @Serializer\Groups({"read"}) + */ + private ?string $defaultFor = null; + /** * @ORM\Id * @ORM\GeneratedValue @@ -87,6 +99,11 @@ class LocationType return $this->contactData; } + public function getDefaultFor(): ?string + { + return $this->defaultFor; + } + public function getId(): ?int { return $this->id; @@ -125,6 +142,13 @@ class LocationType return $this; } + public function setDefaultFor(?string $defaultFor): self + { + $this->defaultFor = $defaultFor; + + return $this; + } + public function setTitle(array $title): self { $this->title = $title; diff --git a/src/Bundle/ChillMainBundle/Form/LocationTypeType.php b/src/Bundle/ChillMainBundle/Form/LocationTypeType.php index 1e4776f8f..41372b48e 100644 --- a/src/Bundle/ChillMainBundle/Form/LocationTypeType.php +++ b/src/Bundle/ChillMainBundle/Form/LocationTypeType.php @@ -71,6 +71,18 @@ final class LocationTypeType extends AbstractType ], 'expanded' => true, ] + ) + ->add( + 'defaultFor', + ChoiceType::class, + [ + 'choices' => [ + 'none' => null, + 'person' => LocationType::DEFAULT_FOR_PERSON, + 'thirdparty' => LocationType::DEFAULT_FOR_3PARTY, + ], + 'expanded' => true, + ] ); } } diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.js b/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.js new file mode 100644 index 000000000..96a95ad93 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.js @@ -0,0 +1,105 @@ +/** + * Generic api method that can be adapted to any fetch request + */ + const makeFetch = (method, url, body) => { + return fetch(url, { + method: method, + headers: { + 'Content-Type': 'application/json;charset=utf-8' + }, + body: (body !== null) ? JSON.stringify(body) : null + }) + .then(response => { + if (response.ok) { + return response.json(); + } + + if (response.status === 422) { + return response.json().then(response => { + throw ValidationException(response) + }); + } + + if (response.status === 403) { + return response.json().then(() => { + throw AccessException(); + }); + } + + throw { + name: 'Exception', + sta: response.status, + txt: response.statusText, + err: new Error(), + violations: response.body + }; + }); +} + +/** + * Fetch results with certain parameters + */ +const _fetchAction = (page, uri, params) => { + const item_per_page = 50; + if (params === undefined) { + params = {}; + } + let url = uri + '?' + new URLSearchParams({ item_per_page, page, ...params }); + + return fetch(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json;charset=utf-8' + }, + }).then(response => { + if (response.ok) { return response.json(); } + throw Error({ m: response.statusText }); + }); +}; + +const fetchResults = async (uri, params) => { + let promises = [], + page = 1; + let firstData = await _fetchAction(page, uri, params); + + promises.push(Promise.resolve(firstData.results)); + + if (firstData.pagination.more) { + do { + page = ++page; + promises.push(_fetchAction(page, uri, params).then(r => Promise.resolve(r.results))); + } while (page * firstData.pagination.items_per_page < firstData.count) + } + + return Promise.all(promises).then(values => values.flat()); +}; + +const fetchScopes = () => { + return fetchResults('/api/1.0/main/scope.json'); +}; + + +/** + * Error objects to be thrown + */ +const ValidationException = (response) => { + const error = {}; + error.name = 'ValidationException'; + error.violations = response.violations.map((violation) => `${violation.title}`); + + return error; +} + +const AccessException = () => { + const error = {}; + error.name = 'AccessException'; + error.violations = ['You are no longer permitted to perform this action']; + + return error; +} + +export { + makeFetch, + fetchResults, + fetchScopes +} diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/download.js b/src/Bundle/ChillMainBundle/Resources/public/lib/api/download.js index 625103ebe..dec8ba727 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/lib/api/download.js +++ b/src/Bundle/ChillMainBundle/Resources/public/lib/api/download.js @@ -1,39 +1,39 @@ -const _fetchAction = (page, uri, params) => { - const item_per_page = 50; - if (params === undefined) { - params = {}; - } - let url = uri + '?' + new URLSearchParams({ item_per_page, page, ...params }); +// const _fetchAction = (page, uri, params) => { +// const item_per_page = 50; +// if (params === undefined) { +// params = {}; +// } +// let url = uri + '?' + new URLSearchParams({ item_per_page, page, ...params }); - return fetch(url, { - method: 'GET', - headers: { - 'Content-Type': 'application/json;charset=utf-8' - }, - }).then(response => { - if (response.ok) { return response.json(); } - throw Error({ m: response.statusText }); - }); -}; +// return fetch(url, { +// method: 'GET', +// headers: { +// 'Content-Type': 'application/json;charset=utf-8' +// }, +// }).then(response => { +// if (response.ok) { return response.json(); } +// throw Error({ m: response.statusText }); +// }); +// }; -const fetchResults = async (uri, params) => { - let promises = [], - page = 1; - let firstData = await _fetchAction(page, uri, params); +// const fetchResults = async (uri, params) => { +// let promises = [], +// page = 1; +// let firstData = await _fetchAction(page, uri, params); - promises.push(Promise.resolve(firstData.results)); +// promises.push(Promise.resolve(firstData.results)); - if (firstData.pagination.more) { - do { - page = ++page; - promises.push(_fetchAction(page, uri, params).then(r => Promise.resolve(r.results))); - } while (page * firstData.pagination.items_per_page < firstData.count) - } +// if (firstData.pagination.more) { +// do { +// page = ++page; +// promises.push(_fetchAction(page, uri, params).then(r => Promise.resolve(r.results))); +// } while (page * firstData.pagination.items_per_page < firstData.count) +// } - return Promise.all(promises).then(values => values.flat()); -}; +// return Promise.all(promises).then(values => values.flat()); +// }; -export { - fetchResults -}; +// export { +// fetchResults +// }; diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/scope.js b/src/Bundle/ChillMainBundle/Resources/public/lib/api/scope.js index 4c4223d77..a155c84a2 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/lib/api/scope.js +++ b/src/Bundle/ChillMainBundle/Resources/public/lib/api/scope.js @@ -1,9 +1,9 @@ -import { fetchResults } from 'ChillMainAssets/lib/api/download.js'; +// import { fetchResults } from 'ChillMainAssets/lib/api/download.js'; -const fetchScopes = () => { - return fetchResults('/api/1.0/main/scope.json'); -}; +// const fetchScopes = () => { +// return fetchResults('/api/1.0/main/scope.json'); +// }; -export { - fetchScopes -}; +// export { +// fetchScopes +// }; diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue index 7bf088fb6..87ecff7fb 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue @@ -588,6 +588,12 @@ export default { newAddress = Object.assign(newAddress, { 'point': this.entity.selected.address.point.coordinates }); + } else { + if (this.entity.selected.postcode.coordinates) { + newAddress = Object.assign(newAddress, { + 'point': this.entity.selected.postcode.coordinates + }); + } } // add the address reference, if any diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue index ca2f5d634..2409dca53 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue @@ -4,6 +4,10 @@ @@ -141,7 +143,6 @@ export default { } }, addAddress() { - console.log('addAddress: pass here ?? never, it seems'); this.entity.selected.writeNew.address = true; } } diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue index 3e3dd98d4..6e6c064b5 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue @@ -12,6 +12,8 @@ label="value" :custom-label="transName" :placeholder="$t('select_city')" + :select-label="$t('press_enter_to_select')" + :deselect-label="$t('create_postal_code')" :taggable="true" :multiple="false" @tag="addPostcode" @@ -101,6 +103,7 @@ export default { this.entity.selected.city = value; this.entity.selected.postcode.name = value.name; this.entity.selected.postcode.code = value.code; + this.entity.selected.postcode.coordinates = value.center.coordinates; this.entity.selected.writeNew.postcode = false; console.log('writeNew.postcode false, in selectCity'); this.$emit('getReferenceAddresses', value); diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue index 2e6ec86a7..c15db8d2a 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue @@ -9,6 +9,8 @@ v-bind:placeholder="$t('select_country')" v-bind:options="sortedCountries" v-model="value" + :select-label="$t('press_enter_to_select')" + :deselect-label="$t('press_enter_to_remove')" @select="selectCountry"> diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/i18n.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/i18n.js index 9d7185696..ab0032de6 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/i18n.js +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/i18n.js @@ -1,5 +1,7 @@ const addressMessages = { fr: { + press_enter_to_select: 'Appuyer sur Entrée pour sélectionner', + press_enter_to_remove: 'Appuyer sur Entrée pour désélectionner', add_an_address_title: 'Créer une adresse', edit_an_address_title: 'Modifier une adresse', create_a_new_address: 'Créer une nouvelle adresse', diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Confidential.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Confidential.vue index 5fe040e14..efdf62926 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Confidential.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Confidential.vue @@ -13,7 +13,6 @@ export default { methods : { toggleBlur: function(e){ if(e.target.matches('.toggle')){ - console.log(e); e.target.previousElementSibling.classList.toggle("blur"); e.target.classList.toggle("fa-eye"); e.target.classList.toggle("fa-eye-slash"); diff --git a/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig index ec617c6c0..5402d5e89 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig @@ -11,6 +11,7 @@ {{ 'Address required'|trans }} {{ 'Contact data'|trans }} {{ 'Active'|trans }} + {{ 'Default for'|trans }} @@ -33,6 +34,7 @@ {%- endif -%} + {{ entity.defaultFor|trans }}