feat: link ratings widget with feedback list filtered by teamer

addresses #869at5mdu
This commit is contained in:
Björn Fromme
2026-08-24 13:50:07 +02:00
parent 43968e4e7b
commit dfa3e63926
12 changed files with 83 additions and 11 deletions
@@ -2,6 +2,7 @@
namespace App\Controller\Administrative\Feedback;
use App\Entity\Teamer;
use App\Repository\FeedbackRepository;
use App\Service\Common\FeedbackFilterHandler;
use Knp\Component\Pager\PaginatorInterface;
@@ -46,4 +47,15 @@ class IndexController extends AbstractController
'filterDto' => $filterDto,
]);
}
#[Route('/administrative/feedback/teamer/{uuid}', name: 'app_administrative_feedback_index_teamer')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function byTeamer(Teamer $teamer): Response
{
// The link means "show me this teamer's feedback", so previously stored
// criteria must not silently hide any of it.
$this->filterHandler->applyTeamerFilter($teamer);
return $this->redirectToRoute('app_administrative_feedback_index');
}
}
+9
View File
@@ -2,6 +2,7 @@
namespace App\Form;
use App\Entity\Teamer;
use App\Model\FeedbackFilterDto;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -15,6 +16,14 @@ class FeedbackFilterType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('teamer', AutocompleteEntityType::class, [
'label' => 'Teamer',
'required' => false,
'class' => Teamer::class,
'label_property' => 'name',
'label_function' => fn (Teamer $teamer) => (string) $teamer,
'endpoint_route' => 'app_admin_autocomplete_teamer',
])
->add('name', TextType::class, [
'label' => 'Name',
'required' => false,
+15
View File
@@ -2,13 +2,28 @@
namespace App\Model;
use App\Entity\Teamer;
class FeedbackFilterDto extends AbstractFilterDto
{
protected ?Teamer $teamer = null;
protected ?string $name = null;
protected ?\DateTimeImmutable $dateFrom = null;
protected ?\DateTimeImmutable $dateTo = null;
protected ?int $averageRating = null;
public function getTeamer(): ?Teamer
{
return $this->teamer;
}
public function setTeamer(?Teamer $teamer): static
{
$this->teamer = $teamer;
return $this;
}
public function getName(): ?string
{
return $this->name;
+7
View File
@@ -38,6 +38,13 @@ class FeedbackRepository extends ServiceEntityRepository
->innerJoin('teamer.user', 'user')
;
if (null !== $teamer = $filterDto->getTeamer()) {
$qb
->andWhere($qb->expr()->eq('feedback.teamer', ':teamer'))
->setParameter('teamer', $teamer)
;
}
if (null !== $name = $filterDto->getName()) {
$qb
->andWhere($qb->expr()->orX(
@@ -2,6 +2,7 @@
namespace App\Service\Common;
use App\Entity\Teamer;
use App\Model\AbstractFilterDto;
use App\Model\FeedbackFilterDto;
@@ -18,6 +19,15 @@ class FeedbackFilterHandler extends AbstractFilterHandler
return $filterDto;
}
if (isset($data['teamer_id'])) {
$teamer = $this
->entityManager
->getRepository(Teamer::class)
->find($data['teamer_id'])
;
$filterDto->setTeamer($teamer);
}
if (isset($data['name'])) {
$filterDto->setName($data['name']);
}
@@ -34,10 +44,16 @@ class FeedbackFilterHandler extends AbstractFilterHandler
return $filterDto;
}
public function applyTeamerFilter(Teamer $teamer): void
{
$this->saveFilterSettings((new FeedbackFilterDto())->setTeamer($teamer));
}
protected function saveFilterSettings(AbstractFilterDto $filterDto): void
{
/* @var FeedbackFilterDto $filterDto */
$this->getSession()->set($this->namespace, [
'teamer_id' => $filterDto->getTeamer()?->getId(),
'name' => $filterDto->getName(),
'date_from' => $filterDto->getDateFrom(),
'date_to' => $filterDto->getDateTo(),
+2
View File
@@ -2,10 +2,12 @@
namespace App\Twig\Components;
use App\Entity\Teamer;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
#[AsTwigComponent(template: 'components/rating_stars.html.twig')]
class RatingStars
{
public ?int $rating;
public ?Teamer $teamer = null;
}