feat(#106): UI-Block 'Abstimmungsergebnis' auf Antrag-Detail
Antrag-Detail-Endpoint liest plenum_votes via get_plenum_votes() und reicht sie an antrag_detail.html durch. Block rendert pro Plenum-Abstimmung eine Karte: - Ergebnis (angenommen/abgelehnt/...) farb-kodiert - 'einstimmig'-Annotation falls gesetzt - Quelle (Protokoll-ID, mit URL als Tooltip) - Fraktions-Chips fuer Ja/Nein/Enthaltung Mehrfach-Abstimmungen einer Drucksache (Ueberweisung + finale Beschlussfassung) erzeugen mehrere Karten — chronologisch via parsed_at DESC im Repository sortiert. Block erscheint nur, wenn Eintraege existieren (kein leerer Header).
This commit is contained in:
parent
e26607854f
commit
7e0f0117e6
@ -304,6 +304,13 @@ async def antrag_detail(request: Request, drucksache: str, current_user: Optiona
|
||||
except Exception:
|
||||
logger.exception("Fehler beim Laden von Abstimmungsverhalten für %s", drucksache)
|
||||
antrag["abstimmungsverhalten"] = None
|
||||
# #106 Phase 2: fraktions-aggregierte Plenum-Abstimmungen aus Plenarprotokollen
|
||||
try:
|
||||
from .database import get_plenum_votes as _gpv
|
||||
antrag["plenum_votes"] = await _gpv(antrag.get("bundesland") or "NRW", drucksache)
|
||||
except Exception:
|
||||
logger.exception("Fehler beim Laden plenum_vote_results für %s", drucksache)
|
||||
antrag["plenum_votes"] = []
|
||||
from .models import MATRIX_LABELS
|
||||
return templates.TemplateResponse("v2/screens/antrag_detail.html", {
|
||||
"request": request,
|
||||
|
||||
@ -264,6 +264,53 @@
|
||||
{% endfor %}
|
||||
{% endif %}{# abstimmungsverhalten #}
|
||||
|
||||
{# ── Fraktions-aggregierte Plenum-Abstimmung aus Plenarprotokoll (#106) ── #}
|
||||
{% if antrag.plenum_votes %}
|
||||
<h3 class="v2-h3" style="margin-top:24px;">Abstimmungsergebnis</h3>
|
||||
{% set ergebnis_color = {
|
||||
"angenommen": "#2da44e",
|
||||
"abgelehnt": "#cf222e",
|
||||
"überwiesen": "#0969da",
|
||||
"zurückgezogen": "#8250df",
|
||||
"bestätigt": "#2da44e",
|
||||
"sammel": "#0969da",
|
||||
} %}
|
||||
{% for v in antrag.plenum_votes %}
|
||||
<div style="border:1px solid var(--hairline);border-radius:6px;padding:12px 14px;margin-bottom:10px;background:var(--paper);">
|
||||
<div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px;">
|
||||
<span style="font-family:var(--font-display);font-size:14px;font-weight:700;color:{{ ergebnis_color.get(v.ergebnis, '#6e7781') }};">
|
||||
{{ v.ergebnis | capitalize }}{% if v.einstimmig %} · einstimmig{% endif %}
|
||||
</span>
|
||||
<span style="font-family:var(--font-mono);font-size:10px;opacity:0.6;" title="{% if v.quelle_url %}{{ v.quelle_url }}{% endif %}">
|
||||
{{ v.quelle_protokoll }}{% if v.quelle_url %} ↗{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% if v.fraktionen_ja or v.fraktionen_nein or v.fraktionen_enthaltung %}
|
||||
<div style="display:flex;flex-wrap:wrap;gap:12px;font-family:var(--font-mono);font-size:11px;">
|
||||
{% if v.fraktionen_ja %}
|
||||
<div><span style="color:#2da44e;font-weight:700;">Ja:</span>
|
||||
{% for f in v.fraktionen_ja %}<span style="display:inline-block;padding:1px 6px;background:color-mix(in srgb,#2da44e 15%,transparent);color:#1a7f37;border-radius:3px;margin-right:3px;">{{ f }}</span>{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if v.fraktionen_nein %}
|
||||
<div><span style="color:#cf222e;font-weight:700;">Nein:</span>
|
||||
{% for f in v.fraktionen_nein %}<span style="display:inline-block;padding:1px 6px;background:color-mix(in srgb,#cf222e 15%,transparent);color:#a40e26;border-radius:3px;margin-right:3px;">{{ f }}</span>{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if v.fraktionen_enthaltung %}
|
||||
<div><span style="color:#6e7781;font-weight:700;">Enth.:</span>
|
||||
{% for f in v.fraktionen_enthaltung %}<span style="display:inline-block;padding:1px 6px;background:color-mix(in srgb,#6e7781 15%,transparent);color:#57606a;border-radius:3px;margin-right:3px;">{{ f }}</span>{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div style="font-family:var(--font-mono);font-size:10px;opacity:0.5;margin-top:-4px;margin-bottom:8px;">
|
||||
Quelle: Plenarprotokoll · automatisch extrahiert
|
||||
</div>
|
||||
{% endif %}{# plenum_votes #}
|
||||
|
||||
{% if antrag.matrix %}
|
||||
<h3 class="v2-h3">Matrix 2.0 · 25 Felder</h3>
|
||||
{{ matrix_mini(antrag.matrix) }}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user