diff --git a/.editorconfig b/.editorconfig index fe115d4c0..d51908caf 100644 --- a/.editorconfig +++ b/.editorconfig @@ -18,3 +18,10 @@ max_line_length = 80 [COMMIT_EDITMSG] max_line_length = 0 +<<<<<<< Updated upstream +======= + +[*.{js, vue, ts}] +indent_size = 2 +indent_style = space +>>>>>>> Stashed changes diff --git a/CHANGELOG.md b/CHANGELOG.md index b9fa2851a..fa4fcd96d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,13 @@ and this project adheres to * [person] add closing motive to closed acc course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/603) +* [person] household filiation: fetch person info when unfolding person (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/586) +* [admin] repair edit of social action in the admin (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/601) +* [admin]: add select2 to Goal form type entity fields (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/702) +* [main] allow hide permissions group list menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577) +* [main] allow hide change user password menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577) +* [main] filter user jobs by active jobs (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577) +* [main] add civility to User (entity, migration and form type) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577) * [admin] refactorisation of the admin section: reorganisation of the menu, translations, form types, new entities (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/592) * [admin] add admin section for languages and countries (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/596) * [activity] activity admin: translations + remove label field for comment on admin activity type (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/587) @@ -33,6 +40,7 @@ and this project adheres to * [person] add maritalStatusComment to PersonDocGenNormalizer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/582) * Load relationships without gender in french fixtures * Add command to remove old draft accompanying periods +* [parcours]: If users assings him/herself as referrer and job is not null. Update parcours job (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/578) ### 2021-04-28 diff --git a/phpstan-deprecations.neon b/phpstan-deprecations.neon index 2de8b8bc8..42981a551 100644 --- a/phpstan-deprecations.neon +++ b/phpstan-deprecations.neon @@ -471,11 +471,6 @@ parameters: count: 1 path: src/Bundle/ChillMainBundle/Form/Type/UserPickerType.php - - - message: "#^Only booleans are allowed in an if condition, mixed given\\.$#" - count: 1 - path: src/Bundle/ChillMainBundle/Form/UserType.php - - message: "#^Only booleans are allowed in an if condition, mixed given\\.$#" count: 2 diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 0c0632722..db0d5c7d1 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -15,6 +15,7 @@ use Chill\ActivityBundle\Validator\Constraints as ActivityValidator; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; +use Chill\MainBundle\Entity\Embeddable\PrivateCommentEmbeddable; use Chill\MainBundle\Entity\HasCenterInterface; use Chill\MainBundle\Entity\HasScopeInterface; use Chill\MainBundle\Entity\Location; @@ -134,6 +135,12 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac */ private ?Collection $persons = null; + /** + * @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\PrivateCommentEmbeddable", columnPrefix="privateComment_") + * @Groups({"docgen:read"}) + */ + private PrivateCommentEmbeddable $privateComment; + /** * @ORM\ManyToMany(targetEntity="Chill\ActivityBundle\Entity\ActivityReason") * @Groups({"docgen:read"}) @@ -193,6 +200,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac { $this->reasons = new ArrayCollection(); $this->comment = new CommentEmbeddable(); + $this->privateComment = new PrivateCommentEmbeddable(); $this->persons = new ArrayCollection(); $this->thirdParties = new ArrayCollection(); $this->documents = new ArrayCollection(); @@ -400,6 +408,11 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return []; } + public function getPrivateComment(): PrivateCommentEmbeddable + { + return $this->privateComment; + } + public function getReasons(): Collection { return $this->reasons; @@ -586,6 +599,13 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this; } + public function setPrivateComment(PrivateCommentEmbeddable $privateComment): self + { + $this->privateComment = $privateComment; + + return $this; + } + public function setReasons(?ArrayCollection $reasons): self { $this->reasons = $reasons; diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php index bdf75ed05..845b31ca2 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php @@ -167,6 +167,16 @@ class ActivityType */ private int $personVisible = self::FIELD_REQUIRED; + /** + * @ORM\Column(type="string", nullable=false, options={"default": ""}) + */ + private string $privateCommentLabel = ''; + + /** + * @ORM\Column(type="smallint", nullable=false, options={"default": 1}) + */ + private int $privateCommentVisible = self::FIELD_OPTIONAL; + /** * @ORM\Column(type="string", nullable=false, options={"default": ""}) */ @@ -416,6 +426,16 @@ class ActivityType return $this->personVisible; } + public function getPrivateCommentLabel(): string + { + return $this->privateCommentLabel; + } + + public function getPrivateCommentVisible(): int + { + return $this->privateCommentVisible; + } + public function getReasonsLabel(): string { return $this->reasonsLabel; @@ -688,6 +708,20 @@ class ActivityType return $this; } + public function setPrivateCommentLabel(string $privateCommentLabel): self + { + $this->privateCommentLabel = $privateCommentLabel; + + return $this; + } + + public function setPrivateCommentVisible(int $privateCommentVisible): self + { + $this->privateCommentVisible = $privateCommentVisible; + + return $this; + } + public function setReasonsLabel(string $reasonsLabel): self { $this->reasonsLabel = $reasonsLabel; diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityType.php b/src/Bundle/ChillActivityBundle/Form/ActivityType.php index 6e75bde25..4c767cd54 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityType.php @@ -20,6 +20,7 @@ use Chill\MainBundle\Entity\User; use Chill\MainBundle\Form\Type\ChillCollectionType; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Form\Type\CommentType; +use Chill\MainBundle\Form\Type\PrivateCommentType; use Chill\MainBundle\Form\Type\ScopePickerType; use Chill\MainBundle\Form\Type\UserPickerType; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; @@ -251,6 +252,13 @@ class ActivityType extends AbstractType ]); } + if ($activityType->isVisible('privateComment')) { + $builder->add('privateComment', PrivateCommentType::class, [ + 'label' => '' === $activityType->getLabel('privateComment') ? 'private comment' : $activityType->getPrivateCommentLabel(), + 'required' => false, + ]); + } + if ($activityType->isVisible('persons')) { $builder->add('persons', HiddenType::class); $builder->get('persons') diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php b/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php index 17d2bb914..4cdcb31f2 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php @@ -57,7 +57,7 @@ class ActivityTypeType extends AbstractType $fields = [ 'persons', 'user', 'date', 'location', 'persons', 'thirdParties', 'durationTime', 'travelTime', 'attendee', - 'reasons', 'sentReceived', 'documents', + 'reasons', 'comment', 'privateComment', 'sentReceived', 'documents', 'emergency', 'socialIssues', 'socialActions', 'users', ]; diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/edit.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/edit.html.twig index 218dc37b0..8d9ee878c 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/edit.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/edit.html.twig @@ -83,6 +83,10 @@ {{ form_row(edit_form.comment) }} {% endif %} +{%- if edit_form.privateComment is defined -%} + {{ form_row(edit_form.privateComment) }} +{% endif %} + {%- if edit_form.attendee is defined -%} {{ form_row(edit_form.attendee) }} {% endif %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/new.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/new.html.twig index 8e078702c..6f6e1fe53 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/new.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/new.html.twig @@ -81,10 +81,13 @@ {% endif %} {%- if form.comment is defined -%} - {# TODO .. public and private #} {{ form_row(form.comment) }} {% endif %} +{%- if form.privateComment is defined -%} + {{ form_row(form.privateComment) }} +{% endif %} + {%- if form.attendee is defined -%} {{ form_row(form.attendee) }} {% endif %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig index ce4c22304..8b47f4de2 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig @@ -1,4 +1,5 @@ {%- set t = entity.type -%} +{% set userId = app.user.id %} {%- import "@ChillDocStore/Macro/macro.html.twig" as m -%}

