feat: toggle faq accordion
This commit is contained in:
@@ -1,22 +1,20 @@
|
||||
from django.views.generic import ListView, TemplateView
|
||||
from django.views.generic.edit import CreateView, UpdateView
|
||||
from django.urls import reverse_lazy
|
||||
from django.views.generic.detail import DetailView
|
||||
from django.views.generic.edit import FormMixin
|
||||
from .forms import CommentForm, TicketForm
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect, render
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import redirect, render
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils import timezone
|
||||
from django.views.generic import ListView, TemplateView
|
||||
from django.views.generic.edit import CreateView, UpdateView
|
||||
from reportlab.lib.enums import TA_CENTER, TA_LEFT
|
||||
from reportlab.lib.pagesizes import A4
|
||||
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
|
||||
from reportlab.lib.units import cm
|
||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
|
||||
from reportlab.lib.enums import TA_LEFT, TA_CENTER
|
||||
from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer
|
||||
|
||||
from .models import Ticket, TicketHistory, FAQ, Course
|
||||
from .forms import CommentForm, TicketForm
|
||||
from .models import FAQ, Course, Ticket, TicketHistory
|
||||
|
||||
|
||||
class HomeView(TemplateView):
|
||||
@@ -92,9 +90,9 @@ class TicketDetailUpdateView(UpdateView):
|
||||
# Bearbeitungsrechte abhängig vom Status
|
||||
if is_superuser:
|
||||
self.can_edit = True
|
||||
elif self.ticket.status == 'resolved' and is_creator:
|
||||
elif self.ticket.status == "resolved" and is_creator:
|
||||
self.can_edit = True
|
||||
elif self.ticket.status == 'closed':
|
||||
elif self.ticket.status == "closed":
|
||||
self.can_edit = False
|
||||
else:
|
||||
self.can_edit = is_assigned_tutor
|
||||
@@ -108,16 +106,16 @@ class TicketDetailUpdateView(UpdateView):
|
||||
def get_form_kwargs(self):
|
||||
"""Übergibt zusätzliche kwargs ans Form"""
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs['user'] = self.request.user
|
||||
kwargs['ticket'] = self.object
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["ticket"] = self.object
|
||||
return kwargs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
# Füge Berechtigungs-Infos zum Context hinzu
|
||||
context['is_creator'] = self.is_creator
|
||||
context['is_tutor'] = self.is_tutor
|
||||
context['can_edit'] = self.can_edit
|
||||
context["is_creator"] = self.is_creator
|
||||
context["is_tutor"] = self.is_tutor
|
||||
context["can_edit"] = self.can_edit
|
||||
|
||||
# Kommentarformular hinzufügen
|
||||
if "comment_form" not in context:
|
||||
@@ -134,7 +132,15 @@ class TicketDetailUpdateView(UpdateView):
|
||||
response = super().form_valid(form) # Speichert das Ticket
|
||||
|
||||
# History tracking für geänderte Felder
|
||||
tracked_fields = ["title", "description", "status", "mistake", "course", "answer", "material"]
|
||||
tracked_fields = [
|
||||
"title",
|
||||
"description",
|
||||
"status",
|
||||
"mistake",
|
||||
"course",
|
||||
"answer",
|
||||
"material",
|
||||
]
|
||||
for field in tracked_fields:
|
||||
if field in form.changed_data:
|
||||
old_value = getattr(original, field)
|
||||
@@ -152,11 +158,15 @@ class TicketDetailUpdateView(UpdateView):
|
||||
new_value = str(new_value)
|
||||
elif field == "answer":
|
||||
if old_value:
|
||||
old_value = old_value[:50] + "..." if len(old_value) > 50 else old_value
|
||||
old_value = (
|
||||
old_value[:50] + "..." if len(old_value) > 50 else old_value
|
||||
)
|
||||
else:
|
||||
old_value = "Keine Antwort"
|
||||
if new_value:
|
||||
new_value = new_value[:50] + "..." if len(new_value) > 50 else new_value
|
||||
new_value = (
|
||||
new_value[:50] + "..." if len(new_value) > 50 else new_value
|
||||
)
|
||||
else:
|
||||
new_value = "Keine Antwort"
|
||||
|
||||
@@ -286,41 +296,54 @@ class TicketUpdateView(LoginRequiredMixin, UpdateView):
|
||||
def faq_list(request):
|
||||
"""Zeigt alle aktiven FAQs an"""
|
||||
faqs = FAQ.objects.filter(is_active=True)
|
||||
return render(request, 'ticketsystem/faq.html', {'faqs': faqs})
|
||||
return render(request, "ticketsystem/faq.html", {"faqs": faqs})
|
||||
|
||||
|
||||
def faq_pdf_download(request):
|
||||
"""Generiert PDF mit allen FAQs"""
|
||||
# Response Setup
|
||||
response = HttpResponse(content_type='application/pdf')
|
||||
response['Content-Disposition'] = 'attachment; filename="FAQ_Ticketsystem.pdf"'
|
||||
|
||||
current_date = timezone.now()
|
||||
date_string = current_date.strftime("%Y-%m-%d")
|
||||
date_display = current_date.strftime("%d.%m.%Y")
|
||||
|
||||
# Response Setup mit Datum im Dateinamen
|
||||
response = HttpResponse(content_type="application/pdf")
|
||||
response["Content-Disposition"] = (
|
||||
f'attachment; filename="FAQ_Ticketsystem_{date_string}.pdf"'
|
||||
)
|
||||
|
||||
# PDF erstellen
|
||||
doc = SimpleDocTemplate(response, pagesize=A4, topMargin=2 * cm, bottomMargin=2 * cm)
|
||||
doc = SimpleDocTemplate(
|
||||
response, pagesize=A4, topMargin=2 * cm, bottomMargin=2 * cm
|
||||
)
|
||||
|
||||
# Styles
|
||||
styles = getSampleStyleSheet()
|
||||
title_style = ParagraphStyle(
|
||||
'CustomTitle',
|
||||
parent=styles['Heading1'],
|
||||
"CustomTitle",
|
||||
parent=styles["Heading1"],
|
||||
fontSize=24,
|
||||
textColor='#1a1a1a',
|
||||
textColor="#1a1a1a",
|
||||
spaceAfter=20,
|
||||
alignment=TA_CENTER,
|
||||
)
|
||||
subtitle_style = ParagraphStyle(
|
||||
"Subtitle",
|
||||
parent=styles["Normal"],
|
||||
fontSize=12,
|
||||
textColor="#666666",
|
||||
spaceAfter=30,
|
||||
alignment=TA_CENTER
|
||||
alignment=TA_CENTER,
|
||||
)
|
||||
question_style = ParagraphStyle(
|
||||
'Question',
|
||||
parent=styles['Heading2'],
|
||||
"Question",
|
||||
parent=styles["Heading2"],
|
||||
fontSize=14,
|
||||
textColor='#2563eb',
|
||||
spaceAfter=10
|
||||
textColor="#2563eb",
|
||||
spaceAfter=10,
|
||||
)
|
||||
answer_style = ParagraphStyle(
|
||||
'Answer',
|
||||
parent=styles['Normal'],
|
||||
fontSize=11,
|
||||
spaceAfter=20,
|
||||
alignment=TA_LEFT
|
||||
"Answer", parent=styles["Normal"], fontSize=11, spaceAfter=20, alignment=TA_LEFT
|
||||
)
|
||||
|
||||
# Content
|
||||
@@ -328,23 +351,29 @@ def faq_pdf_download(request):
|
||||
|
||||
# Titel
|
||||
elements.append(Paragraph("Häufig gestellte Fragen (FAQ)", title_style))
|
||||
|
||||
elements.append(Paragraph(f"Stand: {date_display}", subtitle_style))
|
||||
|
||||
elements.append(Spacer(1, 20))
|
||||
|
||||
# FAQs holen
|
||||
faqs = FAQ.objects.filter(is_active=True)
|
||||
|
||||
# FAQs hinzufügen
|
||||
for i, faq in enumerate(faqs, 1):
|
||||
# Frage
|
||||
elements.append(Paragraph(f"{i}. {faq.question}", question_style))
|
||||
if faqs.exists():
|
||||
# FAQs hinzufügen
|
||||
for i, faq in enumerate(faqs, 1):
|
||||
# Frage
|
||||
elements.append(Paragraph(f"{i}. {faq.question}", question_style))
|
||||
|
||||
# Antwort
|
||||
elements.append(Paragraph(faq.answer.replace('\n', '<br/>'), answer_style))
|
||||
# Antwort
|
||||
elements.append(Paragraph(faq.answer.replace("\n", "<br/>"), answer_style))
|
||||
|
||||
# Abstand zwischen FAQs
|
||||
elements.append(Spacer(1, 10))
|
||||
# Abstand zwischen FAQs
|
||||
elements.append(Spacer(1, 10))
|
||||
else:
|
||||
elements.append(Paragraph("Derzeit sind keine FAQs verfügbar.", answer_style))
|
||||
|
||||
# PDF generieren
|
||||
doc.build(elements)
|
||||
|
||||
return response
|
||||
return response
|
||||
|
||||
Reference in New Issue
Block a user