Release 2.57 (#5929)
This commit is contained in:
44
src/Form/API/CommentApiForm.php
Normal file
44
src/Form/API/CommentApiForm.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?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\API;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
final class CommentApiForm extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder->add('pinned', CheckboxType::class, [
|
||||
'required' => false,
|
||||
'documentation' => [
|
||||
'default' => false,
|
||||
'description' => 'Pinned comments always appear first'
|
||||
],
|
||||
]);
|
||||
|
||||
$builder->add('message', TextareaType::class, [
|
||||
'label' => false,
|
||||
'documentation' => [
|
||||
'description' => 'The actual comment (markdown is supported)'
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'csrf_protection' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ use App\Utils\SearchTerm;
|
||||
use Symfony\Component\Form\DataTransformerInterface;
|
||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||
|
||||
/**
|
||||
* @implements DataTransformerInterface<SearchTerm, string>
|
||||
*/
|
||||
final class SearchTermTransformer implements DataTransformerInterface
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -62,31 +62,21 @@ trait FormTrait
|
||||
/** @var array<string, mixed> $data */
|
||||
$data = $event->getData();
|
||||
$customer = \array_key_exists('customer', $data) && $data['customer'] !== '' ? $data['customer'] : null;
|
||||
$project = \array_key_exists('project', $data) && $data['project'] !== '' ? $data['project'] : $project;
|
||||
|
||||
$event->getForm()->add('project', ProjectType::class, array_merge($options, [
|
||||
'group_by' => null,
|
||||
'query_builder' => function (ProjectRepository $repo) use ($builder, $project, $customer, $isNew) {
|
||||
// is there a better way to prevent starting a record with a hidden project ?
|
||||
$project = \is_string($project) ? (int) $project : $project;
|
||||
$customer = \is_string($customer) ? (int) $customer : $customer;
|
||||
if ($isNew && \is_int($project)) {
|
||||
/** @var Project $project */
|
||||
$project = $repo->find($project);
|
||||
if ($project !== null) {
|
||||
if (!$project->getCustomer()->isVisible()) {
|
||||
$customer = null;
|
||||
$project = null;
|
||||
} elseif (!$project->isVisible()) {
|
||||
$project = null;
|
||||
}
|
||||
if ($isNew && $project instanceof Project) {
|
||||
if (!$project->getCustomer()->isVisible()) {
|
||||
$customer = null;
|
||||
$project = null;
|
||||
} elseif (!$project->isVisible()) {
|
||||
$project = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($project !== null && !\is_int($project) && !($project instanceof Project)) {
|
||||
throw new \InvalidArgumentException('Project type needs a project object or an ID');
|
||||
}
|
||||
|
||||
if ($customer !== null && !\is_int($customer) && !($customer instanceof Customer)) {
|
||||
throw new \InvalidArgumentException('Project type needs a customer object or an ID');
|
||||
}
|
||||
|
||||
@@ -17,11 +17,14 @@ use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @template T of object
|
||||
*/
|
||||
final class MultiUpdateTable extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
/** @var EntityRepository $repository */
|
||||
/** @var EntityRepository<T> $repository */
|
||||
$repository = $options['repository'];
|
||||
/** @var MultiUpdateTableDTO $dto */
|
||||
$dto = $options['data'];
|
||||
|
||||
@@ -19,6 +19,9 @@ use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @implements DataTransformerInterface<string, string>
|
||||
*/
|
||||
final class ColorChoiceType extends AbstractType implements DataTransformerInterface
|
||||
{
|
||||
public function __construct(private readonly SystemConfiguration $systemConfiguration)
|
||||
|
||||
@@ -16,6 +16,9 @@ use Symfony\Component\Form\Extension\Core\Type\ColorType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @implements DataTransformerInterface<string, string>
|
||||
*/
|
||||
final class ColorPickerType extends AbstractType implements DataTransformerInterface
|
||||
{
|
||||
public const DEFAULT_COLOR = Constants::DEFAULT_COLOR;
|
||||
@@ -37,15 +40,21 @@ final class ColorPickerType extends AbstractType implements DataTransformerInter
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function transform(mixed $data): mixed
|
||||
{
|
||||
if (empty($data)) {
|
||||
if (!\is_string($data) || $data === '') {
|
||||
return self::DEFAULT_COLOR;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function reverseTransform(mixed $value): mixed
|
||||
{
|
||||
return null === $value ? self::DEFAULT_COLOR : $value;
|
||||
|
||||
@@ -90,7 +90,11 @@ final class QuickEntryWeekType extends AbstractType
|
||||
}
|
||||
}
|
||||
|
||||
$event->getForm()->add('activity', ActivityType::class, $activityOptions);
|
||||
// exported entries cause the dropdown to be deactivated
|
||||
// we need to make sure to fetch the info before the field is replaced
|
||||
// see https://github.com/kimai/kimai/issues/5642
|
||||
$disabled = $event->getForm()->get('activity')->isDisabled();
|
||||
$event->getForm()->add('activity', ActivityType::class, array_merge(['disabled' => $disabled], $activityOptions));
|
||||
};
|
||||
$builder->addEventListener(FormEvents::PRE_SUBMIT, $activityPreSubmitFunction);
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ final class UserType extends AbstractType
|
||||
return $a->getDisplayName() <=> $b->getDisplayName();
|
||||
});
|
||||
|
||||
return array_values($userById);
|
||||
return $userById;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -97,11 +97,6 @@ class UserEditType extends AbstractType
|
||||
]);
|
||||
}
|
||||
|
||||
$builder->add('systemAccount', YesNoType::class, [
|
||||
'label' => 'system_account',
|
||||
'help' => 'system_account.help',
|
||||
]);
|
||||
|
||||
if ($options['include_supervisor']) {
|
||||
$builder->add('supervisor', UserType::class, [
|
||||
'required' => false,
|
||||
@@ -111,6 +106,11 @@ class UserEditType extends AbstractType
|
||||
}
|
||||
|
||||
if ($options['include_password_reset']) {
|
||||
$builder->add('systemAccount', YesNoType::class, [
|
||||
'label' => 'system_account',
|
||||
'help' => 'system_account.help',
|
||||
]);
|
||||
|
||||
$builder->add('requiresPasswordReset', YesNoType::class, [
|
||||
'label' => 'force_password_change',
|
||||
'help' => 'force_password_change_help',
|
||||
|
||||
Reference in New Issue
Block a user