mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge remote-tracking branch 'origin/master' into issue412_413_activity
This commit is contained in:
commit
08c13b8c98
26
CHANGELOG.md
26
CHANGELOG.md
@ -13,12 +13,34 @@ and this project adheres to
|
||||
<!-- write down unreleased development here -->
|
||||
* [activity] show activity attendee (présence) in the activity list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/412)
|
||||
* [activity] admin: change validation rule for social action visible field (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/413)
|
||||
* [parcours]: component added to change the opening date of a parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/411)
|
||||
* [search]: listing of parcours display changed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/410)
|
||||
* [user]: page with accompanying periods to which is user is referent (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/408)
|
||||
* [person] age added to renderstring + renderbox/ vue component created to display person text (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/389)
|
||||
* [household member editor] allow to push to existing household
|
||||
|
||||
|
||||
## 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)
|
||||
* dispatching list
|
||||
|
||||
|
||||
### test release 2021-01-26
|
||||
|
||||
>>>>>>> origin/master
|
||||
* [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
|
||||
* [person]: possibility to add person resources (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/382)
|
||||
|
||||
## Test releases
|
||||
|
||||
### test release 2022-01-24
|
||||
|
||||
|
@ -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';
|
||||
}
|
||||
|
@ -1,45 +1,48 @@
|
||||
<template>
|
||||
<teleport to="#add-persons" v-if="isComponentVisible">
|
||||
<teleport to="#add-persons" v-if="isComponentVisible">
|
||||
|
||||
<div class="flex-bloc concerned-groups" :class="getContext">
|
||||
<persons-bloc
|
||||
v-for="bloc in contextPersonsBlocs"
|
||||
v-bind:key="bloc.key"
|
||||
v-bind:bloc="bloc"
|
||||
v-bind:blocWidth="getBlocWidth"
|
||||
v-bind:setPersonsInBloc="setPersonsInBloc">
|
||||
</persons-bloc>
|
||||
</div>
|
||||
<div v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0">
|
||||
<ul class="list-suggest add-items inline">
|
||||
<li v-for="(p, i) in suggestedEntities" @click="addSuggestedEntity(p)" :key="`suggestedEntities-${i}`">
|
||||
<span>{{ p.text }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex-bloc concerned-groups" :class="getContext">
|
||||
<persons-bloc
|
||||
v-for="bloc in contextPersonsBlocs"
|
||||
v-bind:key="bloc.key"
|
||||
v-bind:bloc="bloc"
|
||||
v-bind:blocWidth="getBlocWidth"
|
||||
v-bind:setPersonsInBloc="setPersonsInBloc">
|
||||
</persons-bloc>
|
||||
</div>
|
||||
<div v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0">
|
||||
<ul class="list-suggest add-items inline">
|
||||
<li v-for="(p, i) in suggestedEntities" @click="addSuggestedEntity(p)" :key="`suggestedEntities-${i}`">
|
||||
<person-text v-if="p.type === 'person'" :person="p"></person-text>
|
||||
<span v-else>{{ p.text }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<add-persons
|
||||
buttonTitle="activity.add_persons"
|
||||
modalTitle="activity.add_persons"
|
||||
v-bind:key="addPersons.key"
|
||||
v-bind:options="addPersonsOptions"
|
||||
@addNewPersons="addNewPersons"
|
||||
ref="addPersons">
|
||||
</add-persons>
|
||||
<add-persons
|
||||
buttonTitle="activity.add_persons"
|
||||
modalTitle="activity.add_persons"
|
||||
v-bind:key="addPersons.key"
|
||||
v-bind:options="addPersonsOptions"
|
||||
@addNewPersons="addNewPersons"
|
||||
ref="addPersons">
|
||||
</add-persons>
|
||||
|
||||
</teleport>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||
import PersonsBloc from './ConcernedGroups/PersonsBloc.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
export default {
|
||||
name: "ConcernedGroups",
|
||||
components: {
|
||||
AddPersons,
|
||||
PersonsBloc
|
||||
PersonsBloc,
|
||||
PersonText
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -1,21 +1,29 @@
|
||||
<template>
|
||||
<li>
|
||||
<span :title="person.text">
|
||||
<span class="chill_denomination" @click.prevent="$emit('remove', person)">{{ textCutted }}</span>
|
||||
<span class="chill_denomination" @click.prevent="$emit('remove', person)">
|
||||
<person-text :person="person" :isCut="true"></person-text>
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
|
||||
export default {
|
||||
name: "PersonBadge",
|
||||
props: ['person'],
|
||||
computed: {
|
||||
textCutted() {
|
||||
let more = (this.person.text.length > 15) ?'…' : '';
|
||||
return this.person.text.slice(0,15) + more;
|
||||
}
|
||||
components: {
|
||||
PersonText
|
||||
},
|
||||
// computed: {
|
||||
// textCutted() {
|
||||
// let more = (this.person.text.length > 15) ?'…' : '';
|
||||
// return this.person.text.slice(0,15) + more;
|
||||
// }
|
||||
// },
|
||||
emits: ['remove'],
|
||||
}
|
||||
</script>
|
||||
|
@ -48,7 +48,7 @@
|
||||
<li class="associated-persons">
|
||||
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
|
||||
{% for p in activity.personsAssociated %}
|
||||
<span class="badge-person">{{ p|chill_entity_render_box }}</span>
|
||||
<span class="badge-person">{{ p|chill_entity_render_box({'addAgeBadge': true}) }}</span>
|
||||
{% endfor %}
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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 %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
166
src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php
Normal file
166
src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Entity;
|
||||
|
||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Chill\MainBundle\Repository\ResidentialAddressRepository;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass=ResidentialAddressRepository::class)
|
||||
* @ORM\Table(name="chill_main_residential_address")
|
||||
*/
|
||||
class ResidentialAddress
|
||||
{
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Address::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?Address $address = null;
|
||||
|
||||
/**
|
||||
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="residentialAddressComment_")
|
||||
*/
|
||||
private CommentEmbeddable $comment;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime_immutable", nullable=true)
|
||||
*/
|
||||
private ?DateTimeImmutable $endDate = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?Person $hostPerson = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?ThirdParty $hostThirdParty = null;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||
* @ORM\JoinColumn(nullable=false)
|
||||
*/
|
||||
private Person $person;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime_immutable")
|
||||
*/
|
||||
private ?DateTimeImmutable $startDate = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ use function count;
|
||||
class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
class EntityWorkflowComment implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Chill\MainBundle\Entity\ResidentialAddress;
|
||||
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||
use Chill\ThirdPartyBundle\Form\Type\PickThirdpartyDynamicType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
final class ResidentialAddressType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->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,
|
||||
]);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Repository;
|
||||
|
||||
use Chill\MainBundle\Entity\ResidentialAddress;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @method ResidentialAddress|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method ResidentialAddress|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method ResidentialAddress[] findAll()
|
||||
* @method ResidentialAddress[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class ResidentialAddressRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, ResidentialAddress::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return ResidentialAddress[] Returns an array of ResidentialAddress objects
|
||||
// */
|
||||
/*
|
||||
public function findByExampleField($value)
|
||||
{
|
||||
return $this->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()
|
||||
;
|
||||
}
|
||||
*/
|
||||
}
|
@ -12,6 +12,7 @@
|
||||
display: block;
|
||||
top: calc(50% - 7px);
|
||||
right: 10px;
|
||||
line-height: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,14 +63,19 @@ ul.list-suggest {
|
||||
& span:hover {
|
||||
color: $chill-l-gray;
|
||||
}
|
||||
.person-text {
|
||||
span {
|
||||
padding-left: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.remove-items {
|
||||
li {
|
||||
position: relative;
|
||||
span {
|
||||
& > span {
|
||||
display: block;
|
||||
padding-right: .75rem;
|
||||
padding-right: 1.75rem;
|
||||
@include remove_link;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ $chill-theme-buttons: (
|
||||
"cancel": $gray-300,
|
||||
"choose": $gray-300,
|
||||
"notify": $gray-300,
|
||||
"search": $gray-300,
|
||||
"unlink": $chill-red,
|
||||
"tpchild": $chill-pink,
|
||||
);
|
||||
@ -80,6 +81,7 @@ $chill-theme-buttons: (
|
||||
&.btn-notify::before,
|
||||
&.btn-tpchild::before,
|
||||
&.btn-download::before,
|
||||
&.btn-search::before,
|
||||
&.btn-cancel::before {
|
||||
font: normal normal normal 14px/1 ForkAwesome;
|
||||
margin-right: 0.5em;
|
||||
@ -108,6 +110,7 @@ $chill-theme-buttons: (
|
||||
&.btn-notify::before { content: "\f1d8"; } // fa-paper-plane
|
||||
&.btn-tpchild::before { content: "\f007"; } // fa-user
|
||||
&.btn-download::before { content: "\f019"; } // fa-download
|
||||
&.btn-search::before { content: "\f002"; } // fa-search
|
||||
}
|
||||
|
||||
|
||||
|
@ -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', '<i class="fa fa-eye toggle" aria-hidden="true"></i>');
|
||||
}
|
||||
|
||||
var toggles = document.getElementsByClassName("toggle");
|
||||
for(var i=0; i < toggles.length; i++){
|
||||
toggles[i].addEventListener("click", toggleBlur);
|
||||
}
|
||||
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();
|
||||
});
|
||||
|
@ -19,6 +19,12 @@ function loadDynamicPicker(element) {
|
||||
input = element.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'),
|
||||
picked = (isMultiple) ? (JSON.parse(input.value)) : ((input.value === '[]') ? (null) : ([JSON.parse(input.value)]));
|
||||
|
||||
if (!isMultiple) {
|
||||
if (input.value === '[]'){
|
||||
input.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
const app = createApp({
|
||||
template: '<pick-entity ' +
|
||||
':multiple="multiple" ' +
|
||||
|
@ -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,
|
||||
|
@ -6,7 +6,6 @@
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="floor"
|
||||
maxlength=16
|
||||
:placeholder="$t('floor')"
|
||||
v-model="floor"/>
|
||||
<label for="floor">{{ $t('floor') }}</label>
|
||||
@ -15,7 +14,6 @@
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="corridor"
|
||||
maxlength=16
|
||||
:placeholder="$t('corridor')"
|
||||
v-model="corridor"/>
|
||||
<label for="corridor">{{ $t('corridor') }}</label>
|
||||
@ -24,7 +22,6 @@
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="steps"
|
||||
maxlength=16
|
||||
:placeholder="$t('steps')"
|
||||
v-model="steps"/>
|
||||
<label for="steps">{{ $t('steps') }}</label>
|
||||
@ -33,7 +30,6 @@
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="flat"
|
||||
maxlength=16
|
||||
:placeholder="$t('flat')"
|
||||
v-model="flat"/>
|
||||
<label for="flat">{{ $t('flat') }}</label>
|
||||
|
@ -17,12 +17,22 @@
|
||||
<div class="row my-3">
|
||||
<div class="col-lg-6">
|
||||
|
||||
<div class="form-check">
|
||||
<input type="checkbox"
|
||||
class="form-check-input"
|
||||
id="isConfidential"
|
||||
v-model="isConfidential"
|
||||
:value="valueConfidential" />
|
||||
<label class="form-check-label" for="isConfidential">
|
||||
{{ $t('isConfidential') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input type="checkbox"
|
||||
class="form-check-input"
|
||||
id="isNoAddress"
|
||||
v-model="isNoAddress"
|
||||
v-bind:value="value" />
|
||||
:value="value" />
|
||||
<label class="form-check-label" for="isNoAddress">
|
||||
{{ $t('isNoAddress') }}
|
||||
</label>
|
||||
@ -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);
|
||||
|
@ -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',
|
||||
|
@ -24,6 +24,11 @@
|
||||
{{ $t('user')}}
|
||||
</span>
|
||||
|
||||
<span v-if="entity.type === 'household'" class="badge rounded-pill bg-user">
|
||||
{{ $t('household')}}
|
||||
</span>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -40,7 +45,8 @@ export default {
|
||||
company: "Personne morale",
|
||||
contact: "Personne physique",
|
||||
},
|
||||
user: 'TMS'
|
||||
user: 'TMS',
|
||||
household: 'Ménage',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,26 @@
|
||||
<template>
|
||||
<div class="confidential" v-on:click="toggleBlur">
|
||||
<div class="confidential-content blur">
|
||||
<div :class="classes">
|
||||
<div class="confidential-content" :class="{ 'blur': isBlurred }">
|
||||
<slot name="confidential-content"></slot>
|
||||
</div>
|
||||
<i class="fa fa-eye toggle" aria-hidden="true"></i>
|
||||
<div>
|
||||
<i class="fa fa-eye toggle" aria-hidden="true" @click="toggleBlur"></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Confidential",
|
||||
data() {
|
||||
return {
|
||||
isBlurred: true,
|
||||
};
|
||||
},
|
||||
methods : {
|
||||
toggleBlur: function(e){
|
||||
if(e.target.matches('.toggle')){
|
||||
e.target.previousElementSibling.classList.toggle("blur");
|
||||
e.target.classList.toggle("fa-eye");
|
||||
e.target.classList.toggle("fa-eye-slash");
|
||||
}
|
||||
toggleBlur() {
|
||||
console.log('toggle blur');
|
||||
this.isBlurred = !this.isBlurred;
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -39,4 +43,4 @@ export default {
|
||||
-moz-filter: blur(5px);
|
||||
filter: blur(5px);
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,26 +1,58 @@
|
||||
<template>
|
||||
|
||||
<component :is="component" class="chill-entity entity-address my-3">
|
||||
|
||||
<component :is="component" class="address" :class="multiline">
|
||||
<div v-if="isMultiline === true">
|
||||
<p v-for="(l, i) in address.lines" :key="`line-${i}`">
|
||||
{{ l }}
|
||||
</p>
|
||||
|
||||
<div v-if="isConfidential">
|
||||
<confidential>
|
||||
<template v-slot:confidential-content>
|
||||
<div v-if="isMultiline === true">
|
||||
<p v-for="(l, i) in address.lines" :key="`line-${i}`">
|
||||
{{ l }}
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p v-if="address.text"
|
||||
class="street">
|
||||
{{ address.text }}
|
||||
</p>
|
||||
<p v-if="address.postcode"
|
||||
class="postcode">
|
||||
{{ address.postcode.code }} {{ address.postcode.name }}
|
||||
</p>
|
||||
<p v-if="address.country"
|
||||
class="country">
|
||||
{{ address.country.name.fr }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</confidential>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p v-if="address.text"
|
||||
class="street">
|
||||
{{ address.text }}
|
||||
</p>
|
||||
<p v-if="address.postcode"
|
||||
class="postcode">
|
||||
{{ address.postcode.code }} {{ address.postcode.name }}
|
||||
</p>
|
||||
<p v-if="address.country"
|
||||
class="country">
|
||||
{{ address.country.name.fr }}
|
||||
</p>
|
||||
|
||||
<div v-if="!isConfidential">
|
||||
<div v-if="isMultiline === true">
|
||||
<p v-for="(l, i) in address.lines" :key="`line-${i}`">
|
||||
{{ l }}
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p v-if="address.text"
|
||||
class="street">
|
||||
{{ address.text }}
|
||||
</p>
|
||||
<p v-if="address.postcode"
|
||||
class="postcode">
|
||||
{{ address.postcode.code }} {{ address.postcode.name }}
|
||||
</p>
|
||||
<p v-if="address.country"
|
||||
class="country">
|
||||
{{ address.country.name.fr }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</component>
|
||||
|
||||
<!-- <div v-if="isMultiline === true" class="address-more">
|
||||
@ -78,8 +110,14 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||
|
||||
export default {
|
||||
name: 'AddressRenderBox',
|
||||
components: {
|
||||
Confidential
|
||||
},
|
||||
props: {
|
||||
address: {
|
||||
type: Object
|
||||
@ -100,6 +138,9 @@ export default {
|
||||
multiline() {
|
||||
//console.log(this.isMultiline, typeof this.isMultiline);
|
||||
return this.isMultiline === true ? "multiline" : "";
|
||||
},
|
||||
isConfidential() {
|
||||
return this.address.confidential;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -61,14 +61,15 @@ const messages = {
|
||||
woman: "Née le"
|
||||
},
|
||||
deathdate: "Date de décès",
|
||||
years_old: "ans",
|
||||
household_without_address: "Le ménage de l'usager est sans adresse",
|
||||
no_data: "Aucune information renseignée",
|
||||
type: {
|
||||
thirdparty: "Tiers",
|
||||
person: "Usager"
|
||||
},
|
||||
holder: "Titulaire"
|
||||
holder: "Titulaire",
|
||||
years_old: "an | {n} an | {n} ans",
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -59,7 +59,7 @@
|
||||
must be shown in such list
|
||||
#}
|
||||
{%- if render == 'list' -%}
|
||||
<li class="chill-entity entity-address">
|
||||
<li class="chill-entity entity-address {% if address.confidential %}confidential{% endif %}">
|
||||
{% if options['with_picto'] %}
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
{% endif %}
|
||||
@ -68,7 +68,7 @@
|
||||
{%- endif -%}
|
||||
|
||||
{%- if render == 'inline' -%}
|
||||
<span class="chill-entity entity-address">
|
||||
<span class="chill-entity entity-address {% if address.confidential %}confidential{% endif %}">
|
||||
{% if options['with_picto'] %}
|
||||
<i class="fa fa-fw fa-map-marker"></i>
|
||||
{% endif %}
|
||||
@ -77,7 +77,7 @@
|
||||
{%- endif -%}
|
||||
|
||||
{%- if render == 'bloc' -%}
|
||||
<div class="chill-entity entity-address">
|
||||
<div class="chill-entity entity-address {% if address.confidential %}confidential{% endif %}">
|
||||
{% if options['has_no_address'] == true and address.isNoAddress == true %}
|
||||
{% if address.postCode is not empty %}
|
||||
<div class="address{% if options['multiline'] %} multiline{% endif %}{% if options['with_delimiter'] %} delimiter{% endif %}">
|
||||
|
@ -42,6 +42,3 @@
|
||||
{% endif %}
|
||||
|
||||
></span>
|
||||
|
||||
{{ encore_entry_script_tags('vue_onthefly') }}
|
||||
{{ encore_entry_link_tags('vue_onthefly') }}
|
||||
|
@ -13,6 +13,7 @@
|
||||
{{ encore_entry_link_tags('mod_ckeditor5') }}
|
||||
{{ encore_entry_link_tags('chill') }}
|
||||
{{ encore_entry_link_tags('mod_blur') }}
|
||||
{{ encore_entry_link_tags('vue_onthefly') }}
|
||||
{% block css %}<!-- nothing added to css -->{% endblock %}
|
||||
</head>
|
||||
|
||||
@ -94,6 +95,7 @@
|
||||
{{ encore_entry_script_tags('mod_ckeditor5') }}
|
||||
{{ encore_entry_script_tags('mod_blur') }}
|
||||
{{ encore_entry_script_tags('chill') }}
|
||||
{{ encore_entry_script_tags('vue_onthefly') }}
|
||||
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('DOMContentLoaded', function(e) {
|
||||
|
@ -45,13 +45,15 @@ class SearchUserApiProvider implements SearchApiInterface
|
||||
$query
|
||||
->setSelectKey('user')
|
||||
->setSelectJsonbMetadata("jsonb_build_object('id', u.id)")
|
||||
->setSelectPertinence('GREATEST(SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical),
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.emailcanonical))', [$pattern, $pattern])
|
||||
->setSelectPertinence('GREATEST(SIMILARITY(LOWER(UNACCENT(?)), u.label),
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical))', [$pattern, $pattern])
|
||||
->setFromClause('users AS u')
|
||||
->setWhereClauses('SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical) > 0.15
|
||||
OR
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.emailcanonical) > 0.15
|
||||
', [$pattern, $pattern]);
|
||||
->setWhereClauses('
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical) > 0.15
|
||||
OR u.usernamecanonical LIKE \'%\' || LOWER(UNACCENT(?)) || \'%\'
|
||||
OR SIMILARITY(LOWER(UNACCENT(?)), LOWER(UNACCENT(u.label))) > 0.15
|
||||
OR u.label LIKE \'%\' || LOWER(UNACCENT(?)) || \'%\'
|
||||
', [$pattern, $pattern, $pattern, $pattern]);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
@ -22,6 +22,10 @@ class SearchApiQuery
|
||||
|
||||
private array $fromClauseParams = [];
|
||||
|
||||
private bool $isDistinct = false;
|
||||
|
||||
private ?string $isDistinctKey = null;
|
||||
|
||||
private ?string $jsonbMetadata = null;
|
||||
|
||||
private array $jsonbMetadataParams = [];
|
||||
@ -105,6 +109,11 @@ class SearchApiQuery
|
||||
]);
|
||||
}
|
||||
|
||||
public function getDistinct(): bool
|
||||
{
|
||||
return $this->isDistinct;
|
||||
}
|
||||
|
||||
public function getFromClause(): string
|
||||
{
|
||||
return $this->fromClause;
|
||||
@ -139,6 +148,14 @@ class SearchApiQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDistinct(bool $distinct, string $distinctKey): self
|
||||
{
|
||||
$this->isDistinct = $distinct;
|
||||
$this->isDistinctKey = $distinctKey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFromClause(string $fromClause, array $params = []): self
|
||||
{
|
||||
$this->fromClause = $fromClause;
|
||||
@ -185,7 +202,11 @@ class SearchApiQuery
|
||||
private function buildSelectClause(bool $countOnly = false): string
|
||||
{
|
||||
if ($countOnly) {
|
||||
return 'count(*) AS c';
|
||||
if (!$this->isDistinct) {
|
||||
return 'count(*) AS c';
|
||||
}
|
||||
|
||||
return 'count(distinct ' . $this->isDistinctKey . ') AS c';
|
||||
}
|
||||
|
||||
$selects = $this->getSelectClauses();
|
||||
@ -202,7 +223,7 @@ class SearchApiQuery
|
||||
$selects[] = strtr('{pertinence} AS pertinence', ['{pertinence}' => $this->pertinence]);
|
||||
}
|
||||
|
||||
return implode(', ', $selects);
|
||||
return ($this->isDistinct ? 'DISTINCT ' : '') . implode(', ', $selects);
|
||||
}
|
||||
|
||||
private function buildSelectParams(bool $count = false): array
|
||||
|
@ -45,6 +45,7 @@ class AddressNormalizer implements ContextAwareNormalizerInterface, NormalizerAw
|
||||
'extra',
|
||||
'validFrom' => DateTimeInterface::class,
|
||||
'validTo' => DateTimeInterface::class,
|
||||
'confidential',
|
||||
];
|
||||
|
||||
private AddressRender $addressRender;
|
||||
@ -83,6 +84,7 @@ class AddressNormalizer implements ContextAwareNormalizerInterface, NormalizerAw
|
||||
'buildingName' => $address->getBuildingName(),
|
||||
'distribution' => $address->getDistribution(),
|
||||
'extra' => $address->getExtra(),
|
||||
'confidential' => $address->getConfidential(),
|
||||
'lines' => $this->addressRender->renderLines($address),
|
||||
];
|
||||
|
||||
|
@ -55,7 +55,7 @@ class CommentEmbeddableDocGenNormalizer implements ContextAwareNormalizerInterfa
|
||||
$user = $this->userRepository->find($object->getUserId());
|
||||
|
||||
return [
|
||||
'comment' => (string) $object->getComment(),
|
||||
'comment' => $object->getComment(),
|
||||
'isNull' => false,
|
||||
'date' => $this->normalizer->normalize($object->getDate(), $format, array_merge($context, [
|
||||
'docgen:expects' => DateTime::class,
|
||||
|
@ -44,7 +44,9 @@ use function count;
|
||||
final class ExportManagerTest extends KernelTestCase
|
||||
{
|
||||
use PrepareCenterTrait;
|
||||
|
||||
use PrepareScopeTrait;
|
||||
|
||||
use PrepareUserTrait;
|
||||
|
||||
private Prophet $prophet;
|
||||
|
@ -34,8 +34,11 @@ use function in_array;
|
||||
final class AuthorizationHelperTest extends KernelTestCase
|
||||
{
|
||||
use PrepareCenterTrait;
|
||||
|
||||
use PrepareScopeTrait;
|
||||
|
||||
use PrepareUserTrait;
|
||||
|
||||
use ProphecyTrait;
|
||||
|
||||
protected function setUp(): void
|
||||
|
@ -134,6 +134,7 @@ paths:
|
||||
- search
|
||||
- person
|
||||
- thirdparty
|
||||
- household
|
||||
description: >
|
||||
The search is performed across multiple entities. The entities must be listed into
|
||||
`type` parameters.
|
||||
@ -159,6 +160,7 @@ paths:
|
||||
- person
|
||||
- thirdparty
|
||||
- user
|
||||
- household
|
||||
responses:
|
||||
200:
|
||||
description: "OK"
|
||||
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Main;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Alter some address fields + add confidential field on Address.
|
||||
*/
|
||||
final class Version20220124085957 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_main_address DROP confidential');
|
||||
$this->addSql('ALTER TABLE chill_main_address ALTER corridor TYPE VARCHAR(16)');
|
||||
$this->addSql('ALTER TABLE chill_main_address ALTER flat TYPE VARCHAR(16)');
|
||||
$this->addSql('ALTER TABLE chill_main_address ALTER floor TYPE VARCHAR(16)');
|
||||
$this->addSql('ALTER TABLE chill_main_address ALTER steps TYPE VARCHAR(16)');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Alter some address fields + add confidential field on Address';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_main_address ADD confidential BOOLEAN DEFAULT FALSE');
|
||||
$this->addSql('ALTER TABLE chill_main_address ALTER floor TYPE TEXT');
|
||||
$this->addSql('ALTER TABLE chill_main_address ALTER corridor TYPE TEXT');
|
||||
$this->addSql('ALTER TABLE chill_main_address ALTER steps TYPE TEXT');
|
||||
$this->addSql('ALTER TABLE chill_main_address ALTER flat TYPE TEXT');
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Main;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Create a new entity ResidentialAddress.
|
||||
*/
|
||||
final class Version20220125134253 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP SEQUENCE chill_main_residential_address_id_seq CASCADE');
|
||||
$this->addSql('DROP TABLE chill_main_residential_address');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Create a new entity ResidentialAddress';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE SEQUENCE chill_main_residential_address_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE TABLE chill_main_residential_address (id INT NOT NULL, person_id INT NOT NULL, address_id INT DEFAULT NULL, startDate TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, endDate TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, residentialAddressComment_comment TEXT DEFAULT NULL, residentialAddressComment_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, residentialAddressComment_userId INT DEFAULT NULL, hostPerson_id INT DEFAULT NULL, hostThirdParty_id INT DEFAULT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE INDEX IDX_9BC1FD50217BBB47 ON chill_main_residential_address (person_id)');
|
||||
$this->addSql('CREATE INDEX IDX_9BC1FD50DCA38092 ON chill_main_residential_address (hostPerson_id)');
|
||||
$this->addSql('CREATE INDEX IDX_9BC1FD508DFC48DC ON chill_main_residential_address (hostThirdParty_id)');
|
||||
$this->addSql('CREATE INDEX IDX_9BC1FD50F5B7AF75 ON chill_main_residential_address (address_id)');
|
||||
$this->addSql('COMMENT ON COLUMN chill_main_residential_address.startDate IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('COMMENT ON COLUMN chill_main_residential_address.endDate IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('ALTER TABLE chill_main_residential_address ADD CONSTRAINT FK_9BC1FD50217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE chill_main_residential_address ADD CONSTRAINT FK_9BC1FD50DCA38092 FOREIGN KEY (hostPerson_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE chill_main_residential_address ADD CONSTRAINT FK_9BC1FD508DFC48DC FOREIGN KEY (hostThirdParty_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE chill_main_residential_address ADD CONSTRAINT FK_9BC1FD50F5B7AF75 FOREIGN KEY (address_id) REFERENCES chill_main_address (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
}
|
||||
}
|
@ -52,6 +52,8 @@ Since %date%: Depuis le %date%
|
||||
since %date%: depuis le %date%
|
||||
Until %date%: Jusqu'au %date%
|
||||
until %date%: jusqu'au %date%
|
||||
Since: Depuis le
|
||||
Until: Jusqu'au
|
||||
#elements used in software
|
||||
centers: centres
|
||||
Centers: Centres
|
||||
|
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\Entity\ResidentialAddress;
|
||||
use Chill\MainBundle\Form\Type\ResidentialAddressType;
|
||||
use Chill\MainBundle\Repository\ResidentialAddressRepository;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
final class ResidentialAddressController extends AbstractController
|
||||
{
|
||||
private UrlGeneratorInterface $generator;
|
||||
|
||||
private ResidentialAddressRepository $residentialAddressRepository;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(
|
||||
UrlGeneratorInterface $generator,
|
||||
TranslatorInterface $translator,
|
||||
ResidentialAddressRepository $residentialAddressRepository
|
||||
) {
|
||||
$this->generator = $generator;
|
||||
$this->translator = $translator;
|
||||
$this->residentialAddressRepository = $residentialAddressRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/person/residential-address/{id}/delete", name="chill_person_residential_address_delete")
|
||||
*/
|
||||
public function deleteAction(Request $request, ResidentialAddress $residentialAddress): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(PersonVoter::UPDATE, $residentialAddress->getPerson());
|
||||
|
||||
$form = $this->createForm(FormType::class);
|
||||
$form->add('submit', SubmitType::class, ['label' => 'Delete']);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$em->remove($residentialAddress);
|
||||
$em->flush();
|
||||
|
||||
$this->addFlash('success', $this->translator->trans('Residential address had been deleted'));
|
||||
|
||||
return $this->redirectToRoute('chill_person_residential_address_list', ['id' => $residentialAddress->getPerson()->getId()]);
|
||||
}
|
||||
|
||||
return $this->render('@ChillPerson/ResidentialAddress/delete.html.twig', [
|
||||
'person' => $residentialAddress->getPerson(),
|
||||
'residentialAddress' => $residentialAddress,
|
||||
'delete_form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/person/residential-address/{id}/edit", name="chill_person_residential_address_edit")
|
||||
*/
|
||||
public function editAction(Request $request, ResidentialAddress $residentialAddress): Response
|
||||
{
|
||||
if ($request->query->has('kind')) {
|
||||
$kind = $request->query->getAlpha('kind', '');
|
||||
} else {
|
||||
$kind = null;
|
||||
}
|
||||
|
||||
$person = $residentialAddress->getPerson();
|
||||
$this->denyAccessUnlessGranted(PersonVoter::UPDATE, $person);
|
||||
|
||||
$form = $this->createForm(ResidentialAddressType::class, $residentialAddress, ['kind' => $kind]);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->getDoctrine()->getManager()->flush();
|
||||
|
||||
$this->addFlash('success', $this->translator
|
||||
->trans('The residential address was updated successfully'));
|
||||
|
||||
return $this->redirect(
|
||||
$request->get('returnPath', null) ??
|
||||
$this->generator->generate('chill_person_residential_address_list', ['id' => $person->getId()])
|
||||
);
|
||||
}
|
||||
|
||||
return $this->render('@ChillPerson/ResidentialAddress/edit.html.twig', [
|
||||
'residentialAddress' => $residentialAddress,
|
||||
'person' => $person,
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/person/{id}/residential-address/list", name="chill_person_residential_address_list")
|
||||
*/
|
||||
public function listAction(Request $request, Person $person): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person);
|
||||
|
||||
$residentialAddresses = $this->residentialAddressRepository->findBy(['person' => $person], ['startDate' => 'DESC']);
|
||||
|
||||
return $this->render('@ChillPerson/ResidentialAddress/list.html.twig', [
|
||||
'person' => $person,
|
||||
'addresses' => $residentialAddresses,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/person/{id}/residential-address/new", name="chill_person_residential_address_new")
|
||||
*/
|
||||
public function newAction(Request $request, Person $person): Response
|
||||
{
|
||||
$residentialAddress = new ResidentialAddress();
|
||||
$residentialAddress->setPerson($person);
|
||||
|
||||
$this->denyAccessUnlessGranted(PersonVoter::UPDATE, $person);
|
||||
|
||||
if (!$request->query->has('kind')) {
|
||||
return $this->render('@ChillPerson/ResidentialAddress/new_pick_kind.html.twig', ['person' => $person]);
|
||||
}
|
||||
$kind = $request->query->getAlpha('kind', '');
|
||||
|
||||
$form = $this->createForm(ResidentialAddressType::class, $residentialAddress, ['kind' => $kind]);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->getDoctrine()->getManager()->persist($residentialAddress);
|
||||
$this->getDoctrine()->getManager()->flush();
|
||||
|
||||
$this->addFlash('success', $this->translator
|
||||
->trans('The new residential address was created successfully'));
|
||||
|
||||
return $this->redirect(
|
||||
$request->get('returnPath', null) ??
|
||||
$this->generator->generate('chill_person_residential_address_list', ['id' => $residentialAddress->getPerson()->getId()])
|
||||
);
|
||||
}
|
||||
|
||||
return $this->render('@ChillPerson/ResidentialAddress/new.html.twig', [
|
||||
'person' => $person,
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class UserAccompanyingPeriodController extends AbstractController
|
||||
{
|
||||
private AccompanyingPeriodRepository $accompanyingPeriodRepository;
|
||||
|
||||
private PaginatorFactory $paginatorFactory;
|
||||
|
||||
public function __construct(AccompanyingPeriodRepository $accompanyingPeriodRepository, PaginatorFactory $paginatorFactory)
|
||||
{
|
||||
$this->accompanyingPeriodRepository = $accompanyingPeriodRepository;
|
||||
$this->paginatorFactory = $paginatorFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/accompanying-periods", name="chill_person_accompanying_period_user")
|
||||
*/
|
||||
public function listAction(Request $request)
|
||||
{
|
||||
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser()]);
|
||||
$pagination = $this->paginatorFactory->create($total);
|
||||
$accompanyingPeriods = $this->accompanyingPeriodRepository->findBy(
|
||||
['user' => $this->getUser()],
|
||||
['openingDate' => 'DESC'],
|
||||
$pagination->getItemsPerPage(),
|
||||
$pagination->getCurrentPageFirstItemNumber()
|
||||
);
|
||||
|
||||
return $this->render('@ChillPerson/AccompanyingPeriod/user_periods_list.html.twig', [
|
||||
'accompanyingPeriods' => $accompanyingPeriods,
|
||||
'pagination' => $pagination,
|
||||
]);
|
||||
}
|
||||
}
|
@ -212,6 +212,8 @@ class AccompanyingPeriod implements
|
||||
*
|
||||
* @ORM\Column(type="date")
|
||||
* @Groups({"read", "write", "docgen:read"})
|
||||
* @Assert\LessThan(value= "today", groups={AccompanyingPeriod::STEP_CONFIRMED})
|
||||
* @Assert\LessThan(propertyPath="closingDate", groups={AccompanyingPeriod::STEP_CONFIRMED})
|
||||
*/
|
||||
private ?DateTime $openingDate = null;
|
||||
|
||||
|
@ -33,6 +33,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
class HouseholdComposition implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
/**
|
||||
|
@ -784,12 +784,18 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* If the `$at` parameter is now, use the method `getCurrentPersonAddress`, which is optimized
|
||||
* on database side.
|
||||
*
|
||||
* @deprecated since chill2.0, address is linked to the household. Use @see{Person::getCurrentHouseholdAddress}
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getAddressAt(?DateTime $at = null): ?Address
|
||||
public function getAddressAt(?DateTimeInterface $at = null): ?Address
|
||||
{
|
||||
$at ??= new DateTime('now');
|
||||
|
||||
if ($at instanceof DateTimeImmutable) {
|
||||
$at = DateTime::createFromImmutable($at);
|
||||
}
|
||||
|
||||
/** @var ArrayIterator $addressesIterator */
|
||||
$addressesIterator = $this->getAddresses()
|
||||
->filter(static fn (Address $address): bool => $address->getValidFrom() <= $at)
|
||||
@ -950,6 +956,12 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the household address at the given date.
|
||||
*
|
||||
* if the given date is 'now', use instead @see{getCurrentPersonAddress}, which is optimized on
|
||||
* database side.
|
||||
*/
|
||||
public function getCurrentHouseholdAddress(?DateTimeImmutable $at = null): ?Address
|
||||
{
|
||||
if (
|
||||
|
@ -34,6 +34,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
/**
|
||||
|
@ -62,6 +62,16 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
||||
'order' => 50,
|
||||
]);
|
||||
|
||||
$menu->addChild($this->translator->trans('Residential addresses'), [
|
||||
'route' => 'chill_person_residential_address_list',
|
||||
'routeParameters' => [
|
||||
'id' => $parameters['person']->getId(),
|
||||
],
|
||||
])
|
||||
->setExtras([
|
||||
'order' => 60,
|
||||
]);
|
||||
|
||||
$menu->addChild($this->translator->trans('household.person history'), [
|
||||
'route' => 'chill_person_household_person_history',
|
||||
'routeParameters' => [
|
||||
|
54
src/Bundle/ChillPersonBundle/Menu/UserMenuBuilder.php
Normal file
54
src/Bundle/ChillPersonBundle/Menu/UserMenuBuilder.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Menu;
|
||||
|
||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||
use Knp\Menu\MenuItem;
|
||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class UserMenuBuilder implements LocalMenuBuilderInterface
|
||||
{
|
||||
/**
|
||||
* @var AuthorizationCheckerInterface
|
||||
*/
|
||||
public $authorizationChecker;
|
||||
|
||||
/**
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
public $translator;
|
||||
|
||||
public function __construct(
|
||||
AuthorizationCheckerInterface $authorizationChecker
|
||||
) {
|
||||
$this->authorizationChecker = $authorizationChecker;
|
||||
}
|
||||
|
||||
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
||||
{
|
||||
if ($this->authorizationChecker->isGranted('ROLE_USER')) {
|
||||
$menu->addChild('My accompanying periods', [
|
||||
'route' => 'chill_person_accompanying_period_user',
|
||||
])
|
||||
->setExtras([
|
||||
'order' => 20,
|
||||
'icon' => 'tasks',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getMenuIds(): array
|
||||
{
|
||||
return ['user'];
|
||||
}
|
||||
}
|
@ -26,6 +26,11 @@ final class AccompanyingPeriodRepository implements ObjectRepository
|
||||
$this->repository = $entityManager->getRepository(AccompanyingPeriod::class);
|
||||
}
|
||||
|
||||
public function countBy(array $criteria): int
|
||||
{
|
||||
return $this->repository->count($criteria);
|
||||
}
|
||||
|
||||
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder
|
||||
{
|
||||
return $this->repository->createQueryBuilder($alias, $indexBy);
|
||||
|
@ -14,6 +14,7 @@
|
||||
<scopes></scopes>
|
||||
<referrer></referrer>
|
||||
<resources></resources>
|
||||
<start-date v-if="accompanyingCourse.step === 'CONFIRMED'"></start-date>
|
||||
<comment v-if="accompanyingCourse.step === 'DRAFT'"></comment>
|
||||
<confirm v-if="accompanyingCourse.step === 'DRAFT'"></confirm>
|
||||
|
||||
@ -39,6 +40,7 @@ import Referrer from './components/Referrer.vue';
|
||||
import Resources from './components/Resources.vue';
|
||||
import Comment from './components/Comment.vue';
|
||||
import Confirm from './components/Confirm.vue';
|
||||
import StartDate from './components/StartDate.vue';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
@ -56,6 +58,7 @@ export default {
|
||||
Resources,
|
||||
Comment,
|
||||
Confirm,
|
||||
StartDate
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
|
@ -4,7 +4,7 @@
|
||||
<i class="fa fa-home fa-fw text-light" :title="$t('persons_associated.show_household_number', { id: h.id })"></i>
|
||||
</a>
|
||||
<span v-for="person in h.persons" class="me-1" :key="person.id">
|
||||
<on-the-fly :type="person.type" :id="person.id" :buttonText="person.text" :displayBadge="'true' === 'true'" action="show"></on-the-fly>
|
||||
<on-the-fly :type="person.type" :id="person.id" :buttonText="person.textAge" :displayBadge="'true' === 'true'" action="show"></on-the-fly>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
@ -27,7 +27,7 @@
|
||||
:value="p.person.id"
|
||||
/>
|
||||
<label class="form-check-label">
|
||||
{{ p.person.text }}
|
||||
<person-text :person="p.person"></person-text>
|
||||
</label>
|
||||
</div>
|
||||
<input type="hidden" name="expand_suggestions" value="true">
|
||||
@ -50,9 +50,9 @@
|
||||
<div v-if="suggestedPersons.length > 0">
|
||||
<ul class="list-suggest add-items inline">
|
||||
<li v-for="p in suggestedPersons" :key="p.id" @click="addSuggestedPerson(p)">
|
||||
<span>{{ p.text }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<person-text :person="p"></person-text>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@ -76,12 +76,14 @@
|
||||
import {mapGetters, mapState} from 'vuex';
|
||||
import ParticipationItem from "./PersonsAssociated/ParticipationItem.vue";
|
||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
export default {
|
||||
name: 'PersonsAssociated',
|
||||
components: {
|
||||
ParticipationItem,
|
||||
AddPersons
|
||||
AddPersons,
|
||||
PersonText
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -110,15 +112,15 @@ export default {
|
||||
)
|
||||
// filter persons appearing twice in requestor and resources
|
||||
.filter(
|
||||
(e, index, suggested) => {
|
||||
(e, index, suggested) => {
|
||||
for (let i = 0; i < suggested.length; i = i+1) {
|
||||
if (i < index && e.id === suggested[i].id) {
|
||||
return false
|
||||
}
|
||||
if (i < index && e.id === suggested[i].id) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
)
|
||||
}),
|
||||
...mapGetters([
|
||||
|
@ -45,7 +45,8 @@
|
||||
addInfo: true,
|
||||
hLevel: 3,
|
||||
isMultiline: true,
|
||||
isConfidential: false
|
||||
isConfidential: false,
|
||||
addAge: true,
|
||||
}"
|
||||
>
|
||||
<template v-slot:record-actions>
|
||||
@ -136,9 +137,10 @@
|
||||
<div v-if="accompanyingCourse.requestor === null && suggestedEntities.length > 0">
|
||||
<ul class="list-suggest add-items inline">
|
||||
<li v-for="p in suggestedEntities" :key="uniqueId(p)" @click="addSuggestedEntity(p)">
|
||||
<span>{{ p.text }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<person-text v-if="p.type === 'person'" :person="p"></person-text>
|
||||
<span v-else>{{ p.text }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@ -162,6 +164,8 @@ import PersonRenderBox from '../../_components/Entity/PersonRenderBox.vue';
|
||||
import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue';
|
||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||
import { mapState } from 'vuex';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
|
||||
export default {
|
||||
name: 'Requestor',
|
||||
@ -170,7 +174,8 @@ export default {
|
||||
OnTheFly,
|
||||
PersonRenderBox,
|
||||
ThirdPartyRenderBox,
|
||||
Confidential
|
||||
Confidential,
|
||||
PersonText
|
||||
},
|
||||
props: ['isAnonymous'],
|
||||
data() {
|
||||
|
@ -22,7 +22,8 @@
|
||||
<div v-if="suggestedEntities.length > 0">
|
||||
<ul class="list-suggest add-items inline">
|
||||
<li v-for="p in suggestedEntities" :key="uniqueId(p)" @click="addSuggestedEntity(p)">
|
||||
<span>{{ p.text }}</span>
|
||||
<person-text v-if="p.type === 'person'" :person="p"></person-text>
|
||||
<span v-else>{{ p.text }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -45,12 +46,15 @@
|
||||
import { mapState } from 'vuex';
|
||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||
import ResourceItem from './Resources/ResourceItem.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
|
||||
export default {
|
||||
name: 'Resources',
|
||||
components: {
|
||||
AddPersons,
|
||||
ResourceItem
|
||||
ResourceItem,
|
||||
PersonText
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="vue-component">
|
||||
<h2><a id="section-110"></a>
|
||||
{{ $t('startdate.change') }}
|
||||
</h2>
|
||||
<div>
|
||||
<div class="mb-3 row">
|
||||
<label class="col-form-label col-sm-4">{{ $t('startdate.date') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="date" v-model="startDate" @change="updateStartDate" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { datetimeToISO, dateToISO, ISOToDate, ISOToDatetime} from 'ChillMainAssets/chill/js/date.js';
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'startDate',
|
||||
methods: {
|
||||
updateStartDate(event) {
|
||||
const date = event.target.value;
|
||||
// console.log(date)
|
||||
this.$store.dispatch('updateStartDate', date)
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: 'An error occurred'})
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
startDate: state => dateToISO(ISOToDatetime(state.accompanyingCourse.openingDate.datetime))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
@ -151,6 +151,10 @@ const appMessages = {
|
||||
placeholder: "Choisir un métier",
|
||||
not_valid: "Sélectionnez un métier du référent"
|
||||
},
|
||||
startdate: {
|
||||
change: "Modifier la date de début",
|
||||
date: "Date de début",
|
||||
},
|
||||
// catch errors
|
||||
'Error while updating AccompanyingPeriod Course.': "Erreur du serveur lors de la mise à jour du parcours d'accompagnement.",
|
||||
'Error while retriving AccompanyingPeriod Course.': "Erreur du serveur lors du chargement du parcours d'accompagnement.",
|
||||
|
@ -8,6 +8,7 @@ import { getAccompanyingCourse,
|
||||
import { patchPerson } from "ChillPersonAssets/vuejs/_api/OnTheFly";
|
||||
import { patchThirdparty } from "ChillThirdPartyAssets/vuejs/_api/OnTheFly";
|
||||
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
|
||||
import { datetimeToISO, ISOToDate, ISOToDatetime } from 'ChillMainAssets/chill/js/date.js';
|
||||
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production';
|
||||
@ -278,6 +279,10 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
|
||||
if (scopeIds.includes(scope.id)) {
|
||||
state.scopesAtBackend = state.scopesAtBackend.filter(s => s.id !== scope.id);
|
||||
}
|
||||
},
|
||||
updateStartDate(state, date) {
|
||||
console.log('new state date', date)
|
||||
state.accompanyingCourse.openingDate = date;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@ -701,15 +706,30 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
updateStartDate({commit}, payload) {
|
||||
console.log('payload', payload)
|
||||
const date = ISOToDate(payload);
|
||||
const url = `/api/1.0/person/accompanying-course/${id}.json`;
|
||||
const body = { type: "accompanying_period", openingDate: { datetime: datetimeToISO(date) }};
|
||||
console.log('body', body)
|
||||
return makeFetch('PATCH', url, body)
|
||||
.then((response) => {
|
||||
commit('updateStartDate', response.openingDate);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
async fetchReferrersSuggested({ state, commit}) {
|
||||
let users = await getReferrersSuggested(state.accompanyingCourse);
|
||||
commit('setReferrersSuggested', users);
|
||||
commit('setFilteredReferrersSuggested');
|
||||
if (
|
||||
null === state.accompanyingCourse.user
|
||||
&& !state.accompanyingCourse.confidential
|
||||
&& !state.accompanyingCourse.step === 'DRAFT'
|
||||
&& users.length === 1
|
||||
null === state.accompanyingCourse.user
|
||||
&& !state.accompanyingCourse.confidential
|
||||
&& !state.accompanyingCourse.step === 'DRAFT'
|
||||
&& users.length === 1
|
||||
) {
|
||||
// set the user if unique
|
||||
commit('updateReferrer', users[0]);
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
<div id="awc_create_form">
|
||||
|
||||
<div id="picking">
|
||||
<div id="picking" class="">
|
||||
<p>{{ $t('pick_social_issue_linked_with_action') }}</p>
|
||||
<div v-for="si in socialIssues" :key="si.id">
|
||||
<input type="radio" v-bind:value="si.id" name="socialIssue" v-model="socialIssuePicked"><span class="badge bg-chill-l-gray text-dark">{{ si.text }}</span>
|
||||
@ -33,7 +33,7 @@
|
||||
</vue-multiselect>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="hasSocialIssuePicked">
|
||||
<div v-if="hasSocialIssuePicked" class="mb-3">
|
||||
<h2>{{ $t('pick_an_action') }}</h2>
|
||||
<div class="col-11">
|
||||
<vue-multiselect
|
||||
@ -52,26 +52,43 @@
|
||||
<i class="fa fa-circle-o-notch fa-spin fa-fw"></i>
|
||||
</div>
|
||||
|
||||
<div v-if="hasSocialActionPicked" id="persons">
|
||||
<div v-if="hasSocialActionPicked" id="persons" class="mb-5">
|
||||
<h2>{{ $t('persons_involved') }}</h2>
|
||||
|
||||
<ul>
|
||||
<li v-for="p in personsReachables" :key="p.id">
|
||||
<input type="checkbox" :value="p.id" v-model="personsPicked">
|
||||
<person-render-box render="badge" :options="{}" :person="p"></person-render-box>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" :value="p.id" v-model="personsPicked" class="form-check-input" :id="'person_check'+p.id">
|
||||
<label class="form-check-label" :for="'person_check' + p.id">
|
||||
<person-text :person="p"></person-text>
|
||||
</label>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-if="hasSocialActionPicked" id="start_date">
|
||||
<!-- <div v-if="hasSocialActionPicked" id="start_date">
|
||||
<p><label>{{ $t('startDate') }}</label> <input type="date" v-model="startDate" /></p>
|
||||
</div> -->
|
||||
<div class="row">
|
||||
<div v-if="hasSocialActionPicked" id="start_date" class="mb-3 row">
|
||||
<label class="col-form-label col-sm-4">{{ $t('startDate') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="date" v-model="startDate"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="hasSocialActionPicked" id="end_date">
|
||||
<!-- <div v-if="hasSocialActionPicked" id="end_date">
|
||||
<p><label>{{ $t('endDate') }}</label> <input type="date" v-model="endDate" /></p>
|
||||
</div> -->
|
||||
<div v-if="hasSocialActionPicked" id="end_date" class="mb-3 row">
|
||||
<label class="col-form-label col-sm-4">{{ $t('endDate') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="date" v-model="endDate"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="confirm">
|
||||
<div v-if="hasErrors">
|
||||
<p>{{ $t('form_has_errors') }}</p>
|
||||
@ -111,7 +128,7 @@
|
||||
import { mapState, mapActions, mapGetters } from 'vuex';
|
||||
import VueMultiselect from 'vue-multiselect';
|
||||
import { dateToISO, ISOToDate } from 'ChillMainAssets/chill/js/date.js';
|
||||
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
const i18n = {
|
||||
messages: {
|
||||
@ -133,7 +150,7 @@ export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
VueMultiselect,
|
||||
PersonRenderBox,
|
||||
PersonText,
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
|
@ -141,10 +141,12 @@
|
||||
|
||||
<ul class="list-unstyled">
|
||||
<li v-for="p in personsReachables" :key="p.id">
|
||||
<label :for="p.id">
|
||||
<input v-model="personsPicked" :value="p.id" :id="p.id" type="checkbox" class="me-2">
|
||||
{{ p.text }}
|
||||
<div class="form-check">
|
||||
<input v-model="personsPicked" :value="p.id" type="checkbox" class="me-2 form-check-input" :id="'person_check'+p.id">
|
||||
<label :for="'person_check'+p.id" class="form-check-label">
|
||||
<person-text :person="p"></person-text>
|
||||
</label>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -281,6 +283,7 @@ import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/
|
||||
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
||||
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
|
||||
import PickWorkflow from 'ChillMainAssets/vuejs/_components/EntityWorkflow/PickWorkflow.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
const i18n = {
|
||||
messages: {
|
||||
@ -329,7 +332,8 @@ export default {
|
||||
ThirdPartyRenderBox,
|
||||
PickTemplate,
|
||||
PickWorkflow,
|
||||
OnTheFly
|
||||
OnTheFly,
|
||||
PersonText,
|
||||
},
|
||||
i18n,
|
||||
data() {
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
<ul class="list-suggest remove-items inline">
|
||||
<li v-for="c in concerned" :key="c.person.id" @click="removeConcerned(c)">
|
||||
<span>{{ c.person.text }}</span>
|
||||
<span><person-text :person="c.person"></person-text></span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@ -57,12 +57,14 @@
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
export default {
|
||||
name: 'Concerned',
|
||||
components: {
|
||||
AddPersons,
|
||||
PersonRenderBox,
|
||||
PersonText,
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
|
@ -61,6 +61,16 @@
|
||||
<li v-if="hasHousehold">
|
||||
<button @click="resetMode" class="btn btn-sm btn-misc">{{ $t('household_members_editor.household.reset_mode')}}</button>
|
||||
</li>
|
||||
<li v-if="!hasHousehold">
|
||||
<add-persons
|
||||
modalTitle="Chercher un ménage existant"
|
||||
buttonTitle="Chercher un ménage existant"
|
||||
v-bind:key="addPersons.key"
|
||||
v-bind:options="addPersons.options"
|
||||
@addNewPersons="pickHouseholdFound"
|
||||
ref="pickHousehold"> <!-- to cast child method -->
|
||||
</add-persons>
|
||||
</li>
|
||||
<li v-if="!hasHousehold">
|
||||
<button @click="setModeNew" class="btn btn-sm btn-create">{{ $t('household_members_editor.household.create_household') }}</button>
|
||||
</li>
|
||||
@ -77,16 +87,30 @@
|
||||
import { mapGetters, mapState } from 'vuex';
|
||||
import HouseholdRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue';
|
||||
import CurrentHousehold from './CurrentHousehold';
|
||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons';
|
||||
|
||||
export default {
|
||||
name: 'Household',
|
||||
components: {
|
||||
AddPersons,
|
||||
CurrentHousehold,
|
||||
HouseholdRenderBox,
|
||||
},
|
||||
emits: ['readyToGo'],
|
||||
data() {
|
||||
return {
|
||||
addPersons: {
|
||||
key: 'household_find',
|
||||
options: {
|
||||
type: ['household'],
|
||||
priority: null,
|
||||
uniq: true,
|
||||
button: {
|
||||
size: 'btn-sm',
|
||||
type: 'btn-search',
|
||||
}
|
||||
}
|
||||
},
|
||||
addAddress: {
|
||||
key: 'household_new',
|
||||
options: {
|
||||
@ -166,6 +190,13 @@ export default {
|
||||
this.$store.dispatch('selectHousehold', h);
|
||||
this.$emit('readyToGo');
|
||||
},
|
||||
pickHouseholdFound({selected, modal}) {
|
||||
selected.forEach(function(item) {
|
||||
this.selectHousehold(item.result);
|
||||
}, this);
|
||||
this.$refs.pickHousehold.resetSearch(); // to cast child method
|
||||
modal.showModal = false;
|
||||
},
|
||||
removeHouseholdAddress() {
|
||||
this.$store.commit('removeHouseholdAddress');
|
||||
},
|
||||
|
@ -6,12 +6,13 @@
|
||||
<div class="list-household-members flex-table">
|
||||
<div
|
||||
v-for="conc in concerned"
|
||||
class="item-bloc"
|
||||
v-bind:key="conc.person.id"
|
||||
class="item-bloc"
|
||||
v-bind:key="conc.person.id"
|
||||
>
|
||||
<div class="pick-position item-row">
|
||||
<div class="person">
|
||||
<h3>{{ conc.person.text }}</h3>
|
||||
<!-- <h3>{{ conc.person.text }}</h3> -->
|
||||
<h3><person-text :person="conc.person"></person-text></h3>
|
||||
</div>
|
||||
<div class="holder">
|
||||
<button
|
||||
@ -53,6 +54,7 @@ import {mapGetters, mapState} from "vuex";
|
||||
import CurrentHousehold from "./CurrentHousehold";
|
||||
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
||||
import PersonComment from './PersonComment';
|
||||
import PersonText from '../../_components/Entity/PersonText.vue';
|
||||
|
||||
export default {
|
||||
name: "Positioning",
|
||||
@ -60,6 +62,7 @@ export default {
|
||||
CurrentHousehold,
|
||||
PersonRenderBox,
|
||||
PersonComment,
|
||||
PersonText
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
|
@ -0,0 +1,6 @@
|
||||
export const lightGreen = '#43b29d';
|
||||
export const darkGreen = '#368e7e';
|
||||
export const lightBrown = '#a2ac80';
|
||||
export const darkBrown = '#929d69';
|
||||
export const lightBlue = '#8d9dab';
|
||||
export const darkBlue = '#718596';
|
@ -2,6 +2,7 @@ import { createStore } from 'vuex'
|
||||
import { getHouseholdByPerson, getCoursesByPerson, getRelationshipsByPerson } from './api'
|
||||
import { getHouseholdLabel, getHouseholdWidth, getRelationshipLabel, getRelationshipTitle, getRelationshipDirection, splitId, getGender, getAge } from './vis-network'
|
||||
import {visMessages} from "./i18n";
|
||||
import { darkBlue, darkBrown, darkGreen, lightBlue, lightBrown, lightGreen } from './colors';
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production'
|
||||
|
||||
@ -172,8 +173,8 @@ const store = createStore({
|
||||
id: 'relationship_' + splitId(link.id,'id')
|
||||
+ '-person_' + link.fromPerson.id + '-person_' + link.toPerson.id,
|
||||
arrows: getRelationshipDirection(link),
|
||||
color: 'lightblue',
|
||||
font: { color: '#33839d' },
|
||||
color: lightGreen,
|
||||
font: { color: darkGreen },
|
||||
dashes: true,
|
||||
label: getRelationshipLabel(link),
|
||||
title: getRelationshipTitle(link),
|
||||
@ -316,10 +317,10 @@ const store = createStore({
|
||||
to: `${household.id}`,
|
||||
id: `${household.id}-person_${m.person.id}`,
|
||||
arrows: 'from',
|
||||
color: 'pink',
|
||||
font: { color: '#D04A60' },
|
||||
color: lightBrown,
|
||||
font: { color: darkBrown },
|
||||
dashes: (getHouseholdWidth(m) === 1)? [0,4] : false, //edge style: [dash, gap, dash, gap]
|
||||
label: getHouseholdLabel(m),
|
||||
//label: getHouseholdLabel(m),
|
||||
width: getHouseholdWidth(m),
|
||||
})
|
||||
if (!getters.isPersonLoaded(m.person.id)) {
|
||||
@ -375,8 +376,8 @@ const store = createStore({
|
||||
to: `${course.id}`,
|
||||
id: `accompanying_period_${splitId(course.id,'id')}-person_${p.person.id}`,
|
||||
arrows: 'from',
|
||||
color: 'orange',
|
||||
font: { color: 'darkorange' },
|
||||
color: lightBlue,
|
||||
font: { color: darkBlue },
|
||||
})
|
||||
if (!getters.isPersonLoaded(p.person.id)) {
|
||||
dispatch('addMissingPerson', [p.person, course])
|
||||
@ -428,8 +429,8 @@ const store = createStore({
|
||||
id: 'relationship_' + splitId(relationship.id,'id')
|
||||
+ '-person_' + relationship.fromPerson.id + '-person_' + relationship.toPerson.id,
|
||||
arrows: getRelationshipDirection(relationship),
|
||||
color: 'lightblue',
|
||||
font: { color: '#33839d' },
|
||||
color: lightGreen,
|
||||
font: { color: darkGreen },
|
||||
dashes: true,
|
||||
label: getRelationshipLabel(relationship),
|
||||
title: getRelationshipTitle(relationship),
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { visMessages } from './i18n'
|
||||
import { darkGreen, lightBlue, lightBrown, lightGreen } from './colors';
|
||||
import { visMessages } from './i18n';
|
||||
|
||||
/**
|
||||
* Vis-network initial data/configuration script
|
||||
@ -15,12 +16,12 @@ window.options = {
|
||||
/*
|
||||
*/
|
||||
configure: {
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
filter: 'physics',
|
||||
showButton: true
|
||||
},
|
||||
physics: {
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
barnesHut: {
|
||||
theta: 0.5,
|
||||
gravitationalConstant: -2000,
|
||||
@ -89,7 +90,7 @@ window.options = {
|
||||
edges: {
|
||||
font: {
|
||||
color: '#b0b0b0',
|
||||
size: 9,
|
||||
size: 14,
|
||||
face: 'arial',
|
||||
background: 'none',
|
||||
strokeWidth: 2, // px
|
||||
@ -112,30 +113,30 @@ window.options = {
|
||||
},
|
||||
color: {
|
||||
border: '#b0b0b0',
|
||||
background: 'rgb(193,229,222)',
|
||||
background: lightGreen,
|
||||
highlight: {
|
||||
border: '#89c9a9',
|
||||
background: 'rgb(156,213,203)'
|
||||
border: '#216458',
|
||||
background: darkGreen,
|
||||
},
|
||||
hover: {
|
||||
border: '#89c9a9',
|
||||
background: 'rgb(156,213,203)'
|
||||
border: '#216458',
|
||||
background: darkGreen,
|
||||
}
|
||||
},
|
||||
opacity: 0.85,
|
||||
opacity: 0.9,
|
||||
shadow:{
|
||||
enabled: true,
|
||||
color: 'rgba(0,0,0,0.5)',
|
||||
size:10,
|
||||
x:5,
|
||||
y:5
|
||||
y:5,
|
||||
},
|
||||
},
|
||||
household: {
|
||||
color: 'pink'
|
||||
color: lightBrown,
|
||||
},
|
||||
accompanying_period: {
|
||||
color: 'orange',
|
||||
color: lightBlue,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<ul class="record_actions">
|
||||
<ul class="record_actions">
|
||||
<li class="add-persons">
|
||||
<a class="btn" :class="getClassButton" :title="$t(buttonTitle)"
|
||||
@click="openModal"><span v-if="displayTextButton">{{ $t(buttonTitle) }}</span></a>
|
||||
<a class="btn" :class="getClassButton" :title="$t(buttonTitle)"
|
||||
@click="openModal"><span v-if="displayTextButton">{{ $t(buttonTitle) }}</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<teleport to="body">
|
||||
<teleport to="body">
|
||||
<modal v-if="modal.showModal"
|
||||
:modalDialogClass="modal.modalDialogClass"
|
||||
@close="modal.showModal = false">
|
||||
@ -181,7 +181,7 @@ export default {
|
||||
},
|
||||
hasPriorSuggestion() {
|
||||
return this.search.priorSuggestion.key ? true : false;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openModal() {
|
||||
|
@ -25,6 +25,11 @@
|
||||
v-if="item.result.type === 'user'"
|
||||
v-bind:item="item">
|
||||
</suggestion-user>
|
||||
|
||||
<suggestion-household
|
||||
v-if="item.result.type === 'household'"
|
||||
v-bind:item="item">
|
||||
</suggestion-household>
|
||||
</label>
|
||||
|
||||
</div>
|
||||
@ -34,6 +39,7 @@
|
||||
import SuggestionPerson from './TypePerson';
|
||||
import SuggestionThirdParty from './TypeThirdParty';
|
||||
import SuggestionUser from './TypeUser';
|
||||
import SuggestionHousehold from './TypeHousehold';
|
||||
|
||||
export default {
|
||||
name: 'PersonSuggestion',
|
||||
@ -41,6 +47,7 @@ export default {
|
||||
SuggestionPerson,
|
||||
SuggestionThirdParty,
|
||||
SuggestionUser,
|
||||
SuggestionHousehold,
|
||||
},
|
||||
props: [
|
||||
'item',
|
||||
@ -70,7 +77,7 @@ export default {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
div.results {
|
||||
div.list-item {
|
||||
padding: 0.4em 0.8em;
|
||||
@ -83,11 +90,11 @@ export default {
|
||||
label {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
div.container {
|
||||
div.container:not(.household) {
|
||||
& > input {
|
||||
margin-right: 0.8em;
|
||||
}
|
||||
span:not(.name) {
|
||||
> span:not(.name) {
|
||||
margin-left: 0.5em;
|
||||
opacity: 0.5;
|
||||
font-size: 90%;
|
||||
|
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div class="container household">
|
||||
<household-render-box :household="item.result" :isAddressMultiline="false"></household-render-box>
|
||||
</div>
|
||||
|
||||
<div class="right_actions">
|
||||
<badge-entity
|
||||
:entity="item.result"
|
||||
:options="{ displayLong: true }">
|
||||
</badge-entity>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||
import HouseholdRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue';
|
||||
|
||||
export default {
|
||||
name: 'SuggestionHousehold',
|
||||
components: {
|
||||
BadgeEntity,
|
||||
HouseholdRenderBox,
|
||||
},
|
||||
props: ['item'],
|
||||
}
|
||||
</script>
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<span class="name">
|
||||
{{ item.result.text }}
|
||||
<person-text :person="item.result"></person-text>
|
||||
</span>
|
||||
<span class="birthday" v-if="hasBirthdate">
|
||||
{{ $d(item.result.birthdate.datetime, 'short') }}
|
||||
@ -28,12 +28,14 @@
|
||||
<script>
|
||||
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
|
||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
export default {
|
||||
name: 'SuggestionPerson',
|
||||
components: {
|
||||
OnTheFly,
|
||||
BadgeEntity
|
||||
BadgeEntity,
|
||||
PersonText,
|
||||
},
|
||||
props: ['item'],
|
||||
computed: {
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="container tpartycontainer">
|
||||
<div class="tparty-identification">
|
||||
<span class="name">
|
||||
{{ item.result.text }}
|
||||
{{ item.result.text }}
|
||||
</span>
|
||||
<span class="location">
|
||||
<template v-if="hasAddress">
|
||||
|
@ -1,14 +1,15 @@
|
||||
<template>
|
||||
<div v-if="render === 'bloc'" class="item-bloc">
|
||||
<div v-if="render === 'bloc'" class="item-bloc">
|
||||
<section class="chill-entity entity-person">
|
||||
<div class="item-row entity-bloc">
|
||||
<div class="item-row entity-bloc">
|
||||
|
||||
<div class="item-col">
|
||||
<div class="entity-label">
|
||||
|
||||
<div :class="'denomination h' + options.hLevel">
|
||||
|
||||
<a v-if="options.addLink === true" :href="getUrl">
|
||||
<a v-if="options.addLink === true" :href="getUrl">
|
||||
<!-- use person-text here to avoid code duplication ? TODO -->
|
||||
<span class="firstname">{{ person.firstName }}</span>
|
||||
<span class="lastname">{{ person.lastName }}</span>
|
||||
<span v-if="person.altNames && options.addAltNames == true" class="altnames">
|
||||
@ -16,19 +17,20 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<span class="firstname">{{ person.firstName }}</span>
|
||||
<span class="lastname">{{ person.lastName }}</span>
|
||||
<span v-if="person.deathdate" class="deathdate"> (‡)</span>
|
||||
<span v-if="person.altNames && options.addAltNames == true" class="altnames">
|
||||
<span :class="'altname altname-' + altNameKey">{{ altNameLabel }}</span>
|
||||
</span>
|
||||
<!-- use person-text here to avoid code duplication ? TODO -->
|
||||
<span class="firstname">{{ person.firstName }}</span>
|
||||
<span class="lastname">{{ person.lastName }}</span>
|
||||
<span v-if="person.deathdate" class="deathdate"> (‡)</span>
|
||||
<span v-if="person.altNames && options.addAltNames == true" class="altnames">
|
||||
<span :class="'altname altname-' + altNameKey">{{ altNameLabel }}</span>
|
||||
</span>
|
||||
|
||||
<span v-if="options.addId == true" class="id-number" :title="'n° ' + person.id">{{ person.id }}</span>
|
||||
<span v-if="options.addId == true" class="id-number" :title="'n° ' + person.id">{{ person.id }}</span>
|
||||
|
||||
<badge-entity v-if="options.addEntity === true"
|
||||
:entity="person"
|
||||
:options="{ displayLong: options.entityDisplayLong }">
|
||||
</badge-entity>
|
||||
<badge-entity v-if="options.addEntity === true"
|
||||
:entity="person"
|
||||
:options="{ displayLong: options.entityDisplayLong }">
|
||||
</badge-entity>
|
||||
|
||||
</div>
|
||||
|
||||
@ -47,98 +49,96 @@
|
||||
{{ $t('renderbox.deathdate') + ' ' + deathdate }}
|
||||
</time>
|
||||
|
||||
<span v-if="options.addAge && person.birthdate" class="age">{{ getAge }} {{ $t('renderbox.years_old')}}</span>
|
||||
<span v-if="options.addAge && person.birthdate" class="age">{{ $tc('renderbox.years_old', person.age) }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-col">
|
||||
<div class="float-button bottom">
|
||||
<div class="box">
|
||||
<div class="action">
|
||||
<slot name="record-actions"></slot>
|
||||
</div>
|
||||
<ul class="list-content fa-ul">
|
||||
<div class="float-button bottom">
|
||||
<div class="box">
|
||||
<div class="action">
|
||||
<slot name="record-actions"></slot>
|
||||
</div>
|
||||
<ul class="list-content fa-ul">
|
||||
<li v-if="person.current_household_id">
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<address-render-box v-if="person.current_household_address"
|
||||
:address="person.current_household_address"
|
||||
:isMultiline="isMultiline">
|
||||
</address-render-box>
|
||||
<p v-else class="chill-no-data-statement">
|
||||
{{ $t('renderbox.household_without_address') }}
|
||||
</p>
|
||||
<a v-if="options.addHouseholdLink === true"
|
||||
:href="getCurrentHouseholdUrl"
|
||||
:title="$t('persons_associated.show_household_number', {id: person.current_household_id})">
|
||||
<span class="badge rounded-pill bg-chill-beige">
|
||||
<i class="fa fa-fw fa-home"></i><!--{{ $t('persons_associated.show_household') }}-->
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li v-else-if="options.addNoData">
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<p class="chill-no-data-statement">
|
||||
{{ $t('renderbox.no_data') }}
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li v-if="person.current_household_id">
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<address-render-box v-if="person.current_household_address"
|
||||
:address="person.current_household_address"
|
||||
:isMultiline="isMultiline">
|
||||
</address-render-box>
|
||||
<p v-else class="chill-no-data-statement">
|
||||
{{ $t('renderbox.household_without_address') }}
|
||||
</p>
|
||||
<a v-if="options.addHouseholdLink === true"
|
||||
:href="getCurrentHouseholdUrl"
|
||||
:title="$t('persons_associated.show_household_number', {id: person.current_household_id})">
|
||||
<span class="badge rounded-pill bg-chill-beige">
|
||||
<i class="fa fa-fw fa-home"></i><!--{{ $t('persons_associated.show_household') }}-->
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li v-else-if="options.addNoData">
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<p class="chill-no-data-statement">
|
||||
{{ $t('renderbox.no_data') }}
|
||||
</p>
|
||||
</li>
|
||||
<li v-if="person.mobilenumber">
|
||||
<i class="fa fa-li fa-mobile"></i>
|
||||
<a :href="'tel: ' + person.mobilenumber">{{ person.mobilenumber }}</a>
|
||||
</li>
|
||||
<li v-else-if="options.addNoData">
|
||||
<i class="fa fa-li fa-mobile"></i>
|
||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||
</li>
|
||||
<li v-if="person.phonenumber">
|
||||
<i class="fa fa-li fa-phone"></i>
|
||||
<a :href="'tel: ' + person.phonenumber">{{ person.phonenumber }}</a>
|
||||
</li>
|
||||
<li v-else-if="options.addNoData">
|
||||
<i class="fa fa-li fa-phone"></i>
|
||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||
</li>
|
||||
|
||||
<li v-if="person.mobilenumber">
|
||||
<i class="fa fa-li fa-mobile"></i>
|
||||
<a :href="'tel: ' + person.mobilenumber">{{ person.mobilenumber }}</a>
|
||||
</li>
|
||||
<li v-else-if="options.addNoData">
|
||||
<i class="fa fa-li fa-mobile"></i>
|
||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||
</li>
|
||||
<li v-if="person.phonenumber">
|
||||
<i class="fa fa-li fa-phone"></i>
|
||||
<a :href="'tel: ' + person.phonenumber">{{ person.phonenumber }}</a>
|
||||
</li>
|
||||
<li v-else-if="options.addNoData">
|
||||
<i class="fa fa-li fa-phone"></i>
|
||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||
</li>
|
||||
<li v-if="person.centers !== undefined && person.centers.length > 0 && options.addCenter">
|
||||
<i class="fa fa-li fa-long-arrow-right"></i>
|
||||
<template v-for="c in person.centers">{{ c.name }}</template>
|
||||
</li>
|
||||
<li v-else-if="options.addNoData">
|
||||
<i class="fa fa-li fa-long-arrow-right"></i>
|
||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||
</li>
|
||||
<slot name="custom-zone"></slot>
|
||||
|
||||
<li v-if="person.centers !== undefined && person.centers.length > 0 && options.addCenter">
|
||||
<i class="fa fa-li fa-long-arrow-right"></i>
|
||||
<template v-for="c in person.centers">{{ c.name }}</template>
|
||||
</li>
|
||||
<li v-else-if="options.addNoData">
|
||||
<i class="fa fa-li fa-long-arrow-right"></i>
|
||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||
</li>
|
||||
<slot name="custom-zone"></slot>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span v-if="render === 'badge'" class="chill-entity entity-person badge-person">
|
||||
<a v-if="options.addLink === true" :href="getUrl">
|
||||
<span v-if="options.isHolder" class="fa-stack fa-holder" :title="$t('renderbox.holder')">
|
||||
<i class="fa fa-circle fa-stack-1x text-success"></i>
|
||||
<i class="fa fa-stack-1x">T</i>
|
||||
</span>
|
||||
{{ person.text }}
|
||||
<span v-if="person.deathdate" class="deathdate"> (‡)</span>
|
||||
<span v-if="render === 'badge'" class="chill-entity entity-person badge-person">
|
||||
<a v-if="options.addLink === true" :href="getUrl">
|
||||
<span v-if="options.isHolder" class="fa-stack fa-holder" :title="$t('renderbox.holder')">
|
||||
<i class="fa fa-circle fa-stack-1x text-success"></i>
|
||||
<i class="fa fa-stack-1x">T</i>
|
||||
</span>
|
||||
|
||||
<person-text :person="person"></person-text>
|
||||
</a>
|
||||
<span v-else>
|
||||
<span v-if="options.isHolder" class="fa-stack fa-holder" :title="$t('renderbox.holder')">
|
||||
<i class="fa fa-circle fa-stack-1x text-success"></i>
|
||||
<i class="fa fa-stack-1x">T</i>
|
||||
</span>
|
||||
{{ person.text }}
|
||||
<span v-if="person.deathdate" class="deathdate"> (‡)</span>
|
||||
<span v-if="options.isHolder" class="fa-stack fa-holder" :title="$t('renderbox.holder')">
|
||||
<i class="fa fa-circle fa-stack-1x text-success"></i>
|
||||
<i class="fa fa-stack-1x">T</i>
|
||||
</span>
|
||||
<person-text :person="person"></person-text>
|
||||
</span>
|
||||
<slot name="post-badge"></slot>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
</template>
|
||||
|
||||
@ -147,13 +147,15 @@ import {dateToISO} from 'ChillMainAssets/chill/js/date.js';
|
||||
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
export default {
|
||||
name: "PersonRenderBox",
|
||||
components: {
|
||||
AddressRenderBox,
|
||||
Confidential,
|
||||
BadgeEntity
|
||||
BadgeEntity,
|
||||
PersonText
|
||||
},
|
||||
props: ['person', 'options', 'render', 'returnPath'],
|
||||
computed: {
|
||||
@ -168,7 +170,7 @@ export default {
|
||||
return this.person.gender === 'woman' ? 'fa-venus' : this.person.gender === 'man' ? 'fa-mars' : this.person.gender === 'neuter' ? 'fa-neuter' : 'fa-genderless';
|
||||
},
|
||||
getGenderTranslation: function() {
|
||||
return this.person.gender === 'woman' ? 'renderbox.birthday.woman' : 'renderbox.birthday.man';
|
||||
return this.person.gender === 'woman' ? 'renderbox.birthday.woman' : 'renderbox.birthday.man';
|
||||
},
|
||||
getGender() {
|
||||
return this.person.gender === 'woman' ? 'person.gender.woman' : this.person.gender === 'man' ? 'person.gender.man' : this.person.gender === 'neuter' ? 'person.gender.neuter' : 'person.gender.undefined';
|
||||
@ -200,24 +202,6 @@ export default {
|
||||
getUrl: function() {
|
||||
return `/fr/person/${this.person.id}/general`;
|
||||
},
|
||||
getAge: function() {
|
||||
// TODO only one abstract function
|
||||
if(this.person.birthdate && !this.person.deathdate){
|
||||
const birthday = new Date(this.person.birthdate.datetime)
|
||||
const now = new Date()
|
||||
return (now.getFullYear() - birthday.getFullYear())
|
||||
} else if(this.person.birthdate && this.person.deathdate){
|
||||
const birthday = new Date(this.person.birthdate.datetime)
|
||||
const deathdate = new Date(this.person.deathdate.datetime)
|
||||
return (deathdate.getFullYear() - birthday.getFullYear())
|
||||
} else if(!this.person.birthdate && this.person.deathdate.datetime) {
|
||||
// todo: change this
|
||||
return "Age unknown"
|
||||
} else {
|
||||
// todo: change this
|
||||
return "Age unknown"
|
||||
}
|
||||
},
|
||||
getCurrentHouseholdUrl: function() {
|
||||
let returnPath = this.returnPath ? `?returnPath=${this.returnPath}` : ``;
|
||||
return `/fr/person/household/${this.person.current_household_id}/summary${returnPath}`
|
||||
|
@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<span v-if="isCut">{{ cutText }}</span>
|
||||
<span v-else class="person-text">
|
||||
<span class="firstname">{{ person.firstName }}</span>
|
||||
<span class="lastname">{{ person.lastName }}</span>
|
||||
<span v-if="person.altNames && person.altNames.length > 0" class="altnames">
|
||||
<span :class="'altname altname-' + altNameKey"> ({{ altNameLabel }})</span>
|
||||
</span>
|
||||
<span class="age" v-if="this.addAge && person.birthdate !== null && person.deathdate === null">{{ $tc('renderbox.years_old', person.age) }}</span>
|
||||
<span v-else-if="this.addAge && person.deathdate !== null"> (‡)</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "PersonText",
|
||||
props: {
|
||||
person: {
|
||||
required: true,
|
||||
},
|
||||
isCut: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
addAge: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
altNameLabel: function() {
|
||||
for(let i = 0; i < this.person.altNames.length; i++){
|
||||
return this.person.altNames[i].label
|
||||
}
|
||||
},
|
||||
altNameKey: function() {
|
||||
for(let i = 0; i < this.person.altNames.length; i++){
|
||||
return this.person.altNames[i].key
|
||||
}
|
||||
},
|
||||
cutText: function() {
|
||||
let more = (this.person.text.length > 15) ?'…' : '';
|
||||
return this.person.text.slice(0,15) + more;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -151,14 +151,14 @@
|
||||
{% if accompanyingCourse.requestorPerson is not null %}
|
||||
<h4 class="item-key">{{ 'Requestor'|trans }}</h4>
|
||||
{% if accompanyingCourse.requestorAnonymous %}
|
||||
<div class="confidential"><p class="blur">{{ _self.insert_onthefly('person', accompanyingCourse.requestorPerson) }}</p></div>
|
||||
<div class="confidential"><p>{{ _self.insert_onthefly('person', accompanyingCourse.requestorPerson) }}</p></div>
|
||||
{% else %}
|
||||
{{ _self.insert_onthefly('person', accompanyingCourse.requestorPerson) }}
|
||||
{% endif %}
|
||||
{% elseif accompanyingCourse.requestorThirdParty is not null %}
|
||||
<h4 class="item-key">{{ 'Requestor'|trans }}</h4>
|
||||
{% if accompanyingCourse.requestorAnonymous %}
|
||||
<div class="confidential"><p class="blur">{{ _self.insert_onthefly('thirdparty', accompanyingCourse.requestorThirdParty) }}</p></div>
|
||||
<div class="confidential"><p>{{ _self.insert_onthefly('thirdparty', accompanyingCourse.requestorThirdParty) }}</p></div>
|
||||
{% else %}
|
||||
{{ _self.insert_onthefly('thirdparty', accompanyingCourse.requestorThirdParty) }}
|
||||
{% endif %}
|
||||
|
@ -31,7 +31,7 @@
|
||||
<li class="associated-persons">
|
||||
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
|
||||
{% for p in w.persons %}
|
||||
<span class="badge-person">{{ p|chill_entity_render_box }}</span>
|
||||
<span class="badge-person">{{ p|chill_entity_render_box({'addAgeBadge': true}) }}</span>
|
||||
{% endfor %}
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -0,0 +1,30 @@
|
||||
{% extends "@ChillMain/layout.html.twig" %}
|
||||
|
||||
{% set activeRouteKey = 'chill_person_accompanying_period_user_list' %}
|
||||
|
||||
{% block title %}{{ 'My accompanying periods'|trans }}{% endblock title %}
|
||||
|
||||
{% macro recordAction(period) %}
|
||||
<li>
|
||||
<a href="{{ path('chill_person_accompanying_course_index', { 'accompanying_period_id': period.id }) }}"
|
||||
class="btn btn-show" title="{{ 'See accompanying period'|trans }}"></a>
|
||||
</li>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="col-md-10">
|
||||
<h1>{{ 'My accompanying periods'|trans }}</h1>
|
||||
|
||||
<div class="flex-table accompanyingcourse-list">
|
||||
{% for period in accompanyingPeriods %}
|
||||
{% include '@ChillPerson/AccompanyingPeriod/_list_item.html.twig' with {'period': period, 'recordAction': _self.recordAction(period)} %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{{ chill_pagination(pagination) }}
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -11,6 +11,7 @@
|
||||
* addCenter bool
|
||||
* hLevel integer
|
||||
* addDeath bool
|
||||
* addAgeBadge bool
|
||||
* address_multiline bool
|
||||
* customButtons [
|
||||
'before' Twig\Markup, (injected with macro)
|
||||
@ -40,6 +41,11 @@
|
||||
{%- endfor -%}
|
||||
</span>
|
||||
{%- endif -%}
|
||||
{%- if options['addAgeBadge'] -%}
|
||||
{% if person.age is not null and person.deathDate is null %}
|
||||
<span>({{- 'years_old'|trans({ 'age': person.age }) -}})</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endmacro raw %}
|
||||
|
||||
{% macro label(person, options) %}
|
||||
|
@ -14,6 +14,7 @@
|
||||
'render': 'label',
|
||||
'addLink': true,
|
||||
'addInfo': true,
|
||||
'addAgeBadge': true,
|
||||
'customArea': {
|
||||
'afterLabel': _self.addHolder(member.holder)
|
||||
}
|
||||
|
@ -78,16 +78,11 @@
|
||||
{% set app = person.findParticipationForPeriod(acp) %}
|
||||
<div class="item-row separator">
|
||||
<div class="wrap-list periods-list">
|
||||
|
||||
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
<h3 class="courseid mb-2">
|
||||
<a href="{{ path('chill_person_accompanying_course_index', { 'accompanying_period_id': acp.id }) }}"
|
||||
title="{{ 'See accompanying period'|trans }}" class="btn btn-outline-primary">
|
||||
<i class="fa fa-random fa-fw"></i>
|
||||
{{ 'File number'|trans }} {{ acp.id }}
|
||||
</a>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
@ -97,28 +92,37 @@
|
||||
{{ 'Since %date%'|trans({'%date%': app.startDate|format_date('medium') }) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', acp.id) %}
|
||||
{% if notif_counter.total > 0 %}
|
||||
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', acp.id) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
{% if acp.requestorPerson == person %}
|
||||
<span class="as-requestor badge bg-info" title="{{ 'Requestor'|trans|e('html_attr') }}">
|
||||
{{ 'Requestor'|trans({'gender': person.gender}) }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if acp.emergency %}
|
||||
<span class="badge rounded-pill bg-danger">{{- 'Emergency'|trans|upper -}}</span>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if acp.confidential %}
|
||||
<span class="badge rounded-pill bg-confidential">{{- 'Confidential'|trans|upper -}}</span>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if acp.step == 'DRAFT' %}
|
||||
<span class="badge bg-secondary" style="font-size: 85%;" title="{{ 'course.draft'|trans }}">{{ 'course.draft'|trans }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if acp.step == 'CLOSED' %}
|
||||
<span class="badge bg-secondary" style="font-size: 85%;" title="{{ 'course.closed'|trans }}">{{ 'course.closed'|trans }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% if acp.user is not null %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
@ -131,7 +135,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if acp.socialIssues|length > 0 %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
@ -144,24 +148,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ????
|
||||
{% if acp.requestorPerson == person %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
<h3>
|
||||
|
||||
</h3>
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
<span class="as-requestor badge bg-info" title="{{ 'Requestor'|trans|e('html_attr') }}">
|
||||
{{ 'Requestor'|trans({'gender': person.gender}) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
#}
|
||||
|
||||
|
||||
{% if acp.currentParticipations|length > 1 %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
@ -190,7 +177,16 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<ul class="record_actions record_actions_column">
|
||||
<li>
|
||||
<a href="{{ path('chill_person_accompanying_course_index', { 'accompanying_period_id': acp.id }) }}"
|
||||
class="btn btn-sm btn-outline-primary" title="{{ 'See accompanying period'|trans }}">
|
||||
<i class="fa fa-random fa-fw"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% if (acp.requestorPerson is not null and acp.requestorPerson.id != person.id) or acp.requestorThirdParty is not null %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
@ -222,7 +218,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
@ -12,4 +12,4 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
@ -84,6 +84,8 @@
|
||||
<p class="chill-no-data-statement">{{ 'There are no available resources'|trans }}</p>
|
||||
{% endif %}
|
||||
|
||||
<h1 style="margin-bottom: 2rem;">{{ 'Add a person resource'|trans }}</h1>
|
||||
|
||||
{% include "@ChillPerson/PersonResource/create.html.twig" %}
|
||||
|
||||
{% endblock %}
|
||||
|
@ -0,0 +1,37 @@
|
||||
|
||||
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_row(form.startDate) }}
|
||||
{{ form_row(form.endDate) }}
|
||||
|
||||
{% if form.hostPerson is defined %}
|
||||
{{ form_row(form.hostPerson) }}
|
||||
{% endif %}
|
||||
|
||||
{% if form.hostThirdParty is defined %}
|
||||
{{ form_row(form.hostThirdParty) }}
|
||||
{% endif %}
|
||||
|
||||
{% if form.address is defined %}
|
||||
{{ form_row(form.address) }}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('mod_input_address') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('mod_input_address') }}
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{{ form_row(form.comment) }}
|
||||
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<button class="btn btn-update" type="submit">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{ form_end(form) }}
|
@ -0,0 +1,58 @@
|
||||
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||
|
||||
{% set activeRouteKey = '' %}
|
||||
|
||||
{% block title %}{{ 'Delete residential address'|trans }}{% endblock %}
|
||||
|
||||
{% block personcontent %}
|
||||
<div class="address-new">
|
||||
|
||||
<h1>{{ block('title') }}</h1>
|
||||
{% set a = residentialAddress %}
|
||||
<ul class="list-content fa-ul">
|
||||
{% if a.hostPerson is not null %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-home"></i>
|
||||
<span class="item-key">{{ "Address of"|trans}} </span>
|
||||
<span class="chill-entity entity-person badge-person">{{ a.hostPerson|chill_entity_render_box }}</span>
|
||||
</li>
|
||||
<li>
|
||||
{% set address_date = date(a.startDate|date("m/d/Y")) %}
|
||||
{% if a.hostPerson.getCurrentHouseholdAddress(a.endDate) is not null %}
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
{{ a.hostPerson.getCurrentHouseholdAddress(a.endDate)|chill_entity_render_box }}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% elseif a.hostThirdParty is not null %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-home"></i>
|
||||
<span class="item-key">{{ "Address of"|trans}}</span>
|
||||
<span class="chill-entity entity-person badge-person">{{ a.hostThirdParty|chill_entity_render_box }}</span>
|
||||
</li>
|
||||
<li>
|
||||
{% if a.hostThirdParty.address is not null %}
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
{{ a.hostThirdParty.address|chill_entity_render_box }}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
{% if a.address is not null %}
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
{{ a.address|chill_entity_render_box }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{ include('@ChillMain/Util/confirmation_template.html.twig',
|
||||
{
|
||||
'title' : 'Delete residential address ?'|trans,
|
||||
'confirm_question' : 'Are you sure you want to remove this residential address for %name% ?'|trans({'%name%': person|chill_entity_render_string }),
|
||||
'cancel_route' : 'chill_person_residential_address_list',
|
||||
'cancel_parameters' : {'id' : person.Id},
|
||||
'form' : delete_form
|
||||
} ) }}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
@ -0,0 +1,51 @@
|
||||
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||
|
||||
{% set activeRouteKey = '' %}
|
||||
|
||||
{% block title 'Edit a residential address'|trans %}
|
||||
|
||||
{% block personcontent %}
|
||||
<div class="address-edit">
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ block('title') }}</h1>
|
||||
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_row(form.startDate) }}
|
||||
{{ form_row(form.endDate) }}
|
||||
|
||||
{% if residentialAddress.address is not null %}
|
||||
|
||||
{% if form.address is defined %}
|
||||
{{ form_row(form.address) }}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('mod_input_address') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('mod_input_address') }}
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{{ form_row(form.comment) }}
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="cancel">
|
||||
<a href="{{ chill_path_add_return_path('chill_person_residential_address_list', {'id': person.id}) }}" class="btn btn-cancel">
|
||||
{{ 'Cancel'|trans|chill_return_path_label }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<button class="btn btn-update" type="submit">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{ form_end(form) }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
@ -0,0 +1,116 @@
|
||||
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||
|
||||
{% set activeRouteKey = '' %}
|
||||
|
||||
{% block title %}{{ 'Residential addresses history for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}{% endblock %}
|
||||
|
||||
{% block personcontent %}
|
||||
<div class="person-address">
|
||||
|
||||
<h1>{{ 'Residential addresses history'|trans }}</h1>
|
||||
|
||||
{% if is_granted('CHILL_PERSON_SEE', person) %}
|
||||
|
||||
{% if addresses|length == 0 %}
|
||||
<span class="chill-no-data-statement">{{ 'No address given'|trans }}</span>
|
||||
|
||||
{% else %}
|
||||
<div class="flex-table">
|
||||
{% for a in addresses %}
|
||||
|
||||
{% if a.address is not null %}
|
||||
{% set kind = 'address' %}
|
||||
{% else %}
|
||||
{% set kind = null %}
|
||||
{% endif %}
|
||||
|
||||
<div class="item-bloc">
|
||||
<div class="item-row">
|
||||
|
||||
<div class="item-col" style="width: 33%;">
|
||||
<ul class="list-unstyled h3">
|
||||
{% if a.endDate is not null %}
|
||||
<li><span class="item-key">{{'Since'|trans}} : </span>{{ a.startDate|format_date('long') }}</li>
|
||||
{% endif %}
|
||||
<li><span class="item-key">{{'Until'|trans}} : </span><b>{{ a.endDate|format_date('long') }}</b></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="item-col flex-column justify-content-start">
|
||||
<div class="float-button top">
|
||||
<div class="box">
|
||||
<div class="action">
|
||||
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
||||
<a href="{{ path('chill_person_residential_address_edit', { 'id' : a.id, 'kind' : kind } ) }}" class="btn btn-update" title="{{ 'Update'|trans|e('html_attr') }}"></a>
|
||||
<a href="{{ path('chill_person_residential_address_delete', { 'id' : a.id, 'kind' : kind } ) }}" class="btn btn-delete" title="{{ 'Delete'|trans|e('html_attr') }}"></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<ul class="list-content fa-ul">
|
||||
{% if a.hostPerson is not null %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-home"></i>
|
||||
<span class="item-key">{{ "Address of"|trans}} </span>
|
||||
<span class="chill-entity entity-person badge-person">{{ a.hostPerson|chill_entity_render_box }}</span>
|
||||
</li>
|
||||
<li>
|
||||
{% set address_date = date(a.startDate|date("m/d/Y")) %}
|
||||
{% if a.hostPerson.getCurrentHouseholdAddress(a.endDate) is not null %}
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
{{ a.hostPerson.getCurrentHouseholdAddress(a.endDate)|chill_entity_render_box }}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% elseif a.hostThirdParty is not null %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-home"></i>
|
||||
<span class="item-key">{{ "Address of"|trans}}</span>
|
||||
<span class="chill-entity entity-person badge-person">{{ a.hostThirdParty|chill_entity_render_box }}</span>
|
||||
</li>
|
||||
<li>
|
||||
{% if a.hostThirdParty.address is not null %}
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
{{ a.hostThirdParty.address|chill_entity_render_box }}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
{% if a.address is not null %}
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
{{ a.address|chill_entity_render_box }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="item-row">
|
||||
{% if not a.comment.isEmpty %}
|
||||
{{ a.comment|chill_entity_render_box }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="cancel">
|
||||
<a href="{{ path('chill_person_view', { 'person_id' : person.id } ) }}" class="btn btn-cancel">
|
||||
{{ 'Back to the person details'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
||||
<li>
|
||||
<a class="btn btn-create"
|
||||
href="{{ path('chill_person_residential_address_new', { 'id' : person.id } ) }}">
|
||||
{{ 'Add a residential address'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
@ -0,0 +1,29 @@
|
||||
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||
|
||||
{% set activeRouteKey = '' %}
|
||||
|
||||
{% block title %}{{ 'New residential address'|trans }}{% endblock %}
|
||||
|
||||
{% block personcontent %}
|
||||
<div class="address-new">
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ block('title') }}</h1>
|
||||
|
||||
{# TODO #}
|
||||
{% block form %}
|
||||
{% include '@ChillPerson/ResidentialAddress/_form.html.twig' %}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
@ -0,0 +1,49 @@
|
||||
{% extends "@ChillMain/layout.html.twig" %}
|
||||
|
||||
{% block title 'Which kind of residential address would you create ?'|trans %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-10 centered">
|
||||
<h1>{{ block('title') }}</h1>
|
||||
|
||||
<div class="container" style="margin-top: 2rem;">
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-4">
|
||||
<a
|
||||
href="{{ chill_path_forward_return_path('chill_person_residential_address_new', {'id': person.id, 'kind': 'person'}) }}"
|
||||
class="btn btn-outline-chill-green-dark">
|
||||
{{ 'The address of another person'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<p>{{ 'residential_address_person_explanation'|trans }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-4">
|
||||
<a
|
||||
href="{{ chill_path_forward_return_path('chill_person_residential_address_new', {'id': person.id, 'kind': 'thirdparty'}) }}"
|
||||
class="btn btn-outline-chill-green-dark">
|
||||
{{ 'The address of a third party'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<p>{{ 'residential_address_third_party_explanation'|trans }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-4">
|
||||
<a
|
||||
href="{{ chill_path_forward_return_path('chill_person_residential_address_new', {'id': person.id, 'kind': 'address'}) }}"
|
||||
class="btn btn-outline-chill-green-dark">
|
||||
{{ 'A new address'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<p>{{ 'residential_address_new_address_explanation'|trans }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Search;
|
||||
|
||||
use Chill\MainBundle\Search\SearchApiInterface;
|
||||
use Chill\MainBundle\Search\SearchApiQuery;
|
||||
use Chill\MainBundle\Search\Utils\ExtractDateFromPattern;
|
||||
use Chill\MainBundle\Search\Utils\ExtractPhonenumberFromPattern;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
|
||||
use Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function in_array;
|
||||
|
||||
class SearchHouseholdApiProvider implements SearchApiInterface
|
||||
{
|
||||
private AuthorizationHelperInterface $authorizationHelper;
|
||||
|
||||
private ExtractDateFromPattern $extractDateFromPattern;
|
||||
|
||||
private ExtractPhonenumberFromPattern $extractPhonenumberFromPattern;
|
||||
|
||||
private HouseholdRepository $householdRepository;
|
||||
|
||||
private PersonACLAwareRepositoryInterface $personACLAwareRepository;
|
||||
|
||||
private Security $security;
|
||||
|
||||
public function __construct(
|
||||
HouseholdRepository $householdRepository,
|
||||
PersonACLAwareRepositoryInterface $personACLAwareRepository,
|
||||
Security $security,
|
||||
AuthorizationHelperInterface $authorizationHelper,
|
||||
ExtractDateFromPattern $extractDateFromPattern,
|
||||
ExtractPhonenumberFromPattern $extractPhonenumberFromPattern
|
||||
) {
|
||||
$this->householdRepository = $householdRepository;
|
||||
$this->personACLAwareRepository = $personACLAwareRepository;
|
||||
$this->security = $security;
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
$this->extractDateFromPattern = $extractDateFromPattern;
|
||||
$this->extractPhonenumberFromPattern = $extractPhonenumberFromPattern;
|
||||
}
|
||||
|
||||
public function getResult(string $key, array $metadata, float $pertinence)
|
||||
{
|
||||
return $this->householdRepository->find($metadata['id']);
|
||||
}
|
||||
|
||||
public function prepare(array $metadatas): void
|
||||
{
|
||||
$ids = array_map(static fn ($m) => $m['id'], $metadatas);
|
||||
|
||||
$this->householdRepository->findBy(['id' => $ids]);
|
||||
}
|
||||
|
||||
public function provideQuery(string $pattern, array $parameters): SearchApiQuery
|
||||
{
|
||||
$datesResult = $this->extractDateFromPattern->extractDates($pattern);
|
||||
$phoneResult = $this->extractPhonenumberFromPattern->extractPhonenumber($datesResult->getFilteredSubject());
|
||||
$filtered = $phoneResult->getFilteredSubject();
|
||||
|
||||
$query = $this->personACLAwareRepository->buildAuthorizedQuery(
|
||||
$filtered,
|
||||
null,
|
||||
null,
|
||||
count($datesResult->getFound()) > 0 ? $datesResult->getFound()[0] : null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
count($phoneResult->getFound()) > 0 ? $phoneResult->getFound()[0] : null
|
||||
);
|
||||
|
||||
$query
|
||||
->setDistinct(true, 'household_id')
|
||||
->setFromClause(
|
||||
'view_chill_person_household_address AS vcpha ' .
|
||||
'JOIN chill_person_person AS person ON vcpha.person_id = person.id'
|
||||
)
|
||||
->setSelectKey('household')
|
||||
->andWhereClause('vcpha.validTo IS NULL', [])
|
||||
->setSelectJsonbMetadata("jsonb_build_object('id', vcpha.household_id)");
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function supportsResult(string $key, array $metadatas): bool
|
||||
{
|
||||
return 'household' === $key;
|
||||
}
|
||||
|
||||
public function supportsTypes(string $pattern, array $types, array $parameters): bool
|
||||
{
|
||||
return in_array('household', $types, true);
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ use function count;
|
||||
class AccompanyingPeriodResourceNormalizer implements DenormalizerAwareInterface, DenormalizerInterface
|
||||
{
|
||||
use DenormalizerAwareTrait;
|
||||
|
||||
use ObjectToPopulateTrait;
|
||||
|
||||
private ResourceRepository $repository;
|
||||
|
@ -33,6 +33,7 @@ use function is_array;
|
||||
class AccompanyingPeriodWorkDenormalizer implements ContextAwareDenormalizerInterface, DenormalizerAwareInterface
|
||||
{
|
||||
use DenormalizerAwareTrait;
|
||||
|
||||
use ObjectToPopulateTrait;
|
||||
|
||||
public const GROUP_CREATE = 'accompanying_period_work:create';
|
||||
|
@ -40,7 +40,9 @@ class PersonJsonNormalizer implements
|
||||
NormalizerInterface
|
||||
{
|
||||
use DenormalizerAwareTrait;
|
||||
|
||||
use NormalizerAwareTrait;
|
||||
|
||||
use ObjectToPopulateTrait;
|
||||
|
||||
private CenterResolverManagerInterface $centerResolverManager;
|
||||
@ -177,11 +179,13 @@ class PersonJsonNormalizer implements
|
||||
return [
|
||||
'type' => 'person',
|
||||
'id' => $person->getId(),
|
||||
'text' => $this->render->renderString($person),
|
||||
'text' => $this->render->renderString($person, ['addAge' => false]),
|
||||
'textAge' => $this->render->renderString($person, ['addAge' => true]),
|
||||
'firstName' => $person->getFirstName(),
|
||||
'lastName' => $person->getLastName(),
|
||||
'birthdate' => $this->normalizer->normalize($person->getBirthdate(), $format, $context),
|
||||
'deathdate' => $this->normalizer->normalize($person->getDeathdate(), $format, $context),
|
||||
'age' => $this->normalizer->normalize($person->getAge(), $format, $context),
|
||||
'centers' => $this->normalizer->normalize($this->centerResolverManager->resolveCenters($person), $format, $context),
|
||||
'phonenumber' => $person->getPhonenumber(),
|
||||
'mobilenumber' => $person->getMobilenumber(),
|
||||
|
@ -15,6 +15,7 @@ use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
|
||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
@ -27,12 +28,16 @@ class PersonRender extends AbstractChillEntityRender
|
||||
|
||||
private EngineInterface $engine;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(
|
||||
ConfigPersonAltNamesHelper $configAltNamesHelper,
|
||||
EngineInterface $engine
|
||||
EngineInterface $engine,
|
||||
TranslatorInterface $translator
|
||||
) {
|
||||
$this->configAltNamesHelper = $configAltNamesHelper;
|
||||
$this->engine = $engine;
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,6 +58,7 @@ class PersonRender extends AbstractChillEntityRender
|
||||
'customButtons' => $options['customButtons'] ?? [],
|
||||
'customArea' => $options['customArea'] ?? [],
|
||||
'addDeath' => $options['addDeath'] ?? true,
|
||||
'addAgeBadge' => $options['addAgeBadge'] ?? false,
|
||||
];
|
||||
|
||||
return
|
||||
@ -70,6 +76,13 @@ class PersonRender extends AbstractChillEntityRender
|
||||
*/
|
||||
public function renderString($person, array $options): string
|
||||
{
|
||||
$options = array_merge(['addAge' => true], $options);
|
||||
|
||||
if (null !== $person->getAge() && $person->getDeathDate() === null && $options['addAge']) {
|
||||
return $person->getFirstName() . ' ' . $person->getLastName()
|
||||
. $this->addAltNames($person, false) . ' (' . $this->translator->trans('years_old', ['age' => $person->getAge()]) . ')';
|
||||
}
|
||||
|
||||
return $person->getFirstName() . ' ' . $person->getLastName()
|
||||
. $this->addAltNames($person, false);
|
||||
}
|
||||
|
@ -29,7 +29,9 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
final class PersonVoterTest extends KernelTestCase
|
||||
{
|
||||
use PrepareCenterTrait;
|
||||
|
||||
use PrepareScopeTrait;
|
||||
|
||||
use PrepareUserTrait;
|
||||
|
||||
/**
|
||||
|
@ -11,3 +11,7 @@ services:
|
||||
Chill\PersonBundle\Search\SearchPersonApiProvider:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
Chill\PersonBundle\Search\SearchHouseholdApiProvider:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
@ -121,7 +121,6 @@ address_postcode_code: Code postal
|
||||
address_country_name: Pays
|
||||
address_country_code: Code pays
|
||||
|
||||
|
||||
'Alreay existing person': 'Dossiers déjà encodés'
|
||||
'Add the person': 'Ajouter la personne'
|
||||
'Add the person and create an accompanying period': "Créer la personne & créer une période d'accompagnement"
|
||||
@ -225,15 +224,15 @@ Concerned scopes: Services concernés
|
||||
|
||||
# person resource
|
||||
|
||||
person_resources_menu: "Personnes ressources"
|
||||
person_resources_menu: "Ressources"
|
||||
Person resources: "Ressources de la personne"
|
||||
Add a person resource: "Ajouter une personne ressource"
|
||||
edit resource: "Modifier une personne ressource"
|
||||
Remove resource: "Supprimer une personne ressource"
|
||||
Add a person resource: "Ajouter une ressource"
|
||||
edit resource: "Modifier ressource"
|
||||
Remove resource: "Supprimer ressource"
|
||||
Are you sure you want to remove the resource for "%name%" ?: Étes-vous sûr de vouloir supprimer cette ressource de %name%?
|
||||
The resource has been successfully removed.: "La ressource a été supprimée."
|
||||
List of resources: "Liste des ressources"
|
||||
There are no available resources: "Aucune personne ressources renseignée"
|
||||
There are no available resources: "Aucun ressource"
|
||||
no comment found: "Aucun commentaire"
|
||||
Select a type: "Choisissez un type"
|
||||
Select a person: "Choisissez un usager"
|
||||
@ -243,6 +242,7 @@ Select a thirdparty: "Choisissez un tiers"
|
||||
# pickAPersonType
|
||||
Pick a person: Choisir une personne
|
||||
|
||||
# Address
|
||||
No address given: Pas d'adresse renseignée
|
||||
The address has been successfully updated: L'adresse a été mise à jour avec succès
|
||||
Update address for %name%: Mettre à jour une adresse pour %name%
|
||||
@ -257,6 +257,31 @@ The new address was created successfully: La nouvelle adresse a été créée
|
||||
Add an address: Ajouter une adresse
|
||||
Back to the person details: Retour aux détails de la personne
|
||||
|
||||
# Residential address
|
||||
Residential addresses history for %name%: Historique des adresses de résidence de %name%
|
||||
Residential addresses history: Historique des adresses de résidence
|
||||
Add a residential address: Ajouter une adresse de résidence
|
||||
Which kind of residential address would you create ?: Quel type d'adresse de résidence voulez-vous créer?
|
||||
The address of another person: L'adresse d'une autre personne
|
||||
The address of a third party: L'adresse d'un tiers
|
||||
A new address: Une nouvelle adresse
|
||||
residential_address_person_explanation: L'adresse sera positionnée auprès d'un usager. Lorsque l'usager déménage, l'adresse de résidence suivra également cet usager
|
||||
residential_address_third_party_explanation: L'adresse sera associée à celle d'un tiers.
|
||||
residential_address_new_address_explanation: Créer une nouvelle adresse. L'adresse sera fixe.
|
||||
New residential address: Nouvelle adresse de résidence
|
||||
Host person: Choisir l'adresse d'un usager
|
||||
Host third party: Choisir l'adresse d'un tiers
|
||||
The new residential address was created successfully: La nouvelle adresse de résidence a été créée
|
||||
Edit a residential address: Modifier l'addresse de résidence
|
||||
The residential address was updated successfully: L'adresse de résidence a été mise à jour
|
||||
Residential addresses: Adresses de résidence
|
||||
Address of: Adresse de
|
||||
Delete residential address: Supprimer l'adresse de résidence
|
||||
Delete residential address ?: Supprimer l'adresse de résidence ?
|
||||
Are you sure you want to remove this residential address for %name% ?: Êtes-vous sûr de vouloir supprimer l'adresse de résidence pour %name% ?
|
||||
Residential address had been deleted: L'adresse de résidence a été supprimée
|
||||
|
||||
|
||||
#timeline
|
||||
Timeline: Historique
|
||||
Closing the accompanying period: Fermeture de la période d'accompagnement
|
||||
@ -533,3 +558,6 @@ household_composition:
|
||||
|
||||
# docgen
|
||||
Linked evaluations: Évaluations associées
|
||||
|
||||
# Accompanying period per user
|
||||
My accompanying periods: Mes parcours
|
||||
|
@ -28,7 +28,9 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
final class ReportVoterTest extends KernelTestCase
|
||||
{
|
||||
use PrepareCenterTrait;
|
||||
|
||||
use PrepareScopeTrait;
|
||||
|
||||
use PrepareUserTrait;
|
||||
|
||||
/**
|
||||
|
@ -99,7 +99,7 @@
|
||||
<div class="item-col">
|
||||
{% if options['isConfidential'] %}
|
||||
<div class="confidential">
|
||||
<div class="confidential-content blur">
|
||||
<div class="confidential-content">
|
||||
<ul class="list-content fa-ul">
|
||||
<li>
|
||||
{{ thirdparty.getAddress|chill_entity_render_box({
|
||||
|
Loading…
x
Reference in New Issue
Block a user