added supervisor setting for user (#4251)
This commit is contained in:
@@ -197,6 +197,7 @@ final class UserController extends BaseApiController
|
||||
'include_roles' => $this->isGranted('roles', $profile),
|
||||
'include_active_flag' => ($profile->getId() !== $this->getUser()->getId()),
|
||||
'include_preferences' => $this->isGranted('preferences', $profile),
|
||||
'include_supervisor' => $this->isGranted('supervisor', $profile),
|
||||
]);
|
||||
|
||||
$form->setData($profile);
|
||||
|
||||
@@ -316,7 +316,8 @@ final class ProfileController extends AbstractController
|
||||
'action' => $this->generateUrl('user_profile_edit', ['username' => $user->getUserIdentifier()]),
|
||||
'method' => 'POST',
|
||||
'include_active_flag' => ($user->getId() !== $this->getUser()->getId()),
|
||||
'include_preferences' => false,
|
||||
'include_preferences' => true,
|
||||
'include_supervisor' => $this->isGranted('supervisor', $user),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -233,6 +233,7 @@ final class UserController extends AbstractController
|
||||
'method' => 'POST',
|
||||
'include_active_flag' => true,
|
||||
'include_preferences' => true,
|
||||
'include_supervisor' => $this->isGranted('supervisor_other_profile'),
|
||||
'include_teams' => $this->isGranted('teams_other_profile'),
|
||||
'include_roles' => $this->isGranted('roles_other_profile'),
|
||||
]);
|
||||
|
||||
@@ -128,15 +128,15 @@ class User implements UserInterface, EquatableInterface, ThemeUserInterface, Pas
|
||||
*
|
||||
* @var Collection<UserPreference>|null
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: 'App\Entity\UserPreference', mappedBy: 'user', cascade: ['persist'])]
|
||||
#[ORM\OneToMany(targetEntity: UserPreference::class, mappedBy: 'user', cascade: ['persist'])]
|
||||
private ?Collection $preferences = null;
|
||||
/**
|
||||
* List of all team memberships.
|
||||
*
|
||||
* @var Collection<TeamMember>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: 'App\Entity\TeamMember', mappedBy: 'user', fetch: 'LAZY', cascade: ['persist'], orphanRemoval: true)]
|
||||
#[ORM\JoinColumn(onDelete: 'CASCADE')]
|
||||
#[ORM\OneToMany(targetEntity: TeamMember::class, mappedBy: 'user', fetch: 'LAZY', cascade: ['persist'], orphanRemoval: true)]
|
||||
#[ORM\JoinColumn(onDelete: 'CASCADE', nullable: false)]
|
||||
#[Assert\NotNull]
|
||||
#[Serializer\Expose]
|
||||
#[Serializer\Groups(['User_Entity'])]
|
||||
@@ -216,6 +216,12 @@ class User implements UserInterface, EquatableInterface, ThemeUserInterface, Pas
|
||||
private bool $totpEnabled = false;
|
||||
#[ORM\Column(name: 'system_account', type: 'boolean', nullable: false, options: ['default' => false])]
|
||||
private bool $systemAccount = false;
|
||||
#[ORM\ManyToOne(targetEntity: User::class)]
|
||||
#[ORM\JoinColumn(onDelete: 'SET NULL', nullable: true)]
|
||||
#[Serializer\Expose]
|
||||
#[Serializer\Groups(['User_Entity'])]
|
||||
#[OA\Property(ref: '#/components/schemas/User')]
|
||||
private ?User $supervisor = null;
|
||||
|
||||
use ColorTrait;
|
||||
|
||||
@@ -1281,4 +1287,24 @@ class User implements UserInterface, EquatableInterface, ThemeUserInterface, Pas
|
||||
default => throw new \Exception('Unknown day: ' . $dateTime->format('Y-m-d'))
|
||||
};
|
||||
}
|
||||
|
||||
public function isWorkDay(\DateTimeInterface $dateTime): bool
|
||||
{
|
||||
return $this->getWorkHoursForDay($dateTime) > 0;
|
||||
}
|
||||
|
||||
public function hasSupervisor(): bool
|
||||
{
|
||||
return $this->supervisor !== null;
|
||||
}
|
||||
|
||||
public function getSupervisor(): ?User
|
||||
{
|
||||
return $this->supervisor;
|
||||
}
|
||||
|
||||
public function setSupervisor(?User $supervisor): void
|
||||
{
|
||||
$this->supervisor = $supervisor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,18 +16,18 @@ use Symfony\Component\Form\FormEvents;
|
||||
|
||||
trait ColorTrait
|
||||
{
|
||||
protected function addColor(FormBuilderInterface $builder): void
|
||||
protected function addColor(FormBuilderInterface $builder, bool $required = false): void
|
||||
{
|
||||
$builder
|
||||
->add('color', ColorChoiceType::class, [
|
||||
'required' => false,
|
||||
'required' => $required,
|
||||
])
|
||||
;
|
||||
|
||||
// this code exists only for backward compatibility
|
||||
$builder->addEventListener(
|
||||
FormEvents::PRE_SET_DATA,
|
||||
function (FormEvent $event) {
|
||||
function (FormEvent $event) use ($required) {
|
||||
if (!$event->getForm()->getConfig()->hasOption('choices')) {
|
||||
return;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ trait ColorTrait
|
||||
}
|
||||
|
||||
$event->getForm()->add('color', ColorChoiceType::class, [
|
||||
'required' => false,
|
||||
'required' => $required,
|
||||
'choices' => $choices,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -23,47 +23,45 @@ class UserCreateType extends UserEditType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('username', null, [
|
||||
'label' => 'username',
|
||||
'required' => true,
|
||||
'attr' => [
|
||||
'autofocus' => 'autofocus'
|
||||
],
|
||||
])
|
||||
->add('plainPassword', RepeatedType::class, [
|
||||
'required' => true,
|
||||
'type' => PasswordType::class,
|
||||
'first_options' => [
|
||||
'label' => 'password',
|
||||
'attr' => ['autocomplete' => 'new-password'],
|
||||
'block_prefix' => 'secret'
|
||||
],
|
||||
'second_options' => [
|
||||
'label' => 'password_repeat',
|
||||
'attr' => ['autocomplete' => 'new-password'],
|
||||
'block_prefix' => 'secret'
|
||||
],
|
||||
]);
|
||||
$builder->add('username', null, [
|
||||
'label' => 'username',
|
||||
'required' => true,
|
||||
'attr' => [
|
||||
'autofocus' => 'autofocus'
|
||||
],
|
||||
]);
|
||||
|
||||
$builder->add('plainPassword', RepeatedType::class, [
|
||||
'required' => true,
|
||||
'type' => PasswordType::class,
|
||||
'first_options' => [
|
||||
'label' => 'password',
|
||||
'attr' => ['autocomplete' => 'new-password'],
|
||||
'block_prefix' => 'secret'
|
||||
],
|
||||
'second_options' => [
|
||||
'label' => 'password_repeat',
|
||||
'attr' => ['autocomplete' => 'new-password'],
|
||||
'block_prefix' => 'secret'
|
||||
],
|
||||
]);
|
||||
|
||||
parent::buildForm($builder, $options);
|
||||
|
||||
if ($options['include_teams'] === true) {
|
||||
$builder
|
||||
->add('teams', TeamType::class, [
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'required' => false,
|
||||
]);
|
||||
$builder->add('teams', TeamType::class, [
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'required' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
if ($options['include_roles'] === true) {
|
||||
$builder
|
||||
->add('roles', UserRoleType::class, [
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'required' => false,
|
||||
]);
|
||||
$builder->add('roles', UserRoleType::class, [
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'required' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@ namespace App\Form;
|
||||
use App\Configuration\SystemConfiguration;
|
||||
use App\Entity\User;
|
||||
use App\Form\Type\AvatarType;
|
||||
use App\Form\Type\LanguageType;
|
||||
use App\Form\Type\MailType;
|
||||
use App\Form\Type\TimezoneType;
|
||||
use App\Form\Type\UserLanguageType;
|
||||
use App\Form\Type\UserType;
|
||||
use App\Form\Type\YesNoType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
@@ -35,20 +36,26 @@ class UserEditType extends AbstractType
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('alias', TextType::class, [
|
||||
'label' => 'alias',
|
||||
'required' => false,
|
||||
])
|
||||
->add('title', TextType::class, [
|
||||
'label' => 'title',
|
||||
'required' => false,
|
||||
])
|
||||
->add('accountNumber', TextType::class, [
|
||||
'label' => 'account_number',
|
||||
'required' => false,
|
||||
])
|
||||
;
|
||||
/** @var User|null $user */
|
||||
$user = null;
|
||||
if (\array_key_exists('data', $options)) {
|
||||
$user = $options['data'];
|
||||
}
|
||||
|
||||
$builder->add('alias', TextType::class, [
|
||||
'label' => 'alias',
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
$builder->add('title', TextType::class, [
|
||||
'label' => 'title',
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
$builder->add('accountNumber', TextType::class, [
|
||||
'label' => 'account_number',
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
if ($this->configuration->isThemeAllowAvatarUrls()) {
|
||||
$builder->add('avatar', AvatarType::class, [
|
||||
@@ -61,7 +68,7 @@ class UserEditType extends AbstractType
|
||||
$builder->add('email', MailType::class);
|
||||
|
||||
if ($options['include_preferences']) {
|
||||
$builder->add('language', LanguageType::class, [
|
||||
$builder->add('language', UserLanguageType::class, [
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
@@ -75,12 +82,20 @@ class UserEditType extends AbstractType
|
||||
'label' => 'active',
|
||||
'help' => 'active.help'
|
||||
]);
|
||||
|
||||
$builder->add('systemAccount', YesNoType::class, [
|
||||
'label' => 'system_account',
|
||||
'help' => 'system_account.help',
|
||||
]);
|
||||
}
|
||||
|
||||
$builder->add('systemAccount', YesNoType::class, [
|
||||
'label' => 'system_account',
|
||||
'help' => 'system_account.help',
|
||||
]);
|
||||
if ($options['include_supervisor']) {
|
||||
$builder->add('supervisor', UserType::class, [
|
||||
'required' => false,
|
||||
'label' => 'supervisor',
|
||||
'ignore_users' => ($user instanceof User && $user->getId() !== null ? [$user] : []),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
@@ -93,6 +108,7 @@ class UserEditType extends AbstractType
|
||||
'csrf_token_id' => 'edit_user_profile',
|
||||
'include_active_flag' => true,
|
||||
'include_preferences' => true,
|
||||
'include_supervisor' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ final class UserVoter extends Voter
|
||||
'hourly-rate',
|
||||
'view_team_member',
|
||||
'contract',
|
||||
'supervisor',
|
||||
];
|
||||
|
||||
public function __construct(private RolePermissionManager $permissionManager)
|
||||
|
||||
Reference in New Issue
Block a user