feat: integrate with htmx

This commit is contained in:
Björn Fromme
2024-02-07 10:15:59 +01:00
parent 4d1799ca49
commit 1e572606f8
154 changed files with 1447 additions and 1461 deletions
+1
View File
@@ -1,3 +1,4 @@
import 'htmx.org';
import './bootstrap.js';
/*
* Welcome to your app's main JavaScript file!
@@ -1,86 +0,0 @@
import { Controller } from '@hotwired/stimulus'
import { useFetch } from '../mixins/use_fetch'
export default class extends Controller {
static targets = [ 'title', 'content', 'spinner' ]
static values = { loading: Boolean }
connect() {
useFetch(this)
}
show({ title, url }) {
this.titleTarget.innerHTML = title
this.element.classList.remove('hidden')
this.loadContent(url)
}
hide() {
this.element.classList.add('hidden')
}
loadContent(url) {
this.loadingValue = true
fetch(url, this.getInitObject())
.then(this.checkStatus)
.then(this.parseJSON)
.then(response => {
this.handleResponse(response)
})
.catch(error => {
this.handleResponse(this.createErrorResponse(error))
})
.finally(() => {
this.loadingValue = false
})
}
submitForm(event) {
event.preventDefault()
this.loadingValue = true
const form = event.target
const formData = new FormData(form)
formData.append(event.submitter.name, event.submitter.value)
fetch(form.action, this.getInitObject('post', formData))
.then(this.checkStatus)
.then(this.parseJSON)
.then(response => {
this.handleResponse(response)
})
.catch(error => {
this.handleResponse(this.createErrorResponse(error))
})
.finally(() => {
this.loadingValue = false
})
}
handleResponse(modalResponse) {
if (modalResponse.redirect) {
window.location = modalResponse.redirect
return
}
if (true === modalResponse.close) {
this.element.classList.add('hidden')
return
}
this.contentTarget.innerHTML = modalResponse.content
}
createErrorResponse(error) {
return {
close: false,
redirect: null,
content: error.message,
}
}
loadingValueChanged() {
this.spinnerTarget.classList.toggle('hidden', false === this.loadingValue)
this.contentTarget.classList.toggle('hidden', true === this.loadingValue)
}
}
@@ -1,17 +0,0 @@
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
static targets = [ 'form', 'title', 'content' ]
show({ targetUrl, title, content }) {
this.formTarget.action = targetUrl
this.titleTarget.innerText = title
this.contentTarget.innerHTML = content
this.element.classList.remove('hidden')
}
hide() {
this.element.classList.add('hidden')
}
}
@@ -1,35 +0,0 @@
import { Controller } from '@hotwired/stimulus'
import { useFetch } from '../mixins/use_fetch'
export default class extends Controller {
static targets = [ 'form', 'container', 'spinner' ]
static values = { url: String, loading: Boolean }
connect() {
useFetch(this)
}
update() {
this.loadingValue = true
const formData = new FormData(this.formTarget)
fetch(this.urlValue, { method: 'POST', body: formData })
.then(this.checkStatus)
.then(this.parseHTML)
.then(response => {
this.containerTarget.innerHTML = response
})
.catch(error => {
})
.finally(() => {
this.loadingValue = false
})
}
loadingValueChanged(loading) {
if (this.hasSpinnerTarget) {
this.spinnerTarget.classList.toggle('hidden', false === loading)
}
}
}
@@ -1,13 +0,0 @@
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
static outlets = [ 'confirmation-modal', 'ajax-modal' ]
confirmation({ params: { title, targetUrl, content } }) {
this.confirmationModalOutlet.show({ title, targetUrl, content })
}
ajax({ params: { title, url } }) {
this.ajaxModalOutlet.show({ title, url })
}
}
+7
View File
@@ -0,0 +1,7 @@
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
close() {
this.element.remove()
}
}
+10
View File
@@ -30,3 +30,13 @@
font-weight: 900;
src: url('../fonts/lato-v24-latin-900.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
.htmx-indicator{
@apply invisible;
}
.htmx-request .htmx-indicator{
@apply visible;
}
.htmx-request.htmx-indicator{
@apply visible;
}
+2 -1
View File
@@ -1,5 +1,6 @@
.btn {
@apply inline-flex justify-center rounded-lg text-sm uppercase font-semibold py-2.5 px-4 bg-primary text-white hover:bg-primary/80 shadow-md;
@apply inline-flex space-x-1 justify-center rounded-lg text-sm uppercase font-semibold py-2.5 px-4;
@apply bg-primary text-white hover:bg-primary/80 shadow-md;
}
.btn--small {
+6
View File
@@ -7,6 +7,7 @@
"name": "myep-team",
"license": "UNLICENSED",
"dependencies": {
"htmx.org": "^1.9.10",
"sortablejs": "^1.15.0"
},
"devDependencies": {
@@ -5360,6 +5361,11 @@
"entities": "^2.0.0"
}
},
"node_modules/htmx.org": {
"version": "1.9.10",
"resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-1.9.10.tgz",
"integrity": "sha512-UgchasltTCrTuU2DQLom3ohHrBvwr7OqpwyAVJ9VxtNBng4XKkVsqrv0Qr3srqvM9ZNI3f1MmvVQQqK7KW/bTA=="
},
"node_modules/http-deceiver": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+1
View File
@@ -36,6 +36,7 @@
"mjml": "mjml assets/mjml/layout.mjml -o templates/email/layout.html.twig"
},
"dependencies": {
"htmx.org": "^1.9.10",
"sortablejs": "^1.15.0"
}
}
@@ -5,9 +5,11 @@ namespace App\Controller\Admin\Application;
use App\Entity\Application;
use App\Entity\Disposition;
use App\Event\DispositionCreatedEvent;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -25,24 +27,32 @@ class DisposeController extends AbstractController
#[Route('/admin/application/dispose/{uuid}', name: 'app_admin_application_dispose')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
#[IsGranted('DISPOSE', subject: 'application')]
public function index(Application $application): Response
public function index(Application $application, Request $request): Response
{
$disposition = new Disposition($application);
if (true === $request->isMethod('POST')) {
$disposition = new Disposition($application);
$this->entityManager->persist($disposition);
$this->entityManager->remove($application);
$this->entityManager->flush();
$this->entityManager->persist($disposition);
$this->entityManager->remove($application);
$this->entityManager->flush();
$this->eventDispatcher->dispatch(new DispositionCreatedEvent($disposition), DispositionCreatedEvent::NAME);
$this->eventDispatcher->dispatch(new DispositionCreatedEvent($disposition), DispositionCreatedEvent::NAME);
$this->addFlash('success', 'Teamer:in wurde eingeteilt');
$this->logger->info('Create disposition', [
'disposition_id' => $disposition->getId(),
'teamer' => (string) $application->getTeamer(),
]);
$this->addFlash('success', 'Teamer:in wurde eingeteilt');
$this->logger->info('Create disposition', [
'disposition_id' => $disposition->getId(),
'teamer' => (string) $application->getTeamer(),
]);
return $this->redirectToRoute('app_admin_assignment_detail', [
'uuid' => $application->getAssignment()->getUuid(),
$redirectUrl = $this->generateUrl('app_admin_assignment_detail', [
'uuid' => $application->getAssignment()->getUuid(),
]);
return new HxRedirectResponse($redirectUrl);
}
return $this->render('admin/application/modal_dispose.html.twig', [
'application' => $application,
]);
}
}
@@ -3,21 +3,17 @@
namespace App\Controller\Admin\Application;
use App\Entity\Application;
use App\Model\AjaxModalResponseDto;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class InfoController extends AbstractController
{
#[Route('/admin/application/info/{uuid}', name: 'app_admin_application_info')]
public function index(Application $application): JsonResponse
public function index(Application $application): Response
{
$response = new AjaxModalResponseDto();
$response->setContent($this->renderView('admin/application/info.html.twig', [
return $this->render('admin/application/modal_info.html.twig', [
'application' => $application,
]));
return $this->json($response);
]);
}
}
@@ -5,13 +5,13 @@ namespace App\Controller\Admin\Application;
use App\Entity\Application;
use App\Event\ApplicationStatusEvent;
use App\Form\ApplicationStatusType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use App\Model\ApplicationStatusDto;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
@@ -28,12 +28,10 @@ class StatusController extends AbstractController
#[Route('/admin/application/status/{uuid}', name: 'app_admin_application_status')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
#[IsGranted('STATUS', subject: 'application')]
public function index(Application $application, Request $request): JsonResponse
public function index(Application $application, Request $request): Response
{
$response = new AjaxModalResponseDto();
$formAction = $this->generateUrl('app_admin_application_status', ['uuid' => $application->getUuid()]);
$statusDto = new ApplicationStatusDto($application);
$form = $this->createForm(ApplicationStatusType::class, $statusDto, ['action' => $formAction, 'ajax_submit' => true]);
$form = $this->createForm(ApplicationStatusType::class, $statusDto);
$form->handleRequest($request);
@@ -53,15 +51,13 @@ class StatusController extends AbstractController
'teamer' => (string) $application->getTeamer(),
]);
$response->setCloseAndRedirect($this->generateUrl('app_admin_assignment_detail', [
return new HxRedirectResponse($this->generateUrl('app_admin_assignment_detail', [
'uuid' => $application->getAssignment()->getUuid(),
]));
} else {
$response->setContent($this->renderView('admin/application/status.html.twig', [
'form' => $form,
]));
}
return $this->json($response);
return $this->render('admin/application/modal_status.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -30,7 +30,13 @@ class CreateController extends AbstractController
$assignment = new Assignment();
$assignment->setOwner($user);
$form = $this->createForm(AssignmentType::class, $assignment);
$form = $this->createForm(
AssignmentType::class,
$assignment,
[
'pickup_form_url' => $this->generateUrl('app_admin_assignment_pickup_form'),
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -49,7 +55,7 @@ class CreateController extends AbstractController
}
return $this->render('admin/assignment/create.html.twig', [
'form' => $form,
'form' => $form->createView(),
]);
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\Assignment;
use App\Entity\Assignment;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -20,19 +22,25 @@ class DeleteController extends AbstractController
#[Route('/admin/assignment/delete/{uuid}', name: 'app_admin_assignment_delete')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Assignment $assignment): Response
public function index(Assignment $assignment, Request $request): Response
{
$assignment->setDeleted();
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$assignment->setDeleted();
$this->entityManager->flush();
$this->logger->info('Delete assignment', [
'assignment_id' => $assignment->getId(),
'destination' => (string) $assignment->getDestination(),
'job_profile' => $assignment->getJobProfile()->getName(),
$this->logger->info('Delete assignment', [
'assignment_id' => $assignment->getId(),
'destination' => (string) $assignment->getDestination(),
'job_profile' => $assignment->getJobProfile()->getName(),
]);
$this->addFlash('success', 'Der Einsatz wurde gelöscht');
return new HxRedirectResponse($this->generateUrl('app_admin_assignment_index'));
}
return $this->render('admin/assignment/modal_delete.html.twig', [
'assignment' => $assignment,
]);
$this->addFlash('success', 'Der Einsatz wurde gelöscht');
return $this->redirectToRoute('app_admin_assignment_index');
}
}
@@ -26,7 +26,13 @@ class DuplicateController extends AbstractController
{
$copy = Assignment::duplicate($assignment);
$form = $this->createForm(AssignmentType::class, $copy);
$form = $this->createForm(
AssignmentType::class,
$copy,
[
'pickup_form_url' => $this->generateUrl('app_admin_assignment_pickup_form'),
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -48,7 +54,7 @@ class DuplicateController extends AbstractController
}
return $this->render('admin/assignment/duplicate.html.twig', [
'form' => $form,
'form' => $form->createView(),
]);
}
}
@@ -24,7 +24,13 @@ class EditController extends AbstractController
#[IsGranted('EDIT', subject: 'assignment')]
public function index(Assignment $assignment, Request $request): Response
{
$form = $this->createForm(AssignmentType::class, $assignment);
$form = $this->createForm(
AssignmentType::class,
$assignment,
[
'pickup_form_url' => $this->generateUrl('app_admin_assignment_pickup_form'),
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -42,7 +48,7 @@ class EditController extends AbstractController
}
return $this->render('admin/assignment/edit.html.twig', [
'form' => $form,
'form' => $form->createView(),
]);
}
}
@@ -4,13 +4,13 @@ namespace App\Controller\Admin\Disposition;
use App\Entity\Disposition;
use App\Event\DispositionDeletedEvent;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
@@ -27,12 +27,10 @@ class DeleteController extends AbstractController
#[Route('/admin/disposition/delete/{uuid}', name: 'app_admin_disposition_delete')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
#[IsGranted('DELETE', subject: 'disposition')]
public function index(Disposition $disposition, Request $request): JsonResponse
public function index(Disposition $disposition, Request $request): Response
{
$response = new AjaxModalResponseDto();
$formAction = $this->generateUrl('app_admin_disposition_delete', ['uuid' => $disposition->getUuid()]);
$form = $this
->createFormBuilder($disposition, ['action' => $formAction, 'ajax_submit' => true])
->createFormBuilder($disposition)
->add('remarks', TextareaType::class, [
'label' => 'Kommentar/Begründung',
'required' => false,
@@ -56,15 +54,13 @@ class DeleteController extends AbstractController
$this->entityManager->remove($disposition);
$this->entityManager->flush();
$response->setCloseAndRedirect($this->generateUrl('app_admin_assignment_detail', [
return new HxRedirectResponse($this->generateUrl('app_admin_assignment_detail', [
'uuid' => $disposition->getAssignment()->getUuid(),
]));
} else {
$response->setContent($this->renderView('admin/disposition/delete.html.twig', [
'form' => $form,
]));
}
return $this->json($response);
return $this->render('admin/disposition/modal_delete.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -5,14 +5,14 @@ namespace App\Controller\Admin\Document;
use App\Entity\Upload;
use App\Event\DocumentRejectedEvent;
use App\Form\DocumentCheckType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use App\Model\DocumentCheckDto;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Target;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Component\Workflow\WorkflowInterface;
@@ -32,20 +32,10 @@ class CheckController extends AbstractController
#[Route('/admin/document/check/{uuid}', name: 'app_admin_document_check')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
#[IsGranted('CHECK', subject: 'document')]
public function index(Upload $document, Request $request): JsonResponse
public function index(Upload $document, Request $request): Response
{
$response = new AjaxModalResponseDto();
$formData = new DocumentCheckDto($document);
$formAction = $this->generateUrl('app_admin_document_check', ['uuid' => $document->getUuid()]);
$form = $this->createForm(
DocumentCheckType::class,
$formData,
[
'action' => $formAction,
'ajax_submit' => true,
'document_type' => $document->getType(),
]
);
$form = $this->createForm(DocumentCheckType::class, $formData, ['document_type' => $document->getType()]);
$form->handleRequest($request);
@@ -75,16 +65,13 @@ class CheckController extends AbstractController
]);
}
$returnUrl = $this->generateUrl('app_admin_document_index');
$response->setCloseAndRedirect($returnUrl);
} else {
$response->setContent($this->renderView('admin/document/check.html.twig', [
'document' => $document,
'form' => $form,
]));
return new HxRedirectResponse($this->generateUrl('app_admin_document_index'));
}
return $this->json($response);
return $this->render('admin/document/modal_check.html.twig', [
'document' => $document,
'form' => $form->createView(),
]);
}
private function rejectDocument(Upload $document, string $comment = null): void
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\Document;
use App\Entity\Upload;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -21,17 +23,23 @@ class DeleteController extends AbstractController
#[Route('/admin/document/delete/{uuid}', name: 'app_admin_document_delete')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
#[IsGranted('DELETE', subject: 'document')]
public function index(Upload $document): Response
public function index(Upload $document, Request $request): Response
{
$this->entityManager->remove($document);
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$this->entityManager->remove($document);
$this->entityManager->flush();
$this->addFlash('success', 'Das Dokument wurde gelöscht');
$this->logger->info('Delete document', [
'document_filename' => $document->getOriginalFilename(),
'owner' => $document->getOwner()->getFullName(),
$this->addFlash('success', 'Das Dokument wurde gelöscht');
$this->logger->info('Delete document', [
'document_filename' => $document->getOriginalFilename(),
'owner' => $document->getOwner()->getFullName(),
]);
return new HxRedirectResponse($this->generateUrl('app_admin_document_index'));
}
return $this->render('admin/document/modal_delete.html.twig', [
'document' => $document,
]);
return $this->redirectToRoute('app_admin_document_index');
}
}
@@ -4,12 +4,12 @@ namespace App\Controller\Admin\Feedback;
use App\Entity\Feedback;
use App\Form\FeedbackApproveType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -23,11 +23,9 @@ class ApproveController extends AbstractController
#[Route('/admin/feedback/approve/{uuid}', name: 'app_admin_feedback_approve')]
#[IsGranted('ROLE_ADMIN')]
public function index(Feedback $feedback, Request $request): JsonResponse
public function index(Feedback $feedback, Request $request): Response
{
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_feedback_approve', ['uuid' => $feedback->getUuid()]);
$form = $this->createForm(FeedbackApproveType::class, $feedback, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(FeedbackApproveType::class, $feedback);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -39,15 +37,12 @@ class ApproveController extends AbstractController
'feedback_uuid' => $feedback->getUuid(),
]);
$returnUrl = $this->generateUrl('app_admin_index');
$response->setCloseAndRedirect($returnUrl);
} else {
$response->setContent($this->renderView('admin/feedback/approve.html.twig', [
'feedback' => $feedback,
'form' => $form->createView(),
]));
return new HxRedirectResponse($this->generateUrl('app_admin_index'));
}
return $this->json($response);
return $this->render('admin/feedback/modal_approve.html.twig', [
'feedback' => $feedback,
'form' => $form->createView(),
]);
}
}
@@ -4,12 +4,12 @@ namespace App\Controller\Admin\System\Availability;
use App\Entity\Availability;
use App\Form\AvailabilityType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -23,13 +23,10 @@ class CreateController extends AbstractController
#[Route('/admin/system/availability/create', name: 'app_admin_system_availability_create')]
#[IsGranted('ROLE_ADMIN')]
public function index(Request $request): JsonResponse
public function index(Request $request): Response
{
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_system_availability_create');
$availability = new Availability();
$form = $this->createForm(AvailabilityType::class, $availability, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(AvailabilityType::class, $availability);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -42,15 +39,11 @@ class CreateController extends AbstractController
'availability_range' => (string) $availability,
]);
$redirectUrl = $this->generateUrl('app_admin_system_availability_index');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('admin/system/availability/form.html.twig', [
'form' => $form,
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_admin_system_availability_index'));
}
return $this->json($response);
return $this->render('admin/system/availability/modal_create.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\System\Availability;
use App\Entity\Availability;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -20,17 +22,23 @@ class DeleteController extends AbstractController
#[Route('/admin/system/availability/delete/{id}', name: 'app_admin_system_availability_delete', methods: ['POST'])]
#[IsGranted('ROLE_ADMIN')]
public function index(Availability $availability): Response
public function index(Availability $availability, Request $request): Response
{
$availability->setDeleted();
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$availability->setDeleted();
$this->entityManager->flush();
$this->addFlash('success', 'Die Verfügbarkeit wurde gelöscht');
$this->logger->info('Delete availability', [
'availability_id' => $availability->getId(),
'availability_range' => (string) $availability,
$this->addFlash('success', 'Die Verfügbarkeit wurde gelöscht');
$this->logger->info('Delete availability', [
'availability_id' => $availability->getId(),
'availability_range' => (string) $availability,
]);
return new HxRedirectResponse($this->generateUrl('app_admin_system_availability_index'));
}
return $this->render('admin/system/availability/modal_delete.html.twig', [
'availability' => $availability,
]);
return $this->redirectToRoute('app_admin_system_availability_index');
}
}
@@ -4,12 +4,12 @@ namespace App\Controller\Admin\System\Availability;
use App\Entity\Availability;
use App\Form\AvailabilityType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -23,14 +23,11 @@ class DuplicateController extends AbstractController
#[Route('/admin/system/availability/duplicate/{id}', name: 'app_admin_system_availability_duplicate')]
#[IsGranted('ROLE_ADMIN')]
public function index(Availability $availability, Request $request): JsonResponse
public function index(Availability $availability, Request $request): Response
{
$copy = Availability::duplicate($availability);
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_system_availability_duplicate', ['id' => $availability->getId()]);
$form = $this->createForm(AvailabilityType::class, $copy, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(AvailabilityType::class, $copy);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -45,15 +42,11 @@ class DuplicateController extends AbstractController
'duplicate_range' => (string) $copy,
]);
$redirectUrl = $this->generateUrl('app_admin_system_availability_index');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('admin/system/availability/form.html.twig', [
'form' => $form,
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_admin_system_availability_index'));
}
return $this->json($response);
return $this->render('admin/system/availability/modal_duplicate.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -4,12 +4,12 @@ namespace App\Controller\Admin\System\Availability;
use App\Entity\Availability;
use App\Form\AvailabilityType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -23,12 +23,9 @@ class EditController extends AbstractController
#[Route('/admin/system/availability/edit/{id}', name: 'app_admin_system_availability_edit')]
#[IsGranted('ROLE_ADMIN')]
public function index(Availability $availability, Request $request): JsonResponse
public function index(Availability $availability, Request $request): Response
{
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_system_availability_edit', ['id' => $availability->getId()]);
$form = $this->createForm(AvailabilityType::class, $availability, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(AvailabilityType::class, $availability);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -40,15 +37,11 @@ class EditController extends AbstractController
'availability_range' => (string) $availability,
]);
$redirectUrl = $this->generateUrl('app_admin_system_availability_index');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('admin/system/availability/form.html.twig', [
'form' => $form
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_admin_system_availability_index'));
}
return $this->json($response);
return $this->render('admin/system/availability/modal_edit.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -6,13 +6,13 @@ use App\Entity\Contact;
use App\Entity\Upload;
use App\Entity\User;
use App\Form\ContactType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use App\Service\Upload\UploadHandler;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -27,11 +27,9 @@ class CreateController extends AbstractController
#[Route('/admin/system/contact/create', name: 'app_admin_system_contact_create')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Request $request): JsonResponse
public function index(Request $request): Response
{
$response = new AjaxModalResponseDto();
$contact = new Contact();
$formAction = $this->generateUrl('app_admin_system_contact_create');
// Handle upload independently from form submission to avoid issues with failing validation
$uploadSession = $this->uploadHandler->getUploadSession();
@@ -48,15 +46,7 @@ class CreateController extends AbstractController
$this->uploadHandler->destroyUploadSession();
}
$form = $this->createForm(
ContactType::class,
$contact,
[
'action' => $formAction,
'ajax_submit' => true,
'upload_session' => $uploadSession,
]
);
$form = $this->createForm(ContactType::class, $contact, ['upload_session' => $uploadSession]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -68,13 +58,11 @@ class CreateController extends AbstractController
'contact_name' => $contact->getName(),
]);
$response->setCloseAndRedirect($this->generateUrl('app_admin_system_contact_index'));
} else {
$response->setContent($this->renderView('admin/system/contact/create.html.twig', [
'form' => $form,
]));
return new HxRedirectResponse($this->generateUrl('app_admin_system_contact_index'));
}
return $this->json($response);
return $this->render('admin/system/contact/modal_create.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\System\Contact;
use App\Entity\Contact;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -20,17 +22,23 @@ class DeleteController extends AbstractController
#[Route('/admin/system/contact/delete/{id}', name: 'app_admin_system_contact_delete')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Contact $contact): Response
public function index(Contact $contact, Request $request): Response
{
$this->entityManager->remove($contact);
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$this->entityManager->remove($contact);
$this->entityManager->flush();
$this->addFlash('success', 'Die Ansprechperson wurde gelöscht');
$this->logger->info('Delete contact', [
'contact_id' => $contact->getId(),
'contact_name' => $contact->getName(),
$this->addFlash('success', 'Die Ansprechperson wurde gelöscht');
$this->logger->info('Delete contact', [
'contact_id' => $contact->getId(),
'contact_name' => $contact->getName(),
]);
return new HxRedirectResponse($this->generateUrl('app_admin_system_contact_index'));
}
return $this->render('admin/system/contact/modal_delete.html.twig', [
'contact' => $contact,
]);
return $this->redirectToRoute('app_admin_system_contact_index');
}
}
@@ -6,13 +6,13 @@ use App\Entity\Contact;
use App\Entity\Upload;
use App\Entity\User;
use App\Form\ContactType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use App\Service\Upload\UploadHandler;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -27,10 +27,8 @@ class EditController extends AbstractController
#[Route('/admin/system/contact/edit/{id}', name: 'app_admin_system_contact_edit')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Contact $contact, Request $request): JsonResponse
public function index(Contact $contact, Request $request): Response
{
$response = new AjaxModalResponseDto();
$formAction = $this->generateUrl('app_admin_system_contact_edit', ['id' => $contact->getId()]);
// Handle upload independently from form submission to avoid issues with failing validation
$uploadSession = $this->uploadHandler->getUploadSession();
if (true === $request->isMethod('POST') && 0 < $uploadSession->getCount()) {
@@ -46,15 +44,7 @@ class EditController extends AbstractController
$this->uploadHandler->destroyUploadSession();
}
$form = $this->createForm(
ContactType::class,
$contact,
[
'action' => $formAction,
'ajax_submit' => true,
'upload_session' => $uploadSession,
]
);
$form = $this->createForm(ContactType::class, $contact, ['upload_session' => $uploadSession]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -65,13 +55,11 @@ class EditController extends AbstractController
'contact_name' => $contact->getName(),
]);
$response->setCloseAndRedirect($this->generateUrl('app_admin_system_contact_index'));
} else {
$response->setContent($this->renderView('admin/system/contact/edit.html.twig', [
'form' => $form,
]));
return new HxRedirectResponse($this->generateUrl('app_admin_system_contact_index'));
}
return $this->json($response);
return $this->render('admin/system/contact/modal_edit.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\System\Document;
use App\Entity\Upload;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -21,17 +23,23 @@ class DeleteController extends AbstractController
#[Route('/admin/system/document/delete/{uuid}', name: 'app_admin_system_document_delete')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
#[IsGranted('DELETE', subject: 'document')]
public function index(Upload $document): Response
public function index(Upload $document, Request $request): Response
{
$this->entityManager->remove($document);
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$this->entityManager->remove($document);
$this->entityManager->flush();
$this->addFlash('success', 'Das Dokument wurde gelöscht');
$this->logger->info('Delete document', [
'document_id' => $document->getId(),
'document_filename' => $document->getOriginalFilename(),
$this->addFlash('success', 'Das Dokument wurde gelöscht');
$this->logger->info('Delete document', [
'document_id' => $document->getId(),
'document_filename' => $document->getOriginalFilename(),
]);
return new HxRedirectResponse($this->generateUrl('app_admin_system_document_index'));
}
return $this->render('admin/system/document/modal_delete.html.twig', [
'document' => $document,
]);
return $this->redirectToRoute('app_admin_system_document_index');
}
}
@@ -3,14 +3,13 @@
namespace App\Controller\Admin\System\Document;
use App\Entity\Upload;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -24,15 +23,12 @@ class EditController extends AbstractController
#[Route('/admin/system/document/edit/{uuid}', name: 'app_admin_system_document_edit')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Upload $upload, Request $request): JsonResponse
public function index(Upload $upload, Request $request): Response
{
$response = new AjaxModalResponseDto();
$formAction = $this->generateUrl('app_admin_system_document_edit', ['uuid' => $upload->getUuid()]);
$nameBefore = $upload->getDisplayName();
$form = $this
->createFormBuilder($upload, ['action' => $formAction, 'ajax_submit' => true])
->createFormBuilder($upload)
->add('displayName', TextType::class, [
'label' => 'angezeigter Name',
'attr' => [
@@ -54,13 +50,11 @@ class EditController extends AbstractController
'document_name_after' => $upload->getDisplayName(),
]);
$response->setCloseAndRedirect($this->generateUrl('app_admin_system_document_index'));
} else {
$response->setContent($this->renderView('admin/system/document/edit.html.twig', [
'form' => $form->createView(),
]));
return new HxRedirectResponse($this->generateUrl('app_admin_system_document_index'));
}
return $this->json($response);
return $this->render('admin/system/document/modal_edit.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -4,13 +4,13 @@ namespace App\Controller\Admin\System\Document;
use App\Entity\Upload;
use App\Entity\User;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use App\Service\Upload\UploadHandler;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -25,7 +25,7 @@ class ReplaceController extends AbstractController
#[Route('/admin/system/document/replace/{uuid}', name: 'app_admin_system_document_replace')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Upload $upload, Request $request): JsonResponse
public function index(Upload $upload, Request $request): Response
{
// Handle upload independently from form submission to avoid issues with failing validation
$uploadSession = $this->uploadHandler->getUploadSession();
@@ -38,7 +38,6 @@ class ReplaceController extends AbstractController
$this->uploadHandler->destroyUploadSession();
}
$response = new AjaxModalResponseDto();
$formAction = $this->generateUrl('app_admin_system_document_replace', ['uuid' => $upload->getUuid()]);
$filenameBefore = $upload->getOriginalFilename();
@@ -57,13 +56,11 @@ class ReplaceController extends AbstractController
'document_filename_after' => $upload->getOriginalFilename(),
]);
$response->setCloseAndRedirect($this->generateUrl('app_admin_system_document_index'));
} else {
$response->setContent($this->renderView('admin/system/document/replace.html.twig', [
'form' => $form->createView(),
]));
return new HxRedirectResponse($this->generateUrl('app_admin_system_document_index'));
}
return $this->json($response);
return $this->render('admin/system/document/modal_replace.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -4,13 +4,13 @@ namespace App\Controller\Admin\System\Document;
use App\Entity\Upload;
use App\Entity\User;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use App\Service\Upload\UploadHandler;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -25,13 +25,10 @@ class UploadController extends AbstractController
#[Route('/admin/system/document/upload', name: 'app_admin_system_document_upload')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Request $request): JsonResponse
public function index(Request $request): Response
{
$response = new AjaxModalResponseDto();
$formAction = $this->generateUrl('app_admin_system_document_upload');
$form = $this
->createFormBuilder(null, ['action' => $formAction, 'ajax_submit' => true])
->createFormBuilder()
->getForm()
;
$form->handleRequest($request);
@@ -53,7 +50,8 @@ class UploadController extends AbstractController
}
if ($form->isSubmitted() && $form->isValid()) {
$this->addFlash('success', 'Das/die Dokument/e wurden hochgeladen');
$count = count($uploadedDocuments);
$this->addFlash('success', $count === 1 ? 'Das Dokument wurde hochgeladen' : 'Die Dokumente wurden hochgeladen');
$loggerContext = [];
foreach ($uploadedDocuments as $document) {
$loggerContext[] = [
@@ -63,13 +61,11 @@ class UploadController extends AbstractController
}
$this->logger->info('Upload document(s)', $loggerContext);
$response->setCloseAndRedirect($this->generateUrl('app_admin_system_document_index'));
} else {
$response->setContent($this->renderView('admin/system/document/upload.html.twig', [
'form' => $form->createView(),
]));
return new HxRedirectResponse($this->generateUrl('app_admin_system_document_index'));
}
return $this->json($response);
return $this->render('admin/system/document/modal_upload.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\System\Faq;
use App\Entity\Faq;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -18,19 +20,25 @@ class DeleteController extends AbstractController
) {
}
#[Route('/admin/system/faq/delete/{id}', name: 'app_admin_system_faq_delete', methods: ['POST'])]
#[Route('/admin/system/faq/delete/{id}', name: 'app_admin_system_faq_delete')]
#[IsGranted('ROLE_ADMIN')]
public function index(Faq $faq): Response
public function index(Faq $faq, Request $request): Response
{
$this->entityManager->remove($faq);
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$this->entityManager->remove($faq);
$this->entityManager->flush();
$this->addFlash('success', 'Der FAQ-Eintrag wurde gelöscht');
$this->logger->info('Delete faq', [
'faq_id' => $faq->getId(),
'faq_question' => $faq->getQuestion(),
$this->addFlash('success', 'Der FAQ-Eintrag wurde gelöscht');
$this->logger->info('Delete faq', [
'faq_id' => $faq->getId(),
'faq_question' => $faq->getQuestion(),
]);
return new HxRedirectResponse($this->generateUrl('app_admin_system_faq_index'));
}
return $this->render('admin/system/faq/modal_delete.html.twig', [
'faq' => $faq,
]);
return $this->redirectToRoute('app_admin_system_faq_index');
}
}
@@ -4,12 +4,12 @@ namespace App\Controller\Admin\System\Fee;
use App\Entity\Fee;
use App\Form\FeeType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -23,13 +23,10 @@ class CreateController extends AbstractController
#[Route('/admin/system/fee/create', name: 'app_admin_system_fee_create')]
#[IsGranted('ROLE_ADMIN')]
public function index(Request $request): JsonResponse
public function index(Request $request): Response
{
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_system_fee_create');
$fee = new Fee();
$form = $this->createForm(FeeType::class, $fee, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(FeeType::class, $fee);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -42,15 +39,11 @@ class CreateController extends AbstractController
'fee_name' => $fee->getNameInternal() ?? $fee->getName(),
]);
$redirectUrl = $this->generateUrl('app_admin_system_fee_index');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('admin/system/fee/form.html.twig', [
'form' => $form
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_admin_system_fee_index'));
}
return $this->json($response);
return $this->render('admin/system/fee/modal_create.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\System\Fee;
use App\Entity\Fee;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -18,19 +20,25 @@ class DeleteController extends AbstractController
) {
}
#[Route('/admin/system/fee/delete/{id}', name: 'app_admin_system_fee_delete', methods: ['POST'])]
#[Route('/admin/system/fee/delete/{id}', name: 'app_admin_system_fee_delete')]
#[IsGranted('ROLE_ADMIN')]
public function index(Fee $fee): Response
public function index(Fee $fee, Request $request): Response
{
$fee->setDeleted();
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$fee->setDeleted();
$this->entityManager->flush();
$this->addFlash('success', 'Das Honorar wurde gelöscht');
$this->logger->info('Delete fee', [
'fee_id' => $fee->getId(),
'fee_name' => $fee->getNameInternal() ?? $fee->getName(),
$this->addFlash('success', 'Das Honorar wurde gelöscht');
$this->logger->info('Delete fee', [
'fee_id' => $fee->getId(),
'fee_name' => $fee->getNameInternal() ?? $fee->getName(),
]);
return new HxRedirectResponse($this->generateUrl('app_admin_system_fee_index'));
}
return $this->render('admin/system/fee/modal_delete.html.twig', [
'fee' => $fee,
]);
return $this->redirectToRoute('app_admin_system_fee_index');
}
}
@@ -4,12 +4,12 @@ namespace App\Controller\Admin\System\Fee;
use App\Entity\Fee;
use App\Form\FeeType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -23,14 +23,10 @@ class DuplicateController extends AbstractController
#[Route('/admin/system/fee/duplicate/{id}', name: 'app_admin_system_fee_duplicate')]
#[IsGranted('ROLE_ADMIN')]
public function index(Fee $fee, Request $request): JsonResponse
public function index(Fee $fee, Request $request): Response
{
$copy = Fee::duplicate($fee);
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_system_fee_duplicate', ['id' => $fee->getId()]);
$form = $this->createForm(FeeType::class, $copy, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(FeeType::class, $copy);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -45,15 +41,11 @@ class DuplicateController extends AbstractController
'duplicate_name' => $copy->getNameInternal() ?? $copy->getName(),
]);
$redirectUrl = $this->generateUrl('app_admin_system_fee_index');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('admin/system/fee/form.html.twig', [
'form' => $form
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_admin_system_fee_index'));
}
return $this->json($response);
return $this->render('admin/system/fee/modal_duplicate.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -4,12 +4,12 @@ namespace App\Controller\Admin\System\Fee;
use App\Entity\Fee;
use App\Form\FeeType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -23,12 +23,9 @@ class EditController extends AbstractController
#[Route('/admin/system/fee/edit/{id}', name: 'app_admin_system_fee_edit')]
#[IsGranted('ROLE_ADMIN')]
public function index(Fee $fee, Request $request): JsonResponse
public function index(Fee $fee, Request $request): Response
{
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_system_fee_edit', ['id' => $fee->getId()]);
$form = $this->createForm(FeeType::class, $fee, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(FeeType::class, $fee);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -40,15 +37,11 @@ class EditController extends AbstractController
'fee_name' => $fee->getNameInternal() ?? $fee->getName(),
]);
$redirectUrl = $this->generateUrl('app_admin_system_fee_index');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('admin/system/fee/form.html.twig', [
'form' => $form
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_admin_system_fee_index'));
}
return $this->json($response);
return $this->render('admin/system/fee/modal_edit.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\System\FeedbackSet;
use App\Entity\FeedbackSet;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -18,20 +20,26 @@ class DeleteController extends AbstractController
) {
}
#[Route('/admin/system/feedback-set/delete/{id}', name: 'app_admin_system_feedback_set_delete', methods: ['POST'])]
#[Route('/admin/system/feedback-set/delete/{id}', name: 'app_admin_system_feedback_set_delete')]
#[IsGranted('ROLE_ADMIN')]
#[IsGranted('DELETE', subject: 'feedbackSet')]
public function index(FeedbackSet $feedbackSet): Response
public function index(FeedbackSet $feedbackSet, Request $request): Response
{
$this->entityManager->remove($feedbackSet);
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$this->entityManager->remove($feedbackSet);
$this->entityManager->flush();
$this->addFlash('success', 'Die Feedback-Vorlage wurde gelöscht');
$this->logger->info('Delete feedback set', [
'feedback_set_id' => $feedbackSet->getId(),
'feedback_set_name' => $feedbackSet->getName(),
$this->addFlash('success', 'Die Feedback-Vorlage wurde gelöscht');
$this->logger->info('Delete feedback set', [
'feedback_set_id' => $feedbackSet->getId(),
'feedback_set_name' => $feedbackSet->getName(),
]);
return new HxRedirectResponse($this->generateUrl('app_admin_system_feedback_set_index'));
}
return $this->render('admin/system/feedback_set/modal_delete.html.twig', [
'feedbackSet' => $feedbackSet,
]);
return $this->redirectToRoute('app_admin_system_feedback_set_index');
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\System\JobProfile;
use App\Entity\JobProfile;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -18,19 +20,25 @@ class DeleteController extends AbstractController
) {
}
#[Route('/admin/system/job-profile/delete/{id}', name: 'app_admin_system_job_profile_delete', methods: ['POST'])]
#[Route('/admin/system/job-profile/delete/{id}', name: 'app_admin_system_job_profile_delete')]
#[IsGranted('ROLE_ADMIN')]
public function index(JobProfile $jobProfile): Response
public function index(JobProfile $jobProfile, Request $request): Response
{
$jobProfile->setDeleted();
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$jobProfile->setDeleted();
$this->entityManager->flush();
$this->addFlash('success', 'Das Job-Profil wurde gelöscht');
$this->logger->info('Delete job-profile', [
'job_profile_id' => $jobProfile->getId(),
'job_profile_name' => $jobProfile->getName(),
$this->addFlash('success', 'Das Job-Profil wurde gelöscht');
$this->logger->info('Delete job-profile', [
'job_profile_id' => $jobProfile->getId(),
'job_profile_name' => $jobProfile->getName(),
]);
return new HxRedirectResponse($this->generateUrl('app_admin_system_job_profile_index'));
}
return $this->render('admin/system/job_profile/modal_delete.html.twig', [
'jobProfile' => $jobProfile,
]);
return $this->redirectToRoute('app_admin_system_job_profile_index');
}
}
@@ -4,12 +4,12 @@ namespace App\Controller\Admin\System\Training;
use App\Entity\Training;
use App\Form\TrainingType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -23,13 +23,10 @@ class CreateController extends AbstractController
#[Route('/admin/system/training/create', name: 'app_admin_system_training_create')]
#[IsGranted('ROLE_ADMIN')]
public function index(Request $request): JsonResponse
public function index(Request $request): Response
{
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_system_training_create');
$training = new Training();
$form = $this->createForm(TrainingType::class, $training, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(TrainingType::class, $training);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -42,15 +39,11 @@ class CreateController extends AbstractController
'training_name' => $training->getName(),
]);
$redirectUrl = $this->generateUrl('app_admin_system_training_index');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('admin/system/training/form.html.twig', [
'form' => $form
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_admin_system_training_index'));
}
return $this->json($response);
return $this->render('admin/system/training/modal_create.hml.twig', [
'form' => $form->createView(),
]);
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\System\Training;
use App\Entity\Training;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -18,19 +20,25 @@ class DeleteController extends AbstractController
) {
}
#[Route('/admin/system/training/delete/{id}', name: 'app_admin_system_training_delete', methods: ['POST'])]
#[Route('/admin/system/training/delete/{id}', name: 'app_admin_system_training_delete')]
#[IsGranted('ROLE_ADMIN')]
public function index(Training $training): Response
public function index(Training $training, Request $request): Response
{
$training->setDeleted();
$this->entityManager->flush();
if (true === $request->isMethod('POST')) {
$training->setDeleted();
$this->entityManager->flush();
$this->addFlash('success', 'Die Fortbildung wurde gelöscht');
$this->logger->info('Delete training', [
'training_id' => $training->getId(),
'training_name' => $training->getName(),
$this->addFlash('success', 'Die Fortbildung wurde gelöscht');
$this->logger->info('Delete training', [
'training_id' => $training->getId(),
'training_name' => $training->getName(),
]);
return new HxRedirectResponse($this->generateUrl('app_admin_system_training_index'));
}
return $this->render('admin/system/training/modal_delete.html.twig', [
'training' => $training,
]);
return $this->redirectToRoute('app_admin_system_training_index');
}
}
@@ -4,12 +4,12 @@ namespace App\Controller\Admin\System\Training;
use App\Entity\Training;
use App\Form\TrainingType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -23,12 +23,9 @@ class EditController extends AbstractController
#[Route('/admin/system/training/edit/{id}', name: 'app_admin_system_training_edit')]
#[IsGranted('ROLE_ADMIN')]
public function index(Training $training, Request $request): JsonResponse
public function index(Training $training, Request $request): Response
{
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_system_training_edit', ['id' => $training->getId()]);
$form = $this->createForm(TrainingType::class, $training, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(TrainingType::class, $training);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -40,15 +37,11 @@ class EditController extends AbstractController
'training_name' => $training->getName(),
]);
$redirectUrl = $this->generateUrl('app_admin_system_training_index');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('admin/system/training/form.html.twig', [
'form' => $form
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_admin_system_training_index'));
}
return $this->json($response);
return $this->render('admin/system/training/modal_edit.hml.twig', [
'form' => $form->createView(),
]);
}
}
@@ -5,6 +5,7 @@ namespace App\Controller\Admin\Teamer\Availability;
use App\Controller\Traits\ReturnUrlTrait;
use App\Entity\Availability;
use App\Entity\Teamer;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
@@ -33,24 +34,30 @@ class DeleteController extends AbstractController
Availability $availability,
Request $request
): Response {
if (null === $availability->getOwner()) {
$teamer->removeAvailability($availability);
} elseif ($teamer === $availability->getOwner()) {
$this->entityManager->remove($availability);
if (true === $request->isMethod('POST')) {
if (null === $availability->getOwner()) {
$teamer->removeAvailability($availability);
} elseif ($teamer === $availability->getOwner()) {
$this->entityManager->remove($availability);
}
$this->entityManager->flush();
$this->addFlash('success', 'Der Zeitraum wurde entfernt/gelöscht.');
$this->logger->info('Delete teamer availability', [
'availability_id' => $availability->getId(),
'availability_range' => (string) $availability,
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
]);
$redirectUrl = $this->getReturnUrl($request, 'app_admin_teamer_profile', ['uuid' => $teamer->getUuid()]);
return new HxRedirectResponse($redirectUrl);
}
$this->entityManager->flush();
$this->addFlash('success', 'Der Zeitraum wurde entfernt/gelöscht.');
$this->logger->info('Delete teamer availability', [
'availability_id' => $availability->getId(),
'availability_range' => (string) $availability,
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
return $this->render('admin/teamer/availability/modal_delete.html.twig', [
'availability' => $availability,
]);
$redirectUrl = $this->getReturnUrl($request, 'app_admin_teamer_profile', ['uuid' => $teamer->getUuid()]);
return $this->redirect($redirectUrl);
}
}
@@ -1,6 +1,6 @@
<?php
namespace App\Controller\Admin\Teamer;
namespace App\Controller\Admin\Teamer\Availability;
use App\Entity\Teamer;
use App\Service\Teamer\AvailabilityProcessor;
@@ -9,7 +9,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class AvailabilityController extends AbstractController
class IndexController extends AbstractController
{
#[Route('/admin/teamer/availability/{uuid}', name: 'app_admin_teamer_availability')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
@@ -19,7 +19,7 @@ class AvailabilityController extends AbstractController
$availabilities = $teamer->getAvailabilities()->toArray();
$groupedAvailabilities = $processor->groupRecords($availabilities);
return $this->render('admin/teamer/availability.html.twig', [
return $this->render('admin/teamer/availability/index.html.twig', [
'teamer' => $teamer,
'groupedAvailabilities' => $groupedAvailabilities,
]);
@@ -3,10 +3,9 @@
namespace App\Controller\Admin\Teamer;
use App\Entity\Teamer;
use App\Model\AjaxModalResponseDto;
use App\Repository\DispositionRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class InfoController extends AbstractController
@@ -15,16 +14,13 @@ class InfoController extends AbstractController
{}
#[Route('/admin/teamer/info/{uuid}', name: 'app_admin_teamer_info')]
public function index(Teamer $teamer): JsonResponse
public function index(Teamer $teamer): Response
{
$recentDispositions = $this->dispositionRepository->findRecentDispositionsByTeamer($teamer);
$response = new AjaxModalResponseDto();
$response->setContent($this->renderView('admin/teamer/info.html.twig', [
return $this->render('admin/teamer/modal_info.html.twig', [
'teamer' => $teamer,
'recentDispositions' => $recentDispositions,
]));
return $this->json($response);
]);
}
}
@@ -6,14 +6,13 @@ use App\Entity\Teamer;
use App\Entity\Training;
use App\Entity\TrainingAttendance;
use App\Form\AbbreviatedDateType;
use App\Form\FeeType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -33,13 +32,7 @@ class CreateController extends AbstractController
#[MapEntity(mapping: ['teamer_id' => 'id'])]
Teamer $teamer,
Request $request
): JsonResponse {
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_admin_teamer_skills_training_attendance_create', [
'training_id' => $training->getId(),
'teamer_id' => $teamer->getId(),
]);
): Response {
$attendance = new TrainingAttendance();
$attendance
->setTeamer($teamer)
@@ -47,7 +40,7 @@ class CreateController extends AbstractController
;
$form = $this
->createFormBuilder($attendance, ['action' => $action, 'ajax_submit' => true])
->createFormBuilder($attendance)
->add('date', AbbreviatedDateType::class, [
'label' => 'Datum',
])
@@ -69,14 +62,12 @@ class CreateController extends AbstractController
]);
$redirectUrl = $this->generateUrl('app_admin_teamer_skills', ['uuid' => $teamer->getUuid()]);
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('admin/teamer/training_attendance/create.html.twig', [
'form' => $form
]);
$response->setContent($content);
return new HxRedirectResponse($redirectUrl);
}
return $this->json($response);
return $this->render('admin/teamer/training_attendance/modal_create.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -3,9 +3,11 @@
namespace App\Controller\Admin\Teamer\TrainingAttendance;
use App\Entity\TrainingAttendance;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -18,24 +20,32 @@ class DeleteController extends AbstractController
) {
}
#[Route('/admin/teamer/skills/training-attendance/delete/{uuid}', name: 'app_admin_teamer_skills_training_attendance_delete', methods: ['POST'])]
#[Route('/admin/teamer/skills/training-attendance/delete/{uuid}', name: 'app_admin_teamer_skills_training_attendance_delete')]
#[IsGranted('ROLE_ADMIN')]
public function index(TrainingAttendance $attendance): Response
public function index(TrainingAttendance $attendance, Request $request): Response
{
$teamer = $attendance->getTeamer();
if (true === $request->isMethod('POST')) {
$teamer = $attendance->getTeamer();
$this->entityManager->remove($attendance);
$this->entityManager->flush();
$this->entityManager->remove($attendance);
$this->entityManager->flush();
$this->addFlash('success', 'Die Teilnahme an der Fortbilundg wurde gelöscht');
$this->logger->info('Delete training attendance', [
'attendance_id' => $attendance->getId(),
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
'training_id' => $attendance->getTraining()->getId(),
'training_name' => $attendance->getTraining()->getName(),
$this->addFlash('success', 'Die Teilnahme an der Fortbilundg wurde gelöscht');
$this->logger->info('Delete training attendance', [
'attendance_id' => $attendance->getId(),
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
'training_id' => $attendance->getTraining()->getId(),
'training_name' => $attendance->getTraining()->getName(),
]);
return new HxRedirectResponse($this->generateUrl('app_admin_teamer_skills', [
'uuid' => $teamer->getUuid(),
]));
}
return $this->render('admin/teamer/training_attendance/modal_delete.html.twig', [
'attendance' => $attendance,
]);
return $this->redirectToRoute('app_admin_teamer_skills', ['uuid' => $teamer->getUuid()]);
}
}
@@ -4,11 +4,10 @@ namespace App\Controller\Common;
use App\Controller\Traits\ReturnUrlTrait;
use App\Form\AssignmentFilterType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use App\Repository\AssignmentRepository;
use App\Service\Common\AssignmentFilterHandler;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
@@ -26,15 +25,11 @@ class AssignmentFilterController extends AbstractController
#[Route('/common/assignment/filter', name: 'app_common_assignment_filter')]
#[IsGranted('ROLE_USER')]
public function index(Request $request): JsonResponse
public function index(Request $request): Response
{
$response = new AjaxModalResponseDto();
$formAction = $this->generateUrl('app_common_assignment_filter', ['r' => $request->query->get('r')]);
$formData = $this->filterHandler->getFilterSettings();
$filterOptions = $this->assignmentRepository->getFilterOptions();
$formOptions = [
'action' => $formAction,
'ajax_submit' => true,
'min_date' => $filterOptions['minDate'],
'max_date' => $filterOptions['maxDate'],
'job_profiles' => $filterOptions['jobProfiles'],
@@ -47,15 +42,14 @@ class AssignmentFilterController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) {
$this->filterHandler->handleRequest($form);
$returnUrl = $this->getReturnUrl($request, 'app_admin_assignment_index');
$response->setCloseAndRedirect($returnUrl);
} else {
$response->setContent($this->renderView('common/assignment_filter.html.twig', [
'filterForm' => $form,
'filterDto' => $form->getData(),
]));
return new HxRedirectResponse($returnUrl);
}
return $this->json($response);
return $this->render('common/modal_assignment_filter.html.twig', [
'filterForm' => $form->createView(),
'filterDto' => $form->getData(),
]);
}
#[Route('/common/assignment/filter/reset', name: 'app_common_assignment_filter_reset')]
@@ -4,11 +4,10 @@ namespace App\Controller\Common;
use App\Controller\Traits\ReturnUrlTrait;
use App\Form\TeamerFilterType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use App\Repository\TeamerRepository;
use App\Service\Common\TeamerFilterHandler;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
@@ -26,29 +25,23 @@ class TeamerFilterController extends AbstractController
#[Route('/common/teamer/filter', name: 'app_common_teamer_filter')]
#[IsGranted('ROLE_USER')]
public function index(Request $request): JsonResponse
public function index(Request $request): Response
{
$response = new AjaxModalResponseDto();
$formAction = $this->generateUrl('app_common_teamer_filter', ['r' => $request->query->get('r')]);
$formData = $this->filterHandler->getFilterSettings();
$form = $this->createForm(TeamerFilterType::class, $formData, [
'action' => $formAction,
'ajax_submit' => true,
]);
$form = $this->createForm(TeamerFilterType::class, $formData);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->filterHandler->handleRequest($form);
$returnUrl = $this->getReturnUrl($request, 'app_admin_teamer_index');
$response->setCloseAndRedirect($returnUrl);
} else {
$response->setContent($this->renderView('common/teamer_filter.html.twig', [
'filterForm' => $form,
'filterDto' => $form->getData(),
]));
return new HxRedirectResponse($returnUrl);
}
return $this->json($response);
return $this->render('common/modal_teamer_filter.html.twig', [
'filterForm' => $form->createView(),
'filterDto' => $form->getData(),
]);
}
#[Route('/common/teamer/filter/reset', name: 'app_common_teamer_filter_reset')]
@@ -5,6 +5,7 @@ namespace App\Controller\Teamer\Application;
use App\Controller\Traits\ReturnUrlTrait;
use App\Entity\Application;
use App\Entity\User;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -27,24 +28,28 @@ class WithdrawController extends AbstractController
#[IsGranted('WITHDRAW', subject: 'application')]
public function index(Application $application, Request $request): Response
{
/** @var User $user */
$user = $this->getUser();
$teamer = $user->getTeamer();
$assignment = $application->getAssignment();
if (true === $request->isMethod('POST')) {
/** @var User $user */
$user = $this->getUser();
$teamer = $user->getTeamer();
$assignment = $application->getAssignment();
$this->entityManager->remove($application);
$this->entityManager->flush();
$this->entityManager->remove($application);
$this->entityManager->flush();
$this->logger->info('Withdraw application', [
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
'application_id' => $application->getId(),
'assignment_id' => $assignment->getId(),
'destination' => (string) $assignment->getDestination(),
$this->logger->info('Withdraw application', [
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
'application_id' => $application->getId(),
'assignment_id' => $assignment->getId(),
'destination' => (string) $assignment->getDestination(),
]);
return new HxRedirectResponse($this->getReturnUrl($request, 'app_teamer_index'));
}
return $this->render('teamer/application/modal_withdraw.html.twig', [
'application' => $application,
]);
$returnUrl = $this->getReturnUrl($request, 'app_teamer_index');
return $this->redirect($returnUrl);
}
}
+4 -8
View File
@@ -3,9 +3,8 @@
namespace App\Controller\Teamer;
use App\Entity\Feedback;
use App\Model\AjaxModalResponseDto;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -13,13 +12,10 @@ class FeedbackController extends AbstractController
{
#[Route('/teamer/feedback/{uuid}', name: 'app_teamer_feedback')]
#[IsGranted('VIEW', subject: 'feedback')]
public function index(Feedback $feedback): JsonResponse
public function index(Feedback $feedback): Response
{
$response = new AjaxModalResponseDto();
$response->setContent($this->renderView('teamer/feedback/index.html.twig', [
return $this->render('teamer/feedback/modal.html.twig', [
'feedback' => $feedback,
]));
return $this->json($response);
]);
}
}
@@ -5,12 +5,12 @@ namespace App\Controller\Teamer\Profile\Availability;
use App\Entity\Availability;
use App\Entity\User;
use App\Form\AvailabilityType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -24,14 +24,11 @@ class CreateController extends AbstractController
#[Route('/teamer/profile/availability/create', name: 'app_teamer_profile_availability_create')]
#[IsGranted('ROLE_TEAMER')]
public function index(Request $request): JsonResponse
public function index(Request $request): Response
{
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_teamer_profile_availability_create');
$availability = new Availability();
$form = $this->createForm(AvailabilityType::class, $availability, ['action' => $action, 'ajax_submit' => true]);
$form = $this->createForm(AvailabilityType::class, $availability);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -53,15 +50,11 @@ class CreateController extends AbstractController
'availability' => (string) $availability,
]);
$redirectUrl = $this->generateUrl('app_teamer_profile_availability_index');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('teamer/profile/availability/create.html.twig', [
'form' => $form,
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_teamer_profile_availability_index'));
}
return $this->json($response);
return $this->render('teamer/profile/availability/modal_create.html.twig', [
'form' => $form->createView(),
]);
}
}
@@ -4,9 +4,11 @@ namespace App\Controller\Teamer\Profile\Availability;
use App\Entity\Availability;
use App\Entity\User;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -21,27 +23,33 @@ class DeleteController extends AbstractController
#[Route('/teamer/profile/availability/delete/{id}', name: 'app_teamer_profile_availability_delete')]
#[IsGranted('DELETE', subject: 'availability')]
public function index(Availability $availability): Response
public function index(Availability $availability, Request $request): Response
{
/** @var User $user */
$user = $this->getUser();
$teamer = $user->getTeamer();
if (true === $request->isMethod('POST')) {
/** @var User $user */
$user = $this->getUser();
$teamer = $user->getTeamer();
if (null === $availability->getOwner()) {
$teamer->removeAvailability($availability);
} elseif ($teamer === $availability->getOwner()) {
$this->entityManager->remove($availability);
if (null === $availability->getOwner()) {
$teamer->removeAvailability($availability);
} elseif ($teamer === $availability->getOwner()) {
$this->entityManager->remove($availability);
}
$this->entityManager->flush();
$this->addFlash('success', 'Der Zeitraum wurde entfernt/gelöscht.');
$this->logger->info('Delete availability', [
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
'availability' => (string) $availability,
]);
return new HxRedirectResponse($this->generateUrl('app_teamer_profile_availability_index'));
}
$this->entityManager->flush();
$this->addFlash('success', 'Der Zeitraum wurde entfernt/gelöscht.');
$this->logger->info('Delete availability', [
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
'availability' => (string) $availability,
return $this->render('teamer/profile/availability/modal_delete.html.twig', [
'availability' => $availability,
]);
return $this->redirectToRoute('app_teamer_profile_availability_index');
}
}
@@ -6,14 +6,14 @@ use App\Entity\License;
use App\Entity\Upload;
use App\Entity\User;
use App\Form\LicenseType;
use App\Model\AjaxModalResponseDto;
use App\Htmx\HxRedirectResponse;
use App\Model\UploadSessionDto;
use App\Service\Upload\UploadHandler;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -28,11 +28,8 @@ class AddController extends AbstractController
#[Route('/teamer/profile/license/add', name: 'app_teamer_profile_license_add')]
#[IsGranted('ROLE_TEAMER')]
public function index(Request $request): JsonResponse
public function index(Request $request): Response
{
$response = new AjaxModalResponseDto();
$action = $this->generateUrl('app_teamer_profile_license_add');
/** @var User $user */
$user = $this->getUser();
$license = new License();
@@ -43,15 +40,7 @@ class AddController extends AbstractController
$this->updateCertificate($user, $license, $uploadSession);
}
$form = $this->createForm(
LicenseType::class,
$license,
[
'action' => $action,
'ajax_submit' => true,
'upload_session' => $uploadSession,
]
);
$form = $this->createForm(LicenseType::class, $license, ['upload_session' => $uploadSession]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -69,16 +58,12 @@ class AddController extends AbstractController
'license_type' => $license->getType(),
]);
$redirectUrl = $this->generateUrl('app_teamer_profile_skills');
$response->setCloseAndRedirect($redirectUrl);
} else {
$content = $this->renderView('teamer/profile/license/add.html.twig', [
'form' => $form,
]);
$response->setContent($content);
return new HxRedirectResponse($this->generateUrl('app_teamer_profile_skills'));
}
return $this->json($response);
return $this->render('teamer/profile/license/modal_add.html.twig', [
'form' => $form->createView(),
]);
}
private function updateCertificate(User $user, License $license, UploadSessionDto $uploadSession): void
@@ -3,9 +3,11 @@
namespace App\Controller\Teamer\Profile\License;
use App\Entity\License;
use App\Htmx\HxRedirectResponse;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -20,20 +22,26 @@ class DeleteController extends AbstractController
#[Route('//teamer/profile/license/delete/{uuid}', name: 'app_teamer_profile_license_delete')]
#[IsGranted('DELETE', subject: 'license')]
public function index(License $license): Response
public function index(License $license, Request $request): Response
{
$teamer = $license->getTeamer();
if (true === $request->isMethod('POST')) {
$teamer = $license->getTeamer();
$this->entityManager->remove($license);
$this->entityManager->flush();
$this->entityManager->remove($license);
$this->entityManager->flush();
$this->addFlash('success', 'Die Lizenz wurde gelöscht.');
$this->logger->info('Delete license', [
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
'license_type' => $license->getType(),
$this->addFlash('success', 'Die Lizenz wurde gelöscht.');
$this->logger->info('Delete license', [
'teamer_id' => $teamer->getId(),
'teamer_name' => (string) $teamer,
'license_type' => $license->getType(),
]);
return new HxRedirectResponse($this->generateUrl('app_teamer_profile_skills'));
}
return $this->render('teamer/profile/license/modal_delete.html.twig', [
'license' => $license,
]);
return $this->redirectToRoute('app_teamer_profile_skills');
}
}
+7 -1
View File
@@ -54,7 +54,12 @@ class AssignmentType extends AbstractType
'label_property' => 'product',
'label_function' => fn(Destination $destination) => (string) $destination,
'endpoint_route' => 'app_admin_autocomplete_destination',
'controller_action' => 'select->form-partial#update',
'attr' => [
'hx-post' => $options['pickup_form_url'],
'hx-trigger' => 'select',
'hx-target' => '#pickup-form',
'hx-swap' => 'innerHTML',
],
])
->add('jobProfile', EntityType::class, [
'label' => 'Jobprofil',
@@ -189,6 +194,7 @@ class AssignmentType extends AbstractType
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'pickup_form_url' => null,
'data_class' => Assignment::class,
'anti_xss' => true,
]);
@@ -1,32 +0,0 @@
<?php
namespace App\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AjaxSubmitExtension extends AbstractTypeExtension
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'ajax_submit' => false,
'ajax_action' => 'ajax-modal#submitForm',
]);
}
public function buildView(FormView $view, FormInterface $form, array $options): void
{
if (true === $options['ajax_submit']) {
$view->vars['attr'] = array_merge($view->vars['attr'], ['data-action' => $options['ajax_action']]);
}
}
public static function getExtendedTypes(): iterable
{
return [FormType::class];
}
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace App\Htmx;
use Symfony\Component\HttpFoundation\Response;
class HxRedirectResponse extends Response
{
public function __construct(string $url)
{
return parent::__construct(null, Response::HTTP_OK, ['HX-Redirect' => $url]);
}
}
-53
View File
@@ -1,53 +0,0 @@
<?php
namespace App\Model;
class AjaxModalResponseDto
{
private string $content;
private string $redirect;
private bool $close = false;
public function getContent(): ?string
{
return $this->content;
}
public function setContent(string $content): self
{
$this->content = $content;
return $this;
}
public function getRedirect(): ?string
{
return $this->redirect;
}
public function setRedirect(string $redirect): self
{
$this->redirect = $redirect;
$this->close = false;
return $this;
}
public function setCloseAndRedirect(string $redirect): self
{
$this->redirect = $redirect;
$this->close = true;
return $this;
}
public function isClose(): bool
{
return $this->close;
}
public function setClose(bool $close): void
{
$this->close = $close;
}
}
+7 -2
View File
@@ -4,6 +4,7 @@ namespace App\Security\Voter;
use App\Entity\Application;
use App\Entity\User;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
@@ -15,6 +16,10 @@ class ApplicationVoter extends Voter
public const DISPOSE = 'DISPOSE';
public const STATUS = 'STATUS';
public function __construct(private readonly Security $security)
{
}
protected function supports(string $attribute, mixed $subject): bool
{
if (!$subject instanceof Application) {
@@ -36,7 +41,7 @@ class ApplicationVoter extends Voter
$adminAttributes = [static::VIEW, static::DELETE, static::DISPOSE, static::STATUS];
$teamerAttributes = [static::VIEW, static::WITHDRAW, static::DELETE, static::STATUS];
if ($user->hasRole('ROLE_ADMINISTRATIVE') && in_array($attribute, $adminAttributes)) {
if ($this->security->isGranted('ROLE_ADMINISTRATIVE') && in_array($attribute, $adminAttributes)) {
$assignment = $application->getAssignment();
return match ($attribute) {
static::VIEW, static::STATUS => Application::STATUS_REJECTED !== $status,
@@ -47,7 +52,7 @@ class ApplicationVoter extends Voter
};
}
if ($user->hasRole('ROLE_TEAMER') && in_array($attribute, $teamerAttributes)) {
if ($this->security->isGranted('ROLE_TEAMER') && in_array($attribute, $teamerAttributes)) {
$teamer = $user->getTeamer();
return match ($attribute) {
static::WITHDRAW => $teamer === $application->getTeamer(),
+8 -4
View File
@@ -7,6 +7,7 @@ use App\Entity\Assignment;
use App\Entity\Disposition;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
@@ -16,8 +17,11 @@ class AssignmentVoter extends Voter
public const EDIT = 'EDIT';
public const APPLY = 'APPLY';
public function __construct(private readonly EntityManagerInterface $entityManager)
{}
public function __construct(
private readonly Security $security,
private readonly EntityManagerInterface $entityManager
) {
}
protected function supports(string $attribute, mixed $subject): bool
{
@@ -40,7 +44,7 @@ class AssignmentVoter extends Voter
// Only users with administrative role may edit assignments
if (static::EDIT === $attribute) {
return in_array('ROLE_ADMINISTRATIVE', $token->getRoleNames());
return $this->security->isGranted('ROLE_ADMINISTRATIVE');
}
// Only allow applications to open assignments
@@ -61,7 +65,7 @@ class AssignmentVoter extends Voter
}
// Only teamers without existing applications may apply to the assignment
if (in_array('ROLE_TEAMER', $token->getRoleNames())) {
if ($this->security->isGranted('ROLE_TEAMER')) {
/** @var User $user */
$user = $token->getUser();
$teamer = $user->getTeamer();
+8 -5
View File
@@ -5,6 +5,7 @@ namespace App\Security\Voter;
use App\BusProNet\DataProvider\HotelDataProvider;
use App\BusProNet\Model\Hotel;
use App\Entity\Disposition;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
@@ -17,8 +18,10 @@ class DispositionVoter extends Voter
public const INVOICE = 'INVOICE';
public const FEEDBACK = 'FEEDBACK';
public function __construct(private readonly HotelDataProvider $hotelDataProvider)
{
public function __construct(
private readonly Security $security,
private readonly HotelDataProvider $hotelDataProvider
) {
}
protected function supports(string $attribute, mixed $subject): bool
@@ -52,12 +55,12 @@ class DispositionVoter extends Voter
private function assertAdministrativeAccess(TokenInterface $token): bool
{
return in_array('ROLE_ADMINISTRATIVE', $token->getRoleNames());
return $this->security->isGranted('ROLE_ADMINISTRATIVE');
}
private function assertHouseManagerAccess(TokenInterface $token, Disposition $disposition): bool
{
if (false === in_array('ROLE_HOUSE_MANAGER', $token->getRoleNames())) {
if (false === $this->security->isGranted('ROLE_HOUSE_MANAGER')) {
return false;
}
@@ -79,7 +82,7 @@ class DispositionVoter extends Voter
private function assertTeamerAccess(TokenInterface $token, Disposition $disposition): bool
{
if (false === in_array('ROLE_TEAMER', $token->getRoleNames())) {
if (false === $this->security->isGranted('ROLE_TEAMER')) {
return false;
}
+6 -1
View File
@@ -4,6 +4,7 @@ namespace App\Security\Voter;
use App\Entity\Upload;
use App\Entity\User;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
@@ -14,6 +15,10 @@ class UploadVoter extends Voter
public const DOWNLOAD = 'DOWNLOAD';
public const CHECK = 'CHECK';
public function __construct(private readonly Security $security)
{
}
protected function supports(string $attribute, mixed $subject): bool
{
if (! $subject instanceof Upload) {
@@ -29,7 +34,7 @@ class UploadVoter extends Voter
$upload = $subject;
// Administrative users have full access
if (true === in_array('ROLE_ADMINISTRATIVE', $token->getRoleNames())) {
if (true === $this->security->isGranted('ROLE_ADMINISTRATIVE')) {
// Only new documents may be checked
if (static::CHECK === $attribute) {
return in_array($upload->getStatus(), [Upload::STATUS_NEW, Upload::STATUS_PENDING]);
-22
View File
@@ -1,22 +0,0 @@
<div id="ajax-modal"
class="fixed inset-0 w-full h-full z-50 hidden"
{{ stimulus_controller('ajax-modal') }}
>
<div class="absolute inset-0 w-full h-full bg-black/80" {{ stimulus_action('ajax-modal', 'hide', 'click') }}></div>
<div class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 px-4 w-full max-w-2xl">
<div class="bg-white p-8 rounded-md">
<div class="flex justify-between pb-4">
<div class="text-2xl font-bold" {{ stimulus_target('ajax-modal', 'title') }}></div>
<button type="button"
class="inline-block"
{{ stimulus_action('ajax-modal', 'hide') }}>
{{ icon('close', 'w-6 h-6')}}
</button>
</div>
<div class="hidden" {{ stimulus_target('ajax-modal', 'content') }}></div>
<div {{ stimulus_target('ajax-modal', 'spinner') }}>
{% include '_partials/_spinner.html.twig' with { 'class': 'w-8 h-8 mx-auto'} %}
</div>
</div>
</div>
</div>
@@ -1,28 +0,0 @@
<div id="confirmation-modal"
class="fixed top-0 left-0 z-50 inset-0 hidden"
{{ stimulus_controller('confirmation-modal') }}
>
<div class="absolute top-0 left-0 inset-0 bg-black/80" {{ stimulus_action('confirmation-modal', 'hide', 'click') }}></div>
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-8 w-full max-w-3xl rounded-md">
<div class="flex justify-between border-b border-gray-200 pb-2 mb-4">
<div class="flex items-center space-x-2">
{{ icon('alert', 'w-8 h-8') }}
<span class="text-xl font-bold" {{ stimulus_target('confirmation-modal', 'title') }}></span>
</div>
<button class="inline-block" {{ stimulus_action('confirmation-modal', 'hide') }}>
{{ icon('close', 'w-8 h-8') }}
</button>
</div>
<form method="post" {{ stimulus_target('confirmation-modal', 'form') }}>
<div {{ stimulus_target('confirmation-modal', 'content') }}></div>
<div class="mt-6 flex items-center justify-between">
<button type="submit" class="btn bg-red-500">
Ja
</button>
<button type="button" class="btn" {{ stimulus_action('confirmation-modal', 'hide') }}>
Abbrechen
</button>
</div>
</form>
</div>
</div>
+4 -6
View File
@@ -56,7 +56,7 @@
</a>
</td>
<td>
{% if assignment.pickup %}
{% if assignment.pickup and assignment.destination.pickup(assignment.pickup) %}
{% set pickup = assignment.destination.pickup(assignment.pickup) %}
<a href="{{ path('app_admin_assignment_detail', { 'uuid': assignment.uuid, 'r': return_url() }) }}">
<span class="whitespace-nowrap">ab {{ pickup.city }}</span>
@@ -77,11 +77,9 @@
role="button"
title="Bewerber:innen-Info anzeigen"
aria-label="Bewerber:innen-Info anzeigen"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', 'click', {
'title': 'Teamer:innen-Info ' ~ application.teamer,
'url': path('app_admin_teamer_info', { 'uuid': application.teamer.uuid })
}) }}>
hx-get="{{ path('app_admin_teamer_info', { 'uuid': application.teamer.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
{% set requirementsMet = true %}
{% if assignment.pickup and not application.matchesPickup %}
{{ icon('bus', 'w-5 h-5 text-red-500 shrink-0') }}
@@ -1,44 +0,0 @@
<div class="flex items-start">
<div class="flex-1 pr-8">
{% include '_partials/_assignment_requirements_info.html.twig' with {
'assignment': application.assignment,
'teamer': application.teamer
} %}
<ul class="pb-8 divide-y divide-gray-200">
{% for type in ['ski', 'snowboard'] %}
<li class="py-2">
<div class="flex items-center justify-between">
<span class="flex-1">{{ type|license_label }}</span>
{% set license = application.teamer.licenseOfType(type) %}
{% if license %}
<div class="flex items-center space-x-2">
<span>{{ license.date|date('m/Y') }}</span>
{% if is_granted('DOWNLOAD', license.certificate) %}
<a href="{{ path('app_common_download', { 'uuid': license.certificate.uuid, 'inline': true }) }}"
target="_blank"
title="Download Nachweis">
{{ icon('download', 'w-4 h-4') }}
</a>
{% endif %}
</div>
{% else %}
{{ icon('minus', 'w-4 h-4') }}
{% endif %}
</div>
</li>
{% endfor %}
</ul>
</div>
<div>
{% set teamer = application.teamer %}
{% if teamer.photo %}
<img src="{{ asset(teamer.photo.filename | imagine_filter('profile')) }}"
class="w-32 h-auto border-2 border-primary"
alt="{{ teamer.firstName }}">
{% else %}
<div class="border-2 border-primary">
{{ icon('user', 'w-32 h-32 text-gray-200') }}
</div>
{% endif %}
</div>
</div>
@@ -0,0 +1,7 @@
{% extends 'htmx_confirmation_modal.html.twig' %}
{% block content %}
<div>
Möchtest du die Bewerbung von {{ application.teamer }} wirklich löschen?
</div>
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_confirmation_modal.html.twig' %}
{% block content %}
<div>
Möchtest du {{ application.teamer }} wirklich einteilen?
</div>
{% endblock %}
@@ -0,0 +1,50 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Teamer:inneninfo {{ application.teamer }}{% endblock %}
{% block content %}
<div class="flex items-start">
<div class="flex-1 pr-8">
{% include '_partials/_assignment_requirements_info.html.twig' with {
'assignment': application.assignment,
'teamer': application.teamer
} %}
<ul class="pb-8 divide-y divide-gray-200">
{% for type in ['ski', 'snowboard'] %}
<li class="py-2">
<div class="flex items-center justify-between">
<span class="flex-1">{{ type|license_label }}</span>
{% set license = application.teamer.licenseOfType(type) %}
{% if license %}
<div class="flex items-center space-x-2">
<span>{{ license.date|date('m/Y') }}</span>
{% if is_granted('DOWNLOAD', license.certificate) %}
<a href="{{ path('app_common_download', { 'uuid': license.certificate.uuid, 'inline': true }) }}"
target="_blank"
title="Download Nachweis">
{{ icon('download', 'w-4 h-4') }}
</a>
{% endif %}
</div>
{% else %}
{{ icon('minus', 'w-4 h-4') }}
{% endif %}
</div>
</li>
{% endfor %}
</ul>
</div>
<div>
{% set teamer = application.teamer %}
{% if teamer.photo %}
<img src="{{ asset(teamer.photo.filename | imagine_filter('profile')) }}"
class="w-32 h-auto border-2 border-primary"
alt="{{ teamer.firstName }}">
{% else %}
<div class="border-2 border-primary">
{{ icon('user', 'w-32 h-32 text-gray-200') }}
</div>
{% endif %}
</div>
</div>
{% endblock %}
@@ -0,0 +1,17 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Bewerbungsstatus bearbeiten{% endblock %}
{% block content %}
{{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }}
<div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.status) }}
{{ form_row(form.comment) }}
{{ form_row(form.commentVisible) }}
</div>
<button type="submit" class="btn">
Aktualisieren
</button>
{{ form_rest(form) }}
{{ form_end(form) }}
{% endblock %}
@@ -1,11 +0,0 @@
{{ form_start(form) }}
<div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.status) }}
{{ form_row(form.comment) }}
{{ form_row(form.commentVisible) }}
</div>
<button type="submit" class="btn">
Aktualisieren
</button>
{{ form_rest(form) }}
{{ form_end(form) }}
+39 -45
View File
@@ -10,52 +10,46 @@
</div>
{% endmacro %}
<div {{ stimulus_controller('form-partial', { 'url': path('app_admin_assignment_pickup_form') }) }}>
{{ form_start(form, { 'attr': { 'data-form-partial-target': 'form' } }) }}
<div class="flex flex-col space-y-4 pb-8">
<div class="grid lg:grid-cols-6 gap-x-4 gap-y-4">
<div class="lg:col-span-3">
{{ form_row(form.destination) }}
</div>
{{ form_row(form.status) }}
{{ form_row(form.availableDispositions) }}
<div>
<h4 class="font-bold pb-2">
{{ form_label(form.showAvailableDispositions) }}
</h4>
{{ form_widget(form.showAvailableDispositions) }}
</div>
{{ form_start(form) }}
<div class="flex flex-col space-y-4 pb-8">
<div class="grid lg:grid-cols-6 gap-x-4 gap-y-4">
<div class="lg:col-span-3">
{{ form_row(form.destination) }}
</div>
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
{{ form_row(form.jobProfile) }}
{{ form_row(form.jobProfileInfo) }}
{{ form_row(form.benefits) }}
{{ form_row(form.contact) }}
</div>
<div class="relative">
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4" {{ stimulus_target('form-partial', 'container') }}>
{% block partial_form %}
{{ form_row(form.pickup) }}
{#{{ form_row(form.pickupDate) }}#}
{% endblock %}
</div>
<div class="absolute top-0 left-0 inset-0 bg-white/90 flex items-center justify-center" {{ stimulus_target('form-partial', 'spinner') }}>
{% include '_partials/_spinner.html.twig' with { 'class': 'w-8 h-8'} %}
</div>
</div>
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
{{ form_row(form.fees) }}
{{ form_row(form.remarks) }}
{{ form_row(form.status) }}
{{ form_row(form.availableDispositions) }}
<div>
<h4 class="font-bold pb-2">
{{ form_label(form.showAvailableDispositions) }}
</h4>
{{ form_widget(form.showAvailableDispositions) }}
</div>
</div>
<div class="flex items-center space-x-2">
<button type="submit" class="btn">
Speichern
</button>
<a href="{{ path('app_admin_assignment_index') }}" class="btn btn--secondary">
Abbrechen
</a>
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
{{ form_row(form.jobProfile) }}
{{ form_row(form.jobProfileInfo) }}
{{ form_row(form.benefits) }}
{{ form_row(form.contact) }}
</div>
{{ form_rest(form) }}
{{ form_end(form) }}
</div>
<div class="relative">
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4" id="pickup-form">
{% block partial_form %}
{{ form_row(form.pickup) }}
{% endblock %}
</div>
</div>
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
{{ form_row(form.fees) }}
{{ form_row(form.remarks) }}
</div>
</div>
<div class="flex items-center space-x-2">
<button type="submit" class="btn">
Speichern
</button>
<a href="{{ path('app_admin_assignment_index') }}" class="btn btn--secondary">
Abbrechen
</a>
</div>
{{ form_rest(form) }}
{{ form_end(form) }}
+26 -33
View File
@@ -39,11 +39,10 @@
<td>
<button type="button"
class="flex items-center space-x-1"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Teamer:inneninfo ' ~ application.teamer,
'url': path('app_admin_application_info', { 'uuid': application.uuid })
}) }}>
title="Teamer:inneninfo {{ application.teamer }}"
hx-get="{{ path('app_admin_application_info', { 'uuid': application.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
<span>{{ application.teamer }}</span>
{{ icon('info', 'w-4 h-4') }}
</button>
@@ -63,34 +62,30 @@
{% if is_granted('DISPOSE', application) %}
<button type="button"
class="text-green-500"
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
{{ stimulus_action('modal-button', 'confirmation', null, {
'title': 'Bist du sicher?',
'content': 'Möchtest du ' ~ application.teamer ~ ' wirklich einteilen?',
'target-url': path('app_admin_application_dispose', { 'uuid': application.uuid })
}) }}>
title="einteilen"
hx-get="{{ path('app_admin_application_dispose', { 'uuid': application.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('check') }}
</button>
{% endif %}
{% if is_granted('STATUS', application) %}
<button type="button"
class="text-primary"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Bewerbungsstatus bearbeiten',
'url': path('app_admin_application_status', { 'uuid': application.uuid })
}) }}>
title="Bewerbungsstatus bearbeiten"
hx-get="{{ path('app_admin_application_status', { 'uuid': application.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('power') }}
</button>
{% endif %}
{% if is_granted('DELETE', application) %}
<button type="button" class="text-red-500"
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
{{ stimulus_action('modal-button', 'confirmation', null, {
'title': 'Bist du sicher?',
'content': 'Möchtest du die Bewerbung von ' ~ application.teamer ~ ' wirklich löschen?',
'target-url': path('app_admin_application_delete', { 'uuid': application.uuid })
}) }}>
<button type="button"
class="text-red-500"
title="Bewerbung löschen"
hx-get="{{ path('app_admin_application_delete', { 'uuid': application.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('delete') }}
</button>
{% endif %}
@@ -134,11 +129,10 @@
<td>
<button type="button"
class="flex items-center space-x-1"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Teamer:inneninfo ' ~ disposition.teamer,
'url': path('app_admin_teamer_info', { 'uuid': disposition.teamer.uuid })
}) }}>
title="Teamer:inneninfo {{ disposition.teamer }}"
hx-get="{{ path('app_admin_teamer_info', { 'uuid': disposition.teamer.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
<span>{{ disposition.teamer }}</span>
{{ icon('info', 'w-4 h-4') }}
</button>
@@ -155,11 +149,10 @@
{% if is_granted('DELETE', disposition) %}
<button type="button"
class="text-red-500"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Einteilung löschen',
'url': path('app_admin_disposition_delete', { 'uuid': disposition.uuid })
}) }}>
title="Einteilung löschen"
hx-get="{{ path('app_admin_disposition_delete', { 'uuid': disposition.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('delete') }}
</button>
{% endif %}
+7 -13
View File
@@ -10,19 +10,16 @@
<div class="flex flex-col items-end space-y-2 md:flex-row md:items-center md:space-x-2 md:space-y-0">
<button type="button"
class="{{ html_classes('btn btn--small', { 'btn--secondary': filterDto.active }) }}"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Einsätze filtern',
'url': path('app_common_assignment_filter', { 'r': return_url() })
}) }}>
<div class="flex items-center space-x-1">
title="Filter"
hx-get="{{ path('app_common_assignment_filter', { 'r': return_url() }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('filter', 'w-4 h-4 shrink-0') }}
{% if filterDto.active %}
<span class="whitespace-nowrap">{{ filterDto.activeFiltersCount }} Filter aktiv</span>
{% else %}
<span>Filter</span>
{% endif %}
</div>
</button>
{% if filterDto.active %}
<a href="{{ path('app_common_assignment_filter_reset', { 'r': return_url() }) }}" class="btn btn--small btn--secondary">
@@ -109,12 +106,9 @@
<div class="flex items-center space-x-1 justify-end">
<button type="button"
class="text-red-500"
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
{{ stimulus_action('modal-button', 'confirmation', null, {
'title': 'Bist du sicher?',
'content': 'Möchtest du den Einsatz wirklich löschen?',
'target-url': path('app_admin_assignment_delete', { 'uuid': assignment.uuid })
}) }}>
hx-get="{{ path('app_admin_assignment_delete', { 'uuid': assignment.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('delete') }}
</button>
<a href="{{ path('app_admin_assignment_duplicate', { 'uuid': assignment.uuid, 'r': return_url() }) }}">
@@ -0,0 +1,7 @@
{% extends 'htmx_confirmation_modal.html.twig' %}
{% block content %}
<div>
Möchtest du den Einsatz <em>{{ assignment.destination.product }}</em> wirklich löschen?
</div>
{% endblock %}
@@ -1,9 +0,0 @@
{{ form_start(form) }}
<div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.remarks) }}
</div>
<button type="submit" class="btn">
Löschen
</button>
{{ form_rest(form) }}
{{ form_end(form) }}
@@ -0,0 +1,15 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Einteilung löschen{% endblock %}
{% block content %}
{{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }}
<div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.remarks) }}
</div>
<button type="submit" class="btn">
Löschen
</button>
{{ form_rest(form) }}
{{ form_end(form) }}
{% endblock %}
-13
View File
@@ -1,13 +0,0 @@
{{ form_start(form) }}
<h2 class="font-bold text-lg pb-4">
{{ ('label.document.type.' ~ document.type)|trans }} {{ document.disposition.teamer }} vom {{ document.createdAt|date('d.m.Y') }}
</h2>
<div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.status) }}
{{ form_row(form.comment) }}
</div>
<button type="submit" class="btn">
Aktualisieren
</button>
{{ form_rest(form) }}
{{ form_end(form) }}
+6 -11
View File
@@ -69,22 +69,17 @@
{% if is_granted('DELETE', upload) %}
<button type="button"
class="text-red-500"
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
{{ stimulus_action('modal-button', 'confirmation', null, {
'title': 'Bist du sicher?',
'content': 'Möchtest du das Dokument wirklich löschen?',
'target-url': path('app_admin_document_delete', { 'uuid': upload.uuid })
}) }}>
hx-get="{{ path('app_admin_document_delete', { 'uuid': upload.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('delete') }}
</button>
{% endif %}
{% if is_granted('CHECK', upload) %}
<button type="button"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Dokumentenstatus bearbeiten',
'url': path('app_admin_document_check', { 'uuid': upload.uuid })
}) }}>
hx-get="{{ path('app_admin_document_check', { 'uuid': upload.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('edit') }}
</button>
{% endif %}
@@ -0,0 +1,19 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Dokumentenstatus bearbeiten{% endblock %}
{% block content %}
{{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }}
<h2 class="font-bold text-lg pb-4">
{{ ('label.document.type.' ~ document.type)|trans }} {{ document.disposition.teamer }} vom {{ document.createdAt|date('d.m.Y') }}
</h2>
<div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.status) }}
{{ form_row(form.comment) }}
</div>
<button type="submit" class="btn">
Aktualisieren
</button>
{{ form_rest(form) }}
{{ form_end(form) }}
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_confirmation_modal.html.twig' %}
{% block content %}
<div>
Möchtest du das Dokument <em>{{ ('label.document.type.' ~ document.type)|trans }}</em> wirklich löschen?
</div>
{% endblock %}
@@ -1,10 +0,0 @@
{{ form_start(form) }}
<div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.comment) }}
{{ form_row(form.commentInternal) }}
</div>
<button type="submit" class="btn">
Speichern und freigeben
</button>
{{ form_rest(form) }}
{{ form_end(form) }}
@@ -0,0 +1,16 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Feedback freigeben{% endblock %}
{% block content %}
{{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }}
<div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.comment) }}
{{ form_row(form.commentInternal) }}
</div>
<button type="submit" class="btn">
Speichern und freigeben
</button>
{{ form_rest(form) }}
{{ form_end(form) }}
{% endblock %}
+6 -8
View File
@@ -127,20 +127,18 @@
{% for feedback in feedbacks %}
<li class="py-2 first:pt-0 last:pb-0">
<button type="button"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Feedback freigeben',
'url': path('app_admin_feedback_approve', { 'uuid': feedback.uuid })
}) }}>
<div class="flex items-center space-x-1">
hx-get="{{ path('app_admin_feedback_approve', { 'uuid': feedback.uuid }) }}"
hx-target="body"
hx-swap="beforeend">
<span class="flex items-center space-x-1">
{{ icon('feedback', 'w-4 h-4 shrink-0') }}
<div class="flex items-center space-x-1 truncate">
<span class="whitespace-nowrap">{{ feedback.teamer }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ feedback.destinationName }}</span>
</div>
</div>
<div class="pl-5 whitespace-nowrap">{{ feedback.jobProfileName }}</div>
</span>
<span class="pl-5 whitespace-nowrap">{{ feedback.jobProfileName }}</span>
</button>
</li>
{% else %}
@@ -1,4 +1,4 @@
{{ form_start(form) }}
{{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }}
<div class="flex flex-col space-y-4 pb-8">
{{ form_row(form.dateFrom) }}
{{ form_row(form.dateTo) }}
@@ -1,11 +0,0 @@
{{ form_start(form) }}
<div class="flex flex-col space-y-4 pb-8">
{{ form_row(form.dateFrom) }}
{{ form_row(form.dateTo) }}
{{ form_row(form.description) }}
</div>
<button type="submit" class="btn">
Speichern
</button>
{{ form_rest(form) }}
{{ form_end(form) }}
@@ -39,28 +39,24 @@
<div class="flex items-center space-x-2 justify-end">
<button type="button"
class="text-red-500"
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
{{ stimulus_action('modal-button', 'confirmation', null, {
'title': 'Bist du sicher?',
'content': 'Möchtest du den Zeitraum wirklich löschen?',
'target-url': path('app_admin_system_availability_delete', { 'id': availability.id })
}) }}>
title="Zeitraum löschen"
hx-get="{{ path('app_admin_system_availability_delete', { 'id': availability.id }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('delete') }}
</button>
<button type="button"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Verfügbarkeit bearbeiten',
'url': path('app_admin_system_availability_edit', { 'id': availability.id })
}) }}>
title="Verfügbarkeit bearbeiten"
hx-get="{{ path('app_admin_system_availability_edit', { 'id': availability.id }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('edit') }}
</button>
<button type="button"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Verfügbarkeit duplizieren',
'url': path('app_admin_system_availability_duplicate', { 'id': availability.id })
}) }}>
title="Verfügbarkeit duplizieren"
hx-get="{{ path('app_admin_system_availability_duplicate', { 'id': availability.id }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('copy') }}
</button>
</div>
@@ -80,11 +76,10 @@
</div>
<button type="button"
class="btn"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Zeitraum hinzufügen',
'url': path('app_admin_system_availability_create')
}) }}>
title="Zeitraum hinzufügen"
hx-get="{{ path('app_admin_system_availability_create') }}"
hx-target="body"
hx-swap="beforeend">
Zeitraum hinzufügen
</button>
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Zeitraum hinzufügen{% endblock %}
{% block content %}
{% include 'admin/system/availability/_form.html.twig' %}
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_confirmation_modal.html.twig' %}
{% block content %}
<div>
Möchtest du den Zeitraum wirklich löschen?
</div>
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Zeitraum duplizieren{% endblock %}
{% block content %}
{% include 'admin/system/availability/_form.html.twig' %}
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Zeitraum bearbeiten{% endblock %}
{% block content %}
{% include 'admin/system/availability/_form.html.twig' %}
{% endblock %}
@@ -1,4 +1,4 @@
{{ form_start(form) }}
{{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }}
<div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.name) }}
{{ form_row(form.email) }}
@@ -1 +0,0 @@
{% include 'admin/system/contact/_form.html.twig' %}
@@ -1 +0,0 @@
{% include 'admin/system/contact/_form.html.twig' %}
+12 -16
View File
@@ -39,20 +39,17 @@
<div class="flex items-center space-x-2 justify-end">
<button type="button"
class="text-red-500"
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
{{ stimulus_action('modal-button', 'confirmation', null, {
'title': 'Bist du sicher?',
'content': 'Möchtest du die Ansprechperson wirklich löschen?',
'target-url': path('app_admin_system_contact_delete', { 'id': contact.id })
}) }}>
title="Ansprechperson löschen"
hx-get="{{ path('app_admin_system_contact_delete', { 'id': contact.id }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('delete') }}
</button>
<button type="button"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Ansprechperson bearbeiten',
'url': path('app_admin_system_contact_edit', { 'id': contact.id })
}) }}>
title="Ansprechperson bearbeiten"
hx-get="{{ path('app_admin_system_contact_edit', { 'id': contact.id }) }}"
hx-target="body"
hx-swap="beforeend">
{{ icon('edit') }}
</button>
</div>
@@ -71,11 +68,10 @@
</div>
<button type="button"
class="btn"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Ansprechperson hinzufügen',
'url': path('app_admin_system_contact_create')
}) }}>
title="Ansprechperson hinzufügen"
hx-get="{{ path('app_admin_system_contact_create') }}"
hx-target="body"
hx-swap="beforeend">
Neu
</button>
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Ansprechperson hinzufügen{% endblock %}
{% block content %}
{% include 'admin/system/contact/_form.html.twig' %}
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_confirmation_modal.html.twig' %}
{% block content %}
<div>
Möchtest du <em>{{ contact }}</em> als Ansprechperson wirklich löschen?
</div>
{% endblock %}
@@ -0,0 +1,7 @@
{% extends 'htmx_modal.html.twig' %}
{% block title %}Ansprechperson bearbeiten{% endblock %}
{% block content %}
{% include 'admin/system/contact/_form.html.twig' %}
{% endblock %}
@@ -1,9 +0,0 @@
{{ form_start(form) }}
<div class="pb-4">
{{ form_row(form.displayName) }}
</div>
<button type="submit" class="btn">
aktualisieren
</button>
{{ form_rest(form) }}
{{ form_end(form) }}

Some files were not shown because too many files have changed in this diff Show More