Next major version 2 with PHP 8.1, Symfony 6, Tabler UI, 2FA ... (#2902)
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Constants;
|
||||
use App\Event\PageActionsEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
@@ -20,13 +19,8 @@ use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||
*/
|
||||
abstract class AbstractActionsSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
private $auth;
|
||||
private $urlGenerator;
|
||||
|
||||
public function __construct(AuthorizationCheckerInterface $security, UrlGeneratorInterface $urlGenerator)
|
||||
public function __construct(private AuthorizationCheckerInterface $auth, private UrlGeneratorInterface $urlGenerator)
|
||||
{
|
||||
$this->auth = $security;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
}
|
||||
|
||||
protected function isGranted($attributes, $subject = null): bool
|
||||
@@ -39,11 +33,6 @@ abstract class AbstractActionsSubscriber implements EventSubscriberInterface
|
||||
return $this->urlGenerator->generate($route, $parameters);
|
||||
}
|
||||
|
||||
protected function documentationLink(string $url): string
|
||||
{
|
||||
return Constants::HOMEPAGE . '/documentation/' . $url;
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -29,27 +29,28 @@ abstract class AbstractTimesheetSubscriber extends AbstractActionsSubscriber
|
||||
}
|
||||
|
||||
if (!$timesheet->isRunning() && $this->isGranted('start', $timesheet)) {
|
||||
$event->addAction('repeat', ['url' => $this->path('restart_timesheet', ['id' => $timesheet->getId()]), 'class' => 'api-link', 'attr' => ['data-payload' => '{"copy": "all"}', 'data-event' => 'kimai.timesheetStart kimai.timesheetUpdate', 'data-method' => 'PATCH', 'data-msg-error' => 'timesheet.start.error', 'data-msg-success' => 'timesheet.start.success']]);
|
||||
$event->addAction('repeat', ['title' => 'repeat', 'translation_domain' => 'actions', 'url' => $this->path('restart_timesheet', ['id' => $timesheet->getId()]), 'class' => 'api-link', 'attr' => ['data-payload' => '{"copy": "all"}', 'data-event' => 'kimai.timesheetStart kimai.timesheetUpdate', 'data-method' => 'PATCH', 'data-msg-error' => 'timesheet.start.error', 'data-msg-success' => 'timesheet.start.success']]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('edit', $timesheet)) {
|
||||
$class = $event->isView('edit') ? '' : 'modal-ajax-form';
|
||||
$event->addAction('edit', ['url' => $this->path($routeEdit, ['id' => $timesheet->getId()]), 'class' => $class]);
|
||||
$event->addAction('edit', ['title' => 'edit', 'translation_domain' => 'actions', 'url' => $this->path($routeEdit, ['id' => $timesheet->getId()]), 'class' => $class]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('duplicate', $timesheet)) {
|
||||
$class = $event->isView('edit') ? '' : 'modal-ajax-form';
|
||||
$event->addAction('copy', ['url' => $this->path($routeDuplicate, ['id' => $timesheet->getId()]), 'class' => $class]);
|
||||
$event->addAction('copy', ['title' => 'copy', 'translation_domain' => 'actions', 'url' => $this->path($routeDuplicate, ['id' => $timesheet->getId()]), 'class' => $class]);
|
||||
}
|
||||
|
||||
if ($event->countActions() > 0) {
|
||||
$event->addDivider();
|
||||
}
|
||||
|
||||
if ($event->isIndexView() && $this->isGranted('delete', $timesheet)) {
|
||||
if (($event->isIndexView() || $event->isView('calendar')) && $this->isGranted('delete', $timesheet)) {
|
||||
$event->addAction('trash', [
|
||||
'url' => $this->path('delete_timesheet', ['id' => $timesheet->getId()]),
|
||||
'class' => 'api-link',
|
||||
'class' => 'api-link text-red',
|
||||
'translation_domain' => 'actions',
|
||||
'attr' => [
|
||||
'data-event' => 'kimai.timesheetDelete',
|
||||
'data-method' => 'DELETE',
|
||||
@@ -60,9 +61,5 @@ abstract class AbstractTimesheetSubscriber extends AbstractActionsSubscriber
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$event->isIndexView()) {
|
||||
$event->addHelp($this->documentationLink('timesheet.html'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Repository\Query\ActivityQuery;
|
||||
|
||||
class ActivitiesSubscriber extends AbstractActionsSubscriber
|
||||
final class ActivitiesSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -21,23 +20,10 @@ class ActivitiesSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var ActivityQuery $query */
|
||||
$query = $payload['query'];
|
||||
|
||||
$event->addSearchToggle($query);
|
||||
$event->addColumnToggle('#modal_activity_admin');
|
||||
$event->addQuickExport($this->path('activity_export'));
|
||||
|
||||
if ($this->isGranted('create_activity')) {
|
||||
$event->addCreate($this->path('admin_activity_create'));
|
||||
}
|
||||
|
||||
if ($this->isGranted('system_configuration')) {
|
||||
$event->addAction('settings', ['url' => $this->path('system_configuration_section', ['section' => 'activity']), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('activity.html'));
|
||||
$event->addQuickExport($this->path('activity_export'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace App\EventSubscriber\Actions;
|
||||
use App\Entity\Activity;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class ActivitySubscriber extends AbstractActionsSubscriber
|
||||
final class ActivitySubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -31,17 +31,17 @@ class ActivitySubscriber extends AbstractActionsSubscriber
|
||||
}
|
||||
|
||||
if (!$event->isView('activity_details') && $this->isGranted('view', $activity)) {
|
||||
$event->addAction('details', ['url' => $this->path('activity_details', ['id' => $activity->getId()])]);
|
||||
$event->addAction('details', ['title' => 'details', 'translation_domain' => 'actions', 'url' => $this->path('activity_details', ['id' => $activity->getId()])]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('edit', $activity)) {
|
||||
$class = $event->isView('edit') ? '' : 'modal-ajax-form';
|
||||
$event->addAction('edit', ['url' => $this->path('admin_activity_edit', ['id' => $activity->getId()]), 'class' => $class]);
|
||||
$event->addAction('edit', ['title' => 'edit', 'translation_domain' => 'actions', 'url' => $this->path('admin_activity_edit', ['id' => $activity->getId()]), 'class' => $class]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('permissions', $activity)) {
|
||||
$class = $event->isView('permissions') ? '' : 'modal-ajax-form';
|
||||
$event->addAction('permissions', ['url' => $this->path('admin_activity_permissions', ['id' => $activity->getId()]), 'class' => $class]);
|
||||
$event->addAction('permissions', ['title' => 'permissions', 'translation_domain' => 'actions', 'url' => $this->path('admin_activity_permissions', ['id' => $activity->getId()]), 'class' => $class]);
|
||||
}
|
||||
|
||||
if ($event->countActions() > 0) {
|
||||
@@ -66,7 +66,7 @@ class ActivitySubscriber extends AbstractActionsSubscriber
|
||||
if (!$activity->isGlobal()) {
|
||||
$parameters['project'] = $activity->getProject()->getId();
|
||||
}
|
||||
$event->addAction('create-timesheet', ['icon' => 'start', 'url' => $this->path('admin_timesheet_create', $parameters), 'class' => 'modal-ajax-form']);
|
||||
$event->addAction('create-timesheet', ['title' => 'create-timesheet', 'translation_domain' => 'actions', 'icon' => 'start', 'url' => $this->path('admin_timesheet_create', $parameters), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
|
||||
if (($event->isIndexView() || $event->isView('project_details')) && $this->isGranted('delete', $activity)) {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class CalendarSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'calendar';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
if ($this->isGranted('create_own_timesheet')) {
|
||||
$event->addCreate($this->path('timesheet_create'));
|
||||
}
|
||||
|
||||
if ($this->isGranted('system_configuration')) {
|
||||
$event->addAction('settings', ['url' => $this->path('system_configuration_section', ['section' => 'calendar']), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('calendar.html'));
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace App\EventSubscriber\Actions;
|
||||
use App\Entity\Customer;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class CustomerSubscriber extends AbstractActionsSubscriber
|
||||
final class CustomerSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -30,18 +30,35 @@ class CustomerSubscriber extends AbstractActionsSubscriber
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$event->isView('customer_details') && $this->isGranted('view', $customer)) {
|
||||
$event->addAction('details', ['url' => $this->path('customer_details', ['id' => $customer->getId()])]);
|
||||
$canView = $this->isGranted('view', $customer);
|
||||
$isListingView = $event->isIndexView() || $event->isCustomView();
|
||||
|
||||
if (!$event->isView('customer_details') && $canView) {
|
||||
$event->addAction('details', ['title' => 'details', 'translation_domain' => 'actions', 'url' => $this->path('customer_details', ['id' => $customer->getId()])]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('edit', $customer)) {
|
||||
$class = $event->isView('edit') ? '' : 'modal-ajax-form';
|
||||
$event->addAction('edit', ['url' => $this->path('admin_customer_edit', ['id' => $customer->getId()]), 'class' => $class]);
|
||||
$event->addAction('edit', ['title' => 'edit', 'translation_domain' => 'actions', 'url' => $this->path('admin_customer_edit', ['id' => $customer->getId()]), 'class' => $class]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('permissions', $customer)) {
|
||||
$class = $event->isView('permissions') ? '' : 'modal-ajax-form';
|
||||
$event->addAction('permissions', ['url' => $this->path('admin_customer_permissions', ['id' => $customer->getId()]), 'class' => $class]);
|
||||
$event->addAction('permissions', ['title' => 'permissions', 'translation_domain' => 'actions', 'url' => $this->path('admin_customer_permissions', ['id' => $customer->getId()]), 'class' => $class]);
|
||||
}
|
||||
|
||||
if ($canView && $event->isIndexView()) {
|
||||
$event->addAction('vcard', ['title' => 'vcard', 'translation_domain' => 'actions', 'icon' => 'far fa-address-card', 'url' => $this->path('customer_vcard', ['id' => $customer->getId()])]);
|
||||
}
|
||||
|
||||
if ($isListingView) {
|
||||
if ($customer->isVisible() && $this->isGranted('create_project')) {
|
||||
$event->addAction('create-project', [
|
||||
'icon' => 'create',
|
||||
'url' => $this->path('admin_project_create_with_customer', ['customer' => $customer->getId()]),
|
||||
'class' => 'modal-ajax-form'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($event->countActions() > 0) {
|
||||
@@ -64,22 +81,17 @@ class CustomerSubscriber extends AbstractActionsSubscriber
|
||||
$event->addDivider();
|
||||
}
|
||||
|
||||
if (!$event->isView('customer_details')) {
|
||||
if ($customer->isVisible() && $this->isGranted('create_project')) {
|
||||
$event->addAction('create-project', [
|
||||
'icon' => 'create',
|
||||
'url' => $this->path('admin_project_create_with_customer', ['customer' => $customer->getId()]),
|
||||
'class' => 'modal-ajax-form'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($event->isIndexView() && $this->isGranted('delete', $customer)) {
|
||||
$event->addDelete($this->path('admin_customer_delete', ['id' => $customer->getId()]));
|
||||
}
|
||||
|
||||
if ($this->isGranted('view_reporting') && $this->isGranted('budget_any', 'project')) {
|
||||
$event->addAction('report_project_view', ['url' => $this->path('report_project_view', ['customer' => $customer->getId()]), 'icon' => 'reporting', 'translation_domain' => 'reporting']);
|
||||
if ($this->isGranted('report:customer') && $this->isGranted('report:other')) {
|
||||
$event->addActionToSubmenu('report', 'report_customer_monthly_projects', ['title' => 'report_customer_monthly_projects', 'url' => $this->path('report_customer_monthly_projects', ['customer' => $customer->getId()]), 'translation_domain' => 'reporting']);
|
||||
}
|
||||
|
||||
if ($this->isGranted('report:project') && $this->isGranted('budget_any', 'project')) {
|
||||
$event->addActionToSubmenu('report', 'daterange_projects', ['title' => 'report_project_daterange', 'url' => $this->path('report_project_daterange', ['customer' => $customer->getId()]), 'translation_domain' => 'reporting']);
|
||||
$event->addActionToSubmenu('report', 'report_project_view', ['title' => 'report_project_view', 'url' => $this->path('report_project_view', ['customer' => $customer->getId()]), 'translation_domain' => 'reporting']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Repository\Query\CustomerQuery;
|
||||
|
||||
class CustomersSubscriber extends AbstractActionsSubscriber
|
||||
final class CustomersSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -21,23 +20,10 @@ class CustomersSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var CustomerQuery $query */
|
||||
$query = $payload['query'];
|
||||
|
||||
$event->addSearchToggle($query);
|
||||
$event->addColumnToggle('#modal_customer_admin');
|
||||
$event->addQuickExport($this->path('customer_export'));
|
||||
|
||||
if ($this->isGranted('create_customer')) {
|
||||
$event->addCreate($this->path('admin_customer_create'));
|
||||
}
|
||||
|
||||
if ($this->isGranted('system_configuration')) {
|
||||
$event->addAction('settings', ['url' => $this->path('system_configuration_section', ['section' => 'customer']), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('customer.html'));
|
||||
$event->addQuickExport($this->path('customer_export'));
|
||||
}
|
||||
}
|
||||
|
||||
76
src/EventSubscriber/Actions/DashboardSubscriber.php
Normal file
76
src/EventSubscriber/Actions/DashboardSubscriber.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Widget\WidgetInterface;
|
||||
|
||||
final class DashboardSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'dashboard';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var WidgetInterface[] $widgets */
|
||||
$widgets = $payload['widgets'];
|
||||
/** @var WidgetInterface[] $available */
|
||||
$available = $payload['available'];
|
||||
|
||||
if (!$event->isView('edit')) {
|
||||
$event->addConfig($this->path('dashboard_edit'));
|
||||
} else {
|
||||
$ids = [];
|
||||
|
||||
$event->addAction('save', ['title' => 'action.save', 'onclick' => 'saveDashboard(); return false;', 'icon' => 'save']);
|
||||
|
||||
foreach ($widgets as $widget) {
|
||||
$ids[] = $widget->getId();
|
||||
}
|
||||
|
||||
foreach ($available as $widget) {
|
||||
if ($widget->isInternal()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// prevent to use the same widget multiple times
|
||||
if (\in_array($widget->getId(), $ids)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$permissions = $widget->getPermissions();
|
||||
if (\count($permissions) > 0) {
|
||||
$allow = false;
|
||||
foreach ($widget->getPermissions() as $permission) {
|
||||
if ($this->isGranted($permission)) {
|
||||
$allow = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$allow) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($widget->getTitle())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$event->addActionToSubmenu('widget_add', $widget->getId(), ['url' => $this->path('dashboard_add', ['widget' => $widget->getId()]), 'title' => $widget->getTitle()]);
|
||||
}
|
||||
|
||||
$event->addAction('reset', ['title' => 'action.reset', 'url' => $this->path('dashboard_reset'), 'icon' => 'delete', 'class' => 'confirmation-link', 'attr' => ['data-question' => 'confirm.delete']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class ExportSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'export';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$event->addColumnToggle('#modal_export');
|
||||
|
||||
if ($event->isView('preview')) {
|
||||
$event->addAction('off', ['id' => 'export-toggle-button']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('export.html'));
|
||||
}
|
||||
}
|
||||
@@ -10,29 +10,16 @@
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Repository\Query\InvoiceArchiveQuery;
|
||||
|
||||
class InvoiceArchiveSubscriber extends AbstractActionsSubscriber
|
||||
final class InvoiceArchiveSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'invoice_details';
|
||||
return 'invoice_archive';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var InvoiceArchiveQuery $query */
|
||||
$query = $payload['query'];
|
||||
|
||||
if ($this->isGranted('view_invoice')) {
|
||||
$event->addBack($this->path('invoice'));
|
||||
}
|
||||
|
||||
$event->addSearchToggle($query);
|
||||
$event->addColumnToggle('#modal_invoices');
|
||||
$event->addQuickExport($this->path('invoice_export'));
|
||||
$event->addHelp($this->documentationLink('invoices.html'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Entity\InvoiceDocument;
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Model\InvoiceDocument;
|
||||
|
||||
class InvoiceDocumentSubscriber extends AbstractActionsSubscriber
|
||||
final class InvoiceDocumentSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace App\EventSubscriber\Actions;
|
||||
use App\Entity\Invoice;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class InvoiceSubscriber extends AbstractActionsSubscriber
|
||||
final class InvoiceSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -30,15 +30,28 @@ class InvoiceSubscriber extends AbstractActionsSubscriber
|
||||
return;
|
||||
}
|
||||
|
||||
$event->addAction('edit', ['url' => $this->path('admin_invoice_edit', ['id' => $invoice->getId()]), 'class' => 'modal-ajax-form']);
|
||||
$event->addAction('download', ['url' => $this->path('admin_invoice_download', ['id' => $invoice->getId()]), 'target' => '_blank']);
|
||||
$allowCreate = $this->isGranted('create_invoice');
|
||||
$allowView = $this->isGranted('view_invoice');
|
||||
$allowCustomer = $this->isGranted('access', $invoice->getCustomer());
|
||||
|
||||
$event->addDivider();
|
||||
if ($allowCustomer && $allowCreate) {
|
||||
$event->addAction('edit', ['url' => $this->path('admin_invoice_edit', ['id' => $invoice->getId()]), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
|
||||
if (!$invoice->isPending()) {
|
||||
$event->addAction('invoice.pending', ['url' => $this->path('admin_invoice_status', ['id' => $invoice->getId(), 'status' => 'pending', 'token' => $payload['token']])]);
|
||||
} else {
|
||||
$event->addAction('invoice.paid', ['url' => $this->path('admin_invoice_status', ['id' => $invoice->getId(), 'status' => 'paid', 'token' => $payload['token']]), 'class' => 'modal-ajax-form']);
|
||||
if ($allowCustomer && $allowView) {
|
||||
$event->addAction('download', ['url' => $this->path('admin_invoice_download', ['id' => $invoice->getId()]), 'target' => '_blank']);
|
||||
}
|
||||
|
||||
if ($event->countActions() > 0) {
|
||||
$event->addDivider();
|
||||
}
|
||||
|
||||
if ($allowCustomer && $allowCreate) {
|
||||
if (!$invoice->isPending()) {
|
||||
$event->addAction('invoice.pending', ['url' => $this->path('admin_invoice_status', ['id' => $invoice->getId(), 'status' => 'pending', 'token' => $payload['token']])]);
|
||||
} else {
|
||||
$event->addAction('invoice.paid', ['url' => $this->path('admin_invoice_status', ['id' => $invoice->getId(), 'status' => 'paid', 'token' => $payload['token']]), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
}
|
||||
|
||||
$allowDelete = $this->isGranted('delete_invoice');
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace App\EventSubscriber\Actions;
|
||||
use App\Entity\InvoiceTemplate;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class InvoiceTemplateSubscriber extends AbstractActionsSubscriber
|
||||
final class InvoiceTemplateSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -31,12 +31,9 @@ class InvoiceTemplateSubscriber extends AbstractActionsSubscriber
|
||||
}
|
||||
|
||||
if ($this->isGranted('manage_invoice_template')) {
|
||||
if (!$event->isIndexView()) {
|
||||
$event->addBack($this->path('invoice'));
|
||||
}
|
||||
$event->addAction('edit', ['url' => $this->path('admin_invoice_template_edit', ['id' => $template->getId()]), 'class' => 'modal-ajax-form']);
|
||||
$event->addAction('copy', ['url' => $this->path('admin_invoice_template_copy', ['id' => $template->getId()])]);
|
||||
$event->addDelete($this->path('admin_invoice_template_delete', ['id' => $template->getId(), 'token' => $payload['token']]), false);
|
||||
$event->addAction('copy', ['url' => $this->path('admin_invoice_template_copy', ['id' => $template->getId()]), 'class' => 'modal-ajax-form']);
|
||||
$event->addDelete($this->path('admin_invoice_template_delete', ['id' => $template->getId(), 'csrfToken' => $payload['token']]), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class InvoiceTemplateUploadSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'invoice_upload';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
if ($event->isIndexView() && $this->isGranted('manage_invoice_template')) {
|
||||
$event->addBack($this->path('admin_invoice_template'));
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('invoices.html'));
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class InvoiceTemplatesSubscriber extends AbstractActionsSubscriber
|
||||
final class InvoiceTemplatesSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -20,21 +20,13 @@ class InvoiceTemplatesSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
if ($this->isGranted('view_invoice')) {
|
||||
$event->addBack($this->path('invoice'));
|
||||
}
|
||||
|
||||
$event->addColumnToggle('#modal_invoice_template');
|
||||
|
||||
if ($this->isGranted('manage_invoice_template')) {
|
||||
$event->addAction('create', ['url' => $this->path('admin_invoice_template_create'), 'class' => 'modal-ajax-form']);
|
||||
$event->addAction('create', ['url' => $this->path('admin_invoice_template_create'), 'class' => 'modal-ajax-form', 'title' => 'create']);
|
||||
}
|
||||
|
||||
// File upload does not work in a modal right now
|
||||
if ($this->isGranted('upload_invoice_template')) {
|
||||
$event->addAction('upload', ['url' => $this->path('admin_invoice_document_upload')]);
|
||||
$event->addAction('upload', ['url' => $this->path('admin_invoice_document_upload'), 'title' => 'invoice_renderer', 'translation_domain' => 'invoice-renderer']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('invoices.html'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class InvoicesSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'invoices';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$event->addColumnToggle('#modal_invoice');
|
||||
|
||||
$event->addAction('list', ['url' => $this->path('admin_invoice_list')]);
|
||||
|
||||
if ($this->isGranted('manage_invoice_template')) {
|
||||
$event->addAction('invoice-template', ['url' => $this->path('admin_invoice_template')]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('system_configuration')) {
|
||||
$event->addAction('settings', ['url' => $this->path('system_configuration_section', ['section' => 'invoice']), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('invoices.html'));
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class PermissionsSubscriber extends AbstractActionsSubscriber
|
||||
final class PermissionsSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -23,7 +23,5 @@ class PermissionsSubscriber extends AbstractActionsSubscriber
|
||||
if ($this->isGranted('role_permissions')) {
|
||||
$event->addCreate($this->path('admin_user_roles'), !$event->isView('role'));
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('permissions.html'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace App\EventSubscriber\Actions;
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Plugin\Plugin;
|
||||
|
||||
class PluginSubscriber extends AbstractActionsSubscriber
|
||||
final class PluginSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Constants;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class PluginsSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'plugins';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$event->addAction('shop', ['url' => Constants::HOMEPAGE . '/store/', 'target' => '_blank']);
|
||||
$event->addHelp($this->documentationLink('plugins.html'));
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace App\EventSubscriber\Actions;
|
||||
use App\Entity\Project;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class ProjectSubscriber extends AbstractActionsSubscriber
|
||||
final class ProjectSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -25,23 +25,26 @@ class ProjectSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
/** @var Project $project */
|
||||
$project = $payload['project'];
|
||||
$customer = $project->getCustomer();
|
||||
|
||||
if ($project->getId() === null) {
|
||||
if ($project->getId() === null || $customer === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$isListingView = $event->isIndexView() || $event->isCustomView();
|
||||
|
||||
if (!$event->isView('project_details') && $this->isGranted('view', $project)) {
|
||||
$event->addAction('details', ['url' => $this->path('project_details', ['id' => $project->getId()])]);
|
||||
$event->addAction('details', ['title' => 'details', 'translation_domain' => 'actions', 'url' => $this->path('project_details', ['id' => $project->getId()])]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('edit', $project)) {
|
||||
$class = $event->isView('edit') ? '' : 'modal-ajax-form';
|
||||
$event->addAction('edit', ['url' => $this->path('admin_project_edit', ['id' => $project->getId()]), 'class' => $class]);
|
||||
$event->addAction('edit', ['title' => 'edit', 'translation_domain' => 'actions', 'url' => $this->path('admin_project_edit', ['id' => $project->getId()]), 'class' => $class]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('permissions', $project)) {
|
||||
$class = $event->isView('permissions') ? '' : 'modal-ajax-form';
|
||||
$event->addAction('permissions', ['url' => $this->path('admin_project_permissions', ['id' => $project->getId()]), 'class' => $class]);
|
||||
$event->addAction('permissions', ['title' => 'permissions', 'translation_domain' => 'actions', 'url' => $this->path('admin_project_permissions', ['id' => $project->getId()]), 'class' => $class]);
|
||||
}
|
||||
|
||||
if ($event->countActions() > 0) {
|
||||
@@ -49,19 +52,23 @@ class ProjectSubscriber extends AbstractActionsSubscriber
|
||||
}
|
||||
|
||||
if ($this->isGranted('view_activity')) {
|
||||
$event->addActionToSubmenu('filter', 'activity', ['title' => 'activity.filter', 'translation_domain' => 'actions', 'url' => $this->path('admin_activity', ['customers[]' => $project->getCustomer()->getId(), 'projects[]' => $project->getId()])]);
|
||||
$event->addActionToSubmenu('filter', 'activity', ['title' => 'activity.filter', 'translation_domain' => 'actions', 'url' => $this->path('admin_activity', ['customers[]' => $customer->getId(), 'projects[]' => $project->getId()])]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('view_other_timesheet')) {
|
||||
$event->addActionToSubmenu('filter', 'timesheet', ['title' => 'timesheet.filter', 'translation_domain' => 'actions', 'url' => $this->path('admin_timesheet', ['customers[]' => $project->getCustomer()->getId(), 'projects[]' => $project->getId()])]);
|
||||
$event->addActionToSubmenu('filter', 'timesheet', ['title' => 'timesheet.filter', 'translation_domain' => 'actions', 'url' => $this->path('admin_timesheet', ['customers[]' => $customer->getId(), 'projects[]' => $project->getId()])]);
|
||||
}
|
||||
|
||||
if ($this->isGranted('create_export')) {
|
||||
$event->addActionToSubmenu('filter', 'export', ['title' => 'export', 'url' => $this->path('export', ['customers[]' => $customer->getId(), 'projects[]' => $project->getId(), 'exported' => 1, 'daterange' => ''])]);
|
||||
}
|
||||
|
||||
if ($event->hasSubmenu('filter')) {
|
||||
$event->addDivider();
|
||||
}
|
||||
|
||||
if (!$event->isView('project_details')) {
|
||||
if ($project->isVisible() && $project->getCustomer()->isVisible() && $this->isGranted('create_activity')) {
|
||||
if ($isListingView) {
|
||||
if ($project->isVisible() && $customer->isVisible() && $this->isGranted('create_activity')) {
|
||||
$event->addAction('create-activity', [
|
||||
'icon' => 'create',
|
||||
'url' => $this->path('admin_activity_create_with_project', ['project' => $project->getId()]),
|
||||
@@ -70,10 +77,10 @@ class ProjectSubscriber extends AbstractActionsSubscriber
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->isGranted('edit', $project) && $this->isGranted('create_project')) {
|
||||
if (\array_key_exists('token', $payload) && $this->isGranted('edit', $project) && $this->isGranted('create_project')) {
|
||||
$event->addAction(
|
||||
'copy',
|
||||
['url' => $this->path('admin_project_duplicate', ['id' => $project->getId(), 'token' => $payload['token']])]
|
||||
['title' => 'copy', 'translation_domain' => 'actions', 'url' => $this->path('admin_project_duplicate', ['id' => $project->getId(), 'token' => $payload['token']])]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -81,8 +88,8 @@ class ProjectSubscriber extends AbstractActionsSubscriber
|
||||
$event->addDelete($this->path('admin_project_delete', ['id' => $project->getId()]));
|
||||
}
|
||||
|
||||
if ($project->isVisible() && $this->isGranted('view_reporting') && $this->isGranted('details', $project)) {
|
||||
$event->addAction('report_project_details', ['url' => $this->path('report_project_details', ['project' => $project->getId()]), 'icon' => 'reporting', 'translation_domain' => 'reporting']);
|
||||
if (!$event->isView('project_details_report') && $this->isGranted('report:project') && $this->isGranted('details', $project)) {
|
||||
$event->addAction('report_project_details', ['title' => 'report_project_details', 'translation_domain' => 'reporting', 'url' => $this->path('report_project_details', ['project' => $project->getId()]), 'icon' => 'reporting']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Repository\Query\ProjectQuery;
|
||||
|
||||
class ProjectsSubscriber extends AbstractActionsSubscriber
|
||||
final class ProjectsSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -21,24 +20,10 @@ class ProjectsSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var ProjectQuery $query */
|
||||
$query = $payload['query'];
|
||||
|
||||
$event->addSearchToggle($query);
|
||||
|
||||
$event->addColumnToggle('#modal_project_admin');
|
||||
$event->addQuickExport($this->path('project_export'));
|
||||
|
||||
if ($this->isGranted('create_project')) {
|
||||
$event->addCreate($this->path('admin_project_create'));
|
||||
}
|
||||
|
||||
if ($this->isGranted('system_configuration')) {
|
||||
$event->addAction('settings', ['url' => $this->path('system_configuration_section', ['section' => 'project']), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('project.html'));
|
||||
$event->addQuickExport($this->path('project_export'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class QuickEntrySubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'weekly_times';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
if ($this->isGranted('system_configuration')) {
|
||||
$event->addAction('settings', ['url' => $this->path('system_configuration_section', ['section' => 'quick_entry']), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('weekly-times.html'));
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Reporting\Report;
|
||||
use App\Reporting\ReportingService;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||
|
||||
class ReportingSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
private $reportingService;
|
||||
|
||||
public function __construct(AuthorizationCheckerInterface $security, UrlGeneratorInterface $urlGenerator, ReportingService $reportingService)
|
||||
{
|
||||
parent::__construct($security, $urlGenerator);
|
||||
$this->reportingService = $reportingService;
|
||||
}
|
||||
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'reporting';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$reports = $this->reportingService->getAvailableReports($event->getUser());
|
||||
|
||||
foreach ($reports as $report) {
|
||||
$subMenu = 'reporting';
|
||||
if ($report instanceof Report) {
|
||||
$subMenu = $report->getReportIcon();
|
||||
}
|
||||
$event->addActionToSubmenu($subMenu, $report->getId(), ['title' => $report->getLabel(), 'translation_domain' => 'reporting', 'url' => $this->path($report->getRoute()), 'class' => 'report-' . $report->getId()]);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('reporting.html'));
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class SystemConfigurationSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'system_configuration';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$event->addHelp($this->documentationLink('configurations.html'));
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace App\EventSubscriber\Actions;
|
||||
use App\Entity\Tag;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class TagSubscriber extends AbstractActionsSubscriber
|
||||
final class TagSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -53,7 +53,8 @@ class TagSubscriber extends AbstractActionsSubscriber
|
||||
if ($event->isIndexView() && $this->isGranted('delete_tag')) {
|
||||
$event->addAction('trash', [
|
||||
'url' => $this->path('delete_tag', ['id' => $id]),
|
||||
'class' => 'api-link',
|
||||
'class' => 'api-link text-red',
|
||||
'translation_domain' => 'actions',
|
||||
'attr' => [
|
||||
'data-event' => 'kimai.tagDelete kimai.tagUpdate',
|
||||
'data-method' => 'DELETE',
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Repository\Query\TagQuery;
|
||||
|
||||
class TagsSubscriber extends AbstractActionsSubscriber
|
||||
final class TagsSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -21,17 +20,8 @@ class TagsSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var TagQuery $query */
|
||||
$query = $payload['query'];
|
||||
|
||||
$event->addSearchToggle($query);
|
||||
|
||||
if ($this->isGranted('manage_tag')) {
|
||||
if ($this->isGranted('manage_tag') || $this->isGranted('create_tag')) {
|
||||
$event->addCreate($this->path('tags_create'));
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('tags.html'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace App\EventSubscriber\Actions;
|
||||
use App\Entity\Team;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class TeamSubscriber extends AbstractActionsSubscriber
|
||||
final class TeamSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -31,17 +31,20 @@ class TeamSubscriber extends AbstractActionsSubscriber
|
||||
}
|
||||
|
||||
if ($this->isGranted('edit', $team)) {
|
||||
$event->addAction('edit', ['url' => $this->path('admin_team_edit', ['id' => $team->getId()])]);
|
||||
if (!$event->isView('edit')) {
|
||||
$event->addAction('edit', ['url' => $this->path('admin_team_edit', ['id' => $team->getId()]), 'title' => 'action.edit']);
|
||||
}
|
||||
|
||||
if ($this->isGranted('create_team')) {
|
||||
$event->addAction('copy', ['url' => $this->path('team_duplicate', ['id' => $team->getId(), 'token' => $payload['token']])]);
|
||||
$event->addAction('copy', ['url' => $this->path('team_duplicate', ['id' => $team->getId()]), 'title' => 'copy', 'translation_domain' => 'actions', 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($event->isIndexView() && $this->isGranted('delete', $team)) {
|
||||
$event->addAction('trash', [
|
||||
'url' => $this->path('delete_team', ['id' => $team->getId()]),
|
||||
'class' => 'api-link',
|
||||
'class' => 'api-link text-red',
|
||||
'translation_domain' => 'actions',
|
||||
'attr' => [
|
||||
'data-event' => 'kimai.teamDelete kimai.teamUpdate',
|
||||
'data-method' => 'DELETE',
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Repository\Query\TeamQuery;
|
||||
|
||||
class TeamsSubscriber extends AbstractActionsSubscriber
|
||||
final class TeamsSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -21,17 +20,8 @@ class TeamsSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var TeamQuery $query */
|
||||
$query = $payload['query'];
|
||||
|
||||
$event->addSearchToggle($query);
|
||||
|
||||
if ($this->isGranted('create_team')) {
|
||||
$event->addCreate($this->path('admin_team_create'), false);
|
||||
$event->addCreate($this->path('admin_team_create'));
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('teams.html'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class TimesheetMultiUpdateSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'timesheets_multi_update';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$event->addBack($this->path('timesheet'));
|
||||
$event->addHelp($this->documentationLink('timesheet.html'));
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class TimesheetSubscriber extends AbstractTimesheetSubscriber
|
||||
final class TimesheetSubscriber extends AbstractTimesheetSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class TimesheetTeamMultiUpdateSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'timesheets_team_multi_update';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$event->addBack($this->path('admin_timesheet'));
|
||||
$event->addHelp($this->documentationLink('timesheet.html'));
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class TimesheetTeamSubscriber extends AbstractTimesheetSubscriber
|
||||
final class TimesheetTeamSubscriber extends AbstractTimesheetSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Repository\Query\TimesheetQuery;
|
||||
|
||||
class TimesheetsSubscriber extends AbstractActionsSubscriber
|
||||
final class TimesheetsSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -21,22 +20,12 @@ class TimesheetsSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var TimesheetQuery $query */
|
||||
$query = $payload['query'];
|
||||
|
||||
$event->addSearchToggle($query);
|
||||
$event->addColumnToggle('#modal_timesheet');
|
||||
|
||||
if ($this->isGranted('export_own_timesheet')) {
|
||||
$event->addAction('download', ['url' => $this->path('timesheet_export'), 'class' => 'toolbar-action modal-ajax-form']);
|
||||
}
|
||||
|
||||
if ($this->isGranted('create_own_timesheet')) {
|
||||
$event->addCreate($this->path('timesheet_create'));
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('timesheet.html'));
|
||||
if ($this->isGranted('export_own_timesheet')) {
|
||||
$event->addAction('download', ['url' => $this->path('timesheet_export'), 'class' => 'modal-ajax-form', 'title' => 'export']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Repository\Query\TimesheetQuery;
|
||||
|
||||
class TimesheetsTeamSubscriber extends AbstractActionsSubscriber
|
||||
final class TimesheetsTeamSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -21,23 +20,13 @@ class TimesheetsTeamSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var TimesheetQuery $query */
|
||||
$query = $payload['query'];
|
||||
|
||||
$event->addSearchToggle($query);
|
||||
$event->addColumnToggle('#modal_timesheet_admin');
|
||||
if ($this->isGranted('create_other_timesheet')) {
|
||||
$event->addAction('create', ['title' => 'create', 'url' => $this->path('admin_timesheet_create'), 'class' => 'create-ts modal-ajax-form']);
|
||||
$event->addAction('multi-user', ['title' => 'create-timesheet-multiuser', 'translation_domain' => 'actions', 'url' => $this->path('admin_timesheet_create_multiuser'), 'class' => 'create-ts-mu modal-ajax-form', 'icon' => 'fas fa-user-plus']);
|
||||
}
|
||||
|
||||
if ($this->isGranted('export_other_timesheet')) {
|
||||
$event->addAction('download', ['url' => $this->path('admin_timesheet_export'), 'class' => 'toolbar-action modal-ajax-form']);
|
||||
$event->addAction('download', ['url' => $this->path('admin_timesheet_export'), 'class' => 'modal-ajax-form', 'title' => 'export']);
|
||||
}
|
||||
|
||||
if ($this->isGranted('create_other_timesheet')) {
|
||||
$event->addActionToSubmenu('create', 'single', ['title' => 'create', 'url' => $this->path('admin_timesheet_create'), 'class' => 'create-ts modal-ajax-form']);
|
||||
$event->addActionToSubmenu('create', 'multi-user', ['title' => 'create-timesheet-multiuser', 'translation_domain' => 'actions', 'url' => $this->path('admin_timesheet_create_multiuser'), 'class' => 'create-ts-mu modal-ajax-form']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('timesheet.html'));
|
||||
}
|
||||
}
|
||||
|
||||
52
src/EventSubscriber/Actions/UserFormsSubscriber.php
Normal file
52
src/EventSubscriber/Actions/UserFormsSubscriber.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?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\EventSubscriber\Actions;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
final class UserFormsSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
return 'user_forms';
|
||||
}
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var User $user */
|
||||
$user = $payload['user'];
|
||||
|
||||
if ($user->getId() === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->isGranted('edit', $user)) {
|
||||
$event->addAction('edit', ['url' => $this->path('user_profile_edit', ['username' => $user->getUserIdentifier()]), 'title' => 'edit', 'translation_domain' => 'actions']);
|
||||
}
|
||||
if ($this->isGranted('password', $user)) {
|
||||
$event->addAction('password', ['url' => $this->path('user_profile_password', ['username' => $user->getUserIdentifier()]), 'title' => 'profile.password']);
|
||||
}
|
||||
if ($this->isGranted('2fa', $user)) {
|
||||
$event->addAction('2fa', ['url' => $this->path('user_profile_2fa', ['username' => $user->getUserIdentifier()]), 'title' => 'profile.2fa']);
|
||||
}
|
||||
if ($this->isGranted('api-token', $user)) {
|
||||
$event->addAction('api-token', ['url' => $this->path('user_profile_api_token', ['username' => $user->getUserIdentifier()]), 'title' => 'profile.api-token']);
|
||||
}
|
||||
if ($this->isGranted('teams', $user)) {
|
||||
$event->addAction('teams', ['url' => $this->path('user_profile_teams', ['username' => $user->getUserIdentifier()]), 'title' => 'teams']);
|
||||
}
|
||||
if ($this->isGranted('roles', $user)) {
|
||||
$event->addAction('roles', ['url' => $this->path('user_profile_roles', ['username' => $user->getUserIdentifier()]), 'title' => 'profile.roles']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace App\EventSubscriber\Actions;
|
||||
use App\Entity\User;
|
||||
use App\Event\PageActionsEvent;
|
||||
|
||||
class UserSubscriber extends AbstractActionsSubscriber
|
||||
final class UserSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -31,43 +31,30 @@ class UserSubscriber extends AbstractActionsSubscriber
|
||||
}
|
||||
|
||||
if ($this->isGranted('view', $user)) {
|
||||
$event->addAction('profile-stats', ['icon' => 'avatar', 'url' => $this->path('user_profile', ['username' => $user->getUsername()]), 'translation_domain' => 'actions']);
|
||||
$event->addAction('profile-stats', ['icon' => 'avatar', 'url' => $this->path('user_profile', ['username' => $user->getUserIdentifier()]), 'translation_domain' => 'actions', 'title' => 'profile-stats']);
|
||||
$event->addDivider();
|
||||
}
|
||||
|
||||
if ($this->isGranted('edit', $user)) {
|
||||
$event->addActionToSubmenu('edit', 'edit', ['url' => $this->path('user_profile_edit', ['username' => $user->getUsername()]), 'title' => 'edit', 'translation_domain' => 'actions']);
|
||||
$event->addAction('edit', ['url' => $this->path('user_profile_edit', ['username' => $user->getUserIdentifier()]), 'title' => 'edit', 'translation_domain' => 'actions']);
|
||||
}
|
||||
|
||||
if ($this->isGranted('preferences', $user)) {
|
||||
$event->addActionToSubmenu('edit', 'settings', ['url' => $this->path('user_profile_preferences', ['username' => $user->getUsername()]), 'title' => 'settings', 'translation_domain' => 'actions']);
|
||||
}
|
||||
if ($this->isGranted('password', $user)) {
|
||||
$event->addActionToSubmenu('edit', 'password', ['url' => $this->path('user_profile_password', ['username' => $user->getUsername()]), 'title' => 'profile.password']);
|
||||
}
|
||||
if ($this->isGranted('api-token', $user)) {
|
||||
$event->addActionToSubmenu('edit', 'api-token', ['url' => $this->path('user_profile_api_token', ['username' => $user->getUsername()]), 'title' => 'profile.api-token']);
|
||||
}
|
||||
if ($this->isGranted('teams', $user)) {
|
||||
$event->addActionToSubmenu('edit', 'teams', ['url' => $this->path('user_profile_teams', ['username' => $user->getUsername()]), 'title' => 'profile.teams']);
|
||||
}
|
||||
if ($this->isGranted('roles', $user)) {
|
||||
$event->addActionToSubmenu('edit', 'roles', ['url' => $this->path('user_profile_roles', ['username' => $user->getUsername()]), 'title' => 'profile.roles']);
|
||||
$event->addConfig($this->path('user_profile_preferences', ['username' => $user->getUserIdentifier()]));
|
||||
}
|
||||
|
||||
if ($event->hasSubmenu('edit')) {
|
||||
$event->addDivider();
|
||||
if ($this->isGranted('report:other') || ($this->isGranted('report:user') && $event->getUser()->getId() === $user->getId())) {
|
||||
$event->addActionToSubmenu('report', 'weekly', ['url' => $this->path('report_user_week', ['user' => $user->getId()]), 'translation_domain' => 'reporting', 'title' => 'report_user_week']);
|
||||
$event->addActionToSubmenu('report', 'monthly', ['url' => $this->path('report_user_month', ['user' => $user->getId()]), 'translation_domain' => 'reporting', 'title' => 'report_user_month']);
|
||||
$event->addActionToSubmenu('report', 'yearly', ['url' => $this->path('report_user_year', ['user' => $user->getId()]), 'translation_domain' => 'reporting', 'title' => 'report_user_year']);
|
||||
}
|
||||
|
||||
$viewOther = $this->isGranted('view_other_timesheet');
|
||||
if ($this->isGranted('view_reporting')) {
|
||||
// also found in App\Controller\Reporting\ReportByUserController
|
||||
if (($viewOther && $this->isGranted('view_other_reporting')) || ($event->getUser()->getId() === $user->getId())) {
|
||||
$event->addAction('menu.reporting', ['url' => $this->path('report_user_month', ['user' => $user->getId()]), 'icon' => 'reporting']);
|
||||
}
|
||||
if ($this->isGranted('view_other_timesheet') && $user->isEnabled()) {
|
||||
$event->addActionToSubmenu('filter', 'timesheet', ['url' => $this->path('admin_timesheet', ['users[]' => $user->getId()]), 'title' => 'timesheet.filter', 'translation_domain' => 'actions']);
|
||||
}
|
||||
|
||||
if ($viewOther && $user->isEnabled()) {
|
||||
$event->addActionToSubmenu('filter', 'timesheet', ['title' => 'timesheet.filter', 'translation_domain' => 'actions', 'url' => $this->path('admin_timesheet', ['users[]' => $user->getId()])]);
|
||||
if ($this->isGranted('view_team')) {
|
||||
$event->addActionToSubmenu('filter', 'teams', ['url' => $this->path('admin_team', ['users[]' => $user->getId()]), 'title' => 'teams']);
|
||||
}
|
||||
|
||||
if ($event->isIndexView() && $this->isGranted('delete', $user)) {
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
namespace App\EventSubscriber\Actions;
|
||||
|
||||
use App\Event\PageActionsEvent;
|
||||
use App\Repository\Query\UserQuery;
|
||||
|
||||
class UsersSubscriber extends AbstractActionsSubscriber
|
||||
final class UsersSubscriber extends AbstractActionsSubscriber
|
||||
{
|
||||
public static function getActionName(): string
|
||||
{
|
||||
@@ -21,27 +20,16 @@ class UsersSubscriber extends AbstractActionsSubscriber
|
||||
|
||||
public function onActions(PageActionsEvent $event): void
|
||||
{
|
||||
$payload = $event->getPayload();
|
||||
|
||||
/** @var UserQuery $query */
|
||||
$query = $payload['query'];
|
||||
|
||||
$event->addSearchToggle($query);
|
||||
|
||||
if ($event->isIndexView()) {
|
||||
$event->addColumnToggle('#modal_user_admin');
|
||||
if ($this->isGranted('create_user')) {
|
||||
$event->addCreate($this->path('admin_user_create'), true);
|
||||
}
|
||||
|
||||
$event->addQuickExport($this->path('user_export'));
|
||||
|
||||
if ($this->isGranted('create_user')) {
|
||||
$event->addCreate($this->path('admin_user_create'), false);
|
||||
if ($this->isGranted('report:other')) {
|
||||
$event->addActionToSubmenu('report', 'weekly', ['url' => $this->path('report_weekly_users'), 'translation_domain' => 'reporting', 'title' => 'report_weekly_users']);
|
||||
$event->addActionToSubmenu('report', 'monthly', ['url' => $this->path('report_monthly_users'), 'translation_domain' => 'reporting', 'title' => 'report_monthly_users']);
|
||||
$event->addActionToSubmenu('report', 'yearly', ['url' => $this->path('report_yearly_users'), 'translation_domain' => 'reporting', 'title' => 'report_yearly_users']);
|
||||
}
|
||||
|
||||
if ($this->isGranted('system_configuration')) {
|
||||
$event->addAction('settings', ['url' => $this->path('system_configuration_section', ['section' => 'user']), 'class' => 'modal-ajax-form']);
|
||||
}
|
||||
|
||||
$event->addHelp($this->documentationLink('users.html'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user