allow changing calendar entry title (#3272)
This commit is contained in:
@@ -114,6 +114,7 @@ final class CalendarService
|
|||||||
'timeframeBegin' => $this->configuration->getCalendarTimeframeBegin(),
|
'timeframeBegin' => $this->configuration->getCalendarTimeframeBegin(),
|
||||||
'timeframeEnd' => $this->configuration->getCalendarTimeframeEnd(),
|
'timeframeEnd' => $this->configuration->getCalendarTimeframeEnd(),
|
||||||
'dragDropAmount' => $this->configuration->getCalendarDragAndDropMaxEntries(),
|
'dragDropAmount' => $this->configuration->getCalendarDragAndDropMaxEntries(),
|
||||||
|
'entryTitlePattern' => $this->configuration->find('calendar.title_pattern'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$event = new CalendarConfigurationEvent($config);
|
$event = new CalendarConfigurationEvent($config);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use App\Form\Model\SystemConfiguration as SystemConfigurationModel;
|
|||||||
use App\Form\SystemConfigurationForm;
|
use App\Form\SystemConfigurationForm;
|
||||||
use App\Form\Type\ActivityTypePatternType;
|
use App\Form\Type\ActivityTypePatternType;
|
||||||
use App\Form\Type\ArrayToCommaStringType;
|
use App\Form\Type\ArrayToCommaStringType;
|
||||||
|
use App\Form\Type\CalendarTitlePatternType;
|
||||||
use App\Form\Type\CustomerTypePatternType;
|
use App\Form\Type\CustomerTypePatternType;
|
||||||
use App\Form\Type\DatePickerType;
|
use App\Form\Type\DatePickerType;
|
||||||
use App\Form\Type\DateTimeTextType;
|
use App\Form\Type\DateTimeTextType;
|
||||||
@@ -623,6 +624,10 @@ final class SystemConfigurationController extends AbstractController
|
|||||||
->setTranslationDomain('system-configuration')
|
->setTranslationDomain('system-configuration')
|
||||||
->setType(IntegerType::class)
|
->setType(IntegerType::class)
|
||||||
->setConstraints([new Range(['min' => 0, 'max' => 20]), new NotNull()]),
|
->setConstraints([new Range(['min' => 0, 'max' => 20]), new NotNull()]),
|
||||||
|
(new Configuration())
|
||||||
|
->setName('calendar.title_pattern')
|
||||||
|
->setTranslationDomain('system-configuration')
|
||||||
|
->setType(CalendarTitlePatternType::class),
|
||||||
]),
|
]),
|
||||||
(new SystemConfigurationModel('branding'))
|
(new SystemConfigurationModel('branding'))
|
||||||
->setConfiguration([
|
->setConfiguration([
|
||||||
|
|||||||
@@ -429,6 +429,10 @@ class Configuration implements ConfigurationInterface
|
|||||||
->thenInvalid('The dragdrop_amount must be between 0 and 20')
|
->thenInvalid('The dragdrop_amount must be between 0 and 20')
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
|
->enumNode('title_pattern')
|
||||||
|
->values(['{activity}', '{project}', '{customer}', '{description}'])
|
||||||
|
->defaultValue('{activity}')
|
||||||
|
->end()
|
||||||
->end()
|
->end()
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
63
src/Form/Type/CalendarTitlePatternType.php
Normal file
63
src/Form/Type/CalendarTitlePatternType.php
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?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;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select the pattern that will be used for calendar entry titles.
|
||||||
|
*/
|
||||||
|
class CalendarTitlePatternType extends AbstractType
|
||||||
|
{
|
||||||
|
public const PATTERN_CUSTOMER = '{customer}';
|
||||||
|
public const PATTERN_PROJECT = '{project}';
|
||||||
|
public const PATTERN_ACTIVITY = '{activity}';
|
||||||
|
public const PATTERN_DESCRIPTION = '{description}';
|
||||||
|
public const SPACER = ' - ';
|
||||||
|
public const PATTERN_ACTIVITY_DESCRIPTION = self::PATTERN_ACTIVITY . self::SPACER . self::PATTERN_DESCRIPTION;
|
||||||
|
public const PATTERN_PROJECT_DESCRIPTION = self::PATTERN_PROJECT . self::SPACER . self::PATTERN_DESCRIPTION;
|
||||||
|
public const PATTERN_CUSTOMER_DESCRIPTION = self::PATTERN_CUSTOMER . self::SPACER . self::PATTERN_DESCRIPTION;
|
||||||
|
|
||||||
|
private $translator;
|
||||||
|
|
||||||
|
public function __construct(TranslatorInterface $translator)
|
||||||
|
{
|
||||||
|
$this->translator = $translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$customer = $this->translator->trans('label.customer');
|
||||||
|
$project = $this->translator->trans('label.project');
|
||||||
|
$activity = $this->translator->trans('label.activity');
|
||||||
|
$description = $this->translator->trans('label.description');
|
||||||
|
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'label' => 'label.choice_pattern',
|
||||||
|
'choices' => [
|
||||||
|
$activity => CalendarTitlePatternType::PATTERN_ACTIVITY,
|
||||||
|
$project => CalendarTitlePatternType::PATTERN_PROJECT,
|
||||||
|
$customer => CalendarTitlePatternType::PATTERN_CUSTOMER,
|
||||||
|
$description => CalendarTitlePatternType::PATTERN_DESCRIPTION,
|
||||||
|
$activity . self::SPACER . $description => CalendarTitlePatternType::PATTERN_ACTIVITY_DESCRIPTION,
|
||||||
|
$project . self::SPACER . $description => CalendarTitlePatternType::PATTERN_PROJECT_DESCRIPTION,
|
||||||
|
$customer . self::SPACER . $description => CalendarTitlePatternType::PATTERN_CUSTOMER_DESCRIPTION,
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return ChoiceType::class;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,6 +62,10 @@
|
|||||||
<script>
|
<script>
|
||||||
activatePopover();
|
activatePopover();
|
||||||
|
|
||||||
|
document.addEventListener('kimai.initialized', function() {
|
||||||
|
KimaiReloadPageWidget.create('kimai.systemConfigUpdate', true);
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener('kimai.timesheetUpdate', function() {
|
document.addEventListener('kimai.timesheetUpdate', function() {
|
||||||
jQuery('{{ calendarSelector }}').fullCalendar('refetchEvents');
|
jQuery('{{ calendarSelector }}').fullCalendar('refetchEvents');
|
||||||
});
|
});
|
||||||
@@ -98,9 +102,35 @@
|
|||||||
if (color == null) {
|
if (color == null) {
|
||||||
color = defaultColor;
|
color = defaultColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let title = apiItem.activity.name;
|
||||||
|
|
||||||
|
let description = '';
|
||||||
|
if (apiItem.description !== null && apiItem.description !== '') {
|
||||||
|
description = '{{ constant('\\App\\Form\\Type\\CalendarTitlePatternType::SPACER') }}' + apiItem.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if config.entryTitlePattern == constant('\\App\\Form\\Type\\CalendarTitlePatternType::PATTERN_PROJECT') %}
|
||||||
|
title = apiItem.project.name;
|
||||||
|
{% elseif config.entryTitlePattern == constant('\\App\\Form\\Type\\CalendarTitlePatternType::PATTERN_CUSTOMER') %}
|
||||||
|
title = apiItem.project.customer.name;
|
||||||
|
{% elseif config.entryTitlePattern == constant('\\App\\Form\\Type\\CalendarTitlePatternType::PATTERN_DESCRIPTION') %}
|
||||||
|
title = apiItem.description;
|
||||||
|
{% elseif config.entryTitlePattern == constant('\\App\\Form\\Type\\CalendarTitlePatternType::PATTERN_ACTIVITY_DESCRIPTION') %}
|
||||||
|
title = apiItem.activity.name + description;
|
||||||
|
{% elseif config.entryTitlePattern == constant('\\App\\Form\\Type\\CalendarTitlePatternType::PATTERN_PROJECT_DESCRIPTION') %}
|
||||||
|
title = apiItem.project.name + description;
|
||||||
|
{% elseif config.entryTitlePattern == constant('\\App\\Form\\Type\\CalendarTitlePatternType::PATTERN_CUSTOMER_DESCRIPTION') %}
|
||||||
|
title = apiItem.project.customer.name + description;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
if (title === '' || title === null) {
|
||||||
|
title = apiItem.activity.name;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: apiItem.id,
|
id: apiItem.id,
|
||||||
title: apiItem.activity.name,
|
title: title,
|
||||||
description: apiItem.description,
|
description: apiItem.description,
|
||||||
start: apiItem.begin,
|
start: apiItem.begin,
|
||||||
end: apiItem.end,
|
end: apiItem.end,
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ class AppExtensionTest extends TestCase
|
|||||||
],
|
],
|
||||||
'weekends' => true,
|
'weekends' => true,
|
||||||
'dragdrop_amount' => 10,
|
'dragdrop_amount' => 10,
|
||||||
|
'title_pattern' => '{activity}',
|
||||||
],
|
],
|
||||||
'kimai.dashboard' => [],
|
'kimai.dashboard' => [],
|
||||||
'kimai.widgets' => [],
|
'kimai.widgets' => [],
|
||||||
|
|||||||
@@ -360,6 +360,7 @@ class ConfigurationTest extends TestCase
|
|||||||
],
|
],
|
||||||
'weekends' => true,
|
'weekends' => true,
|
||||||
'dragdrop_amount' => 10,
|
'dragdrop_amount' => 10,
|
||||||
|
'title_pattern' => '{activity}',
|
||||||
],
|
],
|
||||||
'theme' => [
|
'theme' => [
|
||||||
'active_warning' => 3,
|
'active_warning' => 3,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||||
<file source-language="en" target-language="de" datatype="plaintext" original="system-configuration.en.xlf">
|
<file source-language="en" target-language="de" datatype="plaintext" original="system-configuration.en.xlf">
|
||||||
<body>
|
<body>
|
||||||
<trans-unit id="ycErWZK" resname="timesheet">
|
<trans-unit id="lt2Y2LO" resname="timesheet">
|
||||||
<source>Time tracking</source>
|
<source>Time tracking</source>
|
||||||
<target state="translated">Zeiterfassung</target>
|
<target state="translated">Zeiterfassung</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@@ -298,6 +298,10 @@
|
|||||||
<source>label.calendar.dragdrop_amount</source>
|
<source>label.calendar.dragdrop_amount</source>
|
||||||
<target>Anzahl an Einträgen für Drag&Drop (0 = deaktiviert)</target>
|
<target>Anzahl an Einträgen für Drag&Drop (0 = deaktiviert)</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="MXabpD7" resname="label.calendar.title_pattern">
|
||||||
|
<source>label.calendar.title_pattern</source>
|
||||||
|
<target>Darstellung der Titel von Kalender Einträgen</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||||
<file source-language="en" target-language="en" datatype="plaintext" original="system-configuration.en.xlf">
|
<file source-language="en" target-language="en" datatype="plaintext" original="system-configuration.en.xlf">
|
||||||
<body>
|
<body>
|
||||||
<trans-unit id="ycErWZK" resname="timesheet">
|
<trans-unit id="lt2Y2LO" resname="timesheet">
|
||||||
<source>Time tracking</source>
|
<source>Time tracking</source>
|
||||||
<target>Time tracking</target>
|
<target>Time tracking</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@@ -298,6 +298,10 @@
|
|||||||
<source>label.calendar.dragdrop_amount</source>
|
<source>label.calendar.dragdrop_amount</source>
|
||||||
<target>Amount of entries for drag&drop (0 = deactivated)</target>
|
<target>Amount of entries for drag&drop (0 = deactivated)</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="MXabpD7" resname="label.calendar.title_pattern">
|
||||||
|
<source>label.calendar.title_pattern</source>
|
||||||
|
<target>Display of the titles of calendar entries</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|||||||
Reference in New Issue
Block a user