Feat: Add popup window to display teamer info per application

This commit is contained in:
Björn Fromme
2023-10-19 15:49:26 +02:00
parent 585f86e45f
commit 67cc7bf4ed
8 changed files with 107 additions and 20 deletions
@@ -0,0 +1,23 @@
<?php
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\Routing\Annotation\Route;
class InfoController extends AbstractController
{
#[Route('/admin/application/info/{uuid}', name: 'app_admin_application_info')]
public function index(Application $application): JsonResponse
{
$response = new AjaxModalResponseDto();
$response->setContent($this->renderView('admin/application/info.html.twig', [
'application' => $application,
]));
return $this->json($response);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Controller\Admin\Teamer;
use App\Entity\Teamer;
use App\Model\AjaxModalResponseDto;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
class InfoController extends AbstractController
{
#[Route('/admin/teamer/info/{uuid}', name: 'app_admin_teamer_info')]
public function index(Teamer $teamer): JsonResponse
{
$response = new AjaxModalResponseDto();
return $this->json($response);
}
}
+6 -2
View File
@@ -5,7 +5,9 @@ namespace App\Controller\Common;
use App\Entity\Upload; use App\Entity\Upload;
use App\Service\Upload\UploadHandler; use App\Service\Upload\UploadHandler;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -17,11 +19,13 @@ class DownloadController extends AbstractController
#[Route('/download/{uuid}', name: 'app_common_download')] #[Route('/download/{uuid}', name: 'app_common_download')]
#[IsGranted('DOWNLOAD', subject: 'upload')] #[IsGranted('DOWNLOAD', subject: 'upload')]
public function index(Upload $upload): Response public function index(Upload $upload, Request $request): Response
{ {
$path = $this->uploadHandler->getUploadFilepath($upload); $path = $this->uploadHandler->getUploadFilepath($upload);
$originalFilename = $upload->getOriginalFilename(); $originalFilename = $upload->getOriginalFilename();
$inline = (bool) $request->get('inline');
$disposition = $inline ? ResponseHeaderBag::DISPOSITION_INLINE : ResponseHeaderBag::DISPOSITION_ATTACHMENT;
return $this->file($path, $originalFilename); return $this->file($path, $originalFilename, $disposition);
} }
} }
+2 -2
View File
@@ -129,7 +129,7 @@ class Application implements TimestampableEntityInterface
return $teamer->hasPickup($pickupId); return $teamer->hasPickup($pickupId);
} }
public function getCompletedTrainingsCount(): int public function matchesRequiredTrainings(): bool
{ {
$count = 0; $count = 0;
$requiredTrainings = $this->getAssignment()->getJobProfile()->getRequiredTrainings(); $requiredTrainings = $this->getAssignment()->getJobProfile()->getRequiredTrainings();
@@ -141,6 +141,6 @@ class Application implements TimestampableEntityInterface
} }
} }
return $count; return $count === $requiredTrainings->count();
} }
} }
@@ -1,24 +1,24 @@
<ul class="list-disc pl-4 pb-4"> <ul class="pb-8 divide-y divide-gray-200">
{% if assignment.pickup and assignment.effectivePickupDate %} {% if assignment.pickup and assignment.effectivePickupDate %}
<li> <li class="py-2">
<div class="flex items-center space-x-2"> <div class="flex items-center justify-between">
<span>Busbegleitung ab {{ assignment.pickup|bpn_pickup_label }} am {{ assignment.effectivePickupDate|date('d.m.Y') }}</span> <span class="flex-1">Busbegleitung {{ assignment.pickup|bpn_pickup_label }} am {{ assignment.effectivePickupDate|date('d.m.Y') }}</span>
{% if teamer.hasPickup(assignment.pickup) %} {% if teamer.hasPickup(assignment.pickup) %}
{{ icon('check', 'w-5 h-5 text-emerald-500') }} {{ icon('check', 'w-5 h-5 text-green-500 shrink-0') }}
{% else %} {% else %}
{{ icon('close', 'w-5 h-5 text-red-500') }} {{ icon('close', 'w-5 h-5 text-red-500 shrink-0') }}
{% endif %} {% endif %}
</div> </div>
</li> </li>
{% endif %} {% endif %}
{% for training in assignment.jobProfile.requiredTrainings %} {% for training in assignment.jobProfile.requiredTrainings %}
<li> <li class="py-2">
<div class="flex items-center space-x-2"> <div class="flex items-center justify-between">
<span>{{ training.name }} absolviert</span> <span class="flex-1">{{ training.name }} absolviert</span>
{% if teamer.trainingAttendance(training) %} {% if teamer.trainingAttendance(training) %}
{{ icon('check', 'w-5 h-5 text-emerald-500') }} {{ icon('check', 'w-5 h-5 text-green-500 shrink-0') }}
{% else %} {% else %}
{{ icon('close', 'w-5 h-5 text-red-500') }} {{ icon('close', 'w-5 h-5 text-red-500 shrink-0') }}
{% endif %} {% endif %}
</div> </div>
</li> </li>
+11 -3
View File
@@ -64,7 +64,15 @@
</a> </a>
</td> </td>
<td> <td>
<div class="flex items-center justify-end space-x-1"> <div class="flex items-center justify-end space-x-1"
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': 'Bewerber:innen-Info',
'url': path('app_admin_application_info', { 'uuid': application.uuid })
}) }}>
{% if assignment.pickup %} {% if assignment.pickup %}
{% if application.matchesPickup %} {% if application.matchesPickup %}
{{ icon('bus', 'w-5 h-5 text-green-500 shrink-0') }} {{ icon('bus', 'w-5 h-5 text-green-500 shrink-0') }}
@@ -73,8 +81,8 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% set requiredTrainingsCount = assignment.jobProfile.requiredTrainings|length %} {% set requiredTrainingsCount = assignment.jobProfile.requiredTrainings|length %}
{% if requiredTrainingsCount > 0 %} {% if not application.matchesRequiredTrainings %}
<span>{{ application.completedTrainingsCount }}/{{ requiredTrainingsCount }}</span> {{ icon('alert', 'w-5 h-5 text-red-500 shrink-0') }}
{% endif %} {% endif %}
</div> </div>
</td> </td>
@@ -0,0 +1,31 @@
<h3 class="text-xl font-bold pb-4">
{{ application.teamer }}
</h3>
{% 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>
+2 -1
View File
@@ -71,7 +71,8 @@
{{ icon('edit') }} {{ icon('edit') }}
</button> </button>
{% endif %} {% endif %}
<a href="{{ path('app_common_download', { 'uuid': upload.uuid }) }}" <a href="{{ path('app_common_download', { 'uuid': upload.uuid, 'inline': true }) }}"
target="_blank"
title="Download"> title="Download">
{{ icon('download') }} {{ icon('download') }}
</a> </a>