Platform: Improve event management by type in calendar - refs #5270

pull/5291/head
christianbeeznst 2 years ago
parent 6096110fd0
commit 2de9ba5832
  1. 51
      assets/vue/views/ccalendarevent/CCalendarEventList.vue
  2. 13
      src/CoreBundle/ApiResource/CalendarEvent.php
  3. 9
      src/CoreBundle/DataProvider/Extension/CCalendarEventExtension.php
  4. 8
      src/CoreBundle/DataTransformer/CalendarEventTransformer.php
  5. 23
      src/CoreBundle/Filter/GlobalEventFilter.php
  6. 32
      src/CourseBundle/Repository/CCalendarEventRepository.php

@ -1,10 +1,10 @@
<template> <template>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<CalendarSectionHeader <!--CalendarSectionHeader
@add-click="showAddEventDialog" @add-click="showAddEventDialog"
@my-students-schedule-click="goToMyStudentsSchedule" @my-students-schedule-click="goToMyStudentsSchedule"
@session-planning-click="goToSessionPanning" @session-planning-click="goToSessionPanning"
/> /-->
<FullCalendar <FullCalendar
ref="cal" ref="cal"
@ -73,17 +73,18 @@
/> />
<BaseButton <BaseButton
v-if="showDeleteButton"
:label="t('Delete')" :label="t('Delete')"
icon="delete" icon="delete"
type="danger" type="danger"
@click="confirmDelete" @click="confirmDelete"
/> />
<BaseButton <BaseButton
v-if="allowToEdit" v-if="allowToEdit && showEditButton"
:label="t('Edit')" :label="t('Edit')"
type="secondary" type="secondary"
@click="dialog = true" @click="dialog = true"
/> icon="delete"/>
</template> </template>
</Dialog> </Dialog>
@ -213,11 +214,23 @@ async function getCalendarEvents({ startStr, endStr }) {
const calendarEvents = await cCalendarEventService.findAll({ params }).then((response) => response.json()) const calendarEvents = await cCalendarEventService.findAll({ params }).then((response) => response.json())
return calendarEvents["hydra:member"].map((event) => ({ return calendarEvents["hydra:member"].map((event) => {
let color = '#007BFF'
if (event.type === 'global') {
color = '#FF0000'
} else if (event.type === 'course') {
color = '#28a745'
} else if (event.type === 'session') {
color = '#800080'
}
return {
...event, ...event,
start: event.startDate, start: event.startDate,
end: event.endDate, end: event.endDate,
})) color,
}
})
} }
const calendarLocale = allLocales.find( const calendarLocale = allLocales.find(
@ -299,6 +312,32 @@ const calendarOptions = ref({
}, },
}) })
const currentContext = computed(() => {
if (route.query.type === 'global') {
return 'global'
} else if (course.value) {
return 'course'
} else if (session.value) {
return 'session'
} else {
return 'personal'
}
});
const allowAction = (eventType) => {
const contextRules = {
global: ['global'],
course: ['course'],
session: ['session'],
personal: ['personal']
};
return contextRules[currentContext.value].includes(eventType);
};
const showEditButton = computed(() => allowAction(item.value.type));
const showDeleteButton = computed(() => allowAction(item.value.type));
const cal = ref(null) const cal = ref(null)
function reFetch() { function reFetch() {

@ -43,7 +43,20 @@ class CalendarEvent extends AbstractResource
#[Groups(['calendar_event:read'])] #[Groups(['calendar_event:read'])]
public ?ResourceNode $resourceNode = null, public ?ResourceNode $resourceNode = null,
?array $resourceLinkListFromEntity = null, ?array $resourceLinkListFromEntity = null,
#[Groups(['calendar_event:read'])]
public ?string $type = null,
) { ) {
$this->resourceLinkListFromEntity = $resourceLinkListFromEntity; $this->resourceLinkListFromEntity = $resourceLinkListFromEntity;
} }
public function getType(): ?string
{
return $this->type;
}
public function setType(?string $type): self
{
$this->type = $type;
return $this;
}
} }

@ -35,15 +35,20 @@ final class CCalendarEventExtension implements QueryCollectionExtensionInterface
?Operation $operation = null, ?Operation $operation = null,
array $context = [] array $context = []
): void { ): void {
$this->addWhere($queryBuilder, $resourceClass); $this->addWhere($queryBuilder, $resourceClass, $context);
} }
private function addWhere(QueryBuilder $qb, string $resourceClass): void private function addWhere(QueryBuilder $qb, string $resourceClass, array $context): void
{ {
if (CCalendarEvent::class !== $resourceClass) { if (CCalendarEvent::class !== $resourceClass) {
return; return;
} }
$isGlobalType = isset($context['filters']['type']) && $context['filters']['type'] === 'global';
if ($isGlobalType) {
return;
}
$courseId = $this->cidReqHelper->getCourseId(); $courseId = $this->cidReqHelper->getCourseId();
$sessionId = $this->cidReqHelper->getSessionId(); $sessionId = $this->cidReqHelper->getSessionId();
$groupId = $this->cidReqHelper->getGroupId(); $groupId = $this->cidReqHelper->getGroupId();

@ -12,6 +12,7 @@ use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\SessionRelCourse; use Chamilo\CoreBundle\Entity\SessionRelCourse;
use Chamilo\CoreBundle\Repository\Node\UsergroupRepository; use Chamilo\CoreBundle\Repository\Node\UsergroupRepository;
use Chamilo\CourseBundle\Entity\CCalendarEvent; use Chamilo\CourseBundle\Entity\CCalendarEvent;
use Chamilo\CourseBundle\Repository\CCalendarEventRepository;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Routing\RouterInterface;
@ -20,6 +21,7 @@ class CalendarEventTransformer implements DataTransformerInterface
public function __construct( public function __construct(
private readonly RouterInterface $router, private readonly RouterInterface $router,
private readonly UsergroupRepository $usergroupRepository, private readonly UsergroupRepository $usergroupRepository,
private readonly CCalendarEventRepository $calendarEventRepository
) {} ) {}
public function transform($object, string $to, array $context = []): object public function transform($object, string $to, array $context = []): object
@ -48,7 +50,8 @@ class CalendarEventTransformer implements DataTransformerInterface
$subscriptionItemTitle = $this->usergroupRepository->find($object->getSubscriptionItemId())?->getTitle(); $subscriptionItemTitle = $this->usergroupRepository->find($object->getSubscriptionItemId())?->getTitle();
} }
return new CalendarEvent( $eventType = $this->calendarEventRepository->determineEventType($object);
$calendarEvent = new CalendarEvent(
'calendar_event_'.$object->getIid(), 'calendar_event_'.$object->getIid(),
$object->getTitle(), $object->getTitle(),
$object->getContent(), $object->getContent(),
@ -65,6 +68,9 @@ class CalendarEventTransformer implements DataTransformerInterface
$object->getResourceNode(), $object->getResourceNode(),
$object->getResourceLinkListFromEntity(), $object->getResourceLinkListFromEntity(),
); );
$calendarEvent->setType($eventType);
return $calendarEvent;
} }
private function mapSessionToDto(object $object): CalendarEvent private function mapSessionToDto(object $object): CalendarEvent

