diff --git a/data/sitetree.json b/data/sitetree.json
index 26c70ca3..b910e5be 100644
--- a/data/sitetree.json
+++ b/data/sitetree.json
@@ -695,13 +695,13 @@
"alias": null,
"description": "",
"hidden": false,
- "hint": "",
+ "hint": "To, co ŘEŠITELÉ poslali",
"inbreadcrumbs": true,
"inmenu": true,
"insitetree": true,
"parent": 21,
- "sort_order": 37,
- "title": "Odevzdaná řešení",
+ "sort_order": 38,
+ "title": "Došlá řešení",
"tree": 1,
"url": "odevzdavatko_tabulka",
"urlaspattern": true
@@ -724,7 +724,7 @@
"inmenu": true,
"insitetree": true,
"parent": 21,
- "sort_order": 38,
+ "sort_order": 42,
"title": "Odhlásit se",
"tree": 1,
"url": "logout",
@@ -806,5 +806,31 @@
},
"model": "sitetree.treeitem",
"pk": 41
+ },
+ {
+ "fields": {
+ "access_guest": false,
+ "access_loggedin": false,
+ "access_perm_type": 1,
+ "access_permissions": [
+ 2
+ ],
+ "access_restricted": true,
+ "alias": null,
+ "description": "",
+ "hidden": false,
+ "hint": "To, co jsem JÁ odevzdal",
+ "inbreadcrumbs": true,
+ "inmenu": true,
+ "insitetree": true,
+ "parent": 21,
+ "sort_order": 37,
+ "title": "Odevzdaná řešení",
+ "tree": 1,
+ "url": "seminar_resitel_odevzdana_reseni",
+ "urlaspattern": true
+ },
+ "model": "sitetree.treeitem",
+ "pk": 42
}
]
\ No newline at end of file
diff --git a/seminar/templates/seminar/odevzdavatko/resitel_prehled.html b/seminar/templates/seminar/odevzdavatko/resitel_prehled.html
new file mode 100644
index 00000000..be2e94bd
--- /dev/null
+++ b/seminar/templates/seminar/odevzdavatko/resitel_prehled.html
@@ -0,0 +1,38 @@
+{% extends "base.html" %}
+{% load static %}
+{% load deadliny %}
+
+{% block custom_css %}
+
+{% endblock custom_css %}
+
+{% block content %}
+{% for rocnik, hodnoceni in podle_rocniku %}
+
Ročník {{ rocnik }}
+
+
+ Doručeno |
+ Problém |
+ Body |
+ Deadline |
+
+ {% for hodn in hodnoceni %}
+
+ {{ hodn.reseni.cas_doruceni }} |
+ {{ hodn.problem }} |
+ {{ hodn.body|default_if_none:"---" }} |
+ {{ hodn.reseni.cas_doruceni | deadline_html }} |
+
+ {% endfor %}
+
+{% endfor %}
+{% endblock %}
diff --git a/seminar/templates/seminar/profil/resitel.html b/seminar/templates/seminar/profil/resitel.html
index 8f29d246..364bd541 100644
--- a/seminar/templates/seminar/profil/resitel.html
+++ b/seminar/templates/seminar/profil/resitel.html
@@ -11,6 +11,7 @@
Odhlásit se
Upravit údaje
+Odevzdaná řešení
{% endblock %}
diff --git a/seminar/templatetags/deadliny.py b/seminar/templatetags/deadliny.py
index b7a0142d..81500d73 100644
--- a/seminar/templatetags/deadliny.py
+++ b/seminar/templatetags/deadliny.py
@@ -13,10 +13,20 @@ def deadline_text(datum):
}
return strings[typ]
+@register.filter(name='deadline_kratseji')
+def deadline_kratsi_text(datum):
+ typ, cislo, dl = deadline(datum)
+ strings = {
+ TypDeadline.PredDeadline: f"1. deadline {cislo}",
+ TypDeadline.SousDeadline: f"Soustřeďkový deadline {cislo}",
+ TypDeadline.FinalDeadline: f"Finální deadline {cislo}",
+ }
+ return strings[typ]
+
@register.filter(name='deadline_html')
def deadline_html(datum):
typ, _, _ = deadline(datum)
- text = deadline_text(datum)
+ text = deadline_kratsi_text(datum)
classes = {
TypDeadline.PredDeadline: 'preddeadline',
TypDeadline.SousDeadline: 'sous_deadline',
diff --git a/seminar/urls.py b/seminar/urls.py
index e5b79e01..8ee67404 100644
--- a/seminar/urls.py
+++ b/seminar/urls.py
@@ -135,6 +135,7 @@ urlpatterns = [
path('prihlasit/', views.LoginView.as_view(), name='login'),
path('odhlasit/', views.LogoutView.as_view(), name='logout'),
path('resitel/', resitel_required(views.ResitelView.as_view()), name='seminar_resitel'),
+ path('resitel/odevzdana_reseni/', resitel_required(views.PrehledOdevzdanychReseni.as_view()), name='seminar_resitel_odevzdana_reseni'),
path('reset-hesla/', views.PasswordResetView.as_view(), name='reset_password'),
path('zmena-hesla/', views.PasswordChangeView.as_view(), name='change_password'),
path('reset-hesla/2/', views.PasswordResetDoneView.as_view(), name='reset_password_done'),
diff --git a/seminar/views/odevzdavatko.py b/seminar/views/odevzdavatko.py
index 3aa7e469..585727a5 100644
--- a/seminar/views/odevzdavatko.py
+++ b/seminar/views/odevzdavatko.py
@@ -25,6 +25,8 @@ logger = logging.getLogger(__name__)
# - ReseniProblemuView
# - Detail konkrétního řešení -- všechny soubory, datum, ...
# - DetailReseniView
+# - Pro řešitele: přehled jejich odevzdaných řešení
+# - PrehledOdevzdanychReseni
#
# Taky se může hodit:
# - Tabulka všech řešitelů x všech problémů?
@@ -238,6 +240,29 @@ def hodnoceniReseniView(request, pk, *args, **kwargs):
return redirect(success_url)
+class PrehledOdevzdanychReseni(ListView):
+ model = m.Hodnoceni
+ template_name = 'seminar/odevzdavatko/resitel_prehled.html'
+
+ def get_queryset(self):
+ if not self.request.user.is_authenticated:
+ raise RuntimeError("Uživatel měl být přihlášený!")
+ resitel = m.Resitel.objects.get(osoba__user=self.request.user)
+ qs = super().get_queryset()
+ qs = qs.filter(reseni__resitele__in=[resitel])
+ return qs
+
+ def get_context_data(self, *args, **kwargs):
+ ctx = super().get_context_data(*args, **kwargs)
+ # Ročník určujeme podle čísla, do jehož deadlinu došlo řešení.
+ # Chceme to mít seřazené, takže místo comphrerehsion ručně postavíme pole polí. Django templates neumí použít OrderedDict :-/
+ podle_rocniku = []
+ for rocnik, hodnoceni in groupby(ctx['object_list'], lambda ho: deadline(ho.reseni.cas_doruceni)[1].rocnik):
+ podle_rocniku.append((rocnik, list(hodnoceni)))
+ ctx['podle_rocniku'] = reversed(podle_rocniku) # Od nejnovějšího ročníku
+ # TODO: Umožnit stažení / zobrazení řešení
+ return ctx
+
# Přehled všech řešení kvůli debugování
class SeznamReseniView(ListView):