feat: selectable feedback author for administrative users
addresses #869at5nbp
This commit is contained in:
@@ -37,8 +37,8 @@ class ProvideController extends AbstractController
|
|||||||
// Feedback provided by admins is published instantly
|
// Feedback provided by admins is published instantly
|
||||||
$feedback->setStatus(Feedback::STATUS_PUBLISHED);
|
$feedback->setStatus(Feedback::STATUS_PUBLISHED);
|
||||||
|
|
||||||
if (null !== $form->get('authorOverride')->getData()) {
|
if (null !== $author = $form->get('authorOverride')->getData()) {
|
||||||
$feedback->setAuthor($form->get('authorOverride')->getData());
|
$feedback->setAuthor($author->getFullName());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->entityManager->persist($feedback);
|
$this->entityManager->persist($feedback);
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ class ProvideController extends AbstractController
|
|||||||
$feedback->setStatus(Feedback::STATUS_PUBLISHED);
|
$feedback->setStatus(Feedback::STATUS_PUBLISHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (true === $form->has('author')) {
|
||||||
|
/** @var User $author */
|
||||||
|
$author = $form->get('author')->getData();
|
||||||
|
$feedback->setAuthor($author->getFullName());
|
||||||
|
}
|
||||||
|
|
||||||
$teamer = $disposition->getTeamer();
|
$teamer = $disposition->getTeamer();
|
||||||
$teamer->addFeedback($feedback);
|
$teamer->addFeedback($feedback);
|
||||||
$disposition->setFeedback($feedback);
|
$disposition->setFeedback($feedback);
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Entity\Feedback;
|
||||||
|
use App\Entity\FeedbackSet;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
abstract class AbstractFeedbackType extends AbstractType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The ratings depend on the feedback set, which one flow knows upfront and the other only once
|
||||||
|
* it has been picked - hence the union type, as the fields are added to a builder in the first
|
||||||
|
* case and to an already built form in the second.
|
||||||
|
*/
|
||||||
|
protected function addFeedbackFields(FormBuilderInterface|FormInterface $form, FeedbackSet $feedbackSet): void
|
||||||
|
{
|
||||||
|
$form
|
||||||
|
->add('ratings', FeedbackRatingsType::class, [
|
||||||
|
'label' => false,
|
||||||
|
'feedback_set' => $feedbackSet,
|
||||||
|
])
|
||||||
|
->add('comment', TextareaType::class, [
|
||||||
|
'label' => 'Kommentar (öffentlich)',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => [
|
||||||
|
'rows' => 5,
|
||||||
|
],
|
||||||
|
'help' => 'Bitte formuliere deinen Kommentar so, dass er an das Team weitergegeben werden kann',
|
||||||
|
])
|
||||||
|
->add('commentInternal', TextareaType::class, [
|
||||||
|
'label' => 'Kommentar (intern)',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => [
|
||||||
|
'rows' => 5,
|
||||||
|
],
|
||||||
|
])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => Feedback::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,21 +2,17 @@
|
|||||||
|
|
||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
use App\Entity\Feedback;
|
|
||||||
use App\Entity\FeedbackSet;
|
use App\Entity\FeedbackSet;
|
||||||
use App\Entity\Teamer;
|
use App\Entity\Teamer;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Repository\FeedbackSetRepository;
|
use App\Repository\FeedbackSetRepository;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Form\FormEvent;
|
use Symfony\Component\Form\FormEvent;
|
||||||
use Symfony\Component\Form\FormEvents;
|
use Symfony\Component\Form\FormEvents;
|
||||||
use Symfony\Component\Form\FormInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
class AdminFeedbackType extends AbstractType
|
class AdminFeedbackType extends AbstractFeedbackType
|
||||||
{
|
{
|
||||||
public function __construct(private readonly FeedbackSetRepository $feedbackSetRepository)
|
public function __construct(private readonly FeedbackSetRepository $feedbackSetRepository)
|
||||||
{
|
{
|
||||||
@@ -34,7 +30,7 @@ class AdminFeedbackType extends AbstractType
|
|||||||
])
|
])
|
||||||
->add('authorOverride', AutocompleteEntityType::class, [
|
->add('authorOverride', AutocompleteEntityType::class, [
|
||||||
'mapped' => false,
|
'mapped' => false,
|
||||||
'label' => 'abweichender Absender',
|
'label' => 'Feedbackgeber:in',
|
||||||
'class' => User::class,
|
'class' => User::class,
|
||||||
'label_property' => 'lastName',
|
'label_property' => 'lastName',
|
||||||
'label_function' => fn (User $user) => (string) $user,
|
'label_function' => fn (User $user) => (string) $user,
|
||||||
@@ -57,7 +53,7 @@ class AdminFeedbackType extends AbstractType
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addDynamicForm($feedbackSet, $form);
|
$this->addFeedbackFields($form, $feedbackSet);
|
||||||
})
|
})
|
||||||
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
|
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
|
||||||
$data = $event->getData();
|
$data = $event->getData();
|
||||||
@@ -67,47 +63,26 @@ class AdminFeedbackType extends AbstractType
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$feedbackSet = $this->feedbackSetRepository->find($data['feedbackSet']);
|
if (null === $feedbackSet = $this->feedbackSetRepository->find($data['feedbackSet'])) {
|
||||||
$this->addDynamicForm($feedbackSet, $form);
|
return;
|
||||||
})
|
}
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addDynamicForm(FeedbackSet $feedbackSet, FormInterface $form): void
|
$this->addFeedbackFields($form, $feedbackSet);
|
||||||
{
|
})
|
||||||
$form
|
|
||||||
->add('ratings', FeedbackRatingsType::class, [
|
|
||||||
'label' => false,
|
|
||||||
'feedback_set' => $feedbackSet,
|
|
||||||
])
|
|
||||||
->add('comment', TextareaType::class, [
|
|
||||||
'label' => 'Kommentar (öffentlich)',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => [
|
|
||||||
'rows' => 5,
|
|
||||||
],
|
|
||||||
'help' => 'Bitte formuliere deinen Kommentar so, dass er an das Team weitergegeben werden kann',
|
|
||||||
])
|
|
||||||
->add('commentInternal', TextareaType::class, [
|
|
||||||
'label' => 'Kommentar (intern)',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => [
|
|
||||||
'rows' => 5,
|
|
||||||
],
|
|
||||||
])
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver): void
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
{
|
{
|
||||||
$resolver
|
parent::configureOptions($resolver);
|
||||||
->setDefaults([
|
|
||||||
'data_class' => Feedback::class,
|
$resolver->setDefaults([
|
||||||
'validation_groups' => [
|
// the disposition-driven flow guarantees teamer and feedback set structurally, here
|
||||||
'Default',
|
// they are picked by hand and must be validated
|
||||||
'admin',
|
'validation_groups' => [
|
||||||
],
|
'Default',
|
||||||
])
|
'admin',
|
||||||
;
|
],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-28
@@ -2,46 +2,70 @@
|
|||||||
|
|
||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
use App\Entity\Feedback;
|
|
||||||
use App\Entity\FeedbackSet;
|
use App\Entity\FeedbackSet;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use App\Entity\User;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
use App\Repository\UserRepository;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
class FeedbackType extends AbstractType
|
class FeedbackType extends AbstractFeedbackType
|
||||||
{
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly Security $security,
|
||||||
|
private readonly UserRepository $userRepository,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
{
|
{
|
||||||
$builder
|
if (true === $this->security->isGranted('ROLE_ADMINISTRATIVE')) {
|
||||||
->add('ratings', FeedbackRatingsType::class, [
|
$this->addAuthorField($builder);
|
||||||
'label' => false,
|
}
|
||||||
'feedback_set' => $options['feedback_set'],
|
|
||||||
])
|
$this->addFeedbackFields($builder, $options['feedback_set']);
|
||||||
->add('comment', TextareaType::class, [
|
}
|
||||||
'label' => 'Kommentar (öffentlich)',
|
|
||||||
'required' => false,
|
/**
|
||||||
'attr' => [
|
* Feedback::$author is a name snapshot rather than a relation, so the field stays unmapped and
|
||||||
'rows' => 5,
|
* the controller writes the chosen user's full name.
|
||||||
],
|
*/
|
||||||
'help' => 'Bitte formuliere deinen Kommentar so, dass er an das Team weitergegeben werden kann',
|
private function addAuthorField(FormBuilderInterface $builder): void
|
||||||
])
|
{
|
||||||
->add('commentInternal', TextareaType::class, [
|
$roles = array_diff(array_keys(User::ROLES), ['ROLE_TEAMER']);
|
||||||
'label' => 'Kommentar (intern)',
|
|
||||||
'required' => false,
|
$choices = $this->userRepository->getUsersByRoles($roles);
|
||||||
'attr' => [
|
|
||||||
'rows' => 5,
|
/** @var User $user */
|
||||||
],
|
$user = $this->security->getUser();
|
||||||
])
|
|
||||||
;
|
// a user granted the role by the hierarchy alone would not be among the choices
|
||||||
|
$choiceIds = array_map(fn (User $choice) => $choice->getId(), $choices);
|
||||||
|
|
||||||
|
if (false === in_array($user->getId(), $choiceIds, true)) {
|
||||||
|
array_unshift($choices, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder->add('author', EntityType::class, [
|
||||||
|
'label' => 'Feedbackgeber:in',
|
||||||
|
'mapped' => false,
|
||||||
|
'class' => User::class,
|
||||||
|
'choices' => $choices,
|
||||||
|
'choice_label' => 'fullName',
|
||||||
|
'data' => $user,
|
||||||
|
'constraints' => [
|
||||||
|
new Assert\NotNull(message: 'Bitte wähle eine:n Feedbackgeber:in'),
|
||||||
|
],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver): void
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
{
|
{
|
||||||
|
parent::configureOptions($resolver);
|
||||||
|
|
||||||
$resolver
|
$resolver
|
||||||
->setDefaults([
|
|
||||||
'data_class' => Feedback::class,
|
|
||||||
])
|
|
||||||
->setRequired(['feedback_set'])
|
->setRequired(['feedback_set'])
|
||||||
->setAllowedTypes('feedback_set', FeedbackSet::class)
|
->setAllowedTypes('feedback_set', FeedbackSet::class)
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -61,6 +61,35 @@ class UserRepository extends ServiceEntityRepository
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Active users holding at least one of the given roles.
|
||||||
|
*
|
||||||
|
* @param string[] $roles
|
||||||
|
*
|
||||||
|
* @return User[]
|
||||||
|
*/
|
||||||
|
public function getUsersByRoles(array $roles): array
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder('user');
|
||||||
|
|
||||||
|
$roleMatches = $qb->expr()->orX();
|
||||||
|
|
||||||
|
foreach ($roles as $index => $role) {
|
||||||
|
$roleMatches->add('JSON_CONTAINS(user.roles, :role_'.$index.') = 1');
|
||||||
|
$qb->setParameter('role_'.$index, json_encode($role));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $qb
|
||||||
|
->andWhere($roleMatches)
|
||||||
|
->andWhere($qb->expr()->isNull('user.deletedAt'))
|
||||||
|
->andWhere($qb->expr()->isNull('user.disabledAt'))
|
||||||
|
->orderBy('user.lastName', 'ASC')
|
||||||
|
->addOrderBy('user.firstName', 'ASC')
|
||||||
|
->getQuery()
|
||||||
|
->getResult()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[]|string $hotelCode
|
* @param string[]|string $hotelCode
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<h2 class="text-lg font-bold pb-2">
|
||||||
|
Bewertungsskala
|
||||||
|
</h2>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th class="whitespace-nowrap">
|
||||||
|
5 Punkte
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
Der/die Wochenteamer:in hat hervorragende Arbeit geleistet und ist beim Team und den Gästen
|
||||||
|
sehr gut angekommen, es gibt nichts auszusetzen.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="whitespace-nowrap">
|
||||||
|
4 Punkte
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
Der/die Wochenteamer:in hat einen sehr guten Job geleistet. Wenn es etwas zu beanstanden oder
|
||||||
|
Ideen zur Verbesserung gibt, dann sind es nur Kleinigkeiten (diese gerne in den Kommentar
|
||||||
|
schreiben).
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="whitespace-nowrap">
|
||||||
|
3 Punkte
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
Der/die Wochenteamer:in hat einen ganz guten Job erledigt. Es gibt einige Dinge, die
|
||||||
|
verbesserungswürdig sind (diese gerne in den Kommentaren vermerken). Der/die Wochenteamer:in
|
||||||
|
ist aber nicht negativ aufgefallen.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="whitespace-nowrap">
|
||||||
|
2 Punkte
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
Der/die Wocheteamer:in hat keinen guten Job geleistet. Der Einsatz hat das Team eher belastet,
|
||||||
|
als es zu unterstützen. Der/die Wochenteamer:in bekommt noch eine Chance sich zu beweisen
|
||||||
|
(hierfür gerne ein schriftliches Feedback im Kommentarfeld hinterlassen).
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="whitespace-nowrap">
|
||||||
|
1 Punkt
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
Der/die Wochenteamer:in hat einen schlechten Job erledigt, ist Team und/oder Gästen negativ
|
||||||
|
aufgefallen und soll keine weiteren Einsätze erhalten.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
@@ -51,59 +51,7 @@
|
|||||||
{{ form_end(form) }}
|
{{ form_end(form) }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-lg font-bold pb-2">
|
{% include '_partials/_feedback_rating_scale.html.twig' %}
|
||||||
Bewertungsskala
|
|
||||||
</h2>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
5 Punkte
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wochenteamer:in hat hervorragende Arbeit geleistet und ist beim Team und den Gästen
|
|
||||||
sehr gut angekommen, es gibt nichts auszusetzen.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
4 Punkte
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wochenteamer:in hat einen sehr guten Job geleistet. Wenn es etwas zu beanstanden oder
|
|
||||||
Ideen zur Verbesserung gibt, dann sind es nur Kleinigkeiten (diese gerne in den Kommentar
|
|
||||||
schreiben).
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
3 Punkte
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wochenteamer:in hat einen ganz guten Job erledigt. Es gibt einige Dinge, die
|
|
||||||
verbesserungswürdig sind (diese gerne in den Kommentaren vermerken). Der/die Wochenteamer:in
|
|
||||||
ist aber nicht negativ aufgefallen.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
2 Punkte
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wocheteamer:in hat keinen guten Job geleistet. Der Einsatz hat das Team eher belastet,
|
|
||||||
als es zu unterstützen. Der/die Wochenteamer:in bekommt noch eine Chance sich zu beweisen
|
|
||||||
(hierfür gerne ein schriftliches Feedback im Kommentarfeld hinterlassen).
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
1 Punkt
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wochenteamer:in hat einen schlechten Job erledigt, ist Team und/oder Gästen negativ
|
|
||||||
aufgefallen und soll keine weiteren Einsätze erhalten.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -13,6 +13,11 @@
|
|||||||
<div>
|
<div>
|
||||||
{{ form_start(form) }}
|
{{ form_start(form) }}
|
||||||
<div class="flex flex-col divide-y divide-gray-200">
|
<div class="flex flex-col divide-y divide-gray-200">
|
||||||
|
{% if form.author is defined %}
|
||||||
|
<div class="py-4">
|
||||||
|
{{ form_row(form.author) }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% for child in form.ratings.children %}
|
{% for child in form.ratings.children %}
|
||||||
<div class="grid grid-cols-4 gap-x-4 items-start py-4">
|
<div class="grid grid-cols-4 gap-x-4 items-start py-4">
|
||||||
<h2 class="col-span-3 text-lg font-bold">
|
<h2 class="col-span-3 text-lg font-bold">
|
||||||
@@ -35,59 +40,7 @@
|
|||||||
{{ form_end(form) }}
|
{{ form_end(form) }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-lg font-bold pb-2">
|
{% include '_partials/_feedback_rating_scale.html.twig' %}
|
||||||
Bewertungsskala
|
|
||||||
</h2>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
5 Punkte
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wochenteamer:in hat hervorragende Arbeit geleistet und ist beim Team und den Gästen
|
|
||||||
sehr gut angekommen, es gibt nichts auszusetzen.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
4 Punkte
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wochenteamer:in hat einen sehr guten Job geleistet. Wenn es etwas zu beanstanden oder
|
|
||||||
Ideen zur Verbesserung gibt, dann sind es nur Kleinigkeiten (diese gerne in den Kommentar
|
|
||||||
schreiben).
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
3 Punkte
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wochenteamer:in hat einen ganz guten Job erledigt. Es gibt einige Dinge, die
|
|
||||||
verbesserungswürdig sind (diese gerne in den Kommentaren vermerken). Der/die Wochenteamer:in
|
|
||||||
ist aber nicht negativ aufgefallen.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
2 Punkte
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wocheteamer:in hat keinen guten Job geleistet. Der Einsatz hat das Team eher belastet,
|
|
||||||
als es zu unterstützen. Der/die Wochenteamer:in bekommt noch eine Chance sich zu beweisen
|
|
||||||
(hierfür gerne ein schriftliches Feedback im Kommentarfeld hinterlassen).
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="whitespace-nowrap">
|
|
||||||
1 Punkt
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
Der/die Wochenteamer:in hat einen schlechten Job erledigt, ist Team und/oder Gästen negativ
|
|
||||||
aufgefallen und soll keine weiteren Einsätze erhalten.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user