From b9e580af9a5809901bac77c37b9f498766328aaf Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Tue, 16 May 2023 02:17:36 +0200 Subject: [PATCH] First Widget Bar + Number of notification unread. All is hardcoded --- .../ChillMainBundle/ChillMainBundle.php | 3 + .../DashboardHomepageController.php | 137 +++++++++--------- .../public/vuejs/HomepageWidget/MyCustoms.vue | 15 -- .../public/vuejs/HomepageWidget/MyWidget.vue | 35 +++-- .../DataFetcher/WidgetBarDataFetcher.php | 55 +++++++ .../Widget/Widgets/WidgetBar.php | 18 +-- .../AccompanyingPeriodRepository.php | 13 ++ 7 files changed, 169 insertions(+), 107 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Widget/Widgets/DataFetcher/WidgetBarDataFetcher.php diff --git a/src/Bundle/ChillMainBundle/ChillMainBundle.php b/src/Bundle/ChillMainBundle/ChillMainBundle.php index 9e276311d..974edde2b 100644 --- a/src/Bundle/ChillMainBundle/ChillMainBundle.php +++ b/src/Bundle/ChillMainBundle/ChillMainBundle.php @@ -32,6 +32,7 @@ use Chill\MainBundle\Security\Resolver\CenterResolverInterface; use Chill\MainBundle\Security\Resolver\ScopeResolverInterface; use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface; use Chill\MainBundle\Templating\UI\NotificationCounterInterface; +use Chill\MainBundle\Widget\WidgetHandlerInterface; use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -62,6 +63,8 @@ class ChillMainBundle extends Bundle ->addTag('chill_main.workflow_handler'); $container->registerForAutoconfiguration(CronJobInterface::class) ->addTag('chill_main.cron_job'); + $container->registerForAutoconfiguration(WidgetHandlerInterface::class) + ->addTag('chill_main.widget_handler'); $container->addCompilerPass(new SearchableServicesCompilerPass()); $container->addCompilerPass(new ConfigConsistencyCompilerPass()); diff --git a/src/Bundle/ChillMainBundle/Controller/DashboardHomepageController.php b/src/Bundle/ChillMainBundle/Controller/DashboardHomepageController.php index 88c4f25a7..da5110efb 100644 --- a/src/Bundle/ChillMainBundle/Controller/DashboardHomepageController.php +++ b/src/Bundle/ChillMainBundle/Controller/DashboardHomepageController.php @@ -11,110 +11,113 @@ declare(strict_types=1); namespace Chill\MainBundle\Controller; + +use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Pagination\PaginatorFactory; +use Chill\MainBundle\Repository\UserRepository; +use Chill\MainBundle\Serializer\Model\Collection; use Chill\MainBundle\Widget\WidgetHandlerManager; use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\Security\Core\Security; +use PHPUnit\Util\Json; use Symfony\Component\HttpFoundation\Request; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Psr\Log\LoggerInterface; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; +use Symfony\Component\Serializer\Serializer; +use Symfony\Component\Serializer\SerializerInterface; /** * @Route("/{_locale}/dashboard") */ class DashboardHomepageController extends AbstractController{ -// private WidgetHandlerManager $widgetHandlerManager; -// -// public function __construct( -// //AccompanyingPeriodRepository $accompanyingPeriodRepository, -// WidgetHandlerManager $widgetHandlerManager -// ) -// { -// //$this->accompanyingPeriodRepository = $accompanyingPeriodRepository; -// $this->widgetHandlerManager = $widgetHandlerManager; -// } private WidgetHandlerManager $widgetHandlerManager; + private Security $security; + + private UserRepository $userRepository; + + private EntityManagerInterface $em; + + private LoggerInterface $logger; + + private SerializerInterface $serializer; + + private PaginatorFactory $paginatorFactory; + public function __construct( + //AccompanyingPeriodRepository $accompanyingPeriodRepository, + WidgetHandlerManager $widgetHandlerManager, + Security $security, + UserRepository $userRepository, + EntityManagerInterface $em, + LoggerInterface $logger, + SerializerInterface $serializer, + PaginatorFactory $paginatorFactory, + ) + { + //$this->accompanyingPeriodRepository = $accompanyingPeriodRepository; + $this->widgetHandlerManager = $widgetHandlerManager; + $this->security = $security; + $this->userRepository = $userRepository; + $this->em = $em; + $this->logger = $logger; + $this->serializer = $serializer; + $this->paginatorFactory = $paginatorFactory; + + } + + /** * @Route("/raw_data", name="chill_main_widget_raw_data") + * @return JsonResponse */ + public function index(): JsonResponse { - // Retrieve data and prepare it for the chart - $chartData = [ - 'data'=> [ - 'labels' => [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December' - ], - 'datasets' =>[ + $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); - [ - 'label' => 'Dataset 1', - 'data' => [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 11], - 'backgroundColor' => ['rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)'], - 'borderColor' => ['rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)'], - 'borderWidth' => 1, - ], - ] - ], + if (!$this->security->getUser() instanceof User) { + throw new AccessDeniedHttpException('You must be authenticated and a user to see the dashboard'); + } + $config = [ + 'alias' => 'bar', ]; - $chartOptions = [ - 'options' => [ - 'responsive'=> 'true', - 'maintainAspectRatio'=> 'false' - - ] + $context = [ + //'user' => $this->security->getUser(), + //Hardcoder pour resultat + 'user' => 19, + 'what' => 'accompanying_period_by_month', ]; - $chartConfig =$chartData + $chartOptions; + $data = $this->widgetHandlerManager->getDataForWidget($config, $context); - //Return the chart data as JSON response - return $this->json($chartConfig, $status = 200,$headers = [], $context= []); + return new JsonResponse($data,Response::HTTP_OK,[]); } /** * @Route("/widget/{context}", name="chill_main_widget_get_data") */ - public function getDataForWidget(Request $request, $context): JsonResponse + public function getDataForWidget(Request $request, string $context): JsonResponse { - //Retrieve data from request in vue component - $requestData = json_decode($request->getContent(),true); - + $requestData = json_decode($request->getContent(), true); + dump($requestData); // Process the widget data using the WidgetHandlerManager - $handler = $this->widgetHandlerManager->getHandler($requestData, $context); - + //$handler = $this->widgetHandlerManager->getHandler($requestData); + //dump($handler); // Return the widget data in JSON response - return new JsonResponse($this->getData($requestData, $context)); + //return new JsonResponse($this->getData($requestData)); + + return new JsonResponse($requestData); } - - private function getData( array $config,array $context) - { - $widgetData = []; - foreach ($config as $widget) { - $widgetData[] = [ - 'data' => $this->widgetHandlerManager->getDataForWidget($config,$context), - 'options'=> 'responsive: true' - ]; - } - return $widgetData; - } - - } diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyCustoms.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyCustoms.vue index 00d938e48..cbda47c74 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyCustoms.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyCustoms.vue @@ -43,21 +43,6 @@ -
-
- Mon dashboard personnalisé -
-
-
-
- Mon dashboard personnalisé -
-
-
-
- Mon dashboard personnalisé -
-
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWidget.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWidget.vue index 9af8e7ec0..0c025cdbf 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWidget.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWidget.vue @@ -1,6 +1,7 @@ @@ -16,7 +17,6 @@ import { } from 'chart.js' import { Bar } from 'vue-chartjs' import {defineComponent} from 'vue' -import * as chartConfig from './js/chartConfig' import {makeFetch} from "../../lib/api/apiMethods"; ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend) @@ -24,29 +24,32 @@ ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend) export default defineComponent({ name: 'MyWidget', components: { - Bar + Bar, }, data() { return { - loaded: false, - chartData: { - labels: [ 'January', 'February', 'March' ], - datasets: [ { data: [40, 20, 12] } ] - }, - chartOptions: { - responsive: true - } + loaded_bar: false, + loaded_number: false, + chartData: null, + chartOptions: null, + number: "", } }, async mounted() { - this.loaded=false; + this.loaded_bar=false; + this.loaded_number=false; const url = '/fr/dashboard/raw_data'; try { - const response: { data: any } = await makeFetch("GET", url); + const response: { data: any, options: any, type: any} = await makeFetch("GET", url); this.chartData = response.data; - console.log(this.chartData); - console.log(chartConfig); - this.loaded = true; + this.chartOptions = response.options; + if(response.type == 'bar'){ + this.loaded_bar = true; + } + else { + this.loaded_number = true + this.number = response.data.datasets[0].data[0]; + } } catch (error) { console.log(error); } diff --git a/src/Bundle/ChillMainBundle/Widget/Widgets/DataFetcher/WidgetBarDataFetcher.php b/src/Bundle/ChillMainBundle/Widget/Widgets/DataFetcher/WidgetBarDataFetcher.php new file mode 100644 index 000000000..457153bed --- /dev/null +++ b/src/Bundle/ChillMainBundle/Widget/Widgets/DataFetcher/WidgetBarDataFetcher.php @@ -0,0 +1,55 @@ +entityManager = $entityManager; + } + + /** + * @throws \Exception + */ + public function fetchDataForWidget(int $userId): array + { + $sql = " + SELECT DATE_TRUNC('month', ap.openingdate) AS month, + COUNT(ap.id) AS count + FROM chill_person_accompanying_period ap + WHERE ap.user_id = :userId + GROUP BY DATE_TRUNC('month', ap.openingdate) + ORDER BY DATE_TRUNC('month', ap.openingdate) ASC + "; + + $rsm = new ResultSetMapping(); + $rsm->addScalarResult('month', 'month'); + $rsm->addScalarResult('count', 'count'); + + $query = $this->entityManager->createNativeQuery($sql, $rsm); + $query->setParameter('userId', $userId); + + $results = $query->getResult(); + + + $counts = []; + $months =[] ; + foreach ($results as $result) { + $date = new \DateTime($result['month']); + $formattedMonth = $date->format('Y-m'); + + $months[] = $formattedMonth; + $counts[] = $result['count']; + } + return [ + 'months'=>$months, + 'counts'=>$counts, + ]; + } +} diff --git a/src/Bundle/ChillMainBundle/Widget/Widgets/WidgetBar.php b/src/Bundle/ChillMainBundle/Widget/Widgets/WidgetBar.php index fbcb5f416..211d70a88 100644 --- a/src/Bundle/ChillMainBundle/Widget/Widgets/WidgetBar.php +++ b/src/Bundle/ChillMainBundle/Widget/Widgets/WidgetBar.php @@ -25,27 +25,27 @@ class WidgetBar implements WidgetHandlerInterface private Security $security; - private AccompanyingPeriodRepository $acpRepository; + //private AccompanyingPeriodRepository $acpRepository; private WidgetBarDataFetcher $dataFetcher; - private NotificationRepository $notificationRepository; + //private NotificationRepository $notificationRepository; - private EntityManagerInterface $em; + //private EntityManagerInterface $em; public function __construct( - AccompanyingPeriodRepository $accompanyingPeriodRepository, + // AccompanyingPeriodRepository $accompanyingPeriodRepository, Security $security, - NotificationRepository $notificationRepository, - EntityManagerInterface $em, + // NotificationRepository $notificationRepository, + // EntityManagerInterface $em, WidgetBarDataFetcher $dataFetcher ) { - $this->acpRepository = $accompanyingPeriodRepository; + // $this->acpRepository = $accompanyingPeriodRepository; $this->security = $security; - $this->notificationRepository = $notificationRepository; - $this->em = $em; + // $this->notificationRepository = $notificationRepository; + // $this->em = $em; $this->dataFetcher = $dataFetcher; } diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodRepository.php index 6b7311207..8a8bb943f 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodRepository.php @@ -113,4 +113,17 @@ final class AccompanyingPeriodRepository implements ObjectRepository return $qb; } + public function countByUserGroupedByMonth(User $user): array + { + $qb = $this->createQueryBuilder('a'); + + $qb->select() + ->addSelect('COUNT(a.id) AS count') + ->andWhere('a.user = :user') + ->setParameter('user', $user) + ->groupBy('month') + ->orderBy('month', 'ASC'); + + return $qb->getQuery()->getResult(); + } }