diff --git a/src/API/TimesheetController.php b/src/API/TimesheetController.php index 00c83e78..22e152ac 100644 --- a/src/API/TimesheetController.php +++ b/src/API/TimesheetController.php @@ -13,6 +13,7 @@ namespace App\API; use App\Configuration\TimesheetConfiguration; use App\Entity\User; +use App\Event\RecentActivityEvent; use App\Event\TimesheetMetaDefinitionEvent; use App\Form\API\TimesheetApiEditForm; use App\Repository\Query\TimesheetQuery; @@ -32,12 +33,12 @@ use Nelmio\ApiDocBundle\Annotation\Security as ApiSecurity; use Pagerfanta\Pagerfanta; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; use Swagger\Annotations as SWG; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Validator\Constraints; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** * @RouteResource("Timesheet") @@ -534,7 +535,10 @@ class TimesheetController extends BaseApiController $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); return $this->viewHandler->handle($view); diff --git a/src/Controller/CalendarController.php b/src/Controller/CalendarController.php index 550db188..29b39eb9 100644 --- a/src/Controller/CalendarController.php +++ b/src/Controller/CalendarController.php @@ -17,6 +17,7 @@ use App\Calendar\TimesheetEntry; use App\Configuration\SystemConfiguration; use App\Event\CalendarDragAndDropSourceEvent; use App\Event\CalendarGoogleSourceEvent; +use App\Event\RecentActivityEvent; use App\Repository\TimesheetRepository; use App\Timesheet\TrackingModeService; use App\Utils\Color; @@ -88,7 +89,7 @@ class CalendarController extends AbstractController */ private function getDragAndDropResources(TimesheetRepository $repository): array { - $sources = []; + $event = new CalendarDragAndDropSourceEvent($this->getUser()); try { $data = $repository->getRecentActivities( @@ -97,25 +98,23 @@ class CalendarController extends AbstractController 10 ); + $recentActivity = new RecentActivityEvent($this->getUser(), $data); + $this->dispatcher->dispatch($recentActivity); + $entries = []; $colorHelper = new Color(); - foreach ($data as $timesheet) { + foreach ($recentActivity->getRecentActivities() as $timesheet) { $entries[] = new TimesheetEntry($timesheet, $colorHelper->getTimesheetColor($timesheet)); } - $sources[] = new RecentActivitiesSource($entries); + $event->addSource(new RecentActivitiesSource($entries)); } catch (\Exception $ex) { $this->logException($ex); } - $event = new CalendarDragAndDropSourceEvent($this->getUser()); $this->dispatcher->dispatch($event); - foreach ($event->getSources() as $source) { - $sources[] = $source; - } - - return $sources; + return $event->getSources(); } private function getGoogleSources(SystemConfiguration $configuration): ?Google diff --git a/src/Controller/LayoutController.php b/src/Controller/LayoutController.php index f5f9aee6..ca292118 100644 --- a/src/Controller/LayoutController.php +++ b/src/Controller/LayoutController.php @@ -10,23 +10,28 @@ namespace App\Controller; use App\Configuration\TimesheetConfiguration; +use App\Event\RecentActivityEvent; use App\Repository\TimesheetRepository; use Symfony\Component\HttpFoundation\Response; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** * Used for the (initial) page rendering. */ 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(); $activeEntries = $repository->getActiveEntries($user); + $recentActivity = new RecentActivityEvent($this->getUser(), $activeEntries); + $dispatcher->dispatch($recentActivity); + return $this->render( 'navbar/active-entries.html.twig', [ - 'entries' => $activeEntries, + 'entries' => $recentActivity->getRecentActivities(), 'soft_limit' => $configuration->getActiveEntriesSoftLimit(), ] ); diff --git a/src/Event/CalendarDragAndDropSourceEvent.php b/src/Event/CalendarDragAndDropSourceEvent.php index f3aa9612..91068a7d 100644 --- a/src/Event/CalendarDragAndDropSourceEvent.php +++ b/src/Event/CalendarDragAndDropSourceEvent.php @@ -41,11 +41,23 @@ final class CalendarDragAndDropSourceEvent extends Event 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[] */ public function getSources(): array { - return $this->sources; + return array_values($this->sources); } } diff --git a/src/Event/RecentActivityEvent.php b/src/Event/RecentActivityEvent.php new file mode 100644 index 00000000..c518717c --- /dev/null +++ b/src/Event/RecentActivityEvent.php @@ -0,0 +1,68 @@ +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; + } +} diff --git a/tests/Event/CalendarDragAndDropSourceEventTest.php b/tests/Event/CalendarDragAndDropSourceEventTest.php index a492a00c..2590a8f7 100644 --- a/tests/Event/CalendarDragAndDropSourceEventTest.php +++ b/tests/Event/CalendarDragAndDropSourceEventTest.php @@ -26,19 +26,41 @@ class CalendarDragAndDropSourceEventTest extends TestCase $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::assertIsArray($sut->getSources()); self::assertEmpty($sut->getSources()); - self::assertInstanceOf(CalendarDragAndDropSourceEvent::class, $sut->addSource(new TestDragAndDropSource())); - self::assertCount(1, $sut->getSources()); + self::assertInstanceOf(CalendarDragAndDropSourceEvent::class, $sut->addSource($tmp1)); + 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 { + private $title; + + public function __construct(string $title) + { + $this->title = $title; + } + public function getTitle(): string { - return ''; + return $this->title; } public function getRoute(): string diff --git a/tests/Event/RecentActivityEventTest.php b/tests/Event/RecentActivityEventTest.php new file mode 100644 index 00000000..a60fd518 --- /dev/null +++ b/tests/Event/RecentActivityEventTest.php @@ -0,0 +1,53 @@ +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()); + } +}