UI updates - new user menu, updated about and profile screen and more (#723)
This commit is contained in:
@@ -18,10 +18,7 @@ use Symfony\Component\HttpKernel\KernelInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* Controller used for executing system relevant tasks.
|
||||
*
|
||||
* @Route(path="/admin/about")
|
||||
* @Security("is_granted('system_information')")
|
||||
* @Route(path="/about")
|
||||
*/
|
||||
class AboutController extends AbstractController
|
||||
{
|
||||
@@ -39,11 +36,13 @@ class AboutController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(path="", name="about", methods={"GET"})
|
||||
* @Route(path="/debug", name="about_debug", methods={"GET"})
|
||||
*
|
||||
* @Security("is_granted('system_information')")
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function indexAction()
|
||||
public function debugAction()
|
||||
{
|
||||
return $this->getAboutView();
|
||||
}
|
||||
@@ -90,16 +89,17 @@ class AboutController extends AbstractController
|
||||
],
|
||||
'info' => $phpInfo,
|
||||
'settings' => $settings,
|
||||
'license' => $this->getLicense(),
|
||||
],
|
||||
$additional
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @Route(path="", name="about", methods={"GET"})
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function getLicense()
|
||||
public function license()
|
||||
{
|
||||
$filename = $this->projectDirectory . '/LICENSE';
|
||||
|
||||
@@ -114,7 +114,31 @@ class AboutController extends AbstractController
|
||||
'Check this instead: ' . Constants::GITHUB . 'blob/master/LICENSE';
|
||||
}
|
||||
|
||||
return $license;
|
||||
return $this->render('about/license.html.twig', [
|
||||
'license' => $license
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(path="/flush-cache", name="system_flush_cache", methods={"GET"})
|
||||
*
|
||||
* @Security("is_granted('system_actions')")
|
||||
*/
|
||||
public function rebuildContainer(KernelInterface $kernel)
|
||||
{
|
||||
$application = new Application($kernel);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$input = new ArrayInput([
|
||||
'command' => 'cache:clear',
|
||||
'--env' => $kernel->getEnvironment(),
|
||||
'-n',
|
||||
]);
|
||||
|
||||
$output = new BufferedOutput();
|
||||
$application->run($input, $output);
|
||||
|
||||
return $this->getAboutView(['content_action' => $output->fetch()]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,26 +177,4 @@ class AboutController extends AbstractController
|
||||
|
||||
return $phpinfo['phpinfo'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(path="/flush-cache", name="system_flush_cache", methods={"GET"})
|
||||
*
|
||||
* @Security("is_granted('system_actions')")
|
||||
*/
|
||||
public function rebuildContainer(KernelInterface $kernel)
|
||||
{
|
||||
$application = new Application($kernel);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$input = new ArrayInput([
|
||||
'command' => 'cache:clear',
|
||||
'--env' => $kernel->getEnvironment(),
|
||||
'-n',
|
||||
]);
|
||||
|
||||
$output = new BufferedOutput();
|
||||
$application->run($input, $output);
|
||||
|
||||
return $this->getAboutView(['content_action' => $output->fetch()]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ use App\Repository\ActivityRepository;
|
||||
use App\Repository\Query\ActivityQuery;
|
||||
use Doctrine\ORM\ORMException;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
@@ -15,7 +15,6 @@ use App\Entity\Timesheet;
|
||||
use App\Repository\Query\TimesheetQuery;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use App\Timesheet\UserDateTimeFactory;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
@@ -18,7 +18,6 @@ use App\Form\UserPasswordType;
|
||||
use App\Form\UserPreferencesForm;
|
||||
use App\Form\UserRolesType;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use App\Timesheet\UserDateTimeFactory;
|
||||
use App\Voter\UserVoter;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
@@ -45,21 +44,14 @@ class ProfileController extends AbstractController
|
||||
*/
|
||||
protected $encoder;
|
||||
|
||||
/**
|
||||
* @var UserDateTimeFactory
|
||||
*/
|
||||
protected $dateTime;
|
||||
|
||||
/**
|
||||
* @param UserPasswordEncoderInterface $encoder
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
* @param UserDateTimeFactory $dateTime
|
||||
*/
|
||||
public function __construct(UserPasswordEncoderInterface $encoder, EventDispatcherInterface $dispatcher, UserDateTimeFactory $dateTime)
|
||||
public function __construct(UserPasswordEncoderInterface $encoder, EventDispatcherInterface $dispatcher)
|
||||
{
|
||||
$this->encoder = $encoder;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->dateTime = $dateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +69,7 @@ class ProfileController extends AbstractController
|
||||
*/
|
||||
public function indexAction(User $profile)
|
||||
{
|
||||
return $this->getProfileView($profile, 'charts');
|
||||
return $this->renderProfileView($profile, 'charts', 'user/stats.html.twig', []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,7 +141,7 @@ class ProfileController extends AbstractController
|
||||
return $this->redirectToRoute('user_profile_api_token', ['username' => $profile->getUsername()]);
|
||||
}
|
||||
|
||||
return $this->getProfileView($profile, 'api-token', null, null, null, null, $form);
|
||||
return $this->getProfileView($profile, 'api-token', null, null, null, $form);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +170,7 @@ class ProfileController extends AbstractController
|
||||
* @Route(path="/{username}/prefs", name="user_profile_preferences", methods={"GET", "POST"})
|
||||
* @Security("is_granted('preferences', profile)")
|
||||
*/
|
||||
public function savePreferencesAction(User $profile, Request $request)
|
||||
public function preferencesAction(User $profile, Request $request)
|
||||
{
|
||||
// we need to prepare the user preferences, which is done via an EventSubscriber
|
||||
$event = new PrepareUserEvent($profile);
|
||||
@@ -228,7 +220,11 @@ class ProfileController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->getProfileView($profile, 'preferences', null, null, null, $form);
|
||||
return $this->render('user/form.html.twig', [
|
||||
'tab' => 'preferences',
|
||||
'user' => $profile,
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,7 +233,6 @@ class ProfileController extends AbstractController
|
||||
* @param Form|null $editForm
|
||||
* @param Form|null $pwdForm
|
||||
* @param Form|null $rolesForm
|
||||
* @param Form|null $prefsForm
|
||||
* @param Form|null $apiTokenForm
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @throws \Doctrine\ORM\NonUniqueResultException
|
||||
@@ -248,9 +243,36 @@ class ProfileController extends AbstractController
|
||||
Form $editForm = null,
|
||||
Form $pwdForm = null,
|
||||
Form $rolesForm = null,
|
||||
Form $prefsForm = null,
|
||||
Form $apiTokenForm = null
|
||||
) {
|
||||
$forms = [];
|
||||
|
||||
if ($this->isGranted(UserVoter::EDIT, $user)) {
|
||||
$editForm = $editForm ?: $this->createEditForm($user);
|
||||
$forms['settings'] = $editForm->createView();
|
||||
}
|
||||
if ($this->isGranted(UserVoter::PASSWORD, $user)) {
|
||||
$pwdForm = $pwdForm ?: $this->createPasswordForm($user);
|
||||
$forms['password'] = $pwdForm->createView();
|
||||
}
|
||||
if ($this->isGranted(UserVoter::API_TOKEN, $user)) {
|
||||
$apiTokenForm = $apiTokenForm ?: $this->createApiTokenForm($user);
|
||||
$forms['api-token'] = $apiTokenForm->createView();
|
||||
}
|
||||
if ($this->isGranted(UserVoter::ROLES, $user)) {
|
||||
$rolesForm = $rolesForm ?: $this->createRolesForm($user);
|
||||
$forms['roles'] = $rolesForm->createView();
|
||||
}
|
||||
|
||||
return $this->render('user/profile.html.twig', [
|
||||
'tab' => $tab,
|
||||
'user' => $user,
|
||||
'forms' => $forms
|
||||
]);
|
||||
}
|
||||
|
||||
protected function renderProfileView(User $user, string $tab, string $template, array $vars)
|
||||
{
|
||||
/* @var $timesheetRepo TimesheetRepository */
|
||||
$timesheetRepo = $this->getDoctrine()->getRepository(Timesheet::class);
|
||||
$userStats = $timesheetRepo->getUserStatistics($user);
|
||||
@@ -261,32 +283,9 @@ class ProfileController extends AbstractController
|
||||
'user' => $user,
|
||||
'stats' => $userStats,
|
||||
'years' => $monthlyStats,
|
||||
'local_time' => $this->dateTime->createDateTime(),
|
||||
'forms' => []
|
||||
];
|
||||
|
||||
if ($this->isGranted(UserVoter::EDIT, $user)) {
|
||||
$editForm = $editForm ?: $this->createEditForm($user);
|
||||
$viewVars['forms']['settings'] = $editForm->createView();
|
||||
}
|
||||
if ($this->isGranted(UserVoter::PASSWORD, $user)) {
|
||||
$pwdForm = $pwdForm ?: $this->createPasswordForm($user);
|
||||
$viewVars['forms']['password'] = $pwdForm->createView();
|
||||
}
|
||||
if ($this->isGranted(UserVoter::API_TOKEN, $user)) {
|
||||
$apiTokenForm = $apiTokenForm ?: $this->createApiTokenForm($user);
|
||||
$viewVars['forms']['api-token'] = $apiTokenForm->createView();
|
||||
}
|
||||
if ($this->isGranted(UserVoter::ROLES, $user)) {
|
||||
$rolesForm = $rolesForm ?: $this->createRolesForm($user);
|
||||
$viewVars['forms']['roles'] = $rolesForm->createView();
|
||||
}
|
||||
if ($this->isGranted(UserVoter::PREFERENCES, $user)) {
|
||||
$prefsForm = $prefsForm ?: $this->createPreferencesForm($user);
|
||||
$viewVars['forms']['preferences'] = $prefsForm->createView();
|
||||
}
|
||||
|
||||
return $this->render('user/profile.html.twig', $viewVars);
|
||||
return $this->render($template, array_merge($viewVars, $vars));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,6 @@ use App\Repository\ProjectRepository;
|
||||
use App\Repository\Query\ProjectQuery;
|
||||
use Doctrine\ORM\ORMException;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
@@ -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\Controller;
|
||||
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Sidebar controller
|
||||
*
|
||||
* @Security("is_granted('ROLE_USER')")
|
||||
*/
|
||||
class SidebarController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @param Request $originalRequest
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function settingsAction(Request $originalRequest)
|
||||
{
|
||||
return $this->render('sidebar/settings.html.twig', [
|
||||
'user' => $this->getUser(),
|
||||
'originalRequest' => $originalRequest,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user