Compare commits

..

2 Commits

Author SHA1 Message Date
cb56c7d0ad Add a counter to the user menu item 2025-11-26 05:32:17 +01:00
42ac813b6f Add a counter for invitations awaiting reply 2025-11-25 16:58:19 +01:00
10 changed files with 44 additions and 109 deletions

View File

@@ -1,6 +0,0 @@
kind: DX
body: Add missing fixtures for proper loading of AccompanyingPeriods
time: 2025-10-30T12:37:32.824593456+01:00
custom:
Issue: "280"
SchemaChange: No schema change

View File

@@ -0,0 +1,6 @@
kind: Feature
body: Add a counter for invitations awaiting reply
time: 2025-11-25T16:58:11.780678466+01:00
custom:
Issue: "459"
SchemaChange: No schema change

View File

@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\CalendarBundle\Menu;
use Chill\CalendarBundle\Repository\InviteRepository;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Security;
@@ -18,10 +19,12 @@ use Symfony\Contracts\Translation\TranslatorInterface;
class UserMenuBuilder implements LocalMenuBuilderInterface
{
public function __construct(private readonly Security $security, public TranslatorInterface $translator) {}
public function __construct(private readonly Security $security, public TranslatorInterface $translator, private readonly InviteRepository $inviteRepository) {}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
$invitationsPending = $this->inviteRepository->countPendingInvitesByUser($this->security->getUser());
if ($this->security->isGranted('ROLE_USER')) {
$menu->addChild('My calendar list', [
'route' => 'chill_calendar_calendar_list_my',
@@ -30,12 +33,14 @@ class UserMenuBuilder implements LocalMenuBuilderInterface
'order' => 8,
'icon' => 'tasks',
]);
$menu->addChild('invite.list.title', [
'route' => 'chill_calendar_invitations_list_my',
])
$menu->addChild(
$this->translator->trans('invite.menu with counter', ['nb' => $invitationsPending]),
['route' => 'chill_calendar_invitations_list_my']
)
->setExtras([
'order' => 9,
'icon' => 'tasks',
'counter' => 0 < $invitationsPending ? $invitationsPending : null,
]);
}
}

View File

@@ -75,6 +75,25 @@ class InviteRepository implements ObjectRepository
->getSingleScalarResult();
}
public function countPendingInvitesByUser(User $user): int
{
$qb = $this->entityRepository->createQueryBuilder('i');
$qb->select('COUNT(i)')
->where(
$qb->expr()->andX(
$qb->expr()->eq('i.user', ':user'),
$qb->expr()->eq('i.status', ':status')
)
)
->setParameters([
'user' => $user,
'status' => Invite::PENDING,
]);
return $qb->getQuery()->getSingleScalarResult();
}
public function buildAcceptedInviteByUserAndDateRangeQuery(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to)
{
$qb = $this->entityRepository->createQueryBuilder('i');

View File

@@ -6,3 +6,11 @@ chill_calendar:
few {# rendez-vous sont ignorés par le filtre de date. Modifiez le filtre de date pour les voir apparaitre.}
other {# rendez-vous sont ignorés par le filtre de date. Modifiez le filtre de date pour les voir apparaitre.}
}
invite:
menu with counter: >-
{nb, plural,
=0 {Mes invitations}
one {# invitation}
few {# invitations}
other {# invitations}
}

View File

@@ -96,6 +96,7 @@ invite:
list:
none: Il n'y aucun invitation
title: Mes invitations
number of invitations waiting: Invitations en attente
# exports
Exports of calendar: Exports des rendez-vous

View File

@@ -1,45 +0,0 @@
<?php
declare(strict_types=1);
/*
* 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.
*/
namespace Chill\MainBundle\DataFixtures\ORM;
use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\LocationType;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
class LoadAdministrativeLocation extends AbstractFixture implements OrderedFixtureInterface
{
final public const ADMINISTRATIVE_LOCATION = 'administrative_location';
public function getOrder(): int
{
return 9000;
}
public function load(ObjectManager $manager): void
{
$o = new Location();
/** @var LocationType $locationType */
$locationType = $this->getReference(LoadLocationType::LOCATION_TYPE.'_0');
$o->setLocationType($locationType);
$o->setName('Commune de Bruxelles');
$o->setAvailableForUsers(true);
$manager->persist($o);
$this->addReference(self::ADMINISTRATIVE_LOCATION, $o);
echo "Adding one Administrative Location\n";
$manager->flush();
}
}

View File

@@ -25,8 +25,6 @@ class LoadLocationType extends AbstractFixture implements ContainerAwareInterfac
{
private ?ContainerInterface $container = null;
final public const LOCATION_TYPE = 'location_type';
public function getOrder(): int
{
return 52;
@@ -55,15 +53,13 @@ class LoadLocationType extends AbstractFixture implements ContainerAwareInterfac
],
];
foreach ($arr as $index => $a) {
foreach ($arr as $a) {
$locationType = (new LocationType())
->setTitle($a['name'])
->setAvailableForUsers(true)
->setActive(true)
->setAddressRequired($a['address_required']);
$manager->persist($locationType);
$this->addReference(self::LOCATION_TYPE.'_'.$index, $locationType);
}
$manager->flush();

View File

@@ -1,41 +0,0 @@
<?php
declare(strict_types=1);
/*
* 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.
*/
namespace Chill\MainBundle\DataFixtures\ORM;
use Chill\MainBundle\Entity\UserJob;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
class LoadUserJob extends AbstractFixture implements OrderedFixtureInterface
{
final public const USER_JOB = 'user_job';
private array $socialWorker = ['en' => 'social worker', 'fr' => 'travailleur social'];
public function getOrder(): int
{
return 9000;
}
public function load(ObjectManager $manager): void
{
$o = new UserJob();
$o->setLabel($this->socialWorker);
$manager->persist($o);
$this->addReference(self::USER_JOB, $o);
echo "Adding one AccompanyingPeriod User Job\n";
$manager->flush();
}
}

View File

@@ -11,19 +11,15 @@ declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadAdministrativeLocation;
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
use Chill\MainBundle\DataFixtures\ORM\LoadUserJob;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Country;
use Chill\MainBundle\Entity\Gender;
use Chill\MainBundle\Entity\GenderEnum;
use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\PostalCode;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Repository\CenterRepository;
use Chill\MainBundle\Repository\CountryRepository;
use Chill\MainBundle\Repository\GenderRepository;
@@ -366,10 +362,6 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
$origin = $this->getReference(LoadAccompanyingPeriodOrigin::ACCOMPANYING_PERIOD_ORIGIN, AccompanyingPeriod\Origin::class);
$accompanyingPeriod->setOrigin($origin);
$accompanyingPeriod->setIntensity('regular');
$userJob = $this->getReference(LoadUserJob::USER_JOB, UserJob::class);
$accompanyingPeriod->setJob($userJob);
$administrativeLocation = $this->getReference(LoadAdministrativeLocation::ADMINISTRATIVE_LOCATION, Location::class);
$accompanyingPeriod->setAdministrativeLocation($administrativeLocation);
$accompanyingPeriod->setAddressLocation($this->createAddress());
$manager->persist($accompanyingPeriod->getAddressLocation());
$workflow = $this->workflowRegistry->get($accompanyingPeriod);