allow to pre-define colors to choose from (#2481)

This commit is contained in:
Kevin Papst
2021-04-06 00:45:54 +02:00
committed by GitHub
parent f4dbdbb427
commit 68bb01d064
28 changed files with 574 additions and 21 deletions

View File

@@ -9,23 +9,21 @@
namespace App\Form;
use App\Form\Type\ColorPickerType;
use App\Form\Type\ColorChoiceType;
use App\Form\Type\DurationType;
use App\Form\Type\MetaFieldsCollectionType;
use App\Form\Type\YesNoType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
trait EntityFormTrait
{
public function addCommonFields(FormBuilderInterface $builder, array $options): void
{
$builder
->add('color', ColorPickerType::class, [
'required' => false,
])
;
$this->addColor($builder);
if ($options['include_budget']) {
$builder
@@ -52,6 +50,39 @@ trait EntityFormTrait
]);
}
public function addColor(FormBuilderInterface $builder): void
{
$builder
->add('color', ColorChoiceType::class, [
'required' => false,
])
;
// this code exists only for backward compatibility
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($builder) {
if (!$builder->get('color')->hasOption('choices')) {
return;
}
$data = $event->getData();
$choices = $builder->get('color')->getOption('choices');
if (\is_object($data) && method_exists($data, 'getColor')) {
$color = $data->getColor();
if (!empty($color) && array_search($color, $choices) === false) {
$choices[$color] = $color;
}
}
$event->getForm()->add('color', ColorChoiceType::class, [
'required' => false,
'choices' => $choices,
]);
}
);
}
public function addCreateMore(FormBuilderInterface $builder): void
{
$builder->add('create_more', CheckboxType::class, [

View File

@@ -0,0 +1,42 @@
<?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\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class ArrayToCommaStringType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer(new CallbackTransformer(
function ($value) {
if ($value === null) {
return null;
}
return $value;
},
function ($value) {
return $value;
}
));
}
/**
* {@inheritdoc}
*/
public function getParent()
{
return TextType::class;
}
}

View File

@@ -0,0 +1,115 @@
<?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 App\Configuration\SystemConfiguration;
use App\Constants;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\ColorType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ColorChoiceType extends AbstractType implements DataTransformerInterface
{
public const DEFAULT_COLOR = Constants::DEFAULT_COLOR;
private $systemConfiguration;
/**
* @var bool|null
*/
private $limitedColors;
public function __construct(SystemConfiguration $systemConfiguration)
{
$this->systemConfiguration = $systemConfiguration;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addViewTransformer($this);
}
private function isLimitedColors(): bool
{
if (null === $this->limitedColors) {
$this->limitedColors = $this->systemConfiguration->isThemeColorsLimited();
}
return $this->limitedColors;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$options = [
'documentation' => [
'type' => 'string',
'description' => sprintf('The hexadecimal color code (default: %s)', self::DEFAULT_COLOR),
],
'label' => 'label.color',
'empty_data' => null,
];
if ($this->isLimitedColors()) {
$choices = [];
foreach ($this->systemConfiguration->getThemeColorChoices() as $name => $color) {
$choices[$name] = $color;
}
$options['choices'] = $choices;
$options['search'] = false;
$options['attr']['data-renderer'] = 'color';
}
$resolver->setDefaults($options);
}
/**
* {@inheritdoc}
*/
public function transform($data)
{
if (empty($data) && !$this->isLimitedColors()) {
return self::DEFAULT_COLOR;
}
return $data;
}
/**
* {@inheritdoc}
*/
public function reverseTransform($data)
{
if (null === $data && !$this->isLimitedColors()) {
return self::DEFAULT_COLOR;
}
return null === $data ? null : $data;
}
/**
* {@inheritdoc}
*/
public function getParent()
{
if ($this->isLimitedColors()) {
return ChoiceType::class;
}
return ColorType::class;
}
}