From 5cfeeb57f0a3bf99e19bde9f7fd48bfd8f2e47e6 Mon Sep 17 00:00:00 2001 From: Marijn Doeve Date: Fri, 10 Jul 2026 23:44:41 +0200 Subject: [PATCH] feat: open candidate edit/add forms in modals with dirty-aware dismissal Rename-candidate modal always blocked backdrop-click dismissal via a hardcoded static backdrop; wire it into the existing bo--modal controller so outside clicks/Escape only get blocked once the name field has actually been edited. Also move "Add Candidate" from a full-page navigation into the same turbo-frame modal pattern already used for editing quiz questions, keeping the full-page form as a fallback for non-JS/turbo requests. --- .../Backoffice/SeasonController.php | 14 ++++++-- .../season/_add_candidates_frame.html.twig | 11 ++++++ .../season/tab_candidates.html.twig | 32 ++++++++++++++--- .../Backoffice/SeasonControllerTest.php | 36 +++++++++++++++++++ 4 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 templates/backoffice/season/_add_candidates_frame.html.twig diff --git a/src/Controller/Backoffice/SeasonController.php b/src/Controller/Backoffice/SeasonController.php index ab63bbb..ca0e90c 100644 --- a/src/Controller/Backoffice/SeasonController.php +++ b/src/Controller/Backoffice/SeasonController.php @@ -129,6 +129,8 @@ class SeasonController extends AbstractController )] public function addCandidates(Season $season, Request $request): Response { + $isTurboFrame = $request->headers->has('Turbo-Frame'); + $form = $this->createForm(AddCandidatesFormType::class); $form->handleRequest($request); @@ -140,10 +142,18 @@ class SeasonController extends AbstractController $this->em->flush(); - return $this->redirectToRoute('tvdt_backoffice_season', ['seasonCode' => $season->seasonCode]); + if ($isTurboFrame) { + return new Response(''); + } + + return $this->redirectToRoute('tvdt_backoffice_season_candidates', ['seasonCode' => $season->seasonCode]); } - return $this->render('backoffice/season_add_candidates.html.twig', ['form' => $form, 'season' => $season]); + $template = $isTurboFrame + ? 'backoffice/season/_add_candidates_frame.html.twig' + : 'backoffice/season_add_candidates.html.twig'; + + return $this->render($template, ['form' => $form, 'season' => $season]); } #[IsCsrfTokenValid('rename_candidate')] diff --git a/templates/backoffice/season/_add_candidates_frame.html.twig b/templates/backoffice/season/_add_candidates_frame.html.twig new file mode 100644 index 0000000..ab5898b --- /dev/null +++ b/templates/backoffice/season/_add_candidates_frame.html.twig @@ -0,0 +1,11 @@ + + {{ form_start(form, {attr: {novalidate: 'novalidate'}}) }} + + + {{ form_end(form) }} + diff --git a/templates/backoffice/season/tab_candidates.html.twig b/templates/backoffice/season/tab_candidates.html.twig index 33fab63..6621621 100644 --- a/templates/backoffice/season/tab_candidates.html.twig +++ b/templates/backoffice/season/tab_candidates.html.twig @@ -1,8 +1,10 @@ -
+
- {{ 'Add Candidate'|trans }} +
    {% for candidate in season.candidates %} @@ -17,7 +19,9 @@ title="{{ 'Delete'|trans }}">
-