diff --git a/.scrutinizer.yml b/.scrutinizer.yml
index fa1c158d..2b3c7882 100644
--- a/.scrutinizer.yml
+++ b/.scrutinizer.yml
@@ -42,5 +42,5 @@ filter:
build_failure_conditions:
- 'project.metric("scrutinizer.quality", < 9.30)'
- - 'project.metric("scrutinizer.test_coverage", < 0.73)'
+ - 'project.metric("scrutinizer.test_coverage", < 0.9)'
- 'project.metric_change("scrutinizer.test_coverage", < -0.01)'
\ No newline at end of file
diff --git a/UPGRADING.md b/UPGRADING.md
index cdd02669..ed902d09 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -26,13 +26,13 @@ Remember to execute the necessary timezone conversion script, if you haven't upd
### BC BREAKS
-This release contains some BC breaks, which were necessary before 1.0 will be released: "now or never" ;-) sorry for the troubles!
+This release contains some BC breaks which were necessary before 1.0 will be released (_now or never_), to prevent those BC breaks after 1.0.
- **Kimai requires PHP 7.2 now => [PHP 7.1 expired 4 month ago](https://www.php.net/supported-versions.php)**
- The `.env` variable `DATABASE_PREFIX` was removed and the table prefix is now hardcoded to `kimai2_`. If you used another prefix,
you have to rename your tables manually before starting the update process. You can delete the row `DATABASE_PREFIX` from your `.env` file.
-- API: Format for DateTime objects changed, now including timezone identifier (previously 2019-03-02 14:23 - now 2019-03-02T14:23:00+00:00), see [#718](https://github.com/kevinpapst/kimai2/pull/718)
-- API: changed from snake_case to camelCase (hourlyRate vs hourly_rate / fixedRate vs fixed_rate / orderNumber vs order_number / i18n config)
+- API: Format for DateTime objects changed, now including timezone identifier (previously `2019-03-02 14:23` - now `2019-03-02T14:23:00+00:00`), see [#718](https://github.com/kevinpapst/kimai2/pull/718)
+- API: changed from snake_case to camelCase (affected fields: hourlyRate vs hourly_rate / fixedRate vs fixed_rate / orderNumber vs order_number / i18n config object)
- Plugin mechanism changed: existing Plugins have to be deleted or updated
### Apply necessary changes to your `local.yaml`:
@@ -42,6 +42,20 @@ New permissions are available:
- `system_actions` - for the experimental feature to flush your cache from the about screen
- `plugins` - for accessing the new plugins screen
+The setting `kimai.timesheet.mode` replaces the setting `kimai.timesheet.duration_only`. If you used the duration_only mode, you need to change your config:
+```yaml
+# Before
+kimai:
+ timesheet:
+ duration_only: true
+
+# After
+kimai:
+ timesheet:
+ mode: duration_only
+```
+Or switch the mode directly in the new System configuration screen within Kimai.
+
## [0.8.1](https://github.com/kevinpapst/kimai2/releases/tag/0.8.1)
A bug fixing release. Remember to execute the necessary timezone conversion script, if you haven't updated to 0.8 before (see below)!
diff --git a/config/packages/kimai.yaml b/config/packages/kimai.yaml
index 26b1b1a1..74f039ef 100644
--- a/config/packages/kimai.yaml
+++ b/config/packages/kimai.yaml
@@ -1,10 +1,20 @@
+# ---------------------------------------------------------------------------------------------
+# DO NOT EDIT THIS FILE, INSTEAD CREATE THE FILE "local.yaml" AND ADD YOUR SETTINGS IN THERE.
+# See https://www.kimai.org/documentation/configurations.html
+#
+# Be aware that this file is YAML format and the indentation is important.
+# Each config level needs to be indented with 4 additional spaces.
+#
+# ---------------------------------------------------------------------------------------------
kimai:
# --------------------------------------------------------------------------------
- # Settings for the user management and login forms
- user:
- registration: true
- password_reset: true
+ # You can disable the user management functions in the authentication screens (default: true).
+ #user:
+ # registration: false
+ # password_reset: false
+ # --------------------------------------------------------------------------------
+
# --------------------------------------------------------------------------------
# All configs related to timesheet and record management
@@ -13,9 +23,11 @@ kimai:
# render timesheet descriptions with markdown
markdown_content: false
- # Whether we display start and end time columns (false) or durations only (true).
- # Setting this to true will also change the "edit timesheet" forms, more infos available in the configurations docu.
- duration_only: false
+ # The time-tracking mode that should be used (allowed values: default, duration_only)
+ #
+ # default: display start and end time columns in timesheet view and form
+ # duration_only: display start time and duration, https://www.kimai.org/documentation/timesheet.html#duration-only-mode
+ mode: default
# Rounding rules are used to round the begin & end dates and the duration for timesheet records.
# The "default" rule will round "begin" down and "end" up to the full minute, the "duration" will not be rounded.
@@ -52,6 +64,7 @@ kimai:
# whether records in the future can be created
allow_future_times: true
+
# --------------------------------------------------------------------------------
# Invoice management
#invoice:
@@ -60,6 +73,7 @@ kimai:
# - 'var/invoices/'
# - 'templates/invoice/renderer/'
+
# --------------------------------------------------------------------------------
# Default settings used to populate forms
#defaults:
diff --git a/src/Configuration/TimesheetConfiguration.php b/src/Configuration/TimesheetConfiguration.php
index ec037fe9..62e004bb 100644
--- a/src/Configuration/TimesheetConfiguration.php
+++ b/src/Configuration/TimesheetConfiguration.php
@@ -11,6 +11,9 @@ namespace App\Configuration;
class TimesheetConfiguration implements SystemBundleConfiguration
{
+ public const MODE_DURATION_ONLY = 'duration_only';
+ public const MODE_DEFAULT = 'default';
+
use StringAccessibleConfigTrait;
public function getPrefix(): string
@@ -25,7 +28,7 @@ class TimesheetConfiguration implements SystemBundleConfiguration
public function isDurationOnly(): bool
{
- return (bool) $this->find('duration_only');
+ return $this->find('mode') === self::MODE_DURATION_ONLY;
}
public function isMarkdownEnabled(): bool
diff --git a/src/Controller/AbstractController.php b/src/Controller/AbstractController.php
index 51f53e6d..cafc98c4 100644
--- a/src/Controller/AbstractController.php
+++ b/src/Controller/AbstractController.php
@@ -9,13 +9,15 @@
namespace App\Controller;
-use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as BaseAbstractController;
use Symfony\Component\Translation\DataCollectorTranslator;
+use Symfony\Contracts\Service\ServiceSubscriberInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
/**
* The abstract base controller.
*/
-abstract class AbstractController extends Controller
+abstract class AbstractController extends BaseAbstractController implements ServiceSubscriberInterface
{
public const FLASH_SUCCESS = 'success';
public const FLASH_WARNING = 'warning';
@@ -89,4 +91,11 @@ abstract class AbstractController extends Controller
$this->addFlash($type, $message);
}
+
+ public static function getSubscribedServices()
+ {
+ return array_merge(parent::getSubscribedServices(), [
+ 'translator' => TranslatorInterface::class
+ ]);
+ }
}
diff --git a/src/Controller/SystemConfigurationController.php b/src/Controller/SystemConfigurationController.php
index ee80b88c..a10cea06 100644
--- a/src/Controller/SystemConfigurationController.php
+++ b/src/Controller/SystemConfigurationController.php
@@ -14,6 +14,7 @@ use App\Event\SystemConfigurationEvent;
use App\Form\Model\Configuration;
use App\Form\Model\SystemConfiguration as SystemConfigurationModel;
use App\Form\SystemConfigurationForm;
+use App\Form\Type\TimesheetModeType;
use App\Repository\ConfigurationRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -199,11 +200,11 @@ class SystemConfigurationController extends AbstractController
->setSection(SystemConfigurationModel::SECTION_TIMESHEET)
->setConfiguration([
(new Configuration())
- ->setName('timesheet.markdown_content')
- ->setType(CheckboxType::class)
+ ->setName('timesheet.mode')
+ ->setType(TimesheetModeType::class)
->setTranslationDomain('system-configuration'),
(new Configuration())
- ->setName('timesheet.duration_only')
+ ->setName('timesheet.markdown_content')
->setType(CheckboxType::class)
->setTranslationDomain('system-configuration'),
(new Configuration())
diff --git a/src/Controller/TimesheetController.php b/src/Controller/TimesheetController.php
index da276d79..20ff6151 100644
--- a/src/Controller/TimesheetController.php
+++ b/src/Controller/TimesheetController.php
@@ -69,7 +69,6 @@ class TimesheetController extends AbstractController
'showFilter' => $form->isSubmitted(),
'toolbarForm' => $form->createView(),
'showSummary' => $this->getUser()->getPreferenceValue('timesheet.daily_stats', false),
- 'duration_only' => $this->configuration->isDurationOnly(),
]);
}
diff --git a/src/Controller/TimesheetTeamController.php b/src/Controller/TimesheetTeamController.php
index c5ffed79..a141f8c1 100644
--- a/src/Controller/TimesheetTeamController.php
+++ b/src/Controller/TimesheetTeamController.php
@@ -65,7 +65,6 @@ class TimesheetTeamController extends AbstractController
'query' => $query,
'showFilter' => $form->isSubmitted(),
'toolbarForm' => $form->createView(),
- 'duration_only' => $this->configuration->isDurationOnly(),
]);
}
diff --git a/src/DataFixtures/CustomerFixtures.php b/src/DataFixtures/CustomerFixtures.php
index faa126cd..05c7297d 100644
--- a/src/DataFixtures/CustomerFixtures.php
+++ b/src/DataFixtures/CustomerFixtures.php
@@ -33,7 +33,7 @@ class CustomerFixtures extends Fixture
public const MIN_BUDGET = 0;
public const MAX_BUDGET = 100000;
public const MIN_GLOBAL_ACTIVITIES = 5;
- public const MAX_GLOBAL_ACTIVITIES = 50;
+ public const MAX_GLOBAL_ACTIVITIES = 30;
public const MIN_PROJECTS_PER_CUSTOMER = 2;
public const MAX_PROJECTS_PER_CUSTOMER = 25;
public const MIN_ACTIVITIES_PER_PROJECT = 0;
@@ -72,7 +72,7 @@ class CustomerFixtures extends Fixture
$amountGlobalActivities = rand(self::MIN_GLOBAL_ACTIVITIES, self::MAX_GLOBAL_ACTIVITIES);
for ($c = 1; $c <= $amountGlobalActivities; $c++) {
- $visibleActivity = 0 != $a % 3;
+ $visibleActivity = 0 != $c % 4;
$activity = $this->createActivity($faker, null, $visibleActivity);
$manager->persist($activity);
}
diff --git a/src/DependencyInjection/AppExtension.php b/src/DependencyInjection/AppExtension.php
index a072b94f..2dd35149 100644
--- a/src/DependencyInjection/AppExtension.php
+++ b/src/DependencyInjection/AppExtension.php
@@ -32,6 +32,14 @@ class AppExtension extends Extension
$config = [];
}
+ // @deprecated since 0.9, duration_only will be removed with 1.0
+ if (isset($config['timesheet']['duration_only'])) {
+ trigger_error('Configuration "kimai.timesheet.duration_only" is deprecated, please remove it', E_USER_DEPRECATED);
+ if (true === $config['timesheet']['duration_only'] && 'duration_only' !== $config['timesheet']['mode']) {
+ trigger_error('Found ambiguous configuration. Please remove "kimai.timesheet.duration_only" and set "kimai.timesheet.mode" instead.');
+ }
+ }
+
// safe alternatives to %kernel.project_dir%
$container->setParameter('kimai.data_dir', $config['data_dir']);
$container->setParameter('kimai.plugin_dir', $config['plugin_dir']);
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
index f48cdc29..166d0fe5 100644
--- a/src/DependencyInjection/Configuration.php
+++ b/src/DependencyInjection/Configuration.php
@@ -75,6 +75,16 @@ class Configuration implements ConfigurationInterface
->children()
->booleanNode('duration_only')
->defaultValue(false)
+ ->setDeprecated()
+ ->end()
+ ->scalarNode('mode')
+ ->defaultValue('default')
+ ->validate()
+ ->ifTrue(function ($value) {
+ return !in_array($value, ['default', 'duration_only']);
+ })
+ ->thenInvalid('Chosen timesheet mode is invalid, allowed values: default, duration_only')
+ ->end()
->end()
->booleanNode('markdown_content')
->defaultValue(false)
diff --git a/src/Form/Type/TimesheetModeType.php b/src/Form/Type/TimesheetModeType.php
new file mode 100644
index 00000000..e254e6ce
--- /dev/null
+++ b/src/Form/Type/TimesheetModeType.php
@@ -0,0 +1,43 @@
+setDefaults([
+ 'label' => 'label.timesheet.mode',
+ 'choices' => [
+ 'label.timesheet.mode_default' => TimesheetConfiguration::MODE_DEFAULT,
+ 'label.timesheet.mode_duration_only' => TimesheetConfiguration::MODE_DURATION_ONLY,
+ ],
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParent()
+ {
+ return ChoiceType::class;
+ }
+}
diff --git a/src/Twig/AssetExtension.php b/src/Twig/AssetExtension.php
index f0f28ad2..1b551677 100644
--- a/src/Twig/AssetExtension.php
+++ b/src/Twig/AssetExtension.php
@@ -17,7 +17,7 @@ class AssetExtension extends BaseAssetExtension
* Overwritten to support subdirectories and subdomains at the same time.
*
* @param string $path
- * @param null $packageName
+ * @param null|string $packageName
* @return mixed|string
*/
public function getAssetUrl($path, $packageName = null)
diff --git a/src/Twig/TimesheetConfigExtension.php b/src/Twig/TimesheetConfigExtension.php
new file mode 100644
index 00000000..c7f88ec0
--- /dev/null
+++ b/src/Twig/TimesheetConfigExtension.php
@@ -0,0 +1,42 @@
+configuration = $configuration;
+ }
+
+ /**
+ * @return TwigFunction[]
+ */
+ public function getFunctions()
+ {
+ return [
+ new TwigFunction('is_duration_only', [$this, 'isDurationOnly']),
+ ];
+ }
+
+ public function isDurationOnly(): bool
+ {
+ return $this->configuration->isDurationOnly();
+ }
+}
diff --git a/templates/timesheet-team/index.html.twig b/templates/timesheet-team/index.html.twig
index 14684767..246ca62b 100644
--- a/templates/timesheet-team/index.html.twig
+++ b/templates/timesheet-team/index.html.twig
@@ -17,6 +17,7 @@
{% if entries.count == 0 %}
{{ widgets.callout('warning', 'error.no_entries_found') }}
{% else %}
+ {% set duration_only = is_duration_only() %}
{% set columns = {'date': ''} %}
{% if not duration_only %}
diff --git a/templates/timesheet/index.html.twig b/templates/timesheet/index.html.twig
index 69c720e5..8907a908 100644
--- a/templates/timesheet/index.html.twig
+++ b/templates/timesheet/index.html.twig
@@ -17,6 +17,7 @@
{% if entries.count == 0 %}
{{ widgets.callout('warning', 'error.no_entries_found') }}
{% else %}
+ {% set duration_only = is_duration_only() %}
{% set canSeeRate = is_granted('view_rate_own_timesheet') %}
{% set columns = {'date': ''} %}
diff --git a/tests/Configuration/SystemConfigurationTest.php b/tests/Configuration/SystemConfigurationTest.php
index e500f7ef..35dd5bad 100644
--- a/tests/Configuration/SystemConfigurationTest.php
+++ b/tests/Configuration/SystemConfigurationTest.php
@@ -38,7 +38,7 @@ class SystemConfigurationTest extends TestCase
'rules' => [
'allow_future_times' => false,
],
- 'duration_only' => true,
+ 'mode' => 'duration_only',
'markdown_content' => false,
'active_entries' => [
'hard_limit' => 99,
@@ -61,7 +61,7 @@ class SystemConfigurationTest extends TestCase
(new Configuration())->setName('defaults.customer.timezone')->setValue('Russia/Moscov'),
(new Configuration())->setName('defaults.customer.currency')->setValue('RUB'),
(new Configuration())->setName('timesheet.rules.allow_future_times')->setValue('1'),
- (new Configuration())->setName('timesheet.duration_only')->setValue('0'),
+ (new Configuration())->setName('timesheet.mode')->setValue('default'),
(new Configuration())->setName('timesheet.markdown_content')->setValue('1'),
(new Configuration())->setName('timesheet.active_entries.hard_limit')->setValue('7'),
(new Configuration())->setName('timesheet.active_entries.soft_limit')->setValue('3'),
@@ -95,9 +95,9 @@ class SystemConfigurationTest extends TestCase
public function testDefaultWithMixedConfigs()
{
$sut = $this->getSut($this->getDefaultSettings(), [
- (new Configuration())->setName('timesheet.duration_only')->setValue(''),
+ (new Configuration())->setName('timesheet.rules.allow_future_times')->setValue(''),
]);
- $this->assertEquals(false, $sut->find('timesheet.duration_only'));
+ $this->assertEquals(false, $sut->find('timesheet.rules.allow_future_times'));
}
/**
diff --git a/tests/Configuration/TimesheetConfigurationTest.php b/tests/Configuration/TimesheetConfigurationTest.php
index 5612f611..3179fcbc 100644
--- a/tests/Configuration/TimesheetConfigurationTest.php
+++ b/tests/Configuration/TimesheetConfigurationTest.php
@@ -37,7 +37,7 @@ class TimesheetConfigurationTest extends TestCase
'rules' => [
'allow_future_times' => false,
],
- 'duration_only' => true,
+ 'mode' => 'duration_only',
'markdown_content' => false,
'active_entries' => [
'hard_limit' => 99,
@@ -50,7 +50,7 @@ class TimesheetConfigurationTest extends TestCase
{
return [
(new Configuration())->setName('timesheet.rules.allow_future_times')->setValue('1'),
- (new Configuration())->setName('timesheet.duration_only')->setValue('0'),
+ (new Configuration())->setName('timesheet.mode')->setValue('default'),
(new Configuration())->setName('timesheet.markdown_content')->setValue('1'),
(new Configuration())->setName('timesheet.active_entries.hard_limit')->setValue('7'),
(new Configuration())->setName('timesheet.active_entries.soft_limit')->setValue('3'),
@@ -86,7 +86,7 @@ class TimesheetConfigurationTest extends TestCase
public function testDefaultWithMixedConfigs()
{
$sut = $this->getSut($this->getDefaultSettings(), [
- (new Configuration())->setName('timesheet.duration_only')->setValue(''),
+ (new Configuration())->setName('timesheet.mode')->setValue('sdf'),
]);
$this->assertEquals(false, $sut->isDurationOnly());
}
diff --git a/tests/Controller/SystemConfigurationControllerTest.php b/tests/Controller/SystemConfigurationControllerTest.php
index e9ba9e25..79108723 100644
--- a/tests/Controller/SystemConfigurationControllerTest.php
+++ b/tests/Controller/SystemConfigurationControllerTest.php
@@ -61,7 +61,7 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
$configService = $client->getContainer()->get(SystemConfiguration::class);
$this->assertEquals(false, $configService->find('timesheet.markdown_content'));
- $this->assertEquals(false, $configService->find('timesheet.duration_only'));
+ $this->assertEquals('default', $configService->find('timesheet.mode'));
$this->assertEquals(true, $configService->find('timesheet.rules.allow_future_times'));
$this->assertEquals(3, $configService->find('timesheet.active_entries.hard_limit'));
$this->assertEquals(1, $configService->find('timesheet.active_entries.soft_limit'));
@@ -70,8 +70,8 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
$client->submit($form, [
'system_configuration_form' => [
'configuration' => [
+ ['name' => 'timesheet.mode', 'value' => 'duration_only'],
['name' => 'timesheet.markdown_content', 'value' => 1],
- ['name' => 'timesheet.duration_only', 'value' => 1],
['name' => 'timesheet.rules.allow_future_times', 'value' => false],
['name' => 'timesheet.active_entries.hard_limit', 'value' => 99],
['name' => 'timesheet.active_entries.soft_limit', 'value' => 77],
@@ -86,7 +86,7 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
$configService = $client->getContainer()->get(SystemConfiguration::class);
$this->assertEquals(true, $configService->find('timesheet.markdown_content'));
- $this->assertEquals(true, $configService->find('timesheet.duration_only'));
+ $this->assertEquals('duration_only', $configService->find('timesheet.mode'));
$this->assertEquals(false, $configService->find('timesheet.rules.allow_future_times'));
$this->assertEquals(99, $configService->find('timesheet.active_entries.hard_limit'));
$this->assertEquals(77, $configService->find('timesheet.active_entries.soft_limit'));
@@ -101,8 +101,8 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
[
'system_configuration_form' => [
'configuration' => [
+ ['name' => 'timesheet.mode', 'value' => 'foo'],
['name' => 'timesheet.markdown_content', 'value' => 1],
- ['name' => 'timesheet.duration_only', 'value' => 1],
['name' => 'timesheet.rules.allow_future_times', 'value' => 1],
['name' => 'timesheet.active_entries.hard_limit', 'value' => -1],
['name' => 'timesheet.active_entries.soft_limit', 'value' => -1],
@@ -110,10 +110,11 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
]
],
[
- '#system_configuration_form_configuration_3_value',
- '#system_configuration_form_configuration_4_value',
+ '#system_configuration_form_configuration_0_value', // mode
+ '#system_configuration_form_configuration_3_value', // hard_limit
+ '#system_configuration_form_configuration_4_value', // soft_limit
],
- false
+ true
);
}
diff --git a/tests/Twig/TimesheetConfigExtensionTest.php b/tests/Twig/TimesheetConfigExtensionTest.php
new file mode 100644
index 00000000..158c5158
--- /dev/null
+++ b/tests/Twig/TimesheetConfigExtensionTest.php
@@ -0,0 +1,47 @@
+getMockBuilder(ConfigLoaderInterface::class)->getMock();
+ $config = new TimesheetConfiguration($loader, ['mode' => 'duration_only']);
+ $sut = new TimesheetConfigExtension($config);
+ $filters = $sut->getFunctions();
+ $this->assertCount(1, $filters);
+ $this->assertEquals('is_duration_only', $filters[0]->getName());
+ }
+
+ public function testIsDurationOnly()
+ {
+ $loader = $this->getMockBuilder(ConfigLoaderInterface::class)->getMock();
+ $config = new TimesheetConfiguration($loader, ['mode' => 'duration_only']);
+ $sut = new TimesheetConfigExtension($config);
+ $this->assertTrue($sut->isDurationOnly());
+ }
+
+ public function testIsNotDurationOnly()
+ {
+ $loader = $this->getMockBuilder(ConfigLoaderInterface::class)->getMock();
+ $config = new TimesheetConfiguration($loader, ['mode' => 'default']);
+ $sut = new TimesheetConfigExtension($config);
+ $this->assertFalse($sut->isDurationOnly());
+ }
+}
diff --git a/tests/Validator/Constraints/TimesheetValidatorTest.php b/tests/Validator/Constraints/TimesheetValidatorTest.php
index 8d498d0d..c51a6fff 100644
--- a/tests/Validator/Constraints/TimesheetValidatorTest.php
+++ b/tests/Validator/Constraints/TimesheetValidatorTest.php
@@ -36,7 +36,7 @@ class TimesheetValidatorTest extends ConstraintValidatorTestCase
'rules' => [
'allow_future_times' => false,
],
- 'duration_only' => false,
+ 'mode' => 'default',
]);
return new TimesheetValidator($authMock, $config);
diff --git a/translations/system-configuration.de.xliff b/translations/system-configuration.de.xliff
index e8624e88..f841ab96 100644
--- a/translations/system-configuration.de.xliff
+++ b/translations/system-configuration.de.xliff
@@ -22,9 +22,17 @@
label.timesheet.markdown_content
Erlaube Markdown in den Beschreibungen der erfassten Zeiten
-
- label.timesheet.duration_only
- "Duration only" Modus - ersetzt das Enddatum durch ein Eingabefeld für Zeitdauer
+
+ label.timesheet.mode
+ Zeiterfassungs Modus
+
+
+ label.timesheet.mode_default
+ Standard Modus: erfasst Start und Enddatum
+
+
+ label.timesheet.mode_duration_only
+ Dauer: ersetzt das Enddatum durch ein Eingabefeld für Dauer
label.timesheet.rules.allow_future_times
diff --git a/translations/system-configuration.en.xliff b/translations/system-configuration.en.xliff
index 30d952a4..34be2643 100644
--- a/translations/system-configuration.en.xliff
+++ b/translations/system-configuration.en.xliff
@@ -22,9 +22,17 @@
label.timesheet.markdown_content
Allow Markdown in the timesheet descriptions
-
- label.timesheet.duration_only
- "Duration only" mode - replaces the endtime field with an input for duration
+
+ label.timesheet.mode
+ Timetracking mode
+
+
+ label.timesheet.mode_default
+ Default: accept start and end date
+
+
+ label.timesheet.mode_duration_only
+ Duration only: replaces the end date field with an input for duration
label.timesheet.rules.allow_future_times
diff --git a/translations/system-configuration.hu.xliff b/translations/system-configuration.hu.xliff
index 6ebbb94b..35d31657 100644
--- a/translations/system-configuration.hu.xliff
+++ b/translations/system-configuration.hu.xliff
@@ -22,8 +22,8 @@
label.timesheet.markdown_content
Markdown használatának engedélyezése a rögzítések leírásában
-
- label.timesheet.duration_only
+
+ label.timesheet.mode_duration_only
"Csak időtartam" mód - a befejezés mezőt kicseréli időtartamra