feat(aufgaben): Aufgaben-Panel auf Ausschreibungs-Detailseite + Sidebar-Link

Aufgaben sind jetzt direkt von der Detailseite erreichbar und anlegbar:
- Aufgaben-Panel mit HTMX-Inline-Formular auf ausschreibung_detail
- Globaler Sidebar-Link /aufgaben/ für ausschreibungsübergreifende Übersicht
- aufgaben-Queryset in ausschreibung_detail-Kontext ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 03:12:23 +02:00
parent f6af101933
commit 9ef6e0950a
3 changed files with 45 additions and 0 deletions

View File

@@ -115,6 +115,10 @@ def ausschreibung_detail(request, pk):
from vergabe_teilnahme.apps.lose.models import Los
a = get_object_or_404(Ausschreibung, pk=pk)
from vergabe_teilnahme.apps.aufgaben.models import Aufgabe as AufgabeModel
aufgaben = AufgabeModel.objects.filter(ausschreibung=a).select_related(
'verantwortlicher', 'los'
).order_by('prioritaet', 'frist')
lose = Los.objects.filter(ausschreibung=a).annotate(
aufgaben_total=Count('aufgaben', distinct=True),
aufgaben_erledigt=Count(
@@ -127,6 +131,7 @@ def ausschreibung_detail(request, pk):
'ausschreibung': a,
'ausschreibung_id': pk,
'lose': lose,
'aufgaben': aufgaben,
'phases': build_phase_nav(a),
'warnungen': get_deadline_warnings(a),
'aufgaben_score': aufgaben_score(Aufgabe.objects.filter(ausschreibung=a)),

View File

@@ -135,6 +135,45 @@
{% endif %}
</div>
<!-- Aufgaben -->
<div class="card mt-6">
<div class="flex items-center justify-between mb-3">
<h2 class="text-sm font-semibold text-slate-700">Aufgaben</h2>
<div class="flex items-center gap-2">
<a href="{% url 'ausschreibungen:aufgaben:liste' ausschreibung.pk %}" class="btn-ghost text-xs">Alle anzeigen</a>
<button class="btn-ghost text-xs"
hx-get="{% url 'ausschreibungen:aufgaben:neu' ausschreibung.pk %}"
hx-target="#aufgaben-form-container"
hx-swap="innerHTML">
+ Aufgabe anlegen
</button>
</div>
</div>
<div id="aufgaben-form-container"></div>
{% if aufgaben %}
<table class="w-full text-sm mt-1">
<thead>
<tr class="border-b border-slate-200 text-left text-xs text-slate-500">
<th class="pb-2 pr-4">Titel</th>
<th class="pb-2 pr-4">Typ</th>
<th class="pb-2 pr-4">Frist</th>
<th class="pb-2 pr-4">Verantwortlicher</th>
<th class="pb-2 pr-4">Status</th>
<th class="pb-2"></th>
</tr>
</thead>
<tbody id="aufgaben-tbody" class="divide-y divide-slate-100">
{% for aufgabe in aufgaben %}
{% include "aufgaben/partials/aufgabe_row.html" %}
{% endfor %}
</tbody>
</table>
{% else %}
<div id="aufgaben-tbody"></div>
<p class="text-sm text-slate-400 mt-1">Noch keine Aufgaben angelegt.</p>
{% endif %}
</div>
<div class="flex gap-3 mt-6">
<a href="{% url 'ausschreibungen:entscheidung' ausschreibung.pk %}" class="btn-ghost text-xs">
Teilnahmeentscheidung

View File

@@ -45,6 +45,7 @@
</div>
</div>
<a href="/aufgaben/" class="sidebar-link">Aufgaben</a>
<a href="/marktbegleiter/" class="sidebar-link">Marktbegleiter</a>
<a href="/feedback/backlog/" class="sidebar-link">Feedback-Backlog</a>