diff --git a/src/Command/ImportProjectCommand.php b/src/Command/ImportCustomerCommand.php
similarity index 99%
rename from src/Command/ImportProjectCommand.php
rename to src/Command/ImportCustomerCommand.php
index 8ee7c960..349af4a0 100644
--- a/src/Command/ImportProjectCommand.php
+++ b/src/Command/ImportCustomerCommand.php
@@ -32,7 +32,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
* @internal
* @codeCoverageIgnore
*/
-class ImportProjectCommand extends Command
+class ImportCustomerCommand extends Command
{
protected static $defaultName = 'kimai:import:customer';
diff --git a/src/Configuration/ThemeConfiguration.php b/src/Configuration/ThemeConfiguration.php
index c7366993..2809b937 100644
--- a/src/Configuration/ThemeConfiguration.php
+++ b/src/Configuration/ThemeConfiguration.php
@@ -23,12 +23,19 @@ class ThemeConfiguration implements SystemBundleConfiguration, \ArrayAccess
return (bool) $this->find('auto_reload_datatable');
}
+ public function isAllowTagCreation(): bool
+ {
+ return (bool) $this->find('tags_create');
+ }
+
/**
* Currently unused, as JS selects are always activated.
* @deprecated since 1.7 will be removed with 2.0
*/
public function getSelectPicker(): string
{
+ @trigger_error('getSelectPicker() is deprecated and will be removed with 2.0', E_USER_DEPRECATED);
+
return (string) $this->find('select_type');
}
diff --git a/src/Controller/SystemConfigurationController.php b/src/Controller/SystemConfigurationController.php
index 6ccf55a5..6379aeec 100644
--- a/src/Controller/SystemConfigurationController.php
+++ b/src/Controller/SystemConfigurationController.php
@@ -301,6 +301,11 @@ class SystemConfigurationController extends AbstractController
->setLabel('theme.markdown_content')
->setType(CheckboxType::class)
->setTranslationDomain('system-configuration'),
+ (new Configuration())
+ ->setName('theme.tags_create')
+ ->setLabel('theme.tags_create')
+ ->setType(CheckboxType::class)
+ ->setTranslationDomain('system-configuration'),
// TODO should that be configurable per user?
/*
(new Configuration())
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
index 5146e142..2aea99a2 100644
--- a/src/DependencyInjection/Configuration.php
+++ b/src/DependencyInjection/Configuration.php
@@ -329,9 +329,12 @@ class Configuration implements ConfigurationInterface
->defaultValue('selectpicker')
->setDeprecated()
->end()
- ->scalarNode('auto_reload_datatable')
+ ->booleanNode('auto_reload_datatable')
->defaultFalse()
->end()
+ ->booleanNode('tags_create')
+ ->defaultTrue()
+ ->end()
->booleanNode('show_about')
->defaultTrue()
->end()
diff --git a/src/Form/API/TimesheetApiEditForm.php b/src/Form/API/TimesheetApiEditForm.php
index 9c90cce9..eff1e67b 100644
--- a/src/Form/API/TimesheetApiEditForm.php
+++ b/src/Form/API/TimesheetApiEditForm.php
@@ -10,6 +10,7 @@
namespace App\Form\API;
use App\Form\TimesheetEditForm;
+use App\Form\Type\TagsInputType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -29,6 +30,19 @@ class TimesheetApiEditForm extends TimesheetEditForm
}
}
+ /**
+ * Method added to prevent API BC breaks.
+ *
+ * @param FormBuilderInterface $builder
+ */
+ protected function addTags(FormBuilderInterface $builder)
+ {
+ $builder
+ ->add('tags', TagsInputType::class, [
+ 'required' => false,
+ ]);
+ }
+
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
diff --git a/src/Form/FormTrait.php b/src/Form/FormTrait.php
index 876d21e5..fa423874 100644
--- a/src/Form/FormTrait.php
+++ b/src/Form/FormTrait.php
@@ -15,7 +15,7 @@ use App\Entity\Project;
use App\Form\Type\ActivityType;
use App\Form\Type\CustomerType;
use App\Form\Type\ProjectType;
-use App\Form\Type\TagsInputType;
+use App\Form\Type\TagsType;
use App\Repository\ActivityRepository;
use App\Repository\CustomerRepository;
use App\Repository\ProjectRepository;
@@ -29,6 +29,7 @@ use Symfony\Component\Form\FormEvents;
/**
* Defines the form used to manipulate Timesheet entries.
+ * @internal
*/
trait FormTrait
{
@@ -148,12 +149,7 @@ trait FormTrait
protected function addTags(FormBuilderInterface $builder)
{
$builder
- ->add('tags', TagsInputType::class, [
- // documentation is for NelmioApiDocBundle
- 'documentation' => [
- 'type' => 'string',
- 'description' => 'Comma separated list of tags',
- ],
+ ->add('tags', TagsType::class, [
'required' => false,
]);
}
diff --git a/src/Form/MultiUpdate/TimesheetMultiUpdate.php b/src/Form/MultiUpdate/TimesheetMultiUpdate.php
index 76698be9..d4ae4669 100644
--- a/src/Form/MultiUpdate/TimesheetMultiUpdate.php
+++ b/src/Form/MultiUpdate/TimesheetMultiUpdate.php
@@ -14,7 +14,7 @@ use App\Form\Type\CustomerType;
use App\Form\Type\FixedRateType;
use App\Form\Type\HourlyRateType;
use App\Form\Type\ProjectType;
-use App\Form\Type\TagsInputType;
+use App\Form\Type\TagsType;
use App\Form\Type\UserType;
use App\Form\Type\YesNoType;
use App\Repository\ActivityRepository;
@@ -180,7 +180,7 @@ class TimesheetMultiUpdate extends AbstractType
]
]);
- $builder->add('tags', TagsInputType::class, [
+ $builder->add('tags', TagsType::class, [
'required' => false,
]);
diff --git a/src/Form/Toolbar/AbstractToolbarForm.php b/src/Form/Toolbar/AbstractToolbarForm.php
index 57f7a114..30d90c17 100644
--- a/src/Form/Toolbar/AbstractToolbarForm.php
+++ b/src/Form/Toolbar/AbstractToolbarForm.php
@@ -15,8 +15,7 @@ use App\Form\Type\DateRangeType;
use App\Form\Type\PageSizeType;
use App\Form\Type\ProjectType;
use App\Form\Type\SearchTermType;
-use App\Form\Type\TagsInputType;
-use App\Form\Type\TagsSelectType;
+use App\Form\Type\TagsType;
use App\Form\Type\UserRoleType;
use App\Form\Type\UserType;
use App\Form\Type\VisibilityType;
@@ -225,20 +224,11 @@ abstract class AbstractToolbarForm extends AbstractType
protected function addTagInputField(FormBuilderInterface $builder)
{
- $builder->add('tags', TagsInputType::class, [
+ $builder->add('tags', TagsType::class, [
'required' => false
]);
}
- // TODO add a system setting to control if tags can be created on the fly
- protected function addTagSelectField(FormBuilderInterface $builder)
- {
- $builder->add('tags', TagsSelectType::class, [
- 'required' => false,
- 'multiple' => true,
- ]);
- }
-
protected function addSearchTermInputField(FormBuilderInterface $builder)
{
$builder->add('searchTerm', SearchTermType::class);
diff --git a/src/Form/Type/TagsInputType.php b/src/Form/Type/TagsInputType.php
index 847f163a..c9bd431a 100644
--- a/src/Form/Type/TagsInputType.php
+++ b/src/Form/Type/TagsInputType.php
@@ -58,6 +58,11 @@ class TagsInputType extends AbstractType
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
+ // documentation is for NelmioApiDocBundle
+ 'documentation' => [
+ 'type' => 'string',
+ 'description' => 'Comma separated list of tags',
+ ],
'label' => 'label.tag',
'attr' => [
'data-autocomplete-url' => $this->router->generate('get_tags'),
diff --git a/src/Form/Type/TagsSelectType.php b/src/Form/Type/TagsSelectType.php
index 8dc046b8..c5788e4f 100644
--- a/src/Form/Type/TagsSelectType.php
+++ b/src/Form/Type/TagsSelectType.php
@@ -28,6 +28,7 @@ class TagsSelectType extends AbstractType
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
+ 'multiple' => true,
'class' => Tag::class,
'label' => 'label.tag',
'choice_label' => function (Tag $tag) {
diff --git a/src/Form/Type/TagsType.php b/src/Form/Type/TagsType.php
new file mode 100644
index 00000000..a738c472
--- /dev/null
+++ b/src/Form/Type/TagsType.php
@@ -0,0 +1,38 @@
+configuration = $configuration;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParent()
+ {
+ if ($this->configuration->isAllowTagCreation()) {
+ return TagsInputType::class;
+ }
+
+ return TagsSelectType::class;
+ }
+}
diff --git a/tests/Configuration/ThemeConfigurationTest.php b/tests/Configuration/ThemeConfigurationTest.php
index 0b45203f..513b7ea7 100644
--- a/tests/Configuration/ThemeConfigurationTest.php
+++ b/tests/Configuration/ThemeConfigurationTest.php
@@ -48,6 +48,7 @@ class ThemeConfigurationTest extends TestCase
'title' => null,
],
'auto_reload_datatable' => false,
+ 'tags_create' => true,
];
}
@@ -61,7 +62,16 @@ class ThemeConfigurationTest extends TestCase
{
$sut = $this->getSut($this->getDefaultSettings(), []);
$this->assertFalse($sut->isAutoReloadDatatable());
- $this->assertEquals('', $sut->getSelectPicker());
+ $this->assertTrue($sut->isAllowTagCreation());
$this->assertNull($sut->getTitle());
}
+
+ /**
+ * @group legacy
+ */
+ public function testDeprecations()
+ {
+ $sut = $this->getSut($this->getDefaultSettings(), []);
+ $this->assertEquals('', $sut->getSelectPicker());
+ }
}
diff --git a/tests/DependencyInjection/AppExtensionTest.php b/tests/DependencyInjection/AppExtensionTest.php
index 8cd6ab17..91cb0006 100644
--- a/tests/DependencyInjection/AppExtensionTest.php
+++ b/tests/DependencyInjection/AppExtensionTest.php
@@ -171,6 +171,7 @@ class AppExtensionTest extends TestCase
],
'auto_reload_datatable' => false,
'autocomplete_chars' => 3,
+ 'tags_create' => true,
],
'kimai.theme.select_type' => 'selectpicker',
'kimai.theme.show_about' => true,
diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php
index e90e8b79..60215405 100644
--- a/tests/DependencyInjection/ConfigurationTest.php
+++ b/tests/DependencyInjection/ConfigurationTest.php
@@ -337,6 +337,7 @@ class ConfigurationTest extends TestCase
'translation' => null,
],
'autocomplete_chars' => 3,
+ 'tags_create' => true,
],
'industry' => [
'translation' => null,
diff --git a/translations/system-configuration.de.xlf b/translations/system-configuration.de.xlf
index 5d632367..f7ac9b4b 100644
--- a/translations/system-configuration.de.xlf
+++ b/translations/system-configuration.de.xlf
@@ -34,6 +34,10 @@
label.theme.markdown_content
Erlaube Markdown-Formatierungen in Beschreibungen und Kommentaren
+
+ label.theme.tags_create
+ Schlagworte: Suche per Auto-Complete und Erstellung von Schlagworten erlauben
+
label.timesheet.mode
Zeiterfassungs Modus
diff --git a/translations/system-configuration.en.xlf b/translations/system-configuration.en.xlf
index b4438e65..2d1d1532 100644
--- a/translations/system-configuration.en.xlf
+++ b/translations/system-configuration.en.xlf
@@ -34,6 +34,10 @@
label.theme.markdown_content
Allow markdown-formattings in descriptions and comments
+
+ label.theme.tags_create
+ Tags: use auto-complete search and allow tag creation
+
label.timesheet.mode
Timetracking mode