diff --git a/src/Controller/Admin/Application/DeleteController.php b/src/Controller/Admin/Application/DeleteController.php index a4005a3..50573cb 100644 --- a/src/Controller/Admin/Application/DeleteController.php +++ b/src/Controller/Admin/Application/DeleteController.php @@ -39,6 +39,7 @@ class DeleteController extends AbstractController return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [ 'uuid' => $application->getAssignment()->getUuid(), + 'r' => $request->query->get('r'), ])); } diff --git a/src/Controller/Admin/Application/DisposeController.php b/src/Controller/Admin/Application/DisposeController.php index 3fdc1ac..8dc4de0 100644 --- a/src/Controller/Admin/Application/DisposeController.php +++ b/src/Controller/Admin/Application/DisposeController.php @@ -46,6 +46,7 @@ class DisposeController extends AbstractController $redirectUrl = $this->generateUrl('app_administrative_assignment_detail', [ 'uuid' => $application->getAssignment()->getUuid(), + 'r' => $request->query->get('r'), ]); return new HxRedirectResponse($redirectUrl); diff --git a/src/Controller/Admin/Application/StatusController.php b/src/Controller/Admin/Application/StatusController.php index ee86b0a..c99283f 100644 --- a/src/Controller/Admin/Application/StatusController.php +++ b/src/Controller/Admin/Application/StatusController.php @@ -57,6 +57,7 @@ class StatusController extends AbstractController return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [ 'uuid' => $application->getAssignment()->getUuid(), + 'r' => $request->query->get('r'), ])); } diff --git a/src/Controller/Admin/Disposition/DeleteController.php b/src/Controller/Admin/Disposition/DeleteController.php index cbfdeee..7cf7f7c 100644 --- a/src/Controller/Admin/Disposition/DeleteController.php +++ b/src/Controller/Admin/Disposition/DeleteController.php @@ -53,6 +53,7 @@ class DeleteController extends AbstractController return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [ 'uuid' => $disposition->getAssignment()->getUuid(), + 'r' => $request->query->get('r'), ])); } diff --git a/src/Controller/Admin/Teamer/SkillsController.php b/src/Controller/Admin/Teamer/SkillsController.php index 1fbe788..4d3371d 100644 --- a/src/Controller/Admin/Teamer/SkillsController.php +++ b/src/Controller/Admin/Teamer/SkillsController.php @@ -44,6 +44,7 @@ class SkillsController extends AbstractController return $this->redirectToRoute('app_admin_teamer_skills', [ 'uuid' => $teamer->getUuid(), + 'r' => $request->query->get('r'), ]); } diff --git a/src/Controller/Administrative/Assignment/DuplicateController.php b/src/Controller/Administrative/Assignment/DuplicateController.php index cc23242..15f5707 100644 --- a/src/Controller/Administrative/Assignment/DuplicateController.php +++ b/src/Controller/Administrative/Assignment/DuplicateController.php @@ -55,6 +55,7 @@ class DuplicateController extends AbstractController return $this->redirectToRoute('app_administrative_assignment_edit', [ 'uuid' => $copy->getUuid(), + 'r' => $request->query->get('r'), ]); } diff --git a/src/Controller/Administrative/Disposition/BusProNetSyncToggleController.php b/src/Controller/Administrative/Disposition/BusProNetSyncToggleController.php index f7e20cd..c8710dd 100644 --- a/src/Controller/Administrative/Disposition/BusProNetSyncToggleController.php +++ b/src/Controller/Administrative/Disposition/BusProNetSyncToggleController.php @@ -38,6 +38,7 @@ class BusProNetSyncToggleController extends AbstractController return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [ 'uuid' => $disposition->getAssignment()->getUuid(), + 'r' => $request->query->get('r'), ])); } } diff --git a/src/Controller/Administrative/Disposition/CallOffController.php b/src/Controller/Administrative/Disposition/CallOffController.php index 2899ca6..3f1f314 100644 --- a/src/Controller/Administrative/Disposition/CallOffController.php +++ b/src/Controller/Administrative/Disposition/CallOffController.php @@ -55,6 +55,7 @@ class CallOffController extends AbstractController return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [ 'uuid' => $assignment->getUuid(), + 'r' => $request->query->get('r'), ])); } diff --git a/src/Controller/Administrative/Disposition/DocumentUploadController.php b/src/Controller/Administrative/Disposition/DocumentUploadController.php index 702cc8c..ca46724 100644 --- a/src/Controller/Administrative/Disposition/DocumentUploadController.php +++ b/src/Controller/Administrative/Disposition/DocumentUploadController.php @@ -61,6 +61,7 @@ class DocumentUploadController extends AbstractController return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [ 'uuid' => $disposition->getAssignment()->getUuid(), + 'r' => $request->query->get('r'), ])); } diff --git a/src/Controller/Administrative/Disposition/SpecialAgreementsController.php b/src/Controller/Administrative/Disposition/SpecialAgreementsController.php index f905dcd..90567fa 100644 --- a/src/Controller/Administrative/Disposition/SpecialAgreementsController.php +++ b/src/Controller/Administrative/Disposition/SpecialAgreementsController.php @@ -38,6 +38,7 @@ class SpecialAgreementsController extends AbstractController return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [ 'uuid' => $disposition->getAssignment()->getUuid(), + 'r' => $request->query->get('r'), ])); } diff --git a/src/Controller/Administrative/Teamer/InfoController.php b/src/Controller/Administrative/Teamer/InfoController.php index 2e83c06..44a7476 100644 --- a/src/Controller/Administrative/Teamer/InfoController.php +++ b/src/Controller/Administrative/Teamer/InfoController.php @@ -24,7 +24,13 @@ class InfoController extends AbstractController #[IsGranted(new Expression('is_granted("ROLE_ADMINISTRATIVE") or is_granted("ROLE_HOUSE_MANAGER")'))] public function index(Teamer $teamer, Request $request): Response { - $returnUrl = $this->getReturnUrl($request, 'app_administrative_assignment_index'); + // House managers reach this modal but not the administrative overviews, + // so their fallback has to stay inside their own area. + $defaultReturnUrlRoute = $this->isGranted('ROLE_ADMINISTRATIVE') + ? 'app_administrative_assignment_index' + : 'app_house_manager_index'; + + $returnUrl = $this->getReturnUrl($request, $defaultReturnUrlRoute); $recentDispositions = $this->dispositionRepository->findRecentDispositionsByTeamer($teamer); diff --git a/src/Controller/Teamer/Disposition/DetailController.php b/src/Controller/Teamer/Disposition/DetailController.php index 3c28852..2ae0c28 100644 --- a/src/Controller/Teamer/Disposition/DetailController.php +++ b/src/Controller/Teamer/Disposition/DetailController.php @@ -66,6 +66,7 @@ class DetailController extends AbstractController return $this->redirectToRoute('app_teamer_disposition_detail', [ 'uuid' => $disposition->getUuid(), + 'r' => $request->query->get('r'), ]); } diff --git a/src/Controller/Traits/ReturnUrlTrait.php b/src/Controller/Traits/ReturnUrlTrait.php index 85efaca..b4f56bf 100644 --- a/src/Controller/Traits/ReturnUrlTrait.php +++ b/src/Controller/Traits/ReturnUrlTrait.php @@ -8,9 +8,15 @@ trait ReturnUrlTrait { public function getReturnUrl(Request $request, string $defaultRoute, array $parameters = []): string { - $defaultUrl = $this->generateUrl($defaultRoute, $parameters); + $returnUrl = $request->query->get('r'); - return rawurldecode($request->query->get('r', $defaultUrl)); + // An empty "r" reaches us whenever a link forwards a return url it never got + // itself, it must not be mistaken for a return url pointing at the root. + if (false === is_string($returnUrl) || '' === $returnUrl) { + return $this->generateUrl($defaultRoute, $parameters); + } + + return rawurldecode($returnUrl); } /** diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php index 04035d9..6389e00 100644 --- a/src/Twig/AppExtension.php +++ b/src/Twig/AppExtension.php @@ -32,6 +32,7 @@ class AppExtension extends AbstractExtension new TwigFunction('icon', [AppRuntime::class, 'renderIcon'], ['needs_environment' => true, 'is_safe' => ['html']]), new TwigFunction('is_current_route', [AppRuntime::class, 'isCurrentRoute']), new TwigFunction('return_url', [AppRuntime::class, 'getEncodedReturnUrl']), + new TwigFunction('forwarded_return_url', [AppRuntime::class, 'getForwardedReturnUrl']), new TwigFunction('qa_attribute', [AppRuntime::class, 'renderQaAttribute'], ['is_safe' => ['html']]), new TwigFunction('has_pickup', [AppRuntime::class, 'hasPickup']), ]; diff --git a/src/Twig/AppRuntime.php b/src/Twig/AppRuntime.php index b329cf9..d32b428 100644 --- a/src/Twig/AppRuntime.php +++ b/src/Twig/AppRuntime.php @@ -192,6 +192,21 @@ class AppRuntime implements RuntimeExtensionInterface return rawurlencode($masterRequest->getRequestUri()); } + /** + * Passes the return url of the current page on to the next one. + * + * Used by links that lead deeper into a detail view or trigger an action on it: + * they have to keep pointing back at where the user originally came from instead + * of at the page they sit on. Null when there is nothing to pass on, so that the + * url generator drops the parameter rather than emitting an empty one. + */ + public function getForwardedReturnUrl(): ?string + { + $returnUrl = $this->requestStack->getMainRequest()?->query->get('r'); + + return is_string($returnUrl) && '' !== $returnUrl ? $returnUrl : null; + } + public function renderQaAttribute(string $label, ?string $value = null): string { if ('test' !== $this->environment) { diff --git a/templates/admin/application/index.html.twig b/templates/admin/application/index.html.twig index 76a78cb..876ca74 100644 --- a/templates/admin/application/index.html.twig +++ b/templates/admin/application/index.html.twig @@ -107,7 +107,7 @@ role="button" title="Bewerber:innen-Info anzeigen" aria-label="Bewerber:innen-Info anzeigen" - hx-get="{{ path('app_administrative_teamer_info', { 'uuid': application.teamer.uuid }) }}" + hx-get="{{ path('app_administrative_teamer_info', { 'uuid': application.teamer.uuid, 'r': return_url() }) }}" hx-target="body" hx-swap="beforeend"> {% set requirementsMet = true %} diff --git a/templates/admin/index.html.twig b/templates/admin/index.html.twig index eb3c4cc..c395b59 100644 --- a/templates/admin/index.html.twig +++ b/templates/admin/index.html.twig @@ -41,7 +41,7 @@ {% for disposition in newDispositions %} {% set assignment = disposition.assignment %}