diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cf2fa64c..f60770f36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,26 @@ and this project adheres to ## Test releases +### test release 2021-01-28 + +* [person] improve filiations vis graph: disable physics, use chill colors for persons-households-course, increase label of relations, remove labels on household arrows and other improvements (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/286, https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/362) +* [activity] Order activity by date and by id (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/364) +* [main] increase length of 4 Address fields (change to TEXT, no size limits) (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/277) +* [main] Add confidential option for address, in edit and view (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/165) +* [person] name suggestions within create person form when person is created departing from a search input (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/377) +* [person] Add residential address entity, form and list for each person +* [aside_activity]: dynamicUserPickerType used (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/399) + + +### test release 2021-01-26 + +* [parcours] comments truncated if too long + link added (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/406) +* [person]: possibility to add person resources (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/382) +* [person ressources]: module added +* [parcours] bugfix if deathdate is not defined (eg. for a thirdparty) parcours is still displayed. Gave error before. +* dispatching list + + ### test release 2022-01-24 * [person] name suggestions within create person form when person is created departing from a search input (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/377) @@ -32,7 +52,6 @@ and this project adheres to * add My workflow section with my opened subscriptions * apply workflow on documents, accompanyingCourseWork and Evaluations * [wopi-link] a new vue component allow to open wopi link in a fullscreen chill-themed modal - ### test release 2022-01-19 * vuejs: add dead information on all on-the-fly person render boxes, in vis graph and other templates (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/271) @@ -40,6 +59,7 @@ and this project adheres to * [main] location form type: fix unmapped address field (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/246) * [activity] fix wrong import of js assets for adding and viewing documents in activity (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/83 & https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/176) * [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380) +* [forms] dynamic picker types for user/person/thirdparty types created (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/386) ### test release 2022-01-17 @@ -49,10 +69,14 @@ and this project adheres to * [main] Add mainLocation field to User entity and add it in user form type * [course list in person context] show full username/label for ref * [accompanying period work] remove the possibility to generate document from an accompanying period work +* vuejs: add validation on required fields for AddPerson, Address and Location components +* vuejs: treat 422 validation errors in locations and AddPerson components +* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380) ## Test releases * vuejs: add validation on required fields for AddPerson, Address and Location components * vuejs: treat 422 validation errors in locations and AddPerson components +* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380) ### test release 2022-01-12 diff --git a/package.json.txt b/package.json.txt deleted file mode 100644 index 58f21ac5d..000000000 --- a/package.json.txt +++ /dev/null @@ -1,3 +0,0 @@ -add npm/yarn dependency in package.json : - -"select2-bootstrap-theme": "0.1.0-beta.10", diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 2947fda38..3e32edfce 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -256,7 +256,7 @@ final class ActivityController extends AbstractController if ($person instanceof Person) { $this->denyAccessUnlessGranted(ActivityVoter::SEE, $person); $activities = $this->activityACLAwareRepository - ->findByPerson($person, ActivityVoter::SEE, 0, null); + ->findByPerson($person, ActivityVoter::SEE, 0, null, ['date' => 'DESC', 'id' => 'DESC']); $event = new PrivacyEvent($person, [ 'element_class' => Activity::class, @@ -269,7 +269,7 @@ final class ActivityController extends AbstractController $this->denyAccessUnlessGranted(ActivityVoter::SEE, $accompanyingPeriod); $activities = $this->activityACLAwareRepository - ->findByAccompanyingPeriod($accompanyingPeriod, ActivityVoter::SEE); + ->findByAccompanyingPeriod($accompanyingPeriod, ActivityVoter::SEE, 0, null, ['date' => 'DESC', 'id' => 'DESC']); $view = 'ChillActivityBundle:Activity:listAccompanyingCourse.html.twig'; } diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 75c2aeaf6..2bb40d432 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -61,7 +61,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac /** * @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod") - * @Groups({"read", "docgen:read"}) + * @Groups({"read"}) */ private ?AccompanyingPeriod $accompanyingPeriod = null; @@ -75,16 +75,19 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac /** * @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityPresence") + * @Groups({"docgen:read"}) */ private ?ActivityPresence $attendee = null; /** * @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_") + * @Groups({"docgen:read"}) */ private CommentEmbeddable $comment; /** * @ORM\Column(type="datetime") + * @Groups({"docgen:read"}) */ private DateTime $date; @@ -100,6 +103,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac /** * @ORM\Column(type="boolean", options={"default": false}) + * @Groups({"docgen:read"}) */ private bool $emergency = false; @@ -130,16 +134,19 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac /** * @ORM\ManyToMany(targetEntity="Chill\ActivityBundle\Entity\ActivityReason") + * @Groups({"docgen:read"}) */ private Collection $reasons; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Scope") + * @Groups({"docgen:read"}) */ private ?Scope $scope = null; /** * @ORM\Column(type="string", options={"default": ""}) + * @Groups({"docgen:read"}) */ private string $sentReceived = ''; @@ -170,12 +177,13 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") + * @Groups({"docgen:read"}) */ private User $user; /** * @ORM\ManyToMany(targetEntity="Chill\MainBundle\Entity\User") - * @Groups({"read"}) + * @Groups({"read", "docgen:read"}) */ private ?Collection $users = null; @@ -302,6 +310,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this->documents; } + /** + * @Groups({"docgen:read"}) + */ + public function getDurationMinute(): int + { + if (null === $this->durationTime) { + return 0; + } + + return (int) round(($this->durationTime->getTimestamp() + $this->durationTime->getOffset()) / 60.0, 0); + } + public function getDurationTime(): ?DateTime { return $this->durationTime; @@ -402,6 +422,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this->travelTime; } + /** + * @Groups({"docgen:read"}) + */ + public function getTravelTimeMinute(): int + { + if (null === $this->travelTime) { + return 0; + } + + return (int) round(($this->travelTime->getTimestamp() + $this->travelTime->getOffset()) / 60.0, 0); + } + /** * @deprecated */ diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php b/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php index 725b1eb8e..89f616dc2 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Entity; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Serializer\Annotation as Serializer; /** * Class ActivityPresence. @@ -31,11 +32,14 @@ class ActivityPresence * @ORM\Id * @ORM\Column(name="id", type="integer") * @ORM\GeneratedValue(strategy="AUTO") + * @Serializer\Groups({"docgen:read"}) */ private ?int $id; /** * @ORM\Column(type="json") + * @Serializer\Groups({"docgen:read"}) + * @Serializer\Context({"is-translatable": true}, groups={"docgen:read"}) */ private array $name = []; diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php index 5ad692bf4..c7448e07d 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php @@ -13,6 +13,7 @@ namespace Chill\ActivityBundle\Entity; use Doctrine\ORM\Mapping as ORM; use InvalidArgumentException; +use Symfony\Component\Serializer\Annotation as Serializer; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Constraints as Assert; @@ -118,6 +119,7 @@ class ActivityType * @ORM\Id * @ORM\Column(name="id", type="integer") * @ORM\GeneratedValue(strategy="AUTO") + * @Groups({"docgen:read"}) */ private ?int $id; @@ -133,7 +135,8 @@ class ActivityType /** * @ORM\Column(type="json") - * @Groups({"read"}) + * @Groups({"read", "docgen:read"}) + * @Serializer\Context({"is-translatable": true}, groups={"docgen:read"}) */ private array $name = []; diff --git a/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php b/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php index b3d8472c6..3ca5aab45 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php @@ -29,9 +29,13 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; final class ActivityVoterTest extends KernelTestCase { use PrepareActivityTrait; + use PrepareCenterTrait; + use PreparePersonTrait; + use PrepareScopeTrait; + use PrepareUserTrait; /** diff --git a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php index eee8c7dc8..e5244009e 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php @@ -32,6 +32,8 @@ final class AsideActivityController extends CRUDController { $asideActivity = new AsideActivity(); + $asideActivity->setAgent($this->getUser()); + $duration = $request->query->get('duration', '300'); $duration = DateTime::createFromFormat('U', $duration); $asideActivity->setDuration($duration); diff --git a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php index 5a4eec9e0..6ade55d07 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php @@ -14,9 +14,9 @@ namespace Chill\AsideActivityBundle\Form; use Chill\AsideActivityBundle\Entity\AsideActivity; use Chill\AsideActivityBundle\Entity\AsideActivityCategory; use Chill\AsideActivityBundle\Templating\Entity\CategoryRender; -use Chill\MainBundle\Entity\User; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Form\Type\ChillTextareaType; +use Chill\MainBundle\Form\Type\PickUserDynamicType; use DateInterval; use DateTime; use DateTimeImmutable; @@ -68,22 +68,10 @@ final class AsideActivityFormType extends AbstractType ]; $builder - ->add( - 'agent', - EntityType::class, - [ - 'label' => 'For agent', - 'required' => true, - 'class' => User::class, - 'data' => $this->storage->getToken()->getUser(), - 'query_builder' => static function (EntityRepository $er) { - return $er->createQueryBuilder('u')->where('u.enabled = true'); - }, - 'attr' => ['class' => 'select2 '], - 'placeholder' => 'Choose the agent for whom this activity is created', - 'choice_label' => 'username', - ] - ) + ->add('agent', PickUserDynamicType::class, [ + 'label' => 'For agent', + 'required' => true, + ]) ->add( 'date', ChillDateType::class, diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/new.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/new.html.twig index 0781272a1..09acf9859 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/new.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/new.html.twig @@ -1,5 +1,15 @@ {% extends '@ChillMain/Admin/layout.html.twig' %} +{% block js %} + {{ parent() }} + {{ encore_entry_script_tags('mod_pickentity_type') }} +{% endblock %} + +{% block css %} + {{ parent() }} + {{ encore_entry_link_tags('mod_pickentity_type') }} +{% endblock %} + {% block title %} {% include('@ChillMain/CRUD/_new_title.html.twig') %} {% endblock %} @@ -8,4 +18,5 @@ {% embed '@ChillMain/CRUD/_new_content.html.twig' %} {% block content_form_actions_save_and_show %}{% endblock %} {% endembed %} -{% endblock %} \ No newline at end of file +{% endblock %} + diff --git a/src/Bundle/ChillDocGeneratorBundle/Resources/public/vuejs/_components/PickTemplate.vue b/src/Bundle/ChillDocGeneratorBundle/Resources/public/vuejs/_components/PickTemplate.vue index f1fb6c84b..04d563782 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Resources/public/vuejs/_components/PickTemplate.vue +++ b/src/Bundle/ChillDocGeneratorBundle/Resources/public/vuejs/_components/PickTemplate.vue @@ -17,7 +17,7 @@ @@ -48,6 +48,7 @@ export default { required: true, }, templates: { + type: Array, required: true, }, // beforeMove execute "something" before @@ -73,7 +74,11 @@ export default { return true; }, getDescription() { - return this.templates.find(t => t.id === this.template).description || ''; + let desc = this.templates.find(t => t.id === this.template); + if (null === desc) { + return ''; + } + return desc.description || ''; }, }, methods: { diff --git a/src/Bundle/ChillMainBundle/Entity/Address.php b/src/Bundle/ChillMainBundle/Entity/Address.php index 070d40468..0e6cd549b 100644 --- a/src/Bundle/ChillMainBundle/Entity/Address.php +++ b/src/Bundle/ChillMainBundle/Entity/Address.php @@ -42,10 +42,16 @@ class Address */ private $buildingName; + /** + * @ORM\Column(type="boolean") + * @Groups({"write"}) + */ + private bool $confidential = false; + /** * @var string|null * - * @ORM\Column(type="string", length=16, nullable=true) + * @ORM\Column(type="string", length=255, nullable=true) * @Groups({"write"}) */ private $corridor; @@ -78,7 +84,7 @@ class Address /** * @var string|null * - * @ORM\Column(type="string", length=16, nullable=true) + * @ORM\Column(type="string", length=255, nullable=true) * @Groups({"write"}) */ private $flat; @@ -86,7 +92,7 @@ class Address /** * @var string|null * - * @ORM\Column(type="string", length=16, nullable=true) + * @ORM\Column(type="string", length=255, nullable=true) * @Groups({"write"}) */ private $floor; @@ -143,7 +149,7 @@ class Address /** * @var string|null * - * @ORM\Column(type="string", length=16, nullable=true) + * @ORM\Column(type="string", length=255, nullable=true) * @Groups({"write"}) */ private $steps; @@ -192,6 +198,7 @@ class Address return (new Address()) ->setAddressReference($original->getAddressReference()) ->setBuildingName($original->getBuildingName()) + ->setConfidential($original->getConfidential()) ->setCorridor($original->getCorridor()) ->setCustoms($original->getCustoms()) ->setDistribution($original->getDistribution()) @@ -229,6 +236,11 @@ class Address return $this->buildingName; } + public function getConfidential(): bool + { + return $this->confidential; + } + public function getCorridor(): ?string { return $this->corridor; @@ -369,6 +381,13 @@ class Address return $this; } + public function setConfidential(bool $confidential): self + { + $this->confidential = $confidential; + + return $this; + } + public function setCorridor(?string $corridor): self { $this->corridor = $corridor; diff --git a/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php b/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php index 51b8978a0..61ebce10b 100644 --- a/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php +++ b/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php @@ -20,10 +20,9 @@ use Doctrine\ORM\Mapping as ORM; class CommentEmbeddable { /** - * @var string * @ORM\Column(type="text", nullable=true) */ - private $comment; + private ?string $comment = null; /** * @var DateTime @@ -39,10 +38,7 @@ class CommentEmbeddable */ private $userId; - /** - * @return string - */ - public function getComment() + public function getComment(): ?string { return $this->comment; } @@ -68,9 +64,6 @@ class CommentEmbeddable return empty($this->getComment()); } - /** - * @param string $comment - */ public function setComment(?string $comment) { $this->comment = $comment; diff --git a/src/Bundle/ChillMainBundle/Entity/Location.php b/src/Bundle/ChillMainBundle/Entity/Location.php index 8496374d8..bff3ff37b 100644 --- a/src/Bundle/ChillMainBundle/Entity/Location.php +++ b/src/Bundle/ChillMainBundle/Entity/Location.php @@ -64,7 +64,7 @@ class Location implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\Column(type="string", length=255, nullable=true) - * @Serializer\Groups({"read", "write"}) + * @Serializer\Groups({"read", "write", "docgen:read"}) */ private ?string $email = null; diff --git a/src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php b/src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php new file mode 100644 index 000000000..7763ea9d5 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php @@ -0,0 +1,166 @@ +comment = new CommentEmbeddable(); + } + + public function getAddress(): ?Address + { + return $this->address; + } + + public function getComment(): CommentEmbeddable + { + return $this->comment; + } + + public function getEndDate(): ?DateTimeImmutable + { + return $this->endDate; + } + + public function getHostPerson(): ?Person + { + return $this->hostPerson; + } + + public function getHostThirdParty(): ?ThirdParty + { + return $this->hostThirdParty; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getPerson(): ?Person + { + return $this->person; + } + + public function getStartDate(): ?DateTimeImmutable + { + return $this->startDate; + } + + public function setAddress(?Address $address): self + { + $this->address = $address; + + return $this; + } + + public function setComment(CommentEmbeddable $comment): self + { + $this->comment = $comment; + + return $this; + } + + public function setEndDate(?DateTimeImmutable $endDate): self + { + $this->endDate = $endDate; + + return $this; + } + + public function setHostPerson(?Person $hostPerson): self + { + $this->hostPerson = $hostPerson; + + return $this; + } + + public function setHostThirdParty(?ThirdParty $hostThirdParty): self + { + $this->hostThirdParty = $hostThirdParty; + + return $this; + } + + public function setPerson(?Person $person): self + { + $this->person = $person; + + return $this; + } + + public function setStartDate(DateTimeImmutable $startDate): self + { + $this->startDate = $startDate; + + return $this; + } +} diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php index b56435f5d..0d7142e9f 100644 --- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php +++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php @@ -37,6 +37,7 @@ use function count; class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface { use TrackCreationTrait; + use TrackUpdateTrait; /** diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowComment.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowComment.php index b041a5aa3..9f4e7f096 100644 --- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowComment.php +++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowComment.php @@ -24,6 +24,7 @@ use Doctrine\ORM\Mapping as ORM; class EntityWorkflowComment implements TrackCreationInterface, TrackUpdateInterface { use TrackCreationTrait; + use TrackUpdateTrait; /** diff --git a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/UserToJsonTransformer.php b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php similarity index 72% rename from src/Bundle/ChillMainBundle/Form/Type/DataTransformer/UserToJsonTransformer.php rename to src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php index ca87ea4f5..95c447119 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/UserToJsonTransformer.php +++ b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php @@ -12,14 +12,18 @@ declare(strict_types=1); namespace Chill\MainBundle\Form\Type\DataTransformer; use Chill\MainBundle\Entity\User; +use Chill\PersonBundle\Entity\Person; +use Chill\ThirdPartyBundle\Entity\ThirdParty; use Symfony\Component\Form\DataTransformerInterface; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\SerializerInterface; +use UnexpectedValueException; + use function array_key_exists; -class UserToJsonTransformer implements DataTransformerInterface +class EntityToJsonTransformer implements DataTransformerInterface { private DenormalizerInterface $denormalizer; @@ -27,11 +31,14 @@ class UserToJsonTransformer implements DataTransformerInterface private SerializerInterface $serializer; - public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer, bool $multiple) + private string $type; + + public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer, bool $multiple, string $type) { $this->denormalizer = $denormalizer; $this->serializer = $serializer; $this->multiple = $multiple; + $this->type = $type; } public function reverseTransform($value) @@ -49,6 +56,10 @@ class UserToJsonTransformer implements DataTransformerInterface ); } + if ('' === $value) { + return null; + } + return $this->denormalizeOne($denormalized); } @@ -66,7 +77,7 @@ class UserToJsonTransformer implements DataTransformerInterface ]); } - private function denormalizeOne(array $item): User + private function denormalizeOne(array $item) { if (!array_key_exists('type', $item)) { throw new TransformationFailedException('the key "type" is missing on element'); @@ -76,10 +87,30 @@ class UserToJsonTransformer implements DataTransformerInterface throw new TransformationFailedException('the key "id" is missing on element'); } + switch ($this->type) { + case 'user': + $class = User::class; + + break; + + case 'person': + $class = Person::class; + + break; + + case 'thirdparty': + $class = ThirdParty::class; + + break; + + default: + throw new UnexpectedValueException('This type is not supported'); + } + return $this->denormalizer->denormalize( ['type' => $item['type'], 'id' => $item['id']], - User::class, + $class, 'json', [AbstractNormalizer::GROUPS => ['read']], ); diff --git a/src/Bundle/ChillMainBundle/Form/Type/PickUserDynamicType.php b/src/Bundle/ChillMainBundle/Form/Type/PickUserDynamicType.php index 52798608e..3bc4df436 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/PickUserDynamicType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/PickUserDynamicType.php @@ -12,7 +12,7 @@ declare(strict_types=1); namespace Chill\MainBundle\Form\Type; use Chill\MainBundle\Entity\User; -use Chill\MainBundle\Form\Type\DataTransformer\UserToJsonTransformer; +use Chill\MainBundle\Form\Type\DataTransformer\EntityToJsonTransformer; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; @@ -38,7 +38,7 @@ class PickUserDynamicType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { - $builder->addViewTransformer(new UserToJsonTransformer($this->denormalizer, $this->serializer, $options['multiple'])); + $builder->addViewTransformer(new EntityToJsonTransformer($this->denormalizer, $this->serializer, $options['multiple'], 'user')); } public function buildView(FormView $view, FormInterface $form, array $options) @@ -58,6 +58,6 @@ class PickUserDynamicType extends AbstractType public function getBlockPrefix() { - return 'pick_user_dynamic'; + return 'pick_entity_dynamic'; } } diff --git a/src/Bundle/ChillMainBundle/Form/Type/ResidentialAddressType.php b/src/Bundle/ChillMainBundle/Form/Type/ResidentialAddressType.php new file mode 100644 index 000000000..0ebe47fef --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/Type/ResidentialAddressType.php @@ -0,0 +1,73 @@ +add('startDate', DateType::class, [ + 'required' => true, + 'input' => 'datetime_immutable', + 'widget' => 'single_text', + ]) + ->add('endDate', DateType::class, [ + 'required' => false, + 'input' => 'datetime_immutable', + 'widget' => 'single_text', + ]) + ->add('comment', CommentType::class, [ + 'required' => false, + ]); + + if ('person' === $options['kind']) { + $builder + ->add('hostPerson', PickPersonDynamicType::class, [ + 'label' => 'Person', + ]); + } + + if ('thirdparty' === $options['kind']) { + $builder + ->add('hostThirdParty', PickThirdpartyDynamicType::class, [ + 'label' => 'Third party', + ]); + } + + if ('address' === $options['kind']) { + $builder + ->add('address', PickAddressType::class, [ + 'required' => false, + 'label' => 'Address', + 'use_valid_from' => false, + 'use_valid_to' => false, + ]); + } + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => ResidentialAddress::class, + 'kind' => null, + ]); + } +} diff --git a/src/Bundle/ChillMainBundle/Repository/ResidentialAddressRepository.php b/src/Bundle/ChillMainBundle/Repository/ResidentialAddressRepository.php new file mode 100644 index 000000000..05cdfdf6c --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/ResidentialAddressRepository.php @@ -0,0 +1,59 @@ +createQueryBuilder('r') + ->andWhere('r.exampleField = :val') + ->setParameter('val', $value) + ->orderBy('r.id', 'ASC') + ->setMaxResults(10) + ->getQuery() + ->getResult() + ; + } + */ + + /* + public function findOneBySomeField($value): ?ResidentialAddress + { + return $this->createQueryBuilder('r') + ->andWhere('r.exampleField = :val') + ->setParameter('val', $value) + ->getQuery() + ->getOneOrNullResult() + ; + } + */ +} diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/show_hide/show_hide.js b/src/Bundle/ChillMainBundle/Resources/public/lib/show_hide/show_hide.js index ec6b796ec..f2bcc9b45 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/lib/show_hide/show_hide.js +++ b/src/Bundle/ChillMainBundle/Resources/public/lib/show_hide/show_hide.js @@ -39,6 +39,7 @@ var ShowHide = function(options) { contents.push(el); } container_content.push(contents); + // console.log('container content', container_content); } // attach the listener on each input diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/blur/index.js b/src/Bundle/ChillMainBundle/Resources/public/module/blur/index.js index 6e3b75f2b..1d66d25e6 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/module/blur/index.js +++ b/src/Bundle/ChillMainBundle/Resources/public/module/blur/index.js @@ -1,21 +1,19 @@ require('./blur.scss'); -var toggleBlur = function(e){ - - var btn = e.target; - - btn.previousElementSibling.classList.toggle("blur"); - btn.classList.toggle("fa-eye"); - btn.classList.toggle("fa-eye-slash"); - -} - -var infos = document.getElementsByClassName("confidential"); -for(var i=0; i < infos.length; i++){ - infos[i].insertAdjacentHTML('beforeend', ''); -} - -var toggles = document.getElementsByClassName("toggle"); -for(var i=0; i < toggles.length; i++){ - toggles[i].addEventListener("click", toggleBlur); -} \ No newline at end of file +document.querySelectorAll('.confidential').forEach(function (el) { + let i = document.createElement('i'); + const classes = ['fa', 'fa-eye', 'toggle']; + i.classList.add(...classes); + el.appendChild(i); + const toggleBlur = function(e) { + for (let child of el.children) { + if (!child.classList.contains('toggle')) { + child.classList.toggle('blur'); + } + } + i.classList.toggle('fa-eye'); + i.classList.toggle('fa-eye-slash'); + } + i.addEventListener('click', toggleBlur); + toggleBlur(); +}); diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js b/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js index 329ac4e6c..1fd6b34f7 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js +++ b/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js @@ -5,18 +5,21 @@ import { appMessages } from 'ChillMainAssets/vuejs/PickEntity/i18n'; const i18n = _createI18n(appMessages); -window.addEventListener('DOMContentLoaded', function(e) { +let appsOnPage = new Map(); - let apps = document.querySelectorAll('[data-module="pick-dynamic"]'); +function loadDynamicPicker(element) { + + let apps = element.querySelectorAll('[data-module="pick-dynamic"]'); apps.forEach(function(el) { const isMultiple = parseInt(el.dataset.multiple) === 1, - input = document.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'), - picked = isMultiple ? JSON.parse(input.value) : [JSON.parse(input.value)]; + uniqId = el.dataset.uniqid, + input = element.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'), + picked = (isMultiple) ? (JSON.parse(input.value)) : ((input.value === '[]') ? (null) : ([JSON.parse(input.value)])); - createApp({ + const app = createApp({ template: ' { + let uniqId = el.dataset.uniqid; + console.log(uniqId); + if (appsOnPage.has(uniqId)) { + appsOnPage.get(uniqId).unmount(); + console.log('App has been unmounted') + appsOnPage.delete(uniqId); + } + }) +}) + +document.addEventListener('DOMContentLoaded', function(e) { + console.log('loaded event', e) + loadDynamicPicker(document) +}) + + + + + 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 1f62269de..2ca73b92c 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue @@ -562,6 +562,7 @@ export default { this.entity.loaded.cities = []; this.entity.loaded.countries = []; + this.entity.selected.confidential = this.context.edit ? this.entity.address.confidential : false; this.entity.selected.isNoAddress = (this.context.edit && this.entity.address.text === '') ? true : false; this.entity.selected.country = this.context.edit ? this.entity.address.country : {}; @@ -593,6 +594,7 @@ export default { { console.log('apply changes'); let newAddress = { + 'confidential': this.entity.selected.confidential, 'isNoAddress': this.entity.selected.isNoAddress, 'street': this.entity.selected.isNoAddress ? '' : this.entity.selected.address.street, 'streetNumber': this.entity.selected.isNoAddress ? '' : this.entity.selected.address.streetNumber, diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue index 1216871ab..93a64ad19 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue @@ -6,7 +6,6 @@ @@ -15,7 +14,6 @@ @@ -24,7 +22,6 @@ @@ -33,7 +30,6 @@ diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue index 486d28e73..5279880bc 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue @@ -17,12 +17,22 @@
+
+ + +
+ :value="value" /> @@ -118,7 +128,8 @@ export default { emits: ['getCities', 'getReferenceAddresses'], data() { return { - value: false + value: false, + valueConfidential: false, } }, computed: { @@ -134,6 +145,14 @@ export default { addressMap() { return this.entity.addressMap; }, + isConfidential: { + set(value) { + this.entity.selected.confidential = value; + }, + get() { + return this.entity.selected.confidential; + } + }, isNoAddress: { set(value) { console.log('isNoAddress value', value); diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/i18n.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/i18n.js index 98f31cbd3..28670f56c 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/i18n.js +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/i18n.js @@ -18,6 +18,7 @@ const addressMessages = { other_address: 'Autre adresse', create_address: 'Adresse inconnue. Cliquez ici pour créer une nouvelle adresse', isNoAddress: 'Pas d\'adresse complète', + isConfidential: 'Adresse confidentielle', street: 'Nom de rue', streetNumber: 'Numéro', floor: 'Étage', diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/PickEntity/PickEntity.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/PickEntity/PickEntity.vue index 43f3ebf94..137224691 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/PickEntity/PickEntity.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/PickEntity/PickEntity.vue @@ -1,5 +1,5 @@