added config for initial calendar view (#363)

This commit is contained in:
Kevin Papst
2018-10-21 15:43:16 +02:00
committed by GitHub
parent 3075276a52
commit 0165658659
8 changed files with 155 additions and 5 deletions

View File

@@ -18,7 +18,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
/** /**
* Class ThemeOptionsSubscriber * Allows dynamic injection of theme related options.
*/ */
class ThemeOptionsSubscriber implements EventSubscriberInterface class ThemeOptionsSubscriber implements EventSubscriberInterface
{ {
@@ -33,7 +33,6 @@ class ThemeOptionsSubscriber implements EventSubscriberInterface
protected $helper; protected $helper;
/** /**
* ThemeOptionsSubscriber constructor.
* @param TokenStorageInterface $storage * @param TokenStorageInterface $storage
* @param ContextHelper $helper * @param ContextHelper $helper
*/ */

View File

@@ -12,6 +12,7 @@ namespace App\EventSubscriber;
use App\Entity\User; use App\Entity\User;
use App\Entity\UserPreference; use App\Entity\UserPreference;
use App\Event\UserPreferenceEvent; use App\Event\UserPreferenceEvent;
use App\Form\Type\CalendarViewType;
use App\Form\Type\SkinType; use App\Form\Type\SkinType;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -95,6 +96,11 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
->setValue(true) ->setValue(true)
->setType(CheckboxType::class), ->setType(CheckboxType::class),
(new UserPreference())
->setName('calendar.initial_view')
->setValue(CalendarViewType::DEFAULT_VIEW)
->setType(CalendarViewType::class),
/* /*
(new UserPreference()) (new UserPreference())
->setName('language') ->setName('language')

View 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\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Custom form field type to select a calendar view.
*/
class CalendarViewType extends AbstractType
{
public const DEFAULT_VIEW = 'month';
public const ALLOWED_VIEWS = [
'month',
'agendaWeek',
'agendaDay',
];
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$choices = [];
foreach (self::ALLOWED_VIEWS as $name) {
$choices[$name] = $name;
}
$resolver->setDefaults([
'required' => true,
'choices' => $choices,
]);
}
/**
* {@inheritdoc}
*/
public function getParent()
{
return ChoiceType::class;
}
}

View File

@@ -24,6 +24,7 @@
<script> <script>
$(function () { $(function () {
$('#calendar').fullCalendar({ $('#calendar').fullCalendar({
defaultView: '{{ app.user.getPreferenceValue('calendar.initial_view') }}',
{% if not google.apiKey is null %} {% if not google.apiKey is null %}
googleCalendarApiKey: '{{ google.apiKey }}', googleCalendarApiKey: '{{ google.apiKey }}',
{% endif %} {% endif %}
@@ -84,7 +85,7 @@
'</div>' '</div>'
, ,
trigger: 'hover', trigger: 'hover',
placement: 'top', placement: 'auto',
container: 'body', container: 'body',
html: true html: true
}); });

View File

@@ -11,6 +11,7 @@ namespace App\Tests\Controller;
use App\DataFixtures\UserFixtures; use App\DataFixtures\UserFixtures;
use App\Entity\User; use App\Entity\User;
use App\Entity\UserPreference;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
/** /**
@@ -206,4 +207,54 @@ class ProfileControllerTest extends ControllerBaseTest
$this->assertEquals(['ROLE_TEAMLEAD', 'ROLE_SUPER_ADMIN', 'ROLE_USER'], $user->getRoles()); $this->assertEquals(['ROLE_TEAMLEAD', 'ROLE_SUPER_ADMIN', 'ROLE_USER'], $user->getRoles());
} }
public function testPreferencesAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER . '/prefs');
/** @var User $user */
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
$user = $this->getUserByRole($em, User::ROLE_USER);
$this->assertEquals(82, $user->getPreferenceValue(UserPreference::HOURLY_RATE));
$this->assertEquals('green', $user->getPreferenceValue(UserPreference::SKIN));
$this->assertEquals(true, $user->getPreferenceValue('theme.fixed_layout'));
$this->assertEquals(false, $user->getPreferenceValue('theme.boxed_layout'));
$this->assertEquals(false, $user->getPreferenceValue('theme.collapsed_sidebar'));
$this->assertEquals(true, $user->getPreferenceValue('theme.mini_sidebar'));
$this->assertEquals('month', $user->getPreferenceValue('calendar.initial_view'));
$form = $client->getCrawler()->filter('form[name=user_preferences_form]')->form();
$client->submit($form, [
'user_preferences_form' => [
'preferences' => [
['name' => UserPreference::HOURLY_RATE, 'value' => 37],
['name' => UserPreference::SKIN, 'value' => 'blue'],
['name' => 'theme.fixed_layout', 'value' => false],
['name' => 'theme.boxed_layout', 'value' => true],
['name' => 'theme.collapsed_sidebar', 'value' => true],
['name' => 'theme.mini_sidebar', 'value' => false],
['name' => 'calendar.initial_view', 'value' => 'agendaDay'],
]
]
]);
$this->assertIsRedirect($client, $this->createUrl('/profile/' . urlencode(UserFixtures::USERNAME_USER) . '/prefs'));
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasFlashSuccess($client);
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
$user = $this->getUserByRole($em, User::ROLE_USER);
$this->assertEquals(37, $user->getPreferenceValue(UserPreference::HOURLY_RATE));
$this->assertEquals('blue', $user->getPreferenceValue(UserPreference::SKIN));
$this->assertEquals(false, $user->getPreferenceValue('theme.fixed_layout'));
$this->assertEquals(true, $user->getPreferenceValue('theme.boxed_layout'));
$this->assertEquals(true, $user->getPreferenceValue('theme.collapsed_sidebar'));
$this->assertEquals(false, $user->getPreferenceValue('theme.mini_sidebar'));
$this->assertEquals('agendaDay', $user->getPreferenceValue('calendar.initial_view'));
}
} }

View File

@@ -383,6 +383,23 @@
<source>label.theme.mini_sidebar</source> <source>label.theme.mini_sidebar</source>
<target>Aktiviert die minimierte Version der linken Navigationsleiste</target> <target>Aktiviert die minimierte Version der linken Navigationsleiste</target>
</trans-unit> </trans-unit>
<trans-unit id="label.calendar.initial_view">
<source>label.calendar.initial_view</source>
<target>Initiale Darstellung des Kalenders</target>
</trans-unit>
<!-- Options for user-preference label.calendar.initial_view -->
<trans-unit id="month">
<source>month</source>
<target>Monat</target>
</trans-unit>
<trans-unit id="agendaWeek">
<source>agendaWeek</source>
<target>Woche</target>
</trans-unit>
<trans-unit id="agendaDay">
<source>agendaDay</source>
<target>Tag</target>
</trans-unit>
<!-- <!--
Help - Manual Help - Manual

View File

@@ -383,6 +383,23 @@
<source>label.theme.mini_sidebar</source> <source>label.theme.mini_sidebar</source>
<target>Toggle the size of the left sidebar's header (full or collapse)</target> <target>Toggle the size of the left sidebar's header (full or collapse)</target>
</trans-unit> </trans-unit>
<trans-unit id="label.calendar.initial_view">
<source>label.calendar.initial_view</source>
<target>Initial calendar view</target>
</trans-unit>
<!-- Options for user-preference label.calendar.initial_view -->
<trans-unit id="month">
<source>month</source>
<target>Month</target>
</trans-unit>
<trans-unit id="agendaWeek">
<source>agendaWeek</source>
<target>Week</target>
</trans-unit>
<trans-unit id="agendaDay">
<source>agendaDay</source>
<target>Day</target>
</trans-unit>
<!-- <!--
Help - Manual Help - Manual

View File

@@ -3,7 +3,7 @@
Kimai 2 provides a calendar view, which displays your timesheet entries in a easy readable format. Kimai 2 provides a calendar view, which displays your timesheet entries in a easy readable format.
You can choose between a monthly, weekly and daily view. You can choose between a monthly, weekly and daily view.
The calendar view look and feel is configured with the config keys below `kimai.calendar` in `kimai.yaml`: The calendar view look and feel is configured with the config keys below `kimai.calendar` in `kimai.yaml` / your [local.yaml](configurations.md):
```yaml ```yaml
kimai: kimai:
@@ -22,7 +22,14 @@ kimai:
- `businessHours.begin` the start time of your working day, which will be highlighted in the weekly and daily view (default: 08:00 / 8am) - `businessHours.begin` the start time of your working day, which will be highlighted in the weekly and daily view (default: 08:00 / 8am)
- `businessHours.end` the end time of your working day, which will be highlighted in the weekly and daily view (default: 20:00 / 8pm) - `businessHours.end` the end time of your working day, which will be highlighted in the weekly and daily view (default: 20:00 / 8pm)
#### Integrating google calender ## Initial view
The initial view for the calendar is `month`.
It is a user specific setting and each user can configure it in his _User profile_ at _Preferences_.
Available options are: `month`, `agendaWeek`, `agendaDay`
## Integrating google calender
If you want to embed Google calendars e.g. to display regional holidays or company events you can import (multiple) Google calendars. If you want to embed Google calendars e.g. to display regional holidays or company events you can import (multiple) Google calendars.