mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-18 04:34:59 +00:00
Compare commits
12 Commits
2.0.0
...
add_user_f
Author | SHA1 | Date | |
---|---|---|---|
714d0ed991 | |||
ed96017c49 | |||
37e92ca58d | |||
593adadef1 | |||
f5b71a0c41 | |||
f42e1723ab | |||
2178833da7 | |||
23ee29ab0d | |||
199223293e
|
|||
520d5ab6d4 | |||
c73beef3af | |||
73b95732db
|
6
.changes/unreleased/DX-20230607-130344.yaml
Normal file
6
.changes/unreleased/DX-20230607-130344.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
kind: DX
|
||||
body: Add methods to RegroupmentRepository and fullfill Center / Regroupment Doctrine
|
||||
mapping
|
||||
time: 2023-06-07T13:03:44.177864269+02:00
|
||||
custom:
|
||||
Issue: ""
|
6
.changes/unreleased/Feature-20230607-194040.yaml
Normal file
6
.changes/unreleased/Feature-20230607-194040.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
kind: Feature
|
||||
body: Add the possibility to filter tasks on the basis of the person involved. Expansion
|
||||
of FilterOrderHelper.
|
||||
time: 2023-06-07T19:40:40.506964817+02:00
|
||||
custom:
|
||||
Issue: ""
|
7
.changes/unreleased/Security-20230607-174702.yaml
Normal file
7
.changes/unreleased/Security-20230607-174702.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
kind: Security
|
||||
body: Rights are checked for display of 'accompanying period' tab in household menu.
|
||||
Rights are also checked for creation of 'accompanying period' from within household
|
||||
context
|
||||
time: 2023-06-07T17:47:02.488819553+02:00
|
||||
custom:
|
||||
Issue: "105"
|
@@ -48,12 +48,19 @@ class Center implements HasCenterInterface
|
||||
*/
|
||||
private string $name = '';
|
||||
|
||||
/**
|
||||
* @var Collection<Regroupment>
|
||||
* @ORM\ManyToMany(targetEntity=Regroupment::class, mappedBy="centers")
|
||||
*/
|
||||
private Collection $regroupments;
|
||||
|
||||
/**
|
||||
* Center constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->groupCenters = new \Doctrine\Common\Collections\ArrayCollection();
|
||||
$this->groupCenters = new ArrayCollection();
|
||||
$this->regroupments = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,6 +113,14 @@ class Center implements HasCenterInterface
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<Regroupment>
|
||||
*/
|
||||
public function getRegroupments(): Collection
|
||||
{
|
||||
return $this->regroupments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
|
@@ -22,11 +22,12 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
class Regroupment
|
||||
{
|
||||
/**
|
||||
* @var Center
|
||||
* @ORM\ManyToMany(
|
||||
* targetEntity=Center::class
|
||||
* targetEntity=Center::class,
|
||||
* inversedBy="regroupments"
|
||||
* )
|
||||
* @ORM\Id
|
||||
* @var Collection<Center>
|
||||
*/
|
||||
private Collection $centers;
|
||||
|
||||
@@ -52,6 +53,26 @@ class Regroupment
|
||||
$this->centers = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function addCenter(Center $center): self
|
||||
{
|
||||
if (!$this->centers->contains($center)) {
|
||||
$this->centers->add($center);
|
||||
$center->getRegroupments()->add($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeCenter(Center $center): self
|
||||
{
|
||||
if ($this->centers->contains($center)) {
|
||||
$this->centers->removeElement($center);
|
||||
$center->getRegroupments()->removeElement($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCenters(): Collection
|
||||
{
|
||||
return $this->centers;
|
||||
|
@@ -31,7 +31,7 @@ class RegroupmentType extends AbstractType
|
||||
->add('centers', EntityType::class, [
|
||||
'class' => Center::class,
|
||||
'multiple' => true,
|
||||
'attr' => ['class' => 'select2'],
|
||||
'expanded' => true,
|
||||
])
|
||||
->add('isActive', CheckboxType::class, [
|
||||
'label' => 'Actif ?',
|
||||
|
@@ -13,6 +13,8 @@ namespace Chill\MainBundle\Form\Type\Listing;
|
||||
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
||||
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||
use Chill\PersonBundle\Form\Type\PickPersonType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SearchType;
|
||||
@@ -97,6 +99,30 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType
|
||||
$builder->add($dateRangesBuilder);
|
||||
}
|
||||
|
||||
if (0 < count($helper->getPersonPickers())) {
|
||||
$personPickersBuilder = $builder->create('personPicker', null, ['compound' => true]);
|
||||
|
||||
foreach ($helper->getPersonPickers() as $name => $opts) {
|
||||
$personPicker = $personPickersBuilder->create($name, null, [
|
||||
'compound' => true,
|
||||
'label' => null === $opts['label'] ? false : $opts['label'] ?? $name,
|
||||
]);
|
||||
|
||||
$personPicker->add(
|
||||
'person',
|
||||
PickPersonDynamicType::class,
|
||||
[
|
||||
'multiple' => false,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
$personPickersBuilder->add($personPicker);
|
||||
}
|
||||
|
||||
$builder->add($personPickersBuilder);
|
||||
}
|
||||
|
||||
foreach ($this->requestStack->getCurrentRequest()->query->getIterator() as $key => $value) {
|
||||
switch ($key) {
|
||||
case 'q':
|
||||
|
@@ -14,6 +14,8 @@ namespace Chill\MainBundle\Repository;
|
||||
use Chill\MainBundle\Entity\Regroupment;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\NonUniqueResultException;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
final class RegroupmentRepository implements ObjectRepository
|
||||
@@ -59,6 +61,30 @@ final class RegroupmentRepository implements ObjectRepository
|
||||
return $this->repository->findOneBy($criteria, $orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NonUniqueResultException
|
||||
* @throws NoResultException
|
||||
*/
|
||||
public function findOneByName(string $name): ?Regroupment
|
||||
{
|
||||
return $this->repository->createQueryBuilder('r')
|
||||
->where('LOWER(r.name) = LOWER(:searched)')
|
||||
->setParameter('searched', $name)
|
||||
->getQuery()
|
||||
->getSingleResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<Regroupment>
|
||||
*/
|
||||
public function findRegroupmentAssociatedToNoCenter(): array
|
||||
{
|
||||
return $this->repository->createQueryBuilder('r')
|
||||
->where('SIZE(r.centers) = 0')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return Regroupment::class;
|
||||
|
@@ -34,6 +34,35 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if form.personPicker is defined %}
|
||||
{% if form.personPicker|length > 0 %}
|
||||
{% for personPickerName, options in form.personPicker %}
|
||||
<div class="row gx-0">
|
||||
{% if form.personPicker[personPickerName].vars.label is not same as(false) %}
|
||||
<div class="col-md-2">
|
||||
{{ form_label(form.personPicker[personPickerName])}}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="col-md-9">
|
||||
{{ form_widget(form.personPicker[personPickerName]) }}
|
||||
</div>
|
||||
</div>
|
||||
{% if form.checkboxes is not defined %}
|
||||
<div class="row gx-0">
|
||||
<div class="col-md-12">
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button type="submit" class="btn btn-misc"><i class="fa fa-filter"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if form.checkboxes is defined %}
|
||||
{% if form.checkboxes|length > 0 %}
|
||||
{% for checkbox_name, options in form.checkboxes %}
|
||||
@@ -61,5 +90,6 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
|
@@ -26,6 +26,8 @@ class FilterOrderHelper
|
||||
|
||||
private array $dateRanges = [];
|
||||
|
||||
private array $personPickers = [];
|
||||
|
||||
private FormFactoryInterface $formFactory;
|
||||
|
||||
private ?string $formName = 'f';
|
||||
@@ -70,6 +72,13 @@ class FilterOrderHelper
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addPersonPickers(string $name, ?string $label = null): self
|
||||
{
|
||||
$this->personPickers[$name] = ['label' => $label];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildForm(): FormInterface
|
||||
{
|
||||
return $this->formFactory
|
||||
@@ -91,6 +100,16 @@ class FilterOrderHelper
|
||||
return $this->checkboxes;
|
||||
}
|
||||
|
||||
public function getPersonPickers(): array
|
||||
{
|
||||
return $this->personPickers;
|
||||
}
|
||||
|
||||
public function getPersonPickerData(string $name): array
|
||||
{
|
||||
return $this->getFormData()['personPickers'][$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<'to': DateTimeImmutable, 'from': DateTimeImmutable>
|
||||
*/
|
||||
@@ -133,6 +152,10 @@ class FilterOrderHelper
|
||||
$r['checkboxes'][$name] = $c['default'];
|
||||
}
|
||||
|
||||
foreach ($this->personPickers as $name => $defaults) {
|
||||
$r['personPickers'][$name]['label'] = $defaults['label'];
|
||||
}
|
||||
|
||||
foreach ($this->dateRanges as $name => $defaults) {
|
||||
$r['dateRanges'][$name]['from'] = $defaults['from'];
|
||||
$r['dateRanges'][$name]['to'] = $defaults['to'];
|
||||
|
@@ -21,6 +21,8 @@ class FilterOrderHelperBuilder
|
||||
|
||||
private array $dateRanges = [];
|
||||
|
||||
private array $personPickers = [];
|
||||
|
||||
private FormFactoryInterface $formFactory;
|
||||
|
||||
private RequestStack $requestStack;
|
||||
@@ -56,6 +58,13 @@ class FilterOrderHelperBuilder
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addPersonPicker(string $name, ?string $label = null): self
|
||||
{
|
||||
$this->personPickers[$name] = ['label' => $label];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function build(): FilterOrderHelper
|
||||
{
|
||||
$helper = new FilterOrderHelper(
|
||||
@@ -85,6 +94,14 @@ class FilterOrderHelperBuilder
|
||||
$helper->addDateRange($name, $label, $from, $to);
|
||||
}
|
||||
|
||||
foreach (
|
||||
$this->personPickers as $name => [
|
||||
'label' => $label,
|
||||
]
|
||||
) {
|
||||
$helper->addPersonPickers($name, $label);
|
||||
}
|
||||
|
||||
return $helper;
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,9 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Menu;
|
||||
|
||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Knp\Menu\MenuItem;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
||||
@@ -22,9 +24,12 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
private Security $security;
|
||||
|
||||
public function __construct(TranslatorInterface $translator, Security $security)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
public function buildMenu($menuId, MenuItem $menu, array $parameters): void
|
||||
@@ -53,12 +58,14 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
||||
], ])
|
||||
->setExtras(['order' => 17]);
|
||||
|
||||
$menu->addChild($this->translator->trans('household.Accompanying period'), [
|
||||
'route' => 'chill_person_household_accompanying_period',
|
||||
'routeParameters' => [
|
||||
'household_id' => $household->getId(),
|
||||
], ])
|
||||
->setExtras(['order' => 20]);
|
||||
if ($this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['household'])) {
|
||||
$menu->addChild($this->translator->trans('household.Accompanying period'), [
|
||||
'route' => 'chill_person_household_accompanying_period',
|
||||
'routeParameters' => [
|
||||
'household_id' => $household->getId(),
|
||||
],])
|
||||
->setExtras(['order' => 20]);
|
||||
}
|
||||
|
||||
$menu->addChild($this->translator->trans('household.Addresses'), [
|
||||
'route' => 'chill_person_household_addresses',
|
||||
|
@@ -40,13 +40,14 @@
|
||||
{{ 'Household summary'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{# TODO: add ACL to check if user is allowed to edit household? #}
|
||||
<li>
|
||||
<a class="btn btn-create"
|
||||
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
||||
{{ 'Create an accompanying period'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% if is_granted('CHILL_PERSON_HOUSEHOLD_EDIT', household) %}
|
||||
<li>
|
||||
<a class="btn btn-create"
|
||||
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
||||
{{ 'Create an accompanying period'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
@@ -303,6 +303,7 @@ final class SingleTaskController extends AbstractController
|
||||
$filterOrder->getCheckboxData('status'),
|
||||
array_map(static fn ($i) => 'state_' . $i, $filterOrder->getCheckboxData('states'))
|
||||
);
|
||||
|
||||
$nb = $this->singleTaskAclAwareRepository->countByAllViewable(
|
||||
$filterOrder->getQueryString(),
|
||||
$flags
|
||||
@@ -678,6 +679,7 @@ final class SingleTaskController extends AbstractController
|
||||
return $this->filterOrderHelperFactory
|
||||
->create(self::class)
|
||||
->addSearchBox()
|
||||
->addPersonPicker('personPicker')
|
||||
->addCheckbox('status', $statuses, $statuses, $statusTrans)
|
||||
->addCheckbox('states', $states, ['new', 'in_progress'])
|
||||
->build();
|
||||
|
@@ -27,8 +27,10 @@
|
||||
{% block css %}
|
||||
{{ parent() }}
|
||||
{{ encore_entry_link_tags('page_task_list') }}
|
||||
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
{{ parent() }}
|
||||
{{ encore_entry_script_tags('page_task_list') }}
|
||||
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
|
@@ -119,3 +119,5 @@ CHILL_TASK_TASK_UPDATE: Modifier une tâche
|
||||
CHILL_TASK_TASK_CREATE_FOR_COURSE: Créer une tâche pour un parcours
|
||||
CHILL_TASK_TASK_CREATE_FOR_PERSON: Créer une tâche pour un usager
|
||||
|
||||
filter:
|
||||
Filter on user: Filtrer par utilisateur/ utilisatrice
|
||||
|
Reference in New Issue
Block a user