allow to select reports as initial view (#2403)

This commit is contained in:
Kevin Papst
2021-03-06 12:59:13 +01:00
committed by GitHub
parent 5583caa9e4
commit 70f7f35009
7 changed files with 134 additions and 59 deletions

View File

@@ -9,10 +9,14 @@
namespace App\Form\Type;
use App\Entity\User;
use App\Reporting\ReportingService;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Custom form field type to select the initial view, where the user should be redirected to after login.
@@ -21,7 +25,7 @@ class InitialViewType extends AbstractType
{
public const DEFAULT_VIEW = 'timesheet';
public const ALLOWED_VIEWS = [
private const ALLOWED_VIEWS = [
'dashboard' => 'menu.homepage',
'timesheet' => 'menu.timesheet',
'calendar' => 'calendar.title',
@@ -34,7 +38,7 @@ class InitialViewType extends AbstractType
'admin_activity' => 'menu.admin_activity',
];
protected const ROUTE_PERMISSION = [
private const ROUTE_PERMISSION = [
'dashboard' => '',
'timesheet' => 'view_own_timesheet',
'calendar' => 'view_own_timesheet',
@@ -47,17 +51,15 @@ class InitialViewType extends AbstractType
'admin_activity' => 'view_activity',
];
/**
* @var AuthorizationCheckerInterface
*/
protected $voter;
private $voter;
private $reportingService;
private $translator;
/**
* @param AuthorizationCheckerInterface $voter
*/
public function __construct(AuthorizationCheckerInterface $voter)
public function __construct(AuthorizationCheckerInterface $voter, ReportingService $reportingService, TranslatorInterface $translator)
{
$this->voter = $voter;
$this->reportingService = $reportingService;
$this->translator = $translator;
}
/**
@@ -65,18 +67,26 @@ class InitialViewType extends AbstractType
*/
public function configureOptions(OptionsResolver $resolver)
{
$choices = [];
foreach (self::ROUTE_PERMISSION as $route => $permission) {
if (empty($permission) || $this->voter->isGranted($permission)) {
$name = self::ALLOWED_VIEWS[$route];
$choices[$name] = $route;
$resolver->setDefault('required', true);
$resolver->setDefault('choices', function (Options $options) {
$choices = [];
foreach (self::ROUTE_PERMISSION as $route => $permission) {
if (empty($permission) || $this->voter->isGranted($permission)) {
$name = self::ALLOWED_VIEWS[$route];
$choices[$name] = $route;
}
}
}
$resolver->setDefaults([
'required' => true,
'choices' => $choices,
]);
/** @var User $user */
$user = $options['user'];
foreach ($this->reportingService->getAvailableReports($user) as $report) {
$label = $this->translator->trans('menu.reporting') . ': ' . $this->translator->trans($report->getLabel(), [], 'reporting');
$choices[$label] = $report->getRoute();
}
return $choices;
});
}
/**

View File

@@ -7,18 +7,14 @@
* file that was distributed with this source code.
*/
namespace App\Twig;
namespace App\Reporting;
use App\Entity\User;
use App\Event\ReportingEvent;
use App\Reporting\Report;
use App\Reporting\ReportInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
final class ReportingExtension extends AbstractExtension
final class ReportingService
{
/**
* @var EventDispatcherInterface
@@ -35,16 +31,6 @@ final class ReportingExtension extends AbstractExtension
$this->security = $security;
}
/**
* {@inheritdoc}
*/
public function getFunctions()
{
return [
new TwigFunction('available_reports', [$this, 'getAvailableReports'], []),
];
}
/**
* @param User $user
* @return ReportInterface[]

View File

@@ -0,0 +1,34 @@
<?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\Twig\Runtime;
use App\Entity\User;
use App\Reporting\ReportingService;
use App\Reporting\ReportInterface;
use Twig\Extension\RuntimeExtensionInterface;
final class ReportingExtension implements RuntimeExtensionInterface
{
private $service;
public function __construct(ReportingService $reportingService)
{
$this->service = $reportingService;
}
/**
* @param User $user
* @return ReportInterface[]
*/
public function getAvailableReports(User $user): array
{
return $this->service->getAvailableReports($user);
}
}

View File

@@ -12,6 +12,7 @@ namespace App\Twig;
use App\Twig\Runtime\EncoreExtension;
use App\Twig\Runtime\ExporterExtension;
use App\Twig\Runtime\MarkdownExtension;
use App\Twig\Runtime\ReportingExtension;
use App\Twig\Runtime\ThemeExtension;
use App\Twig\Runtime\TimesheetExtension;
use App\Twig\Runtime\WidgetExtension;
@@ -34,6 +35,7 @@ class RuntimeExtensions extends AbstractExtension
new TwigFunction('active_timesheets', [TimesheetExtension::class, 'activeEntries']),
new TwigFunction('encore_entry_css_source', [EncoreExtension::class, 'getEncoreEntryCssSource']),
new TwigFunction('render_widget', [WidgetExtension::class, 'renderWidget'], ['is_safe' => ['html']]),
new TwigFunction('available_reports', [ReportingExtension::class, 'getAvailableReports'], []),
];
}