Files
vergabe-teilnahme/vergabe_teilnahme/apps/feedback/views.py
tegwick 40e70e64f0 fix(feedback): inline edit + live status change without reload
- Replaced broken status_aendern (missing status_choices in response)
  with a single eintrag_bearbeiten view that always returns the full
  partial context
- eintrag_zeile.html is now a <tbody x-data="{ editing: false }"> with
  two rows: display row + collapsible edit form
- Click anywhere on a row to expand the edit form; @click.stop on the
  status cell prevents accidental toggles
- Status dropdown in the display row posts via HTMX and swaps the whole
  <tbody> — no page reload needed
- Edit form covers all fields: titel, beschreibung, kategorie,
  dringlichkeit, status, bewertung, entscheidung

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 23:45:10 +02:00

97 lines
3.4 KiB
Python

from django.shortcuts import get_object_or_404, render
from django.views.decorators.http import require_GET, require_POST
from .models import Feedbackeintrag
@require_GET
def modal(request):
return render(request, 'partials/feedback_modal.html')
@require_POST
def submit(request):
beschreibung = request.POST.get('beschreibung', '').strip()
if not beschreibung:
return render(request, 'partials/feedback_modal.html',
{'error': 'Beschreibung ist erforderlich.'})
entry = Feedbackeintrag(
titel=request.POST.get('titel', 'Ohne Titel') or 'Ohne Titel',
beschreibung=beschreibung,
seite_kontext=request.POST.get('seite_kontext', ''),
kategorie=request.POST.get('kategorie', 'hinweis'),
dringlichkeit=request.POST.get('dringlichkeit', 'mittel'),
)
ausschreibung_pk = request.POST.get('ausschreibung')
if ausschreibung_pk:
try:
from vergabe_teilnahme.apps.ausschreibungen.models import Ausschreibung
entry.ausschreibung = Ausschreibung.objects.get(pk=ausschreibung_pk)
except (Ausschreibung.DoesNotExist, ValueError):
pass
if request.user.is_authenticated:
entry.erfasst_von = request.user
entry.save()
return render(request, 'partials/feedback_success.html', {})
def backlog(request):
qs = Feedbackeintrag.objects.select_related('erfasst_von', 'ausschreibung').all()
status_filter = request.GET.get('status')
if status_filter:
qs = qs.filter(status=status_filter)
kategorie_filter = request.GET.get('kategorie')
if kategorie_filter:
qs = qs.filter(kategorie=kategorie_filter)
dringlichkeit_filter = request.GET.get('dringlichkeit')
if dringlichkeit_filter:
qs = qs.filter(dringlichkeit=dringlichkeit_filter)
ctx = {
'eintraege': qs,
'status_choices': Feedbackeintrag.STATUS_CHOICES,
'kategorie_choices': Feedbackeintrag.KATEGORIE_CHOICES,
'dringlichkeit_choices': Feedbackeintrag.DRINGLICHKEIT_CHOICES,
'current_status': status_filter or '',
'current_kategorie': kategorie_filter or '',
'current_dringlichkeit': dringlichkeit_filter or '',
'breadcrumbs': [{'label': 'Feedback-Backlog', 'url': None}],
}
return render(request, 'feedback/backlog.html', ctx)
def _eintrag_ctx(eintrag):
return {
'eintrag': eintrag,
'status_choices': Feedbackeintrag.STATUS_CHOICES,
'kategorie_choices': Feedbackeintrag.KATEGORIE_CHOICES,
'dringlichkeit_choices': Feedbackeintrag.DRINGLICHKEIT_CHOICES,
}
@require_POST
def eintrag_bearbeiten(request, pk):
eintrag = get_object_or_404(Feedbackeintrag, pk=pk)
for field, choices in [
('status', Feedbackeintrag.STATUS_CHOICES),
('kategorie', Feedbackeintrag.KATEGORIE_CHOICES),
('dringlichkeit', Feedbackeintrag.DRINGLICHKEIT_CHOICES),
]:
val = request.POST.get(field)
if val and val in dict(choices):
setattr(eintrag, field, val)
for field in ('beschreibung', 'bewertung', 'entscheidung'):
val = request.POST.get(field)
if val is not None:
setattr(eintrag, field, val)
titel = request.POST.get('titel', '').strip()
if titel:
eintrag.titel = titel
eintrag.save()
return render(request, 'feedback/partials/eintrag_zeile.html', _eintrag_ctx(eintrag))