diff --git a/project/assets/app.js b/project/assets/app.js index 8b5c084..8f2571d 100755 --- a/project/assets/app.js +++ b/project/assets/app.js @@ -14,4 +14,7 @@ import './styles/main.less'; global.jQuery = global.$ = require('jquery'); require('@fortawesome/fontawesome-free/css/all.min.css'); require('bootstrap'); -$('[data-toggle="tooltip"]').tooltip(); \ No newline at end of file + +$(function () { + $('[data-toggle="tooltip"]').tooltip() +}) \ No newline at end of file diff --git a/project/assets/bootstrap.js b/project/assets/bootstrap.js index 5728e8d..848d203 100755 --- a/project/assets/bootstrap.js +++ b/project/assets/bootstrap.js @@ -1,9 +1,11 @@ import { startStimulusApp } from '@symfony/stimulus-bridge'; -import './services/theme_controller' +import {tmp} from "./services/theme_controller"; + // Registers Stimulus controllers from controllers.json and in the controllers/ directory export const app = startStimulusApp(require.context( '@symfony/stimulus-bridge/lazy-controller-loader!./controllers', true, /\.[jt]sx?$/ )); +new tmp() // register any custom, 3rd party controllers here diff --git a/project/assets/controllers/thememode_controller.js b/project/assets/controllers/thememode_controller.js index 29065ba..4e054be 100644 --- a/project/assets/controllers/thememode_controller.js +++ b/project/assets/controllers/thememode_controller.js @@ -1,4 +1,6 @@ import { Controller } from '@hotwired/stimulus'; +import { tmp } from '../services/theme_controller' + export default class extends Controller { modes; currentState; @@ -6,6 +8,8 @@ export default class extends Controller { this.modes = $(this.element).find('p'); this.currentState = localStorage.getItem('themeMode'); this.changeState() + var tmp1 = new tmp(); + tmp1.update(); } switch(event) { var mode = event.params.mode; diff --git a/project/assets/services/theme_controller.js b/project/assets/services/theme_controller.js index 6a2d363..5bd8b10 100644 --- a/project/assets/services/theme_controller.js +++ b/project/assets/services/theme_controller.js @@ -1,29 +1,38 @@ -(() => { - 'use strict' +export class tmp { + constructor() { + const getStoredTheme = () => localStorage.getItem('theme') + const getPreferredTheme = () => { + const storedTheme = getStoredTheme() + if (storedTheme) { + return storedTheme + } - const getStoredTheme = () => localStorage.getItem('theme') - const setStoredTheme = theme => localStorage.setItem('theme', theme) - - const getPreferredTheme = () => { - const storedTheme = getStoredTheme() - if (storedTheme) { - return storedTheme + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' } - return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' + this.setTheme(getPreferredTheme()) + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { + const storedTheme = getStoredTheme() + if (storedTheme !== 'light' && storedTheme !== 'dark') { + this.setTheme(getPreferredTheme()) + } + }) + + window.addEventListener('DOMContentLoaded', () => { + this.showActiveTheme(getPreferredTheme()) + this.update(); + }) } - const setTheme = theme => { + setTheme = theme => { if (theme === 'auto') { document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')) } else { document.documentElement.setAttribute('data-bs-theme', theme) } } - - setTheme(getPreferredTheme()) - - const showActiveTheme = (theme, focus = false) => { + setStoredTheme = theme => localStorage.setItem('theme', theme) + showActiveTheme = (theme, focus = false) => { const themeSwitcher = document.querySelector('#bd-theme') if (!themeSwitcher) { @@ -50,26 +59,15 @@ themeSwitcher.focus() } } - - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { - const storedTheme = getStoredTheme() - if (storedTheme !== 'light' && storedTheme !== 'dark') { - setTheme(getPreferredTheme()) - } - }) - - window.addEventListener('DOMContentLoaded', () => { - showActiveTheme(getPreferredTheme()) - + update() { document.querySelectorAll('[data-bs-theme-value]') .forEach(toggle => { toggle.addEventListener('click', () => { const theme = toggle.getAttribute('data-bs-theme-value') - console.log(theme) - setStoredTheme(theme) - setTheme(theme) - showActiveTheme(theme, true) + this.setStoredTheme(theme) + this.setTheme(theme) + this.showActiveTheme(theme, true) }) }) - }) -})() \ No newline at end of file + } +} \ No newline at end of file diff --git a/project/assets/styles/main.less b/project/assets/styles/main.less index f1826dd..948c4d5 100644 --- a/project/assets/styles/main.less +++ b/project/assets/styles/main.less @@ -59,5 +59,10 @@ body { /* background-color: lightgray;*/ /*}*/ a { - text-decoration: none !important; + //text-decoration: none !important; +} +.spinner-grow.overdue { + position: absolute; + top: 2px; + right: 2px; } diff --git a/project/src/Controller/BaseController.php b/project/src/Controller/BaseController.php index 0de3ac8..ef42d98 100644 --- a/project/src/Controller/BaseController.php +++ b/project/src/Controller/BaseController.php @@ -9,6 +9,7 @@ use App\Enum\Months; use App\Enum\ReportStatus; use App\Enum\ReportTodoEnum; use App\Helper\MonthHelper; +use App\Services\OverdueReports; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -26,12 +27,6 @@ use Symfony\Component\Security\Http\Attribute\IsGranted; class BaseController extends AbstractController { - private MonthHelper $monthHelper; - - public function __construct(){ - $this->monthHelper = new MonthHelper(); - } - #[Route('/', name: 'index')] public function index(): Response { @@ -42,12 +37,13 @@ class BaseController extends AbstractController } #[Route('/reports/{monthId}', name: 'app_base')] #[IsGranted('reportView')] - public function reportsIndex(EntityManagerInterface $entityManager, int $monthId = 0) : Response + public function reportsIndex(EntityManagerInterface $entityManager, OverdueReports $overdueReports, int $monthId = 0) : Response { + $monthHelper = new MonthHelper($overdueReports); $isOverdue = false; if ($monthId > -1) { - $monthCurrent = $this->monthHelper->getCurrentMonth($monthId); - $reportsAll = $entityManager->getRepository(Reports::class)->findAllInMonth($monthCurrent); + $monthCurrentDate = $monthHelper->getCurrentMonthDate($monthId); + $reportsAll = $entityManager->getRepository(Reports::class)->findAllInMonth($monthCurrentDate); } else { $reportsAll = $entityManager->getRepository(Reports::class)->findAllOverdue(); $isOverdue = true; @@ -67,10 +63,11 @@ class BaseController extends AbstractController ksort($reports); return $this->render('reports/list.html.twig', [ 'reportsGroup' => $reports, - 'months' => $this->monthHelper->takeMonths(), - 'currentMonth' => $monthCurrent ?? null, + 'months' => $monthHelper->takeMonths(), + 'currentMonth' => $monthCurrentDate ?? null, 'reportToDoList' => ReportTodoEnum::cases(), 'isOverdue' => $isOverdue, + 'countOverdueLeft' => $overdueReports->getLeftCount() ]); } } diff --git a/project/src/Controller/ReportsController.php b/project/src/Controller/ReportsController.php index 576a0da..9e70875 100644 --- a/project/src/Controller/ReportsController.php +++ b/project/src/Controller/ReportsController.php @@ -22,7 +22,6 @@ class ReportsController extends AbstractController $token = $request->get("token"); if ($this->isCsrfTokenValid('report-status', $token)) { $reportsService->setClient($report->getClient()); - $isDone = false; if ($request->get("unDone")){ $todo = $entityManager->getRepository(ReportsTodo::class)->findOneBy([ "report" => $report->getId(), @@ -30,8 +29,12 @@ class ReportsController extends AbstractController ]); $todo->setDeleted(true); $entityManager->persist($todo); + $report->setDone(false); } else { foreach (ReportTodoEnum::cases() as $case) { + if (!$request->get($case->value)) { + continue; + } $todo = $entityManager->getRepository(ReportsTodo::class)->findOneBy([ "report" => $report->getId(), "name" => $case->value @@ -40,19 +43,19 @@ class ReportsController extends AbstractController $todo = new ReportsTodo(); $todo->setReport($report); $todo->setName($case); - } - if ($request->get($case->value) !== null) { - $todo->setDeleted(false); } else { - $todo->setDeleted(true); + $todo->setDeleted(!$todo->isDeleted()); } - if ($todo->getName() === ReportTodoEnum::COMPLETE && !$todo->isDeleted()) { - $isDone = true; + if ($todo->getName() === ReportTodoEnum::COMPLETE) { + if ($todo->isDeleted()) { + $report->setDone(false); + } else { + $report->setDone(true); + } } $entityManager->persist($todo); } } - $report->setDone($isDone); $entityManager->persist($report); $entityManager->flush(); $reportsService->tryAddNextReport(); diff --git a/project/src/Controller/ScheduleController.php b/project/src/Controller/ScheduleController.php index eab8ffe..63ea051 100644 --- a/project/src/Controller/ScheduleController.php +++ b/project/src/Controller/ScheduleController.php @@ -18,6 +18,7 @@ class ScheduleController extends AbstractController { if ($typeId == 1) { $schedulesTmp = $entityManager->getRepository(Schedule::class)->findAllCurrent(); + $isOverdue = $entityManager->getRepository(Schedule::class)->findAllOverdue(true); } else { $schedulesTmp = $entityManager->getRepository(Schedule::class)->findAllOverdue(); } @@ -25,16 +26,15 @@ class ScheduleController extends AbstractController return $this->render('schedule/index.html.twig', [ 'typeId' => $typeId, 'schedules' => $schedulesTmp, + 'isOverdue' => $isOverdue ?? false, ]); } - #[Route('/schedule_status', name: 'app_schedule_status')] - public function setDone(EntityManagerInterface $entityManager, Request $request): Response + #[Route('/schedule_status/{id}', name: 'app_schedule_status', methods: ['POST'])] + public function setDone(EntityManagerInterface $entityManager, Request $request, Schedule $schedule): Response { - $scheduleId = $request->getPayload()->get('scheduleId'); - $token = $request->getPayload()->get("token"); - if ($scheduleId && $this->isCsrfTokenValid('schedule-status', $token)) { - $schedule = $entityManager->getRepository(Schedule::class)->find($scheduleId); + $token = $request->get("token"); + if ($this->isCsrfTokenValid('schedule-status', $token)) { $isDone = true; if ($schedule->isDone()) { $isDone = false; diff --git a/project/src/Enum/ScheduleStatus.php b/project/src/Enum/ScheduleStatus.php index a40b23d..15a33c2 100644 --- a/project/src/Enum/ScheduleStatus.php +++ b/project/src/Enum/ScheduleStatus.php @@ -18,4 +18,15 @@ enum ScheduleStatus: int ScheduleStatus::COMPLETED => 'success', }; } + + public function borderColor(): string + { + return match ($this) { + ScheduleStatus::TODO => '', + ScheduleStatus::INCOMING => 'warning', + ScheduleStatus::OVERDUE => 'danger', + ScheduleStatus::COMPLETED => 'success', + + }; + } } \ No newline at end of file diff --git a/project/src/Helper/MonthHelper.php b/project/src/Helper/MonthHelper.php index e060632..0cbb974 100644 --- a/project/src/Helper/MonthHelper.php +++ b/project/src/Helper/MonthHelper.php @@ -1,38 +1,53 @@ modify("first day of this month"); $return = []; + $overdueCounts = $this->overdueReports->getList(); for ($i=1; $i<=11; $i++) { $tmp = clone $startDate; $tmp->modify("+$i month"); - $return[$i] = $tmp; + $return[$i] = [ + 'date' => $tmp, + 'overdueCount' => 0 + ]; + $key = $tmp->format('Y-m'); + if (isset($overdueCounts[$key])) { + $return[$i]['overdueCount'] = $overdueCounts[$key]; + unset($overdueCounts[$key]); + } + } + if (count($overdueCounts) > 0) { + $this->overdueReports->setLeftCount(array_sum($overdueCounts)); } return $return; } - public function getCurrentMonth(int $monthId) : \DateTime + public function getCurrentMonthDate(int $monthId) : \DateTime { $months = $this->takeMonths(); if ($monthId==0) { $currentMonth = intval(date("n")); foreach ($months as $mId => $monthObj) { - if ($monthObj->format("m") == $currentMonth) { + $date = $monthObj['date']->format('m'); + if ($date == $currentMonth) { $monthCurrent = $monthObj; - $monthId = $mId; break; } } } else { $monthCurrent = $months[$monthId]; } - return $monthCurrent; + return $monthCurrent['date']; } } \ No newline at end of file diff --git a/project/src/Repository/ScheduleRepository.php b/project/src/Repository/ScheduleRepository.php index 7d91380..940f006 100644 --- a/project/src/Repository/ScheduleRepository.php +++ b/project/src/Repository/ScheduleRepository.php @@ -11,25 +11,49 @@ use Doctrine\Persistence\ManagerRegistry; */ class ScheduleRepository extends ServiceEntityRepository { + private const _OVERDUE_DAYS_START = 15; + private const _OVERDUE_DAYS_END = 30; public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Schedule::class); } - public function findAllOverdue() + public function findAllOverdue(bool $onlyCount = false) : array|int { $dateEnd = new \DateTime("now"); + $dateEnd->modify("-".self::_OVERDUE_DAYS_START." days"); $reports = $this->createQueryBuilder('s') ->where('s.isDone = :isDone') ->andWhere('s.dateEnd < :dateEnd') // ->andWhere('s.isDelete = :isDelete') ->setParameter('isDone', 0) +// ->setParameter('isDelete', 0) + ->setParameter('dateEnd', $dateEnd); + + if ($onlyCount) { + $reports->select('COUNT(s.id)'); + return $reports->getQuery()->getSingleScalarResult(); + } + + return $reports->getQuery()->getResult(); + } + + public function isOverdue(): bool + { + $dateEnd = new \DateTime("now"); + $dateEnd->modify("-".self::_OVERDUE_DAYS_START." days"); + $query = $this->createQueryBuilder('s') + ->select('count(s.id)') + ->where('s.isDone = :isDone') + ->andWhere('s.dateEnd < :dateEnd') +// ->andWhere('s.isDelete = :isDelete') + ->setParameter('isDone', 0) // ->setParameter('isDelete', 0) ->setParameter('dateEnd', $dateEnd) ->getQuery() - ->getResult(); + ->getSingleScalarResult(); - return $reports; + trigger_error(var_export($query,true)); } /** @@ -39,9 +63,9 @@ class ScheduleRepository extends ServiceEntityRepository { $date = new \DateTime(); $dateStart = clone $date; - $dateStart->modify("-15 days"); + $dateStart->modify("-".self::_OVERDUE_DAYS_START." days"); $dateEnd = clone $date; - $dateEnd->modify("+30 days"); + $dateEnd->modify("+".self::_OVERDUE_DAYS_END." days"); return $this->createQueryBuilder('r') ->where('r.dateEnd >= :dateStart') ->andWhere('r.dateEnd <= :dateEnd') diff --git a/project/src/Services/OverdueReports.php b/project/src/Services/OverdueReports.php new file mode 100644 index 0000000..269d859 --- /dev/null +++ b/project/src/Services/OverdueReports.php @@ -0,0 +1,49 @@ +list = $this->takeOverdueList(); + } + + public function getList(): array + { + return $this->list; + } + + public function setLeftCount(int $leftCount): void + { + $this->leftCount = $leftCount; + } + + public function getLeftCount(): int + { + return $this->leftCount; + } + + private function takeOverdueList() : array + { + $reports = $this->entity->getRepository(Reports::class)->findAllOverdue(); + if (!$reports) { + return []; + } + $toReturn = []; + /** @var Reports $report */ + foreach ($reports as $report) { + $date = $report->getDateStart()->format('Y-m'); + if (!array_key_exists($date, $toReturn)) { + $toReturn[$date] = 1; + } else { + $toReturn[$date]++; + } + } + + return $toReturn; + } +} \ No newline at end of file diff --git a/project/templates/navigation/switch_months.html.twig b/project/templates/navigation/switch_months.html.twig index cb138b3..60ebe9b 100644 --- a/project/templates/navigation/switch_months.html.twig +++ b/project/templates/navigation/switch_months.html.twig @@ -1,31 +1,20 @@ -{% macro month_menu(routeName, months, currentMonth) %} +{% macro month_menu(routeName, months, currentMonth, countOverdueLeft) %}
- {#
#} - {#
#} - {# Zaległe#} - {#
#} - {#
#} - {# {% for id,month in months %}#} - {# {% set isCurrent = currentMonth is not null and month | date("Y-m") == currentMonth | date("Y-m") %}#} - {#
#} - {# #} - {#
#} - {# {% endfor %}#} diff --git a/project/templates/reports/list.html.twig b/project/templates/reports/list.html.twig index aafe794..d741b78 100644 --- a/project/templates/reports/list.html.twig +++ b/project/templates/reports/list.html.twig @@ -2,7 +2,7 @@ {% import 'navigation/switch_months.html.twig' as navigation %} {% import 'reports/listInclude.html.twig' as sets %} {% block body %} - {{ navigation.month_menu('app_base',months,currentMonth) }} + {{ navigation.month_menu('app_base',months,currentMonth,countOverdueLeft) }}
{% for todo in reportToDoList %} - -