{{ "Activity"|trans }}

@@ -146,6 +147,21 @@ {% endif %} + {% if t.privateCommentVisible and is_granted('CHILL_ACTIVITY_SEE_DETAILS', entity) and entity.privateComment.hasCommentForUser(app.user) %} + {% if t.privateCommentLabel is not empty %} +
{{ t.privateCommentLabel }}
+ {% else %} +
{{ 'Private comment'|trans }}
+ {% endif %} +
+
+
+ {{ entity.privateComment.comments[userId] }} +
+
+
+ {% endif %} + {% if t.documentsVisible and is_granted('CHILL_ACTIVITY_SEE_DETAILS', entity) %}
{{ 'Documents'|trans }}
diff --git a/src/Bundle/ChillActivityBundle/migrations/Version20220425133027.php b/src/Bundle/ChillActivityBundle/migrations/Version20220425133027.php new file mode 100644 index 000000000..4a829f18c --- /dev/null +++ b/src/Bundle/ChillActivityBundle/migrations/Version20220425133027.php @@ -0,0 +1,35 @@ +addSql('ALTER TABLE activitytype DROP privateCommentLabel'); + $this->addSql('ALTER TABLE activitytype DROP privateCommentVisible'); + } + + public function getDescription(): string + { + return 'add private comment option to activity types'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE activitytype ADD privateCommentLabel VARCHAR(255) DEFAULT \'\' NOT NULL'); + $this->addSql('ALTER TABLE activitytype ADD privateCommentVisible SMALLINT DEFAULT 1 NOT NULL'); + } +} diff --git a/src/Bundle/ChillActivityBundle/migrations/Version20220527124438.php b/src/Bundle/ChillActivityBundle/migrations/Version20220527124438.php new file mode 100644 index 000000000..2661edf4b --- /dev/null +++ b/src/Bundle/ChillActivityBundle/migrations/Version20220527124438.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE chill_person_accompanying_period_work DROP privateComment_comments'); + } + + public function getDescription(): string + { + return 'add private comment to activity'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE activity ADD privateComment_comments JSON DEFAULT \'{}\''); + } +} diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index 3ca4def7c..abfa0ea89 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -44,6 +44,7 @@ Received: Recevoir by: 'Par ' location: Lieu Reasons: Sujets +Private comment: Commentaire privé #forms @@ -175,6 +176,8 @@ Reasons visible: Visibilité du champ Sujet Reasons label: Libellé du champ Sujet Comment visible: Visibilité du champ Commentaire Comment label: Libellé du champ Commentaire +Private comment visible: Visibilité du champ Commentaire Privé +Private comment label: Libellé du champ Commentaire Privé Emergency visible: Visibilité du champ Urgent Emergency label: Libellé du champ Urgent Accompanying period visible: Visibilité du champ Période d'accompagnement diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php index 11104cc6a..c40bddb44 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php +++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php @@ -14,6 +14,7 @@ namespace Chill\CalendarBundle\Entity; use Chill\ActivityBundle\Entity\Activity; use Chill\CalendarBundle\Repository\CalendarRepository; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; +use Chill\MainBundle\Entity\Embeddable\PrivateCommentEmbeddable; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\AccompanyingPeriod; @@ -115,6 +116,12 @@ class Calendar */ private Collection $persons; + /** + * @ORM\Embedded(class=PrivateCommentEmbeddable::class, columnPrefix="privateComment_") + * @Serializer\Groups({"calendar:read"}) + */ + private PrivateCommentEmbeddable $privateComment; + /** * @ORM\ManyToMany( * targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty", @@ -151,6 +158,7 @@ class Calendar public function __construct() { $this->comment = new CommentEmbeddable(); + $this->privateComment = new PrivateCommentEmbeddable(); $this->persons = new ArrayCollection(); $this->professionals = new ArrayCollection(); $this->invites = new ArrayCollection(); @@ -278,6 +286,11 @@ class Calendar return []; } + public function getPrivateComment(): PrivateCommentEmbeddable + { + return $this->privateComment; + } + /** * @return Collection|ThirdParty[] */ @@ -407,6 +420,13 @@ class Calendar return $this; } + public function setPrivateComment(PrivateCommentEmbeddable $privateComment): self + { + $this->privateComment = $privateComment; + + return $this; + } + public function setSendSMS(?bool $sendSMS): self { $this->sendSMS = $sendSMS; diff --git a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php index 05dc362b4..b1dccb5fd 100644 --- a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php +++ b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php @@ -18,6 +18,7 @@ use Chill\CalendarBundle\Entity\Invite; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Form\Type\CommentType; +use Chill\MainBundle\Form\Type\PrivateCommentType; use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\PersonBundle\Entity\Person; use Chill\ThirdPartyBundle\Entity\ThirdParty; @@ -51,6 +52,10 @@ class CalendarType extends AbstractType ->add('comment', CommentType::class, [ 'required' => false, ]) + ->add('privateComment', PrivateCommentType::class, [ + 'required' => false, + 'label' => 'private comment', + ]) // ->add('cancelReason', EntityType::class, [ // 'required' => false, // 'class' => CancelReason::class, diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/edit.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/edit.html.twig index d67202920..b96d12c06 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/edit.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/edit.html.twig @@ -47,6 +47,10 @@ {{ form_row(form.comment) }} {% endif %} +{%- if form.privateComment is defined -%} + {{ form_row(form.privateComment) }} +{% endif %} + {%- if form.sendSMS is defined -%} {{ form_row(form.sendSMS) }} {% endif %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/new.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/new.html.twig index 255c2641b..41adb52cc 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/new.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/new.html.twig @@ -43,6 +43,10 @@ {{ form_row(form.comment) }} {% endif %} +{%- if form.privateComment is defined -%} + {{ form_row(form.privateComment) }} +{% endif %} + {%- if form.sendSMS is defined -%} {{ form_row(form.sendSMS) }} {% endif %} @@ -50,22 +54,22 @@
{{ form_end(form) }} diff --git a/src/Bundle/ChillCalendarBundle/migrations/Version20220527124558.php b/src/Bundle/ChillCalendarBundle/migrations/Version20220527124558.php new file mode 100644 index 000000000..39c4cb7c3 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/migrations/Version20220527124558.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE chill_calendar.calendar DROP privateComment_comments'); + } + + public function getDescription(): string + { + return 'add private comment to calendar'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_calendar.calendar ADD privateComment_comments JSON DEFAULT NULL'); + } +} diff --git a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml index aafa26622..da244fd13 100644 --- a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml @@ -26,6 +26,7 @@ The calendar item has been successfully removed.: Le rendez-vous a été supprim From the day: Du to the day: au Transform to activity: Transformer en échange + canceledBy: supprimé par Canceled by: supprimé par Calendar configuration: Gestion des rendez-vous @@ -36,4 +37,4 @@ crud: title: Liste des motifs d'annulation add_new: Ajouter un nouveau title_new: Nouveau motif d'annulation - title_edit: Modifier le motif d'annulation \ No newline at end of file + title_edit: Modifier le motif d'annulation diff --git a/src/Bundle/ChillMainBundle/Controller/UserController.php b/src/Bundle/ChillMainBundle/Controller/UserController.php index 068bd9f73..b6ded6653 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserController.php @@ -23,6 +23,7 @@ use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Psr\Log\LoggerInterface; use RuntimeException; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Form; use Symfony\Component\Form\FormInterface; @@ -37,6 +38,8 @@ class UserController extends CRUDController { public const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter'; + protected ParameterBagInterface $parameterBag; + private LoggerInterface $logger; private UserPasswordEncoderInterface $passwordEncoder; @@ -49,12 +52,14 @@ class UserController extends CRUDController LoggerInterface $chillLogger, ValidatorInterface $validator, UserPasswordEncoderInterface $passwordEncoder, - UserRepository $userRepository + UserRepository $userRepository, + ParameterBagInterface $parameterBag ) { $this->logger = $chillLogger; $this->userRepository = $userRepository; $this->validator = $validator; $this->passwordEncoder = $passwordEncoder; + $this->parameterBag = $parameterBag; } /** @@ -104,6 +109,7 @@ class UserController extends CRUDController return $this->render('@ChillMain/User/edit.html.twig', [ 'entity' => $user, + 'access_permissions_group_list' => $this->parameterBag->get('chill_main.access_permissions_group_list'), 'edit_form' => $this->createEditForm($user)->createView(), 'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($user, $request)->createView(), 'delete_groupcenter_form' => array_map( @@ -153,6 +159,73 @@ class UserController extends CRUDController return $this->redirect($this->generateUrl('chill_crud_admin_user_edit', ['id' => $uid])); } + public function edit(Request $request, $id): Response + { + $action = 'edit'; + $entity = $this->getEntity($action, $id, $request); + + if (null === $entity) { + throw $this->createNotFoundException( + sprintf( + 'The %s with id %s is not found', + $this->getCrudName(), + $id + ) + ); + } + + $response = $this->checkACL($action, $entity); + + if ($response instanceof Response) { + return $response; + } + + $response = $this->onPostCheckACL($action, $request, $entity); + + if ($response instanceof Response) { + return $response; + } + + $form = $this->createFormFor($action, $entity); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->onFormValid($action, $entity, $form, $request); + $em = $this->getDoctrine()->getManager(); + + $this->onPreFlush($action, $entity, $form, $request); + $em->flush(); + $this->onPostFlush($action, $entity, $form, $request); + + $this->addFlash('success', $this->generateFormSuccessMessage($action, $entity)); + + $result = $this->onBeforeRedirectAfterSubmission($action, $entity, $form, $request); + + if ($result instanceof Response) { + return $result; + } + + return $this->redirectToRoute('chill_crud_' . $this->getCrudName() . '_index'); + } + + if ($form->isSubmitted()) { + $this->addFlash('error', $this->generateFormErrorMessage($action, $form)); + } + + $defaultTemplateParameters = [ + 'form' => $form->createView(), + 'entity' => $entity, + 'crud_name' => $this->getCrudName(), + 'access_permissions_group_list' => $this->parameterBag->get('chill_main.access_permissions_group_list'), + ]; + + return $this->render( + $this->getTemplateFor($action, $entity, $request), + $this->generateTemplateParameter($action, $entity, $request, $defaultTemplateParameters) + ); + } + /** * Displays a form to edit the user current location. * @@ -271,6 +344,11 @@ class UserController extends CRUDController ), ] ); + } elseif ('index' === $action) { + return array_merge( + ['allow_change_password' => $this->parameterBag->get('chill_main.access_user_change_password')], + $defaultTemplateParameters + ); } // default behaviour @@ -307,7 +385,7 @@ class UserController extends CRUDController protected function onPrePersist(string $action, $entity, FormInterface $form, Request $request) { // for "new", encode the password - if ('new' === $action) { + if ('new' === $action && $this->parameterBag->get('chill_main.access_user_change_password')) { $entity->setPassword($this->passwordEncoder ->encodePassword($entity, $form['plainPassword']->getData())); } diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index 0611b9848..929bffe14 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -129,6 +129,16 @@ class ChillMainExtension extends Extension implements $config['access_global_history'] ); + $container->setParameter( + 'chill_main.access_user_change_password', + $config['access_user_change_password'] + ); + + $container->setParameter( + 'chill_main.access_permissions_group_list', + $config['access_permissions_group_list'] + ); + $container->setParameter( 'chill_main.routing.resources', $config['routing']['resources'] diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php index 7ced6aac6..a9b3ffec0 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php @@ -116,6 +116,12 @@ class Configuration implements ConfigurationInterface ->booleanNode('access_global_history') ->defaultTrue() ->end() + ->booleanNode('access_user_change_password') + ->defaultTrue() + ->end() + ->booleanNode('access_permissions_group_list') + ->defaultTrue() + ->end() ->arrayNode('redis') ->children() ->scalarNode('host') diff --git a/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php new file mode 100644 index 000000000..09a35324e --- /dev/null +++ b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php @@ -0,0 +1,70 @@ + + */ + private array $comments = []; + + public function getCommentForUser(User $user): string + { + return $this->comments[$user->getId()] ?? ''; + } + + public function getComments(): ?array + { + return $this->comments; + } + + public function hasCommentForUser(User $user): bool + { + return array_key_exists($user->getId(), $this->comments) + && '' !== $this->comments[$user->getId()]; + } + + public function merge(PrivateCommentEmbeddable $newComment): self + { + $currentComments = null === $this->getComments() ? [] : $this->getComments(); + + $mergedComments = $newComment->getComments() + $currentComments; + + $this->setComments($mergedComments); + + return $this; + } + + public function setCommentForUser(User $user, string $content): self + { + $this->comments[$user->getId()] = trim($content); + + return $this; + } + + public function setComments($comments) + { + $this->comments = $comments; + + return $this; + } +} diff --git a/src/Bundle/ChillMainBundle/Entity/User.php b/src/Bundle/ChillMainBundle/Entity/User.php index ad4888d58..80848e2cf 100644 --- a/src/Bundle/ChillMainBundle/Entity/User.php +++ b/src/Bundle/ChillMainBundle/Entity/User.php @@ -47,6 +47,11 @@ class User implements AdvancedUserInterface */ private array $attributes = []; + /** + * @ORM\ManyToOne(targetEntity=Civility::class) + */ + private ?Civility $civility = null; + /** * @ORM\ManyToOne(targetEntity=Location::class) */ @@ -184,6 +189,11 @@ class User implements AdvancedUserInterface return $this->attributes; } + public function getCivility(): ?Civility + { + return $this->civility; + } + public function getCurrentLocation(): ?Location { return $this->currentLocation; @@ -363,6 +373,13 @@ class User implements AdvancedUserInterface return $this; } + public function setCivility(?Civility $civility): User + { + $this->civility = $civility; + + return $this; + } + public function setCurrentLocation(?Location $currentLocation): User { $this->currentLocation = $currentLocation; diff --git a/src/Bundle/ChillMainBundle/Form/DataMapper/PrivateCommentDataMapper.php b/src/Bundle/ChillMainBundle/Form/DataMapper/PrivateCommentDataMapper.php new file mode 100644 index 000000000..2c03c59f1 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/DataMapper/PrivateCommentDataMapper.php @@ -0,0 +1,50 @@ +security = $security; + } + + public function mapDataToForms($viewData, $forms) + { + if (null === $viewData) { + return null; + } + + if (!$viewData instanceof PrivateCommentEmbeddable) { + throw new UnexpectedTypeException($viewData, PrivateCommentEmbeddable::class); + } + + $forms = iterator_to_array($forms); + + $forms['comments']->setData($viewData->getCommentForUser($this->security->getUser())); + } + + public function mapFormsToData($forms, &$viewData) + { + $forms = iterator_to_array($forms); + + $viewData->setCommentForUser($this->security->getUser(), $forms['comments']->getData()); + } +} diff --git a/src/Bundle/ChillMainBundle/Form/Type/PrivateCommentType.php b/src/Bundle/ChillMainBundle/Form/Type/PrivateCommentType.php new file mode 100644 index 000000000..d4c0d1611 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/Type/PrivateCommentType.php @@ -0,0 +1,62 @@ +user = $tokenStorage->getToken()->getUser(); + $this->dataMapper = $dataMapper; + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('comments', ChillTextareaType::class, [ + 'disable_editor' => $options['disable_editor'], + 'label' => false, + ]) + ->setDataMapper($this->dataMapper); + } + + public function buildView(FormView $view, FormInterface $form, array $options) + { + $view->vars['hideLabel'] = true; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver + ->setDefined('disable_editor') + ->setAllowedTypes('disable_editor', 'bool') + ->setDefaults([ + 'data_class' => PrivateCommentEmbeddable::class, + 'disable_editor' => false, + ]); + } +} diff --git a/src/Bundle/ChillMainBundle/Form/UserType.php b/src/Bundle/ChillMainBundle/Form/UserType.php index 6662d0bab..34c49bc38 100644 --- a/src/Bundle/ChillMainBundle/Form/UserType.php +++ b/src/Bundle/ChillMainBundle/Form/UserType.php @@ -15,9 +15,11 @@ use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\UserJob; +use Chill\MainBundle\Form\Type\PickCivilityType; use Chill\MainBundle\Templating\TranslatableStringHelper; use Doctrine\ORM\EntityRepository; use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\EmailType; @@ -32,11 +34,16 @@ use Symfony\Component\Validator\Constraints\Regex; class UserType extends AbstractType { + protected ParameterBagInterface $parameterBag; + private TranslatableStringHelper $translatableStringHelper; - public function __construct(TranslatableStringHelper $translatableStringHelper) - { + public function __construct( + TranslatableStringHelper $translatableStringHelper, + ParameterBagInterface $parameterBag + ) { $this->translatableStringHelper = $translatableStringHelper; + $this->parameterBag = $parameterBag; } public function buildForm(FormBuilderInterface $builder, array $options) @@ -47,6 +54,11 @@ class UserType extends AbstractType 'required' => true, ]) ->add('label', TextType::class) + ->add('civility', PickCivilityType::class, [ + 'required' => false, + 'label' => 'Civility', + 'placeholder' => 'choose civility', + ]) ->add('mainCenter', EntityType::class, [ 'label' => 'Main center', 'required' => false, @@ -76,6 +88,12 @@ class UserType extends AbstractType 'choice_label' => function (UserJob $c) { return $this->translatableStringHelper->localize($c->getLabel()); }, + 'query_builder' => static function (EntityRepository $er) { + $qb = $er->createQueryBuilder('uj'); + $qb->where('uj.active = TRUE'); + + return $qb; + }, ]) ->add('mainLocation', EntityType::class, [ 'label' => 'Main location', @@ -94,7 +112,8 @@ class UserType extends AbstractType }, ]); - if ($options['is_creation']) { + // @phpstan-ignore-next-line + if ($options['is_creation'] && $this->parameterBag->get('chill_main.access_user_change_password')) { $builder->add('plainPassword', RepeatedType::class, [ 'mapped' => false, 'type' => PasswordType::class, diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss index 99376088e..f8bd42442 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss @@ -298,6 +298,10 @@ table.table-bordered { } } +.private-quote { + border-left: 10px solid $pink; +} + /// meta-data div.createdBy, div.updatedBy, diff --git a/src/Bundle/ChillMainBundle/Resources/views/Form/fields.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Form/fields.html.twig index 1da384920..f45f91692 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Form/fields.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Form/fields.html.twig @@ -198,6 +198,23 @@ {% endfor %} {% endblock %} + +{% block private_comment_row %} + {{ form_label(form) }} + {{ form_row(form) }} +{% endblock %} + +{% block private_comment_widget %} + {% for entry in form %} + {{ form_widget(entry) }} + {% endfor %} +{% endblock %} + +{% block comment_row %} + {{ form_label(form) }} + {{ form_row(form) }} +{% endblock %} + {% block comment_widget %} {% for entry in form %} {{ form_widget(entry) }} diff --git a/src/Bundle/ChillMainBundle/Resources/views/User/edit.html.twig b/src/Bundle/ChillMainBundle/Resources/views/User/edit.html.twig index 0fa376b34..0ecbdef9f 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/User/edit.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/User/edit.html.twig @@ -3,54 +3,56 @@ {% block admin_content -%} {% embed '@ChillMain/CRUD/_edit_content.html.twig' %} {% block crud_content_after_form %} -

{{ 'Permissions granted'|trans }}

+ {% if access_permissions_group_list %} +

{{ 'Permissions granted'|trans }}

- {% if entity.groupcenters|length > 0 %} - - - - - - - - - - {% for groupcenter in entity.groupcenters %} + {% if entity.groupcenters|length > 0 %} +
{{ 'Permission group'|trans }}{{ 'Center'|trans }} 
+ - - - + + + - {% endfor %} - -
- - {{ groupcenter.permissionsgroup.name }} - - - - {{ groupcenter.center.name }} - - - {{ form_start(delete_groupcenter_form[groupcenter.id]) }} - {{ form_row(delete_groupcenter_form[groupcenter.id].submit, { 'attr': { 'class': 'btn btn-chill-red' } } ) }} - {{ form_rest(delete_groupcenter_form[groupcenter.id]) }} - {{ form_end(delete_groupcenter_form[groupcenter.id]) }} - {{ 'Permission group'|trans }}{{ 'Center'|trans }} 
- {% else %} -

{{ 'Any permissions granted to this user'|trans }}.

+ + + {% for groupcenter in entity.groupcenters %} + + + + {{ groupcenter.permissionsgroup.name }} + + + + + {{ groupcenter.center.name }} + + + + {{ form_start(delete_groupcenter_form[groupcenter.id]) }} + {{ form_row(delete_groupcenter_form[groupcenter.id].submit, { 'attr': { 'class': 'btn btn-chill-red' } } ) }} + {{ form_rest(delete_groupcenter_form[groupcenter.id]) }} + {{ form_end(delete_groupcenter_form[groupcenter.id]) }} + + + {% endfor %} + + + {% else %} +

{{ 'Any permissions granted to this user'|trans }}.

+ {% endif %} + +

{{ 'Grant new permissions'|trans }}

+ + {{ form_start(add_groupcenter_form) }} + {{ form_row(add_groupcenter_form.composed_groupcenter.center) }} + {{ form_row(add_groupcenter_form.composed_groupcenter.permissionsgroup) }} + {{ form_row(add_groupcenter_form.submit, { 'attr' : { 'class': 'btn btn-chill-green' } } ) }} + + {{ form_end(add_groupcenter_form) }} {% endif %} - -

{{ 'Grant new permissions'|trans }}

- - {{ form_start(add_groupcenter_form) }} - {{ form_row(add_groupcenter_form.composed_groupcenter.center) }} - {{ form_row(add_groupcenter_form.composed_groupcenter.permissionsgroup) }} - {{ form_row(add_groupcenter_form.submit, { 'attr' : { 'class': 'btn btn-chill-green' } } ) }} - - {{ form_end(add_groupcenter_form) }} - {% endblock %} + {% block content_form_actions_save_and_show %}{% endblock %} {% endembed %} {% endblock %} diff --git a/src/Bundle/ChillMainBundle/Resources/views/User/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/User/index.html.twig index bab54d56e..ec93cf8a7 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/User/index.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/User/index.html.twig @@ -11,6 +11,11 @@
+ {% if entity.civility is not null %} + {% if entity.civility.name|length > 0 %} + {{ entity.civility.name|first }} + {% endif %} + {% endif %} {{ entity.label }} {% if entity.isEnabled %} @@ -45,9 +50,13 @@
  • + + {% if allow_change_password is same as(true) %}
  • + {% endif %} + {% if is_granted('ROLE_ALLOWED_TO_SWITCH') %}
  • diff --git a/src/Bundle/ChillMainBundle/Routing/MenuBuilder/AdminUserMenuBuilder.php b/src/Bundle/ChillMainBundle/Routing/MenuBuilder/AdminUserMenuBuilder.php index 7b3399503..b885e1641 100644 --- a/src/Bundle/ChillMainBundle/Routing/MenuBuilder/AdminUserMenuBuilder.php +++ b/src/Bundle/ChillMainBundle/Routing/MenuBuilder/AdminUserMenuBuilder.php @@ -13,6 +13,7 @@ namespace Chill\MainBundle\Routing\MenuBuilder; use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Knp\Menu\MenuItem; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; class AdminUserMenuBuilder implements LocalMenuBuilderInterface @@ -22,9 +23,14 @@ class AdminUserMenuBuilder implements LocalMenuBuilderInterface */ protected $authorizationChecker; - public function __construct(AuthorizationCheckerInterface $authorizationChecker) - { + protected ParameterBagInterface $parameterBag; + + public function __construct( + AuthorizationCheckerInterface $authorizationChecker, + ParameterBagInterface $parameterBag + ) { $this->authorizationChecker = $authorizationChecker; + $this->parameterBag = $parameterBag; } public function buildMenu($menuId, MenuItem $menu, array $parameters) @@ -51,9 +57,11 @@ class AdminUserMenuBuilder implements LocalMenuBuilderInterface 'route' => 'admin_scope', ])->setExtras(['order' => 1020]); - $menu->addChild('Permissions group list', [ - 'route' => 'admin_permissionsgroup', - ])->setExtras(['order' => 1030]); + if ($this->parameterBag->get('chill_main.access_permissions_group_list')) { + $menu->addChild('Permissions group list', [ + 'route' => 'admin_permissionsgroup', + ])->setExtras(['order' => 1030]); + } $menu->addChild('crud.admin_user.index.title', [ 'route' => 'chill_crud_admin_user_index', diff --git a/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php b/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php index b2fd5180e..6b6f9cceb 100644 --- a/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php +++ b/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php @@ -15,11 +15,14 @@ use Chill\MainBundle\Entity\User; use Chill\MainBundle\Notification\Counter\NotificationByUserCounter; use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Workflow\Counter\WorkflowByUserCounter; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; class UserMenuBuilder implements LocalMenuBuilderInterface { + protected ParameterBagInterface $parameterBag; + private NotificationByUserCounter $notificationByUserCounter; private Security $security; @@ -32,12 +35,14 @@ class UserMenuBuilder implements LocalMenuBuilderInterface NotificationByUserCounter $notificationByUserCounter, WorkflowByUserCounter $workflowByUserCounter, Security $security, - TranslatorInterface $translator + TranslatorInterface $translator, + ParameterBagInterface $parameterBag ) { $this->notificationByUserCounter = $notificationByUserCounter; $this->workflowByUserCounter = $workflowByUserCounter; $this->security = $security; $this->translator = $translator; + $this->parameterBag = $parameterBag; } public function buildMenu($menuId, \Knp\Menu\MenuItem $menu, array $parameters) @@ -85,14 +90,16 @@ class UserMenuBuilder implements LocalMenuBuilderInterface 'order' => 700, ]); - $menu - ->addChild( - 'Change password', - ['route' => 'change_my_password'] - ) - ->setExtras([ - 'order' => 99999999998, - ]); + if ($this->parameterBag->get('chill_main.access_user_change_password')) { + $menu + ->addChild( + 'Change password', + ['route' => 'change_my_password'] + ) + ->setExtras([ + 'order' => 99999999998, + ]); + } } $menu diff --git a/src/Bundle/ChillMainBundle/Serializer/Normalizer/PrivateCommentEmbeddableNormalizer.php b/src/Bundle/ChillMainBundle/Serializer/Normalizer/PrivateCommentEmbeddableNormalizer.php new file mode 100644 index 000000000..fc5853c17 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Serializer/Normalizer/PrivateCommentEmbeddableNormalizer.php @@ -0,0 +1,55 @@ +security = $security; + } + + public function denormalize($data, string $type, ?string $format = null, array $context = []): PrivateCommentEmbeddable + { + $comment = new PrivateCommentEmbeddable(); + + if (null === $data) { + return $comment; + } + + $comment->setCommentForUser($this->security->getUser(), $data); + + return $comment; + } + + public function normalize($object, $format = null, array $context = []): string + { + return $object->getCommentForUser($this->security->getUser()); + } + + public function supportsDenormalization($data, string $type, ?string $format = null): bool + { + return PrivateCommentEmbeddable::class === $type; + } + + public function supportsNormalization($data, ?string $format = null): bool + { + return $data instanceof PrivateCommentEmbeddable; + } +} diff --git a/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php b/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php index 365433ef3..eba8fc7bc 100644 --- a/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php +++ b/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\MainBundle\Serializer\Normalizer; use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Entity\Civility; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\User; @@ -60,9 +61,14 @@ class UserNormalizer implements ContextAwareNormalizerInterface, NormalizerAware $context, ['docgen:expects' => Location::class, 'groups' => 'docgen:read'] ); + $civilityContext = array_merge( + $context, + ['docgen:expects' => Civility::class, 'groups' => 'docgen:read'] + ); if (null === $user && 'docgen' === $format) { return array_merge(self::NULL_USER, [ + 'civility' => $this->normalizer->normalize(null, $format, $civilityContext), 'user_job' => $this->normalizer->normalize(null, $format, $userJobContext), 'main_center' => $this->normalizer->normalize(null, $format, $centerContext), 'main_scope' => $this->normalizer->normalize(null, $format, $scopeContext), @@ -84,6 +90,7 @@ class UserNormalizer implements ContextAwareNormalizerInterface, NormalizerAware ]; if ('docgen' === $format) { + $data['civility'] = $this->normalizer->normalize($user->getCivility(), $format, $civilityContext); $data['current_location'] = $this->normalizer->normalize($user->getCurrentLocation(), $format, $locationContext); $data['main_location'] = $this->normalizer->normalize($user->getMainLocation(), $format, $locationContext); } diff --git a/src/Bundle/ChillMainBundle/config/services/form.yaml b/src/Bundle/ChillMainBundle/config/services/form.yaml index f2dc7803a..407a1b6af 100644 --- a/src/Bundle/ChillMainBundle/config/services/form.yaml +++ b/src/Bundle/ChillMainBundle/config/services/form.yaml @@ -143,3 +143,7 @@ services: Chill\MainBundle\Form\Type\LocationFormType: ~ Chill\MainBundle\Form\WorkflowStepType: ~ + + Chill\MainBundle\Form\DataMapper\PrivateCommentDataMapper: + autowire: true + autoconfigure: true diff --git a/src/Bundle/ChillMainBundle/config/services/serializer.yaml b/src/Bundle/ChillMainBundle/config/services/serializer.yaml index 4d8aa9954..5ec936b6c 100644 --- a/src/Bundle/ChillMainBundle/config/services/serializer.yaml +++ b/src/Bundle/ChillMainBundle/config/services/serializer.yaml @@ -10,4 +10,9 @@ services: Chill\MainBundle\Serializer\Normalizer\DoctrineExistingEntityNormalizer: tags: - { name: 'serializer.normalizer', priority: 8 } + Chill\MainBundle\Serializer\Normalizer\PrivateCommentEmbeddableNormalizer: + autowire: true + autoconfigure: true + tags: + - { name: 'serializer.normalizer', priority: 64 } diff --git a/src/Bundle/ChillMainBundle/migrations/Version20220513151853.php b/src/Bundle/ChillMainBundle/migrations/Version20220513151853.php index 31319ce1b..ec99ce2ba 100644 --- a/src/Bundle/ChillMainBundle/migrations/Version20220513151853.php +++ b/src/Bundle/ChillMainBundle/migrations/Version20220513151853.php @@ -1,5 +1,12 @@ addSql('update users set attributes = \'[]\'::json where attributes IS NULL'); } - - public function down(Schema $schema): void - { - - } } diff --git a/src/Bundle/ChillMainBundle/migrations/Version20220516085659.php b/src/Bundle/ChillMainBundle/migrations/Version20220516085659.php new file mode 100644 index 000000000..8e4d7347b --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20220516085659.php @@ -0,0 +1,40 @@ +addSql('ALTER TABLE users DROP CONSTRAINT FK_1483A5E923D6A298'); + $this->addSql('DROP INDEX IDX_1483A5E923D6A298'); + $this->addSql('ALTER TABLE users DROP civility_id'); + } + + public function getDescription(): string + { + return 'Add civility to User'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE users ADD civility_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE users ADD CONSTRAINT FK_1483A5E923D6A298 FOREIGN KEY (civility_id) REFERENCES chill_main_civility (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_1483A5E923D6A298 ON users (civility_id)'); + } +} diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 34ca5d7c9..e25045131 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -65,6 +65,7 @@ Read more: Lire la suite # comment embeddable No comment associated: Aucun commentaire +private comment: Notes privées #pagination Previous: Précédent diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php index 055507162..9c0eade3b 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php @@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; +use Chill\MainBundle\Entity\Embeddable\PrivateCommentEmbeddable; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodLinkedWithSocialIssuesEntityInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; @@ -143,6 +144,12 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues */ private Collection $persons; + /** + * @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\PrivateCommentEmbeddable", columnPrefix="privateComment_") + * @Serializer\Groups({"read", "accompanying_period_work:edit"}) + */ + private PrivateCommentEmbeddable $privateComment; + /** * @ORM\ManyToMany(targetEntity=User::class) * @ORM\JoinTable(name="chill_person_accompanying_period_work_referrer") @@ -202,6 +209,7 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues public function __construct() { $this->goals = new ArrayCollection(); + $this->privateComment = new PrivateCommentEmbeddable(); $this->results = new ArrayCollection(); $this->thirdParties = new ArrayCollection(); $this->persons = new ArrayCollection(); @@ -328,6 +336,11 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues return $this->persons; } + public function getPrivateComment(): PrivateCommentEmbeddable + { + return $this->privateComment; + } + /** * @return Collection|User[] */ @@ -505,6 +518,13 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues return $this; } + public function setPrivateComment(PrivateCommentEmbeddable $privateComment): self + { + $this->privateComment->merge($privateComment); + + return $this; + } + public function setSocialAction(?SocialAction $socialAction): self { $this->socialAction = $socialAction; diff --git a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php index 904950489..fbd271b44 100644 --- a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php +++ b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php @@ -46,10 +46,8 @@ class SocialAction private $desactivationDate; /** - * @ORM\ManyToMany( - * targetEntity=Evaluation::class, - * mappedBy="socialActions" - * ) + * @ORM\ManyToMany(targetEntity=Evaluation::class, inversedBy="socialActions") + * @ORM\JoinTable(name="chill_person_social_work_evaluation_action") */ private Collection $evaluations; @@ -110,6 +108,15 @@ class SocialAction return $this; } + public function addEvaluation(Evaluation $evaluation): self + { + if (!$this->evaluations->contains($evaluation)) { + $this->evaluations[] = $evaluation; + } + + return $this; + } + public function addGoal(Goal $goal): self { if (!$this->goals->contains($goal)) { @@ -300,6 +307,13 @@ class SocialAction return $this; } + public function removeEvaluation(Evaluation $evaluation): self + { + $this->evaluations->removeElement($evaluation); + + return $this; + } + public function removeGoal(Goal $goal): self { $this->goals->removeElement($goal); diff --git a/src/Bundle/ChillPersonBundle/Form/SocialWork/GoalType.php b/src/Bundle/ChillPersonBundle/Form/SocialWork/GoalType.php index 45a43897d..812062137 100644 --- a/src/Bundle/ChillPersonBundle/Form/SocialWork/GoalType.php +++ b/src/Bundle/ChillPersonBundle/Form/SocialWork/GoalType.php @@ -43,16 +43,6 @@ class GoalType extends AbstractType ->add('title', TranslatableStringFormType::class, [ 'label' => 'Nom', ]) - - ->add('socialActions', EntityType::class, [ - 'class' => SocialAction::class, - 'required' => false, - 'multiple' => true, - 'choice_label' => function (SocialAction $issue) { - return $this->translatableStringHelper->localize($issue->getTitle()); - }, - ]) - ->add('results', EntityType::class, [ 'class' => Result::class, 'required' => false, @@ -60,8 +50,8 @@ class GoalType extends AbstractType 'choice_label' => function (Result $r) { return $this->translatableStringHelper->localize($r->getTitle()); }, + 'attr' => ['class' => 'select2 '], ]) - ->add('desactivationDate', ChillDateType::class, [ 'required' => false, 'label' => 'goal.desactivationDate', diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js index 57415565b..c5150b015 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js @@ -253,7 +253,6 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou state.accompanyingCourse.administrativeLocation = value; }, updateReferrer(state, value) { - //console.log('value', value); state.accompanyingCourse.user = value; }, updateJob(state, value) { @@ -775,9 +774,7 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou throw error; }) }, - updateReferrer({ commit }, payload) { - console.log('update referrer', payload); - console.log('payload !== null', payload !== null); + updateReferrer({ commit, state }, payload) { const url = `/api/1.0/person/accompanying-course/${id}.json`; let body = { type: "accompanying_period", user: null }; @@ -788,7 +785,10 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou return makeFetch('PATCH', url, body) .then((response) => { commit('updateReferrer', response.user); - commit('setFilteredReferrersSuggested'); + if (null !== payload.user_job && payload.user_job !== state.accompanyingCourse.job) { + this.dispatch('updateJob', payload.user_job); + } + // commit('setFilteredReferrersSuggested'); // this mutation doesn't exist? }) .catch((error) => { commit('catchError', error); @@ -799,6 +799,8 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou const url = `/api/1.0/person/accompanying-course/${id}.json`; let body = { type: "accompanying_period", job: null }; + console.log('update job', payload); + if (payload !== null) { body = { type: "accompanying_period", job: { id: payload.id, type: payload.type } }; } diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue index bab64018a..fb8796de5 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue @@ -24,6 +24,15 @@
  • +
    + + +
    +
    +

    {{ $t('goals_title') }}

    @@ -141,12 +151,12 @@
    • -
      - - -
      +
      + + +
    @@ -274,18 +284,18 @@
    -