mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-12-04 01:18:29 +00:00
Compare commits
2 Commits
475-sugges
...
459-invita
| Author | SHA1 | Date | |
|---|---|---|---|
| cb56c7d0ad | |||
| 42ac813b6f |
6
.changes/unreleased/Feature-20251125-165811.yaml
Normal file
6
.changes/unreleased/Feature-20251125-165811.yaml
Normal 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
|
||||||
7
.changes/unreleased/Fixed-20251118-140559.yaml
Normal file
7
.changes/unreleased/Fixed-20251118-140559.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: |
|
||||||
|
Associate activity's creator as a participant by default, and retro-actively append the creator to each activity
|
||||||
|
time: 2025-11-18T14:05:59.904993123+01:00
|
||||||
|
custom:
|
||||||
|
Issue: "466"
|
||||||
|
SchemaChange: Add columns or tables
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
kind: Fixed
|
|
||||||
body: Do not suggest a user that is no longer active in the activity form.
|
|
||||||
time: 2025-12-01T18:58:59.410998029+01:00
|
|
||||||
custom:
|
|
||||||
Issue: "475"
|
|
||||||
SchemaChange: No schema change
|
|
||||||
6
.changes/unreleased/UX-20251119-153706.yaml
Normal file
6
.changes/unreleased/UX-20251119-153706.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: UX
|
||||||
|
body: Alphabetically order userJobs and mainLocations within user creation form
|
||||||
|
time: 2025-11-19T15:37:06.393470745+01:00
|
||||||
|
custom:
|
||||||
|
Issue: "470"
|
||||||
|
SchemaChange: No schema change
|
||||||
6
.changes/unreleased/UX-20251124-151115.yaml
Normal file
6
.changes/unreleased/UX-20251124-151115.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: UX
|
||||||
|
body: Change position and color of confirm parcours button
|
||||||
|
time: 2025-11-24T15:11:15.960279853+01:00
|
||||||
|
custom:
|
||||||
|
Issue: "437"
|
||||||
|
SchemaChange: No schema change
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
## v4.8.2 - 2025-11-26
|
|
||||||
### Fixed
|
|
||||||
* ([#466](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/466)) Associate activity's creator as a participant by default, and retro-actively append the creator to each activity
|
|
||||||
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
* Fix template parameter for update_multiple route on event participations
|
|
||||||
### UX
|
|
||||||
* ([#470](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/470)) Alphabetically order userJobs and mainLocations within user creation form
|
|
||||||
* ([#437](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/437)) Change position and color of confirm parcours button
|
|
||||||
@@ -6,15 +6,6 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
|||||||
and is generated by [Changie](https://github.com/miniscruff/changie).
|
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||||
|
|
||||||
|
|
||||||
## v4.8.2 - 2025-11-26
|
|
||||||
### Fixed
|
|
||||||
* ([#466](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/466)) Associate activity's creator as a participant by default, and retro-actively append the creator to each activity
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
* Fix template parameter for update_multiple route on event participations
|
|
||||||
### UX
|
|
||||||
* ([#470](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/470)) Alphabetically order userJobs and mainLocations within user creation form
|
|
||||||
* ([#437](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/437)) Change position and color of confirm parcours button
|
|
||||||
|
|
||||||
## v4.8.1 - 2025-11-20
|
## v4.8.1 - 2025-11-20
|
||||||
### Fixed
|
### Fixed
|
||||||
* Insert name of file as the document title when uploading
|
* Insert name of file as the document title when uploading
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ const store = createStore({
|
|||||||
}
|
}
|
||||||
// console.log("suggested users", suggestedUsers);
|
// console.log("suggested users", suggestedUsers);
|
||||||
|
|
||||||
return suggestedUsers.filter((u) => u.enabled === true);
|
return suggestedUsers;
|
||||||
},
|
},
|
||||||
suggestedResources(state) {
|
suggestedResources(state) {
|
||||||
// const resources = state.activity.accompanyingPeriod.resources;
|
// const resources = state.activity.accompanyingPeriod.resources;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\CalendarBundle\Menu;
|
namespace Chill\CalendarBundle\Menu;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Repository\InviteRepository;
|
||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
@@ -18,10 +19,12 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
|
|
||||||
class UserMenuBuilder implements LocalMenuBuilderInterface
|
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)
|
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
||||||
{
|
{
|
||||||
|
$invitationsPending = $this->inviteRepository->countPendingInvitesByUser($this->security->getUser());
|
||||||
|
|
||||||
if ($this->security->isGranted('ROLE_USER')) {
|
if ($this->security->isGranted('ROLE_USER')) {
|
||||||
$menu->addChild('My calendar list', [
|
$menu->addChild('My calendar list', [
|
||||||
'route' => 'chill_calendar_calendar_list_my',
|
'route' => 'chill_calendar_calendar_list_my',
|
||||||
@@ -30,12 +33,14 @@ class UserMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
'order' => 8,
|
'order' => 8,
|
||||||
'icon' => 'tasks',
|
'icon' => 'tasks',
|
||||||
]);
|
]);
|
||||||
$menu->addChild('invite.list.title', [
|
$menu->addChild(
|
||||||
'route' => 'chill_calendar_invitations_list_my',
|
$this->translator->trans('invite.menu with counter', ['nb' => $invitationsPending]),
|
||||||
])
|
['route' => 'chill_calendar_invitations_list_my']
|
||||||
|
)
|
||||||
->setExtras([
|
->setExtras([
|
||||||
'order' => 9,
|
'order' => 9,
|
||||||
'icon' => 'tasks',
|
'icon' => 'tasks',
|
||||||
|
'counter' => 0 < $invitationsPending ? $invitationsPending : null,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,25 @@ class InviteRepository implements ObjectRepository
|
|||||||
->getSingleScalarResult();
|
->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)
|
public function buildAcceptedInviteByUserAndDateRangeQuery(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to)
|
||||||
{
|
{
|
||||||
$qb = $this->entityRepository->createQueryBuilder('i');
|
$qb = $this->entityRepository->createQueryBuilder('i');
|
||||||
|
|||||||
@@ -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.}
|
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.}
|
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}
|
||||||
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ invite:
|
|||||||
list:
|
list:
|
||||||
none: Il n'y aucun invitation
|
none: Il n'y aucun invitation
|
||||||
title: Mes invitations
|
title: Mes invitations
|
||||||
|
number of invitations waiting: Invitations en attente
|
||||||
|
|
||||||
# exports
|
# exports
|
||||||
Exports of calendar: Exports des rendez-vous
|
Exports of calendar: Exports des rendez-vous
|
||||||
|
|||||||
@@ -52,31 +52,36 @@ interface BaseMetadataWithHtml extends BaseMetadata {
|
|||||||
html: string;
|
html: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenericDocForAccompanyingCourseDocument extends GenericDocForAccompanyingPeriod {
|
export interface GenericDocForAccompanyingCourseDocument
|
||||||
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "accompanying_course_document";
|
key: "accompanying_course_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
storedObject: StoredObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenericDocForAccompanyingCourseActivityDocument extends GenericDocForAccompanyingPeriod {
|
export interface GenericDocForAccompanyingCourseActivityDocument
|
||||||
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "accompanying_course_activity_document";
|
key: "accompanying_course_activity_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
storedObject: StoredObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenericDocForAccompanyingCourseCalendarDocument extends GenericDocForAccompanyingPeriod {
|
export interface GenericDocForAccompanyingCourseCalendarDocument
|
||||||
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "accompanying_course_calendar_document";
|
key: "accompanying_course_calendar_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
storedObject: StoredObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenericDocForAccompanyingCoursePersonDocument extends GenericDocForAccompanyingPeriod {
|
export interface GenericDocForAccompanyingCoursePersonDocument
|
||||||
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "person_document";
|
key: "person_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
storedObject: StoredObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenericDocForAccompanyingCourseWorkEvaluationDocument extends GenericDocForAccompanyingPeriod {
|
export interface GenericDocForAccompanyingCourseWorkEvaluationDocument
|
||||||
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "accompanying_period_work_evaluation_document";
|
key: "accompanying_period_work_evaluation_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
storedObject: StoredObject;
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ export interface StoredObjectVersionCreated extends StoredObjectVersion {
|
|||||||
persisted: false;
|
persisted: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StoredObjectVersionPersisted extends StoredObjectVersionCreated {
|
export interface StoredObjectVersionPersisted
|
||||||
|
extends StoredObjectVersionCreated {
|
||||||
version: number;
|
version: number;
|
||||||
id: number;
|
id: number;
|
||||||
createdAt: DateTime | null;
|
createdAt: DateTime | null;
|
||||||
@@ -60,7 +61,8 @@ export interface StoredObjectStatusChange {
|
|||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StoredObjectVersionWithPointInTime extends StoredObjectVersionPersisted {
|
export interface StoredObjectVersionWithPointInTime
|
||||||
|
extends StoredObjectVersionPersisted {
|
||||||
"point-in-times": StoredObjectPointInTime[];
|
"point-in-times": StoredObjectPointInTime[];
|
||||||
"from-restored": StoredObjectVersionPersisted | null;
|
"from-restored": StoredObjectVersionPersisted | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -486,7 +486,7 @@ final class ParticipationController extends AbstractController
|
|||||||
|
|
||||||
return $this->redirectToRoute(
|
return $this->redirectToRoute(
|
||||||
'chill_event__event_show',
|
'chill_event__event_show',
|
||||||
['id' => $event->getId()]
|
['event_id' => $event->getId()]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ export interface TransportExceptionInterface {
|
|||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ValidationExceptionInterface extends TransportExceptionInterface {
|
export interface ValidationExceptionInterface
|
||||||
|
extends TransportExceptionInterface {
|
||||||
name: "ValidationException";
|
name: "ValidationException";
|
||||||
error: object;
|
error: object;
|
||||||
violations: string[];
|
violations: string[];
|
||||||
@@ -40,7 +41,8 @@ export interface AccessExceptionInterface extends TransportExceptionInterface {
|
|||||||
violations: string[];
|
violations: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NotFoundExceptionInterface extends TransportExceptionInterface {
|
export interface NotFoundExceptionInterface
|
||||||
|
extends TransportExceptionInterface {
|
||||||
name: "NotFoundException";
|
name: "NotFoundException";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +53,8 @@ export interface ServerExceptionInterface extends TransportExceptionInterface {
|
|||||||
body: string;
|
body: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConflictHttpExceptionInterface extends TransportExceptionInterface {
|
export interface ConflictHttpExceptionInterface
|
||||||
|
extends TransportExceptionInterface {
|
||||||
name: "ConflictHttpException";
|
name: "ConflictHttpException";
|
||||||
violations: string[];
|
violations: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ class UserNormalizer implements ContextAwareNormalizerInterface, NormalizerAware
|
|||||||
'isAbsent' => false,
|
'isAbsent' => false,
|
||||||
'absenceStart' => null,
|
'absenceStart' => null,
|
||||||
'absenceEnd' => null,
|
'absenceEnd' => null,
|
||||||
'enabled' => true,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(private readonly UserRender $userRender, private readonly ClockInterface $clock) {}
|
public function __construct(private readonly UserRender $userRender, private readonly ClockInterface $clock) {}
|
||||||
@@ -109,7 +108,6 @@ class UserNormalizer implements ContextAwareNormalizerInterface, NormalizerAware
|
|||||||
'isAbsent' => $object->isAbsent(),
|
'isAbsent' => $object->isAbsent(),
|
||||||
'absenceStart' => $this->normalizer->normalize($object->getAbsenceStart(), $format, $absenceDatesContext),
|
'absenceStart' => $this->normalizer->normalize($object->getAbsenceStart(), $format, $absenceDatesContext),
|
||||||
'absenceEnd' => $this->normalizer->normalize($object->getAbsenceEnd(), $format, $absenceDatesContext),
|
'absenceEnd' => $this->normalizer->normalize($object->getAbsenceEnd(), $format, $absenceDatesContext),
|
||||||
'enabled' => $object->isEnabled(),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if ('docgen' === $format) {
|
if ('docgen' === $format) {
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ final class UserNormalizerTest extends TestCase
|
|||||||
'main_center' => ['context' => Center::class],
|
'main_center' => ['context' => Center::class],
|
||||||
'absenceStart' => ['context' => \DateTimeImmutable::class],
|
'absenceStart' => ['context' => \DateTimeImmutable::class],
|
||||||
'absenceEnd' => ['context' => \DateTimeImmutable::class],
|
'absenceEnd' => ['context' => \DateTimeImmutable::class],
|
||||||
'enabled' => true
|
|
||||||
]];
|
]];
|
||||||
|
|
||||||
yield [$userNoPhone, 'docgen', ['docgen:expects' => User::class],
|
yield [$userNoPhone, 'docgen', ['docgen:expects' => User::class],
|
||||||
@@ -125,7 +124,6 @@ final class UserNormalizerTest extends TestCase
|
|||||||
'main_center' => ['context' => Center::class],
|
'main_center' => ['context' => Center::class],
|
||||||
'absenceStart' => ['context' => \DateTimeImmutable::class],
|
'absenceStart' => ['context' => \DateTimeImmutable::class],
|
||||||
'absenceEnd' => ['context' => \DateTimeImmutable::class],
|
'absenceEnd' => ['context' => \DateTimeImmutable::class],
|
||||||
'enabled' => true
|
|
||||||
]];
|
]];
|
||||||
|
|
||||||
yield [null, 'docgen', ['docgen:expects' => User::class], [
|
yield [null, 'docgen', ['docgen:expects' => User::class], [
|
||||||
@@ -146,7 +144,6 @@ final class UserNormalizerTest extends TestCase
|
|||||||
'main_center' => ['context' => Center::class],
|
'main_center' => ['context' => Center::class],
|
||||||
'absenceStart' => null,
|
'absenceStart' => null,
|
||||||
'absenceEnd' => null,
|
'absenceEnd' => null,
|
||||||
'enabled' => true
|
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user