- Aufgabe.erstellt_am für implizite 7-Tage-Fälligkeit - frist_effektiv property; ist_ueberfaellig nutzt sie - AufgabenVerknuepfung (GenericForeignKey) mit HTMX-Panel - ExternalIssue (OneToOne) mit IssueAdapter-ABC und HTMX-Panel - link_registry.py und issue_facade.py als zentrale Registries - 8 neue Tests, 76 gesamt grün Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
99 lines
4.1 KiB
HTML
99 lines
4.1 KiB
HTML
{% extends "base.html" %}
|
|
{% load vergabe_tags %}
|
|
{% block title %}{{ aufgabe.titel }}{% endblock %}
|
|
{% block content %}
|
|
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h1 class="page-title">{{ aufgabe.titel }}</h1>
|
|
<div class="flex gap-2">
|
|
<a href="{% url 'ausschreibungen:aufgaben:bearbeiten' ausschreibung.pk aufgabe.pk %}" class="btn-secondary text-xs">Bearbeiten</a>
|
|
<a href="{% url 'ausschreibungen:aufgaben:loeschen' ausschreibung.pk aufgabe.pk %}" class="btn-ghost text-xs text-red-600">Verwerfen</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-3 gap-4">
|
|
<div class="col-span-2 space-y-4">
|
|
<div class="card space-y-3">
|
|
{% render_field aufgabe "typ" "Typ" %}
|
|
{% render_field aufgabe "prioritaet" "Priorität" %}
|
|
{% render_field aufgabe "status" "Status" %}
|
|
<div class="flex justify-between text-sm py-0.5">
|
|
<dt class="text-slate-500">Frist</dt>
|
|
<dd class="text-slate-800">
|
|
{% if aufgabe.frist %}
|
|
{{ aufgabe.frist }}
|
|
{% else %}
|
|
<span class="text-slate-400">keine</span>
|
|
<span class="text-xs text-amber-600 ml-1">(implizit fällig: {{ aufgabe.frist_effektiv|date:"d.m.Y" }})</span>
|
|
{% endif %}
|
|
</dd>
|
|
</div>
|
|
{% render_field aufgabe "verantwortlicher" "Verantwortlich" %}
|
|
{% if aufgabe.beschreibung %}
|
|
<div>
|
|
<p class="text-xs text-slate-500 mb-1">Beschreibung</p>
|
|
<p class="text-sm text-slate-800 whitespace-pre-wrap">{{ aufgabe.beschreibung }}</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if aufgabe.status == 'erledigt' or aufgabe.ergebnis %}
|
|
<div class="card">
|
|
<p class="text-xs font-medium text-slate-500 uppercase tracking-wide mb-3">Ergebnis</p>
|
|
<form method="post" action="{% url 'ausschreibungen:aufgaben:ergebnis' ausschreibung.pk aufgabe.pk %}">
|
|
{% csrf_token %}
|
|
<textarea name="ergebnis" rows="3" class="form-input w-full">{{ aufgabe.ergebnis }}</textarea>
|
|
<button type="submit" class="btn-primary text-xs mt-2">Speichern</button>
|
|
</form>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
{% if aufgabe.anforderung %}
|
|
<div class="card">
|
|
<p class="text-xs font-medium text-slate-500 uppercase tracking-wide mb-2">Anforderung</p>
|
|
<a href="{% url 'ausschreibungen:lose:anforderung_detail' ausschreibung.pk aufgabe.anforderung.pk %}"
|
|
class="text-sm text-blue-600 hover:underline">{{ aufgabe.anforderung.titel }}</a>
|
|
</div>
|
|
{% endif %}
|
|
{% if aufgabe.bieterfrage %}
|
|
<div class="card">
|
|
<p class="text-xs font-medium text-slate-500 uppercase tracking-wide mb-2">Bieterfrage</p>
|
|
<a href="{% url 'ausschreibungen:bieterfragen:detail' ausschreibung.pk aufgabe.bieterfrage.pk %}"
|
|
class="text-sm text-blue-600 hover:underline">{{ aufgabe.bieterfrage }}</a>
|
|
</div>
|
|
{% endif %}
|
|
{% if aufgabe.los %}
|
|
<div class="card">
|
|
<p class="text-xs font-medium text-slate-500 uppercase tracking-wide mb-2">Los</p>
|
|
<a href="{% url 'ausschreibungen:lose:detail' ausschreibung.pk aufgabe.los.pk %}"
|
|
class="text-sm text-blue-600 hover:underline">{{ aufgabe.los.lostitel }}</a>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Verknüpfungen -->
|
|
<div class="card">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<p class="text-xs font-medium text-slate-500 uppercase tracking-wide">Verknüpfungen</p>
|
|
<button class="btn-ghost text-xs"
|
|
hx-get="{% url 'ausschreibungen:aufgaben:verknuepfung_neu' ausschreibung.pk aufgabe.pk %}"
|
|
hx-target="#verknuepfung-form-container"
|
|
hx-swap="innerHTML">+ Verknüpfen</button>
|
|
</div>
|
|
<div id="verknuepfung-form-container"></div>
|
|
<ul id="verknuepfungen-list" class="space-y-1 mt-1">
|
|
{% for v in aufgabe.verknuepfungen.all %}
|
|
{% include "aufgaben/partials/verknuepfung_row.html" %}
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Externes Issue -->
|
|
<div class="card" id="external-issue-panel">
|
|
{% include "aufgaben/partials/external_issue_panel.html" %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %}
|