Compare commits
2 Commits
6dd1a7e1c3
...
3e17050c40
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e17050c40 | |||
| 63a66f6d3e |
68
ticketsystem/static/js/ticket_detail.js
Normal file
68
ticketsystem/static/js/ticket_detail.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
function initializeTicketDetail(config) {
|
||||||
|
// Course-Tutor Mapping
|
||||||
|
if (config.canEdit) {
|
||||||
|
const courseSelect = document.getElementById('id_course');
|
||||||
|
const tutorText = document.getElementById('tutor_text');
|
||||||
|
const tutorDisplay = document.getElementById('tutor_display');
|
||||||
|
|
||||||
|
if (courseSelect && config.courseTutorMap) {
|
||||||
|
courseSelect.addEventListener('change', function() {
|
||||||
|
const selectedCourseId = this.value;
|
||||||
|
|
||||||
|
if (selectedCourseId && config.courseTutorMap[selectedCourseId]) {
|
||||||
|
tutorText.textContent = config.courseTutorMap[selectedCourseId];
|
||||||
|
tutorDisplay.classList.remove('bg-gray-100');
|
||||||
|
tutorDisplay.classList.add('bg-blue-50');
|
||||||
|
} else if (selectedCourseId) {
|
||||||
|
tutorText.textContent = 'Kein Tutor zugewiesen';
|
||||||
|
tutorDisplay.classList.remove('bg-blue-50');
|
||||||
|
tutorDisplay.classList.add('bg-gray-100');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Answer Field Toggle (nur für Tutoren)
|
||||||
|
if (config.canEdit && !config.isCreator) {
|
||||||
|
const statusSelect = document.querySelector('select[name="status"]');
|
||||||
|
const answerField = document.querySelector('textarea[name="answer"]');
|
||||||
|
const answerLabel = answerField?.previousElementSibling;
|
||||||
|
|
||||||
|
function toggleAnswerField() {
|
||||||
|
if (!answerField) return;
|
||||||
|
|
||||||
|
if (statusSelect.value === 'resolved') {
|
||||||
|
answerField.disabled = false;
|
||||||
|
answerField.classList.remove('bg-gray-100', 'cursor-not-allowed');
|
||||||
|
answerField.classList.add('bg-white');
|
||||||
|
answerField.required = true;
|
||||||
|
|
||||||
|
if (answerLabel && !answerLabel.querySelector('.text-red-500')) {
|
||||||
|
answerLabel.innerHTML = answerLabel.textContent + ' <span class="text-red-500">*</span>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
answerField.disabled = true;
|
||||||
|
answerField.classList.add('bg-gray-100', 'cursor-not-allowed');
|
||||||
|
answerField.classList.remove('bg-white');
|
||||||
|
answerField.required = false;
|
||||||
|
|
||||||
|
if (answerLabel) {
|
||||||
|
answerLabel.innerHTML = answerLabel.textContent.replace(' *', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusSelect && answerField) {
|
||||||
|
toggleAnswerField();
|
||||||
|
statusSelect.addEventListener('change', toggleAnswerField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialisierung wenn DOM geladen
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Config wird vom Template bereitgestellt
|
||||||
|
if (window.ticketDetailConfig) {
|
||||||
|
initializeTicketDetail(window.ticketDetailConfig);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
{% extends "ticketsystem/base.html" %}
|
{% extends "ticketsystem/base.html" %}
|
||||||
|
{% load static %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<!-- Messages -->
|
<!-- Messages -->
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
@@ -75,7 +76,7 @@
|
|||||||
{% if form.status.errors %}<div class="text-red-600 text-sm mt-1">{{ form.status.errors }}</div>{% endif %}
|
{% if form.status.errors %}<div class="text-red-600 text-sm mt-1">{{ form.status.errors }}</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-sm font-medium mb-1">Priorität:</label>
|
<label class="block text-sm font-medium mb-1">Fehlerart:</label>
|
||||||
<select name="mistake"
|
<select name="mistake"
|
||||||
{% if not view.can_edit or form.mistake.field.disabled %}disabled{% endif %}
|
{% if not view.can_edit or form.mistake.field.disabled %}disabled{% endif %}
|
||||||
class="w-full p-2 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 {% if not view.can_edit or form.mistake.field.disabled %}bg-gray-100{% endif %}">
|
class="w-full p-2 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 {% if not view.can_edit or form.mistake.field.disabled %}bg-gray-100{% endif %}">
|
||||||
@@ -119,12 +120,12 @@
|
|||||||
<!-- Bearbeitbares Feld -->
|
<!-- Bearbeitbares Feld -->
|
||||||
<textarea name="answer"
|
<textarea name="answer"
|
||||||
rows="4"
|
rows="4"
|
||||||
{% if not view.can_edit or ticket.status != 'resolved' %}disabled{% endif %}
|
{% if not view.can_edit or form.answer.field.disabled %}disabled{% endif %}
|
||||||
placeholder="Beschreibe die Lösung des Problems..."
|
placeholder="Beschreibe die Lösung des Problems..."
|
||||||
class="w-full p-2 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-black {% if not view.can_edit or ticket.status != 'resolved' %}bg-gray-100 cursor-not-allowed{% endif %}">{{ ticket.answer|default:'' }}</textarea>
|
class="w-full p-2 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-gray-900 {% if not view.can_edit or ticket.status != 'resolved' or form.answer.field.disabled %}bg-gray-100 cursor-not-allowed{% endif %}">{{ ticket.answer|default:'' }}</textarea>
|
||||||
{% if form.answer.errors %}<div class="text-red-600 text-sm mt-1">{{ form.answer.errors }}</div>{% endif %}
|
{% if form.answer.errors %}<div class="text-red-600 text-sm mt-1">{{ form.answer.errors }}</div>{% endif %}
|
||||||
<p class="text-xs text-gray-500 mt-1">
|
<p class="text-xs text-gray-500 mt-1">
|
||||||
{% if ticket.status != 'resolved' or ticket.status != 'closed' %}
|
{% if ticket.status != 'resolved' %}
|
||||||
Eine Antwort ist erforderlich beim Setzen des Status auf "Gelöst"
|
Eine Antwort ist erforderlich beim Setzen des Status auf "Gelöst"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
@@ -197,70 +198,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- JavaScript für dynamische Tutor-Anzeige -->
|
<!-- JavaScript für dynamische Tutor-Anzeige -->
|
||||||
|
<script src="{% static 'js/ticket_detail.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
window.ticketDetailConfig = {
|
||||||
const courseSelect = document.getElementById('id_course');
|
canEdit: {% if view.can_edit %}true{% else %}false{% endif %},
|
||||||
const tutorText = document.getElementById('tutor_text');
|
isCreator: {% if is_creator %}true{% else %}false{% endif %},
|
||||||
const tutorDisplay = document.getElementById('tutor_display');
|
courseTutorMap: {
|
||||||
|
|
||||||
// Course-Tutor Mapping
|
|
||||||
const courseTutorMap = {
|
|
||||||
{% for course in form.course.field.queryset %}
|
{% for course in form.course.field.queryset %}
|
||||||
{% if course.tutor %}'{{ course.pk }}': '{{ course.tutor.username }}',{% endif %}
|
{% if course.tutor %}'{{ course.pk }}': '{{ course.tutor.username }}',{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Nur aktivieren wenn User bearbeiten kann
|
|
||||||
{% if view.can_edit %}
|
|
||||||
courseSelect.addEventListener('change', function() {
|
|
||||||
const selectedCourseId = this.value;
|
|
||||||
|
|
||||||
if (selectedCourseId && courseTutorMap[selectedCourseId]) {
|
|
||||||
tutorText.textContent = courseTutorMap[selectedCourseId];
|
|
||||||
tutorDisplay.classList.remove('bg-gray-100');
|
|
||||||
tutorDisplay.classList.add('bg-blue-50');
|
|
||||||
} else if (selectedCourseId) {
|
|
||||||
tutorText.textContent = 'Kein Tutor zugewiesen';
|
|
||||||
tutorDisplay.classList.remove('bg-blue-50');
|
|
||||||
tutorDisplay.classList.add('bg-gray-100');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
{% endif %}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Answer Feld nur bei Status "resolved" aktivieren
|
|
||||||
{% if view.can_edit %}
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
const statusSelect = document.querySelector('select[name="status"]');
|
|
||||||
const answerField = document.querySelector('textarea[name="answer"]');
|
|
||||||
const answerLabel = answerField.previousElementSibling;
|
|
||||||
|
|
||||||
function toggleAnswerField() {
|
|
||||||
if (statusSelect.value === 'resolved' || statusSelect.value === 'closed') {
|
|
||||||
answerField.disabled = false;
|
|
||||||
answerField.classList.remove('bg-gray-100', 'cursor-not-allowed');
|
|
||||||
answerField.classList.add('bg-white');
|
|
||||||
answerField.required = true;
|
|
||||||
// Pflichtfeld-Stern anzeigen
|
|
||||||
if (!answerLabel.querySelector('.text-red-500')) {
|
|
||||||
answerLabel.innerHTML = answerLabel.textContent + ' <span class="text-red-500">*</span>';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
answerField.disabled = true;
|
|
||||||
answerField.classList.add('bg-gray-100', 'cursor-not-allowed');
|
|
||||||
answerField.classList.remove('bg-white');
|
|
||||||
answerField.required = false;
|
|
||||||
// Pflichtfeld-Stern entfernen
|
|
||||||
answerLabel.innerHTML = answerLabel.textContent.replace(' *', '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initial prüfen
|
|
||||||
toggleAnswerField();
|
|
||||||
|
|
||||||
// Bei Status-Änderung prüfen
|
|
||||||
statusSelect.addEventListener('change', toggleAnswerField);
|
|
||||||
});
|
|
||||||
{% endif %}
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Filter und Suche -->
|
<!-- Filter und Suche -->
|
||||||
<div class="bg-white rounded-lg shadow p-4 mb-6">
|
<div class="bg-white rounded-lg shadow p-4 mb-6">
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-4">
|
<div class="grid grid-cols-1 lg:grid-cols-5 gap-4">
|
||||||
<!-- Status Filter -->
|
<!-- Status Filter -->
|
||||||
<div>
|
<div>
|
||||||
<form method="get">
|
<form method="get">
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
name="assigned_to"
|
name="assigned_to"
|
||||||
value="{{ request.GET.assigned_to }}">
|
value="{{ request.GET.assigned_to }}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if request.GET.course %}<input type="hidden" name="course" value="{{ request.GET.course }}">{% endif %}
|
||||||
{% if search_query %}<input type="hidden" name="q" value="{{ search_query }}">{% endif %}
|
{% if search_query %}<input type="hidden" name="q" value="{{ search_query }}">{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -54,18 +55,44 @@
|
|||||||
<label class="block text-sm font-medium mb-1">Zuweisung:</label>
|
<label class="block text-sm font-medium mb-1">Zuweisung:</label>
|
||||||
{% if request.GET.assigned_to == user.id|stringformat:'s' %}
|
{% if request.GET.assigned_to == user.id|stringformat:'s' %}
|
||||||
<!-- Wenn aktiv: Button zum Deaktivieren -->
|
<!-- Wenn aktiv: Button zum Deaktivieren -->
|
||||||
<a href="?{% if selected_status %}status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}"
|
<a href="?{% if selected_status %}status={{ selected_status }}{% endif %}{% if selected_course %}&course={{ selected_course }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}"
|
||||||
class="block w-full h-10 px-3 border border-purple-300 rounded shadow-sm text-center bg-purple-200 hover:bg-purple-300 transition-colors flex items-center justify-center">
|
class="block w-full h-10 px-3 border border-purple-300 rounded shadow-sm text-center bg-purple-200 hover:bg-purple-300 transition-colors flex items-center justify-center">
|
||||||
👤 Meine Tickets ✓
|
👤 Meine Tickets ✓
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<!-- Wenn nicht aktiv: Button zum Aktivieren -->
|
<!-- Wenn nicht aktiv: Button zum Aktivieren -->
|
||||||
<a href="?assigned_to={{ user.id }}{% if selected_status %}&status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}"
|
<a href="?assigned_to={{ user.id }}{% if selected_status %}&status={{ selected_status }}{% endif %}{% if selected_course %}&course={{ selected_course }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}"
|
||||||
class="block w-full h-10 px-3 border border-purple-300 rounded shadow-sm text-center bg-purple-50 hover:bg-purple-100 transition-colors flex items-center justify-center">
|
class="block w-full h-10 px-3 border border-purple-300 rounded shadow-sm text-center bg-purple-50 hover:bg-purple-100 transition-colors flex items-center justify-center">
|
||||||
👤 Meine Tickets
|
👤 Meine Tickets
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Kurs Filter -->
|
||||||
|
<div>
|
||||||
|
<form method="get">
|
||||||
|
<label class="block text-sm font-medium mb-1">Kurs:</label>
|
||||||
|
<select name="course"
|
||||||
|
onchange="this.form.submit()"
|
||||||
|
class="w-full h-10 px-3 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||||
|
<option value="">Alle Kurse</option>
|
||||||
|
{% for course in courses %}
|
||||||
|
<option value="{{ course.id }}"
|
||||||
|
{% if selected_course == course.id|stringformat:'s' %}selected{% endif %}>
|
||||||
|
{{ course.code }} - {{ course.name }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<!-- Andere Filter beibehalten -->
|
||||||
|
{% if selected_status %}<input type="hidden" name="status" value="{{ selected_status }}">{% endif %}
|
||||||
|
{% if selected_course %}<input type="hidden" name="course" value="{{ selected_course }}">{% endif %}
|
||||||
|
{% if request.GET.assigned_to %}
|
||||||
|
<input type="hidden"
|
||||||
|
name="assigned_to"
|
||||||
|
value="{{ request.GET.assigned_to }}">
|
||||||
|
{% endif %}
|
||||||
|
{% if search_query %}<input type="hidden" name="q" value="{{ search_query }}">{% endif %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<!-- Suche -->
|
<!-- Suche -->
|
||||||
<div class="lg:col-span-2">
|
<div class="lg:col-span-2">
|
||||||
<form method="get">
|
<form method="get">
|
||||||
@@ -77,6 +104,7 @@
|
|||||||
placeholder="Titel oder Beschreibung durchsuchen..."
|
placeholder="Titel oder Beschreibung durchsuchen..."
|
||||||
class="flex-1 h-10 px-3 border border-gray-300 rounded-l shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
class="flex-1 h-10 px-3 border border-gray-300 rounded-l shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||||
{% if selected_status %}<input type="hidden" name="status" value="{{ selected_status }}">{% endif %}
|
{% if selected_status %}<input type="hidden" name="status" value="{{ selected_status }}">{% endif %}
|
||||||
|
{% if selected_course %}<input type="hidden" name="course" value="{{ selected_course }}">{% endif %}
|
||||||
{% if request.GET.assigned_to %}
|
{% if request.GET.assigned_to %}
|
||||||
<input type="hidden"
|
<input type="hidden"
|
||||||
name="assigned_to"
|
name="assigned_to"
|
||||||
@@ -117,6 +145,16 @@
|
|||||||
class="ml-1 text-green-600 hover:text-green-800">×</a>
|
class="ml-1 text-green-600 hover:text-green-800">×</a>
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if selected_course %}
|
||||||
|
<span class="px-2 py-1 bg-green-100 text-green-800 text-sm rounded">
|
||||||
|
Kurs:
|
||||||
|
{% for course in courses %}
|
||||||
|
{% if course.id|stringformat:'s' == selected_course %}{{ course.code }}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<a href="?{% if selected_status %}status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}{% if request.GET.assigned_to %}&assigned_to={{ request.GET.assigned_to }}{% endif %}"
|
||||||
|
class="ml-1 text-green-600 hover:text-green-800">×</a>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
<a href="{% url 'ticket-list' %}"
|
<a href="{% url 'ticket-list' %}"
|
||||||
class="text-sm text-gray-600 hover:text-gray-800 font-medium">Alle Filter entfernen</a>
|
class="text-sm text-gray-600 hover:text-gray-800 font-medium">Alle Filter entfernen</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,6 +169,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th class="px-4 py-3 text-center text-sm font-bold">#</th>
|
<th class="px-4 py-3 text-center text-sm font-bold">#</th>
|
||||||
<th class="px-4 py-3 text-left text-sm font-bold">Titel</th>
|
<th class="px-4 py-3 text-left text-sm font-bold">Titel</th>
|
||||||
|
<th class="px-4 py-3 text-center text-sm font-bold">Kurs</th>
|
||||||
<th class="px-4 py-3 text-center text-sm font-bold">Status</th>
|
<th class="px-4 py-3 text-center text-sm font-bold">Status</th>
|
||||||
<th class="px-4 py-3 text-center text-sm font-bold">Fehlerart</th>
|
<th class="px-4 py-3 text-center text-sm font-bold">Fehlerart</th>
|
||||||
<th class="px-4 py-3 text-left text-sm font-bold">Zugewiesen an</th>
|
<th class="px-4 py-3 text-left text-sm font-bold">Zugewiesen an</th>
|
||||||
@@ -147,6 +186,11 @@
|
|||||||
{{ ticket.title }}
|
{{ ticket.title }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="px-4 py-3 text-center text-sm">
|
||||||
|
<span class="px-2 py-1 bg-white border border-gray-900 rounded-full text-xs font-bold text-gray-900">
|
||||||
|
{{ ticket.course.code }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
<td class="px-4 py-3 text-center">
|
<td class="px-4 py-3 text-center">
|
||||||
{% if ticket.status == 'new' %}
|
{% if ticket.status == 'new' %}
|
||||||
<span class="px-2 py-1 rounded-full text-xs font-bold bg-blue-500 text-white">{{ ticket.get_status_display }}</span>
|
<span class="px-2 py-1 rounded-full text-xs font-bold bg-blue-500 text-white">{{ ticket.get_status_display }}</span>
|
||||||
@@ -161,9 +205,10 @@
|
|||||||
{% elif ticket.status == 'closed' %}
|
{% elif ticket.status == 'closed' %}
|
||||||
<span class="px-2 py-1 rounded-full text-xs font-bold bg-gray-600 text-white">{{ ticket.get_status_display }}</span>
|
<span class="px-2 py-1 rounded-full text-xs font-bold bg-gray-600 text-white">{{ ticket.get_status_display }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
|
||||||
<td class="px-4 py-3 text-center">
|
<td class="px-4 py-3 text-center">
|
||||||
<span class="px-2 py-1 rounded-full text-xs font-bold bg-blue-500 text-white">{{ ticket.get_mistake_display }}</span>
|
<span class="px-2 py-1 rounded-full text-xs font-bold {% if ticket.mistake == 'typo' %}bg-blue-500 {% elif ticket.mistake == 'formatting_issue' %}bg-purple-500 {% elif ticket.mistake == 'missing_content' %}bg-red-500 {% elif ticket.mistake == 'outdated_content' %}bg-orange-500 {% elif ticket.mistake == 'audio_problem' %}bg-green-500 {% elif ticket.mistake == 'video_problem' %}bg-yellow-500 {% elif ticket.mistake == 'other' %}bg-gray-500 {% else %}bg-gray-400 {% endif %} text-white">
|
||||||
|
{{ ticket.get_mistake_display }}
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3 text-sm text-gray-600">
|
<td class="px-4 py-3 text-sm text-gray-600">
|
||||||
{% if ticket.assigned_to %}
|
{% if ticket.assigned_to %}
|
||||||
@@ -187,11 +232,11 @@
|
|||||||
<div class="text-sm text-gray-600">Seite {{ page_obj.number }} von {{ page_obj.paginator.num_pages }}</div>
|
<div class="text-sm text-gray-600">Seite {{ page_obj.number }} von {{ page_obj.paginator.num_pages }}</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
{% if page_obj.has_previous %}
|
{% if page_obj.has_previous %}
|
||||||
<a href="?page={{ page_obj.previous_page_number }}{% if selected_status %}&status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}"
|
<a href="?page={{ page_obj.previous_page_number }}{% if selected_status %}&status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}{% if selected_course %}&course={{ selected_course }}{% endif %}"
|
||||||
class="px-3 py-1 border border-gray-300 rounded hover:bg-gray-50">Zurück</a>
|
class="px-3 py-1 border border-gray-300 rounded hover:bg-gray-50">Zurück</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if page_obj.has_next %}
|
{% if page_obj.has_next %}
|
||||||
<a href="?page={{ page_obj.next_page_number }}{% if selected_status %}&status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}"
|
<a href="?page={{ page_obj.next_page_number }}{% if selected_status %}&status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}{% if selected_course %}&course={{ selected_course }}{% endif %}"
|
||||||
class="px-3 py-1 border border-gray-300 rounded hover:bg-gray-50">Weiter</a>
|
class="px-3 py-1 border border-gray-300 rounded hover:bg-gray-50">Weiter</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from reportlab.lib.units import cm
|
|||||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
|
||||||
from reportlab.lib.enums import TA_LEFT, TA_CENTER
|
from reportlab.lib.enums import TA_LEFT, TA_CENTER
|
||||||
|
|
||||||
from .models import Ticket, TicketHistory, FAQ
|
from .models import Ticket, TicketHistory, FAQ, Course
|
||||||
|
|
||||||
|
|
||||||
class HomeView(TemplateView):
|
class HomeView(TemplateView):
|
||||||
@@ -47,23 +47,27 @@ class TicketListView(ListView):
|
|||||||
status = self.request.GET.get("status")
|
status = self.request.GET.get("status")
|
||||||
assigned_to = self.request.GET.get("assigned_to")
|
assigned_to = self.request.GET.get("assigned_to")
|
||||||
query = self.request.GET.get("q")
|
query = self.request.GET.get("q")
|
||||||
|
course = self.request.GET.get("course")
|
||||||
|
|
||||||
if status:
|
if status:
|
||||||
queryset = queryset.filter(status=status)
|
queryset = queryset.filter(status=status)
|
||||||
if assigned_to:
|
if assigned_to:
|
||||||
queryset = queryset.filter(assigned_to_id=assigned_to)
|
queryset = queryset.filter(assigned_to_id=assigned_to)
|
||||||
|
if course: # NEU
|
||||||
|
queryset = queryset.filter(course_id=course)
|
||||||
if query:
|
if query:
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
Q(title__icontains=query) | Q(description__icontains=query)
|
Q(title__icontains=query) | Q(description__icontains=query)
|
||||||
)
|
)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context["selected_status"] = self.request.GET.get("status", "")
|
context["selected_status"] = self.request.GET.get("status", "")
|
||||||
|
context["selected_course"] = self.request.GET.get("course", "")
|
||||||
context["search_query"] = self.request.GET.get("q", "")
|
context["search_query"] = self.request.GET.get("q", "")
|
||||||
context["status_choices"] = Ticket.STATUS_CHOICES
|
context["status_choices"] = Ticket.STATUS_CHOICES
|
||||||
|
context["courses"] = Course.objects.filter(is_active=True)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user