* @throws \Exception */ private function getAllAvailableWidgets(User $user): array { if ($this->widgets === null) { $all = []; foreach ($this->service->getAllWidgets() as $widget) { $widget->setUser($user); $permissions = $widget->getPermissions(); if (\count($permissions) > 0) { $add = false; foreach ($permissions as $perm) { if ($this->isGranted($perm)) { $add = true; break; } } if (!$add) { continue; } } $all[] = $widget; } $this->widgets = $all; } return $this->widgets; } private function getBookmark(User $user): ?Bookmark { return $this->repository->findBookmark($user, self::BOOKMARK_TYPE, self::BOOKMARK_NAME); } private function getDefaultConfig(): array { $event = new DashboardEvent($this->getUser()); // default widgets $dashboard = [ 'PaginatedWorkingTimeChart', //'UserAmountToday', //'UserAmountWeek', //'UserAmountMonth', //'UserAmountYear', //'UserTeams', //'UserTeamProjects', 'DurationToday', 'DurationWeek', 'DurationMonth', 'DurationYear', //'ActiveUsersToday', //'ActiveUsersWeek', //'ActiveUsersMonth', //'ActiveUsersYear', //'AmountToday', //'AmountWeek', //'AmountMonth', //'AmountYear', //'TotalsUser', //'TotalsCustomer', //'TotalsProject', //'TotalsActivity', ]; foreach ($dashboard as $widgetName) { $event->addWidget($widgetName); } $this->eventDispatcher->dispatch($event); return $event->getWidgets(); } /** * Returns the list of widgets names and options for a user. * * @param User $user * @return array> */ private function getUserConfig(User $user): array { $bookmark = $this->getBookmark($user); if ($bookmark !== null) { return $bookmark->getContent(); } $widgets = []; foreach ($this->getDefaultConfig() as $name) { $widgets[] = ['id' => $name, 'options' => []]; } return $widgets; } /** * @param array $widgets * @param User $user * @return array */ private function filterWidgets(array $widgets, User $user): array { $filteredWidgets = []; foreach ($this->getUserConfig($user) as $setting) { $id = $setting['id']; $options = $setting['options']; foreach ($widgets as $widget) { if ($widget->getId() === $id) { $tmpWidget = clone $widget; foreach ($options as $key => $value) { $tmpWidget->setOption($key, $value); } $filteredWidgets[] = $tmpWidget; break; } } } return $filteredWidgets; } #[Route(path: '/', defaults: [], name: 'dashboard', methods: ['GET'])] public function index(): Response { $user = $this->getUser(); $available = $this->getAllAvailableWidgets($user); $widgets = $this->filterWidgets($available, $user); $page = new PageSetup('dashboard.title'); $page->setHelp('dashboard.html'); $page->setActionName('dashboard'); $page->setActionPayload(['widgets' => $widgets, 'available' => $available]); return $this->render('dashboard/index.html.twig', [ 'page_setup' => $page, 'widgets' => $widgets, 'available' => $available, ]); } #[Route(path: '/reset/', defaults: [], name: 'dashboard_reset', methods: ['GET', 'POST'])] public function reset(): RedirectResponse { $bookmark = $this->getBookmark($this->getUser()); if ($bookmark !== null) { $this->repository->deleteBookmark($bookmark); } return $this->redirectToRoute('dashboard'); } #[Route(path: '/add-widget/{widget}', defaults: [], name: 'dashboard_add', methods: ['GET'])] public function add(string $widget): Response { $user = $this->getUser(); $widgets = $this->getUserConfig($user); // prevent to add the same widget multiple times foreach ($widgets as $id => $setting) { if ($setting['id'] === $widget) { return $this->redirectToRoute('dashboard_edit'); } } $widgets[] = ['id' => $widget, 'options' => []]; $this->saveBookmark($user, $widgets); return $this->redirectToRoute('dashboard_edit'); } private function saveBookmark(User $user, array $widgets): void { $bookmark = $this->getBookmark($user); if ($bookmark === null) { $bookmark = new Bookmark(); $bookmark->setUser($user); $bookmark->setType(self::BOOKMARK_TYPE); $bookmark->setName(self::BOOKMARK_NAME); } $bookmark->setContent($widgets); $this->repository->saveBookmark($bookmark); } #[Route(path: '/edit/', defaults: [], name: 'dashboard_edit', methods: ['GET', 'POST'])] public function edit(Request $request): Response { $user = $this->getUser(); $available = $this->getAllAvailableWidgets($user); $widgets = $this->filterWidgets($available, $user); $choices = []; // the list of widgets for the dropdown is created in the EventListener and not here // this form is mainly used for saving foreach ($available as $widget) { if (empty($widget->getTitle())) { continue; } $choices[$widget->getId()] = $widget->getId(); } $form = $this->createFormBuilder(null, []) ->add('widgets', ChoiceType::class, ['choices' => $choices, 'multiple' => true]) ->setAction($this->generateUrl('dashboard_edit')) ->setMethod('POST') ->getForm(); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { try { $userWidgets = $this->getUserConfig($user); $saveWidgets = []; foreach ($form->getData()['widgets'] as $widgetId) { $options = []; foreach ($userWidgets as $setting) { if ($setting['id'] === $widgetId) { $options = $setting['options']; } } $saveWidgets[] = ['id' => $widgetId, 'options' => $options]; } $this->saveBookmark($user, $saveWidgets); $this->flashSuccess('action.update.success'); return $this->redirectToRoute('dashboard'); } catch (\Exception $ex) { $this->flashDeleteException($ex); } } $page = new PageSetup('dashboard.title'); $page->setHelp('dashboard.html'); $page->setActionName('dashboard'); $page->setActionView('edit'); $page->setActionPayload(['widgets' => $widgets, 'available' => $available]); return $this->render('dashboard/grid.html.twig', [ 'page_setup' => $page, 'widgets' => $widgets, 'form' => $form->createView(), ]); } }