@ -35,11 +35,13 @@ class GlobalEventFilter extends AbstractFilter
array $context = [] array $context = []
): void { ): void {
$isGlobalType = isset($context['filters']['type']) && $context['filters']['type'] === 'global'; $isGlobalType = isset($context['filters']['type']) && $context['filters']['type'] === 'global';
if (!$isGlobalType) {
return;
}
$rootAlias = $queryBuilder->getRootAliases()[0]; $rootAlias = $queryBuilder->getRootAliases()[0];
$resourceNodeAlias = $queryNameGenerator->generateJoinAlias('resourceNode'); $resourceNodeAlias = $queryNameGenerator->generateJoinAlias('resourceNode');
$resourceLinkAlias = $queryNameGenerator->generateJoinAlias('resourceLink'); $resourceLinkAlias = $queryNameGenerator->generateJoinAlias('resourceLink');
if ($isGlobalType) {
$queryBuilder $queryBuilder
->innerJoin("$rootAlias.resourceNode", $resourceNodeAlias) ->innerJoin("$rootAlias.resourceNode", $resourceNodeAlias)
->innerJoin("$resourceNodeAlias.resourceLinks", $resourceLinkAlias) ->innerJoin("$resourceNodeAlias.resourceLinks", $resourceLinkAlias)
@ -47,25 +49,6 @@ class GlobalEventFilter extends AbstractFilter
->andWhere("$resourceLinkAlias.session IS NULL") ->andWhere("$resourceLinkAlias.session IS NULL")
->andWhere("$resourceLinkAlias.group IS NULL") ->andWhere("$resourceLinkAlias.group IS NULL")
->andWhere("$resourceLinkAlias.user IS NULL"); ->andWhere("$resourceLinkAlias.user IS NULL");
return;
}
if (!$isGlobalType) {
$subQueryBuilder = $queryBuilder->getEntityManager()->createQueryBuilder();
$subRN = $queryNameGenerator->generateJoinAlias('subResourceNode');
$subRL = $queryNameGenerator->generateJoinAlias('subResourceLink');
$subQueryBuilder->select('1')
->from(ResourceNode::class, $subRN)
->innerJoin("$subRN.resourceLinks", $subRL)
->where("$subRL.course IS NULL")
->andWhere("$subRL.session IS NULL")
->andWhere("$subRL.group IS NULL")
->andWhere("$subRL.user IS NULL")
->andWhere("$subRN.id = $rootAlias.resourceNode");
$queryBuilder->andWhere($queryBuilder->expr()->not($queryBuilder->expr()->exists($subQueryBuilder->getDQL())));
}
} }
public function getDescription(string $resourceClass): array public function getDescription(string $resourceClass): array

@ -8,6 +8,7 @@ namespace Chamilo\CourseBundle\Repository;
use Chamilo\CoreBundle\Entity\AbstractResource; use Chamilo\CoreBundle\Entity\AbstractResource;
use Chamilo\CoreBundle\Entity\Course; use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\ResourceLink;
use Chamilo\CoreBundle\Entity\Session; use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\User; use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Repository\ResourceRepository; use Chamilo\CoreBundle\Repository\ResourceRepository;
@ -76,4 +77,35 @@ final class CCalendarEventRepository extends ResourceRepository
return $event; return $event;
} }
public function determineEventType(CCalendarEvent $event): string
{
$em = $this->getEntityManager();
$queryBuilder = $em->createQueryBuilder();
$queryBuilder
->select('rl')
->from(ResourceLink::class, 'rl')
->innerJoin('rl.resourceNode', 'rn')
->where('rn.id = :resourceNodeId')
->setParameter('resourceNodeId', $event->getResourceNode()->getId());
$resourceLinks = $queryBuilder->getQuery()->getResult();
foreach ($resourceLinks as $link) {
if (null === $link->getCourse() && null === $link->getSession() && null === $link->getGroup() && null === $link->getUser()) {
return 'global';
}
if (null !== $link->getCourse()) {
return 'course';
}
if (null !== $link->getSession()) {
return 'session';
}
}
return 'personal';
}
} }

Loading…
Cancel
Save