added event for recent activities (#2254)

This commit is contained in:
Kevin Papst
2021-01-11 19:13:14 +01:00
committed by GitHub
parent 1de6b5d385
commit cb6924e6d6
7 changed files with 180 additions and 17 deletions

View File

@@ -13,6 +13,7 @@ namespace App\API;
use App\Configuration\TimesheetConfiguration; use App\Configuration\TimesheetConfiguration;
use App\Entity\User; use App\Entity\User;
use App\Event\RecentActivityEvent;
use App\Event\TimesheetMetaDefinitionEvent; use App\Event\TimesheetMetaDefinitionEvent;
use App\Form\API\TimesheetApiEditForm; use App\Form\API\TimesheetApiEditForm;
use App\Repository\Query\TimesheetQuery; use App\Repository\Query\TimesheetQuery;
@@ -32,12 +33,12 @@ use Nelmio\ApiDocBundle\Annotation\Security as ApiSecurity;
use Pagerfanta\Pagerfanta; use Pagerfanta\Pagerfanta;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Swagger\Annotations as SWG; use Swagger\Annotations as SWG;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Validator\Constraints; use Symfony\Component\Validator\Constraints;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/** /**
* @RouteResource("Timesheet") * @RouteResource("Timesheet")
@@ -534,7 +535,10 @@ class TimesheetController extends BaseApiController
$data = $this->repository->getRecentActivities($user, $begin, $limit); $data = $this->repository->getRecentActivities($user, $begin, $limit);
$view = new View($data, 200); $recentActivity = new RecentActivityEvent($this->getUser(), $data);
$this->dispatcher->dispatch($recentActivity);
$view = new View($recentActivity->getRecentActivities(), 200);
$view->getContext()->setGroups(self::GROUPS_COLLECTION_FULL); $view->getContext()->setGroups(self::GROUPS_COLLECTION_FULL);
return $this->viewHandler->handle($view); return $this->viewHandler->handle($view);

View File

@@ -17,6 +17,7 @@ use App\Calendar\TimesheetEntry;
use App\Configuration\SystemConfiguration; use App\Configuration\SystemConfiguration;
use App\Event\CalendarDragAndDropSourceEvent; use App\Event\CalendarDragAndDropSourceEvent;
use App\Event\CalendarGoogleSourceEvent; use App\Event\CalendarGoogleSourceEvent;
use App\Event\RecentActivityEvent;
use App\Repository\TimesheetRepository; use App\Repository\TimesheetRepository;
use App\Timesheet\TrackingModeService; use App\Timesheet\TrackingModeService;
use App\Utils\Color; use App\Utils\Color;
@@ -88,7 +89,7 @@ class CalendarController extends AbstractController
*/ */
private function getDragAndDropResources(TimesheetRepository $repository): array private function getDragAndDropResources(TimesheetRepository $repository): array
{ {
$sources = []; $event = new CalendarDragAndDropSourceEvent($this->getUser());
try { try {
$data = $repository->getRecentActivities( $data = $repository->getRecentActivities(
@@ -97,25 +98,23 @@ class CalendarController extends AbstractController
10 10
); );
$recentActivity = new RecentActivityEvent($this->getUser(), $data);
$this->dispatcher->dispatch($recentActivity);
$entries = []; $entries = [];
$colorHelper = new Color(); $colorHelper = new Color();
foreach ($data as $timesheet) { foreach ($recentActivity->getRecentActivities() as $timesheet) {
$entries[] = new TimesheetEntry($timesheet, $colorHelper->getTimesheetColor($timesheet)); $entries[] = new TimesheetEntry($timesheet, $colorHelper->getTimesheetColor($timesheet));
} }
$sources[] = new RecentActivitiesSource($entries); $event->addSource(new RecentActivitiesSource($entries));
} catch (\Exception $ex) { } catch (\Exception $ex) {
$this->logException($ex); $this->logException($ex);
} }
$event = new CalendarDragAndDropSourceEvent($this->getUser());
$this->dispatcher->dispatch($event); $this->dispatcher->dispatch($event);
foreach ($event->getSources() as $source) { return $event->getSources();
$sources[] = $source;
}
return $sources;
} }
private function getGoogleSources(SystemConfiguration $configuration): ?Google private function getGoogleSources(SystemConfiguration $configuration): ?Google

View File

@@ -10,23 +10,28 @@
namespace App\Controller; namespace App\Controller;
use App\Configuration\TimesheetConfiguration; use App\Configuration\TimesheetConfiguration;
use App\Event\RecentActivityEvent;
use App\Repository\TimesheetRepository; use App\Repository\TimesheetRepository;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/** /**
* Used for the (initial) page rendering. * Used for the (initial) page rendering.
*/ */
class LayoutController extends AbstractController class LayoutController extends AbstractController
{ {
public function activeEntries(TimesheetRepository $repository, TimesheetConfiguration $configuration): Response public function activeEntries(TimesheetRepository $repository, TimesheetConfiguration $configuration, EventDispatcherInterface $dispatcher): Response
{ {
$user = $this->getUser(); $user = $this->getUser();
$activeEntries = $repository->getActiveEntries($user); $activeEntries = $repository->getActiveEntries($user);
$recentActivity = new RecentActivityEvent($this->getUser(), $activeEntries);
$dispatcher->dispatch($recentActivity);
return $this->render( return $this->render(
'navbar/active-entries.html.twig', 'navbar/active-entries.html.twig',
[ [
'entries' => $activeEntries, 'entries' => $recentActivity->getRecentActivities(),
'soft_limit' => $configuration->getActiveEntriesSoftLimit(), 'soft_limit' => $configuration->getActiveEntriesSoftLimit(),
] ]
); );

View File

@@ -41,11 +41,23 @@ final class CalendarDragAndDropSourceEvent extends Event
return $this; return $this;
} }
public function removeSource(DragAndDropSource $source): bool
{
$key = array_search($source, $this->sources, true);
if (false === $key) {
return false;
}
unset($this->sources[$key]);
return true;
}
/** /**
* @return DragAndDropSource[] * @return DragAndDropSource[]
*/ */
public function getSources(): array public function getSources(): array
{ {
return $this->sources; return array_values($this->sources);
} }
} }

View File

@@ -0,0 +1,68 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Event;
use App\Entity\Timesheet;
use App\Entity\User;
use Symfony\Contracts\EventDispatcher\Event;
final class RecentActivityEvent extends Event
{
/**
* @var User
*/
private $user;
/**
* @var Timesheet[]
*/
private $recentActivities = [];
/**
* @param User $user
* @param Timesheet[] $recentActivities
*/
public function __construct(User $user, array $recentActivities)
{
$this->user = $user;
$this->recentActivities = $recentActivities;
}
public function getUser(): User
{
return $this->user;
}
/**
* @return Timesheet[]
*/
public function getRecentActivities(): array
{
return array_values($this->recentActivities);
}
public function addRecentActivity(Timesheet $recentActivity): RecentActivityEvent
{
$this->recentActivities[] = $recentActivity;
return $this;
}
public function removeRecentActivity(Timesheet $recentActivity): bool
{
$key = array_search($recentActivity, $this->recentActivities, true);
if (false === $key) {
return false;
}
unset($this->recentActivities[$key]);
return true;
}
}

View File

@@ -26,19 +26,41 @@ class CalendarDragAndDropSourceEventTest extends TestCase
$sut = new CalendarDragAndDropSourceEvent($user); $sut = new CalendarDragAndDropSourceEvent($user);
$hello = new TestDragAndDropSource('hello');
$tmp1 = new TestDragAndDropSource('foo');
$tmp2 = new TestDragAndDropSource('bar');
$tmp3 = new TestDragAndDropSource('hello');
self::assertSame($user, $sut->getUser()); self::assertSame($user, $sut->getUser());
self::assertIsArray($sut->getSources()); self::assertIsArray($sut->getSources());
self::assertEmpty($sut->getSources()); self::assertEmpty($sut->getSources());
self::assertInstanceOf(CalendarDragAndDropSourceEvent::class, $sut->addSource(new TestDragAndDropSource())); self::assertInstanceOf(CalendarDragAndDropSourceEvent::class, $sut->addSource($tmp1));
self::assertCount(1, $sut->getSources()); self::assertInstanceOf(CalendarDragAndDropSourceEvent::class, $sut->addSource($tmp2));
self::assertInstanceOf(CalendarDragAndDropSourceEvent::class, $sut->addSource($hello));
self::assertInstanceOf(CalendarDragAndDropSourceEvent::class, $sut->addSource($tmp3));
self::assertCount(4, $sut->getSources());
self::assertEquals([$tmp1, $tmp2, $hello, $tmp3], $sut->getSources());
self::assertFalse($sut->removeSource(new TestDragAndDropSource('foo')));
self::assertTrue($sut->removeSource($hello));
self::assertFalse($sut->removeSource(new TestDragAndDropSource('world')));
self::assertCount(3, $sut->getSources());
self::assertEquals([$tmp1, $tmp2, $tmp3], $sut->getSources());
} }
} }
class TestDragAndDropSource implements DragAndDropSource class TestDragAndDropSource implements DragAndDropSource
{ {
private $title;
public function __construct(string $title)
{
$this->title = $title;
}
public function getTitle(): string public function getTitle(): string
{ {
return ''; return $this->title;
} }
public function getRoute(): string public function getRoute(): string

View File

@@ -0,0 +1,53 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Event;
use App\Entity\Timesheet;
use App\Entity\User;
use App\Event\RecentActivityEvent;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Event\RecentActivityEvent
*/
class RecentActivityEventTest extends TestCase
{
public function testGetterAndSetter()
{
$user = new User();
$user->setAlias('foo');
$tmp1 = new Timesheet();
$tmp2 = new Timesheet();
$tmp3 = new Timesheet();
$tmp4 = new Timesheet();
$tmp5 = new Timesheet();
$tmp6 = new Timesheet();
$tmp7 = new Timesheet();
$timesheets = [
$tmp1,
$tmp2,
$tmp3,
$tmp4,
$tmp5,
];
$sut = new RecentActivityEvent($user, $timesheets);
self::assertCount(5, $sut->getRecentActivities());
self::assertEquals($user, $sut->getUser());
self::assertEquals([$tmp1, $tmp2, $tmp3, $tmp4, $tmp5], $sut->getRecentActivities());
self::assertFalse($sut->removeRecentActivity($tmp6));
self::assertTrue($sut->removeRecentActivity($tmp3));
self::assertInstanceOf(RecentActivityEvent::class, $sut->addRecentActivity($tmp6));
self::assertFalse($sut->removeRecentActivity($tmp7));
self::assertEquals([$tmp1, $tmp2, $tmp4, $tmp5, $tmp6], $sut->getRecentActivities());
}
}