diff --git a/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php index 0c2af22f7..5ada822c4 100644 --- a/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php +++ b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php @@ -63,4 +63,28 @@ class PrivateCommentEmbeddable return $this; } + + /** + * Merges comments from the provided object into the current object. + * + * Identifies common user IDs between the current object's comments and the + * newComment's comments. If a user ID exists in both, their comments are + * concatenated with the provided separator. If a user ID exists only in the + * newComment, their comment is added to the current object directly. + * + * @param self $commentsToAppend the object containing the new comments to be merged + * @param string $separator the string used to separate concatenated comments + */ + public function concatenateComments(self $commentsToAppend, string $separator = "\n\n-----------\n\n"): void + { + $commonUserIds = array_intersect(array_keys($this->comments), array_keys($commentsToAppend->getComments())); + + foreach ($commentsToAppend->getComments() as $userId => $comment) { + if (in_array($userId, $commonUserIds, true)) { + $this->comments[$userId] = $this->comments[$userId].$separator.$commentsToAppend->getComments()[$userId]; + } else { + $this->comments[$userId] = $commentsToAppend->getComments()[$userId]; + } + } + } } diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.ts b/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.ts index b50bb5534..e8256b348 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.ts +++ b/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.ts @@ -61,6 +61,9 @@ export interface ConflictHttpExceptionInterface /** * Generic api method that can be adapted to any fetch request + * + * This method is suitable make a single fetch. When performing a GET to fetch a list of elements, always consider pagination + * and use of the @link{fetchResults} method. */ export const makeFetch = ( method: "POST" | "GET" | "PUT" | "PATCH" | "DELETE", diff --git a/src/Bundle/ChillMainBundle/Resources/views/Form/fields.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Form/fields.html.twig index 9f07b3aa0..033fdb342 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Form/fields.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Form/fields.html.twig @@ -281,10 +281,10 @@ {% endblock %} {% block pick_linked_entities_widget %} - -
+ + {% endblock %} {% block pick_postal_code_widget %} diff --git a/src/Bundle/ChillMainBundle/Tests/Entity/Workflow/PrivateCommentEmbeddableTest.php b/src/Bundle/ChillMainBundle/Tests/Entity/Workflow/PrivateCommentEmbeddableTest.php new file mode 100644 index 000000000..359b194a8 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Tests/Entity/Workflow/PrivateCommentEmbeddableTest.php @@ -0,0 +1,56 @@ +prophesize(User::class); + $userA->getId()->willReturn(1); + $userB = $this->prophesize(User::class); + $userB->getId()->willReturn(2); + $userC = $this->prophesize(User::class); + $userC->getId()->willReturn(3); + + $toKeep = new PrivateCommentEmbeddable(); + $toKeep->setCommentForUser($userA->reveal(), 'My comment for A'); + $toKeep->setCommentForUser($userB->reveal(), 'My comment for B'); + + $toDelete = new PrivateCommentEmbeddable(); + $toDelete->setCommentForUser($userC->reveal(), 'My comment for C'); + $toDelete->setCommentForUser($userB->reveal(), 'Another comment for B'); + + $toKeep->concatenateComments($toDelete, '----'); + + self::assertTrue($toKeep->hasCommentForUser($userA->reveal())); + self::assertEquals('My comment for A', $toKeep->getCommentForUser($userA->reveal())); + + self::assertTrue($toKeep->hasCommentForUser($userB->reveal())); + self::assertEquals('My comment for B----Another comment for B', $toKeep->getCommentForUser($userB->reveal())); + + self::assertTrue($toKeep->hasCommentForUser($userC->reveal())); + self::assertEquals('My comment for C', $toKeep->getCommentForUser($userC->reveal())); + } +} diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php index ac7c7dec4..9212a96dc 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php @@ -314,7 +314,6 @@ final class AccompanyingCourseApiController extends ApiController $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingPeriod); $works = $this->accompanyingPeriodWorkRepository->findBy(['accompanyingPeriod' => $accompanyingPeriod]); - dump($works); return $this->json($works, Response::HTTP_OK, [], ['groups' => ['read']]); } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php index 748174e19..44713c476 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php @@ -218,14 +218,6 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU public function setAccompanyingPeriodWork(?AccompanyingPeriodWork $accompanyingPeriodWork): AccompanyingPeriodWorkEvaluation { - if ( - $accompanyingPeriodWork instanceof AccompanyingPeriodWork - && $this->accompanyingPeriodWork instanceof AccompanyingPeriodWork - && $this->accompanyingPeriodWork->getId() !== $accompanyingPeriodWork->getId() - ) { - throw new \RuntimeException('Changing the accompanyingPeriodWork is not allowed'); - } - $this->accompanyingPeriodWork = $accompanyingPeriodWork; return $this; diff --git a/src/Bundle/ChillPersonBundle/Form/FindAccompanyingPeriodWorkType.php b/src/Bundle/ChillPersonBundle/Form/FindAccompanyingPeriodWorkType.php index 1f862353e..ab78cb541 100644 --- a/src/Bundle/ChillPersonBundle/Form/FindAccompanyingPeriodWorkType.php +++ b/src/Bundle/ChillPersonBundle/Form/FindAccompanyingPeriodWorkType.php @@ -24,8 +24,9 @@ class FindAccompanyingPeriodWorkType extends AbstractType { $builder ->add('acpw', PickLinkedAccompanyingPeriodWorkType::class, [ - 'label' => 'Accompanying period work', + 'label' => 'Social action', 'multiple' => false, + 'accompanyingPeriod' => $options['accompanyingPeriod'], ]) ->add('direction', HiddenType::class, [ 'data' => 'starting', diff --git a/src/Bundle/ChillPersonBundle/Form/Type/PickLinkedAccompanyingPeriodWorkType.php b/src/Bundle/ChillPersonBundle/Form/Type/PickLinkedAccompanyingPeriodWorkType.php index ad199f882..a2a282d19 100644 --- a/src/Bundle/ChillPersonBundle/Form/Type/PickLinkedAccompanyingPeriodWorkType.php +++ b/src/Bundle/ChillPersonBundle/Form/Type/PickLinkedAccompanyingPeriodWorkType.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Form\Type; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; @@ -19,29 +20,25 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; class PickLinkedAccompanyingPeriodWorkType extends AbstractType { - public function __construct(private readonly NormalizerInterface $normalizer) {} - public function buildView(FormView $view, FormInterface $form, array $options) { $view->vars['multiple'] = $options['multiple']; $view->vars['types'] = ['acpw']; $view->vars['uniqid'] = uniqid('pick_acpw_dyn'); - $view->vars['suggested'] = []; $view->vars['as_id'] = true === $options['as_id'] ? '1' : '0'; $view->vars['submit_on_adding_new_entity'] = false; - - foreach ($options['suggested'] as $suggestion) { - $view->vars['suggested'][] = $this->normalizer->normalize($suggestion, 'json', ['groups' => 'read']); - } + $view->vars['pick-entities-type'] = 'acpw'; + $view->vars['attr']['data-accompanying-period-id'] = $options['accompanyingPeriod']->getId(); } public function configureOptions(OptionsResolver $resolver) { $resolver + ->setRequired('accompanyingPeriod') + ->setAllowedTypes('accompanyingPeriod', [AccompanyingPeriod::class]) ->setDefault('multiple', false) ->setAllowedTypes('multiple', ['bool']) ->setDefault('compound', false) - ->setDefault('suggested', []) ->setDefault('as_id', false) ->setAllowedTypes('as_id', ['bool']) ->setDefault('submit_on_adding_new_entity', false) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/mod/DuplicateSelector/AccompanyingPeriodWorkSelector.js b/src/Bundle/ChillPersonBundle/Resources/public/mod/DuplicateSelector/AccompanyingPeriodWorkSelector.js deleted file mode 100644 index 1c7a5023b..000000000 --- a/src/Bundle/ChillPersonBundle/Resources/public/mod/DuplicateSelector/AccompanyingPeriodWorkSelector.js +++ /dev/null @@ -1,12 +0,0 @@ -import { createApp } from "vue"; -import AccompanyingPeriodWorkSelectorModal from "../../vuejs/_components/AccompanyingPeriodWorkSelector/AccompanyingPeriodWorkSelectorModal.vue"; - -document.addEventListener("DOMContentLoaded", () => { - const el = document.getElementById("linked-acpw-selector"); - if (el) { - const accompanyingPeriodId = el.dataset.accompanyingPeriod; - createApp(AccompanyingPeriodWorkSelectorModal, { - accompanyingPeriodId, - }).mount(el); - } -}); diff --git a/src/Bundle/ChillPersonBundle/Resources/public/mod/DuplicateSelector/AccompanyingPeriodWorkSelector.ts b/src/Bundle/ChillPersonBundle/Resources/public/mod/DuplicateSelector/AccompanyingPeriodWorkSelector.ts new file mode 100644 index 000000000..0ac3b4d6f --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/public/mod/DuplicateSelector/AccompanyingPeriodWorkSelector.ts @@ -0,0 +1,47 @@ +import { createApp } from "vue"; +import AccompanyingPeriodWorkSelectorModal from "../../vuejs/_components/AccompanyingPeriodWorkSelector/AccompanyingPeriodWorkSelectorModal.vue"; +import {AccompanyingPeriodWork} from "../../types"; + +document.addEventListener("DOMContentLoaded", () => { + const elements = document.querySelectorAll