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

pull/5291/head
christianbeeznst 2 years ago
parent 6096110fd0
commit 2de9ba5832
  1. 57
      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. 37
      src/CoreBundle/Filter/GlobalEventFilter.php
  6. 32
      src/CourseBundle/Repository/CCalendarEventRepository.php

@ -1,10 +1,10 @@
<template>
<div class="flex flex-col gap-4">
<CalendarSectionHeader
<!--CalendarSectionHeader
@add-click="showAddEventDialog"
@my-students-schedule-click="goToMyStudentsSchedule"
@session-planning-click="goToSessionPanning"
/>
/-->
<FullCalendar
ref="cal"
@ -73,17 +73,18 @@
/>
<BaseButton
v-if="showDeleteButton"
:label="t('Delete')"
icon="delete"
type="danger"
@click="confirmDelete"
/>
<BaseButton
v-if="allowToEdit"
v-if="allowToEdit && showEditButton"
:label="t('Edit')"
type="secondary"
@click="dialog = true"
/>
icon="delete"/>
</template>
</Dialog>
@ -213,11 +214,23 @@ async function getCalendarEvents({ startStr, endStr }) {
const calendarEvents = await cCalendarEventService.findAll({ params }).then((response) => response.json())
return calendarEvents["hydra:member"].map((event) => ({
...event,
start: event.startDate,
end: event.endDate,
}))
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,
start: event.startDate,
end: event.endDate,
color,
}
})
}
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)
function reFetch() {

@ -43,7 +43,20 @@ class CalendarEvent extends AbstractResource
#[Groups(['calendar_event:read'])]
public ?ResourceNode $resourceNode = null,
?array $resourceLinkListFromEntity = null,
#[Groups(['calendar_event:read'])]
public ?string $type = null,
) {
$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,
array $context = []
): 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) {
return;
}
$isGlobalType = isset($context['filters']['type']) && $context['filters']['type'] === 'global';
if ($isGlobalType) {
return;
}
$courseId = $this->cidReqHelper->getCourseId();
$sessionId = $this->cidReqHelper->getSessionId();
$groupId = $this->cidReqHelper->getGroupId();

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

@ -35,37 +35,20 @@ class GlobalEventFilter extends AbstractFilter
array $context = []
): void {
$isGlobalType = isset($context['filters']['type']) && $context['filters']['type'] === 'global';
if (!$isGlobalType) {
return;
}
$rootAlias = $queryBuilder->getRootAliases()[0];
$resourceNodeAlias = $queryNameGenerator->generateJoinAlias('resourceNode');
$resourceLinkAlias = $queryNameGenerator->generateJoinAlias('resourceLink');
if ($isGlobalType) {
$queryBuilder
->innerJoin("$rootAlias.resourceNode", $resourceNodeAlias)
->innerJoin("$resourceNodeAlias.resourceLinks", $resourceLinkAlias)
->andWhere("$resourceLinkAlias.course IS NULL")
->andWhere("$resourceLinkAlias.session IS NULL")
->andWhere("$resourceLinkAlias.group 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())));
}
$queryBuilder
->innerJoin("$rootAlias.resourceNode", $resourceNodeAlias)
->innerJoin("$resourceNodeAlias.resourceLinks", $resourceLinkAlias)
->andWhere("$resourceLinkAlias.course IS NULL")
->andWhere("$resourceLinkAlias.session IS NULL")
->andWhere("$resourceLinkAlias.group IS NULL")
->andWhere("$resourceLinkAlias.user IS NULL");
}
public function getDescription(string $resourceClass): array

@ -8,6 +8,7 @@ namespace Chamilo\CourseBundle\Repository;
use Chamilo\CoreBundle\Entity\AbstractResource;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\ResourceLink;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Repository\ResourceRepository;
@ -76,4 +77,35 @@ final class CCalendarEventRepository extends ResourceRepository
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