Skip to content
Snippets Groups Projects
Verified Commit b385fc4c authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Start migrating the timetable view to SchoolApps' templates

Current status: Time and weekday headings are shown

- Add custom stylesheets from SchoolApps to timetable.css
- Customize plan.html for new data structure
- Change sorting of lessons from column-based to row-based system to support CSS and HTML structures better
- Add plan.html instead of tt_week.html to timetable view
- Add short variants of weekday names
parent cccf3fc9
No related branches found
No related tags found
1 merge request!31Biscuit merge. Closes #53.
......@@ -158,6 +158,16 @@ class TimePeriod(models.Model):
(6, _("Saturday")),
]
WEEKDAY_CHOICES_SHORT = [
(0, _("Sun")),
(1, _("Mon")),
(2, _("Tue")),
(3, _("Wed")),
(4, _("Thu")),
(5, _("Fri")),
(6, _("Sat")),
]
weekday = models.PositiveSmallIntegerField(verbose_name=_("Week day"), choices=WEEKDAY_CHOICES)
period = models.PositiveSmallIntegerField(verbose_name=_("Number of period"))
......
.chronos-lesson {
height: 6em;
/*+++++++++++*/
/* Timetable */
/*+++++++++++*/
.smart-plan-badge {
margin: 5px 20px 5px 0;
}
ul#timetable_select_form li {
dispaly: inline;
li.active > a > .sidenav-badge {
background-color: whitesmoke !important;
color: #DA3D56 !important;
}
.timetable-plan .row, .timetable-plan .col {
display: flex;
padding: 0 .25rem;
}
.timetable-plan .row {
margin-bottom: .25rem;
}
.lesson-card, .timetable-title-card {
margin: 0;
display: flex;
flex-grow: 1;
min-height: 65px;
}
.lesson-card .card-content {
padding: 0;
text-align: center;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.lesson-card .card-content div {
padding: 3px;
flex: auto;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.timetable-title-card .card-content {
padding: 10px;
text-align: center;
width: 100%;
}
.timetable-mobile-title-card {
margin-top: 50px;
margin-bottom: .60rem;
}
.timetable-mobile-title-card:first-child {
margin-top: -10px;
margin-bottom: .60rem;
}
.timetable-mobile-title-card .card-content {
padding: 10px;
text-align: center;
width: 100%;
}
.timetable-mobile-title-card .card-content .card-title {
font-weight: bold;
}
table.substitutions td, table.substitutions th {
padding: 10px 5px;
}
.chronos-lesson-cancelled {
background-color: inherit !important;
text-decoration: line-through;
.lesson-with-sub {
border: 3px solid red;
border-radius: 3px;
}
.lesson-with-sub .badge {
margin: 0;
}
.lesson-with-event {
border: 3px solid #9c27b0;
border-radius: 3px;
}
.lesson-card a, .substitutions a {
color: inherit;
}
/*.timetable-time {*/
/*margin-right: 20px;*/
/*}*/
{% extends 'core/base.html' %}
{% load copy_filter %}
<script type="text/javascript">
{% load data_helpers static %}
{% block extra_head %}
<link rel="stylesheet" href="{% static 'css/chronos/timetable.css' %}">
{% endblock %}
{% block content %}
<script type="text/javascript">
{% if smart %}
var week = {{ selected_week }};
var year = {{ selected_year }};
function goToCalendarWeek(cw, year) {
window.location.href = "{% url "timetable_smart_plan" raw_type id %}/" + year + "/" + cw;
}
function onCalendarWeekChanged(where) {
goToCalendarWeek($(where).val(), year);
}
var week = {{ selected_week }};
var year = {{ selected_year }};
function goToCalendarWeek(cw, year) {
window.location.href = "{% url "timetable_smart_plan" type pk %}/" + year + "/" + cw;
}
function onCalendarWeekChanged(where) {
goToCalendarWeek($(where).val(), year);
}
function weekBefore() {
if (week > 1) {
goToCalendarWeek(week - 1, year)
} else {
goToCalendarWeek(52, year - 1)
}
function weekBefore() {
if (week > 1) {
goToCalendarWeek(week - 1, year)
} else {
goToCalendarWeek(52, year - 1)
}
}
function weekNext() {
if (week < 52) {
goToCalendarWeek(week + 1, year);
} else {
goToCalendarWeek(1, year + 1);
}
function weekNext() {
if (week < 52) {
goToCalendarWeek(week + 1, year);
} else {
goToCalendarWeek(1, year + 1);
}
}
$(document).ready(function () {
$("#calendar-week-1").change(function () {
onCalendarWeekChanged("#calendar-week-1");
});
$("#calendar-week-2").change(function () {
onCalendarWeekChanged("#calendar-week-2");
});
$("#calendar-week-3").change(function () {
onCalendarWeekChanged("#calendar-week-3");
});
$("#week-before").click(weekBefore);
$("#week-next").click(weekNext);
$(document).ready(function () {
$("#calendar-week-1").change(function () {
onCalendarWeekChanged("#calendar-week-1");
});
$("#calendar-week-2").change(function () {
onCalendarWeekChanged("#calendar-week-2");
});
$("#calendar-week-3").change(function () {
onCalendarWeekChanged("#calendar-week-3");
});
$("#week-before").click(weekBefore);
$("#week-next").click(weekNext);
});
{% endif %}
</script>
{% block content %}
<div class="row no-margin">
<div class="col s8 m6 l8 xl9">
<h3>
Stundenplan <i>{{ el }}</i>
</h3>
</script>
<div class="row no-margin">
<div class="col s8 m6 l8 xl9">
<h4>
Stundenplan <i>{{ el }}</i>
</h4>
{# Show class teacher and deputy class teacher #}
{% if type == 2 and el.teachers %}
<h5>Klassenlehrkräfte:
{% for teacher in el.teachers %}
{# Show class teacher and deputy class teacher #}
{% if type == 2 and el.teachers %}
<h5>Klassenlehrkräfte:
{% for teacher in el.teachers %}
<span data-position="bottom" class="tooltipped"
data-tooltip="{{ teacher }}">
<a href="{% url "timetable_smart_plan" "teacher" teacher.id %}">
<span data-position="bottom" class="tooltipped"
data-tooltip="{{ teacher }}">
<a href="{% url "timetable" "teacher" teacher.id %}">
{{ teacher.shortcode }}</a></span>{% if not forloop.last %},{% endif %}
{% endfor %}
</h5>
{% endif %}
</div>
{# Show print button only if not on mobile #}
<div class="col s4 m6 l4 xl3 right align-right no-print">
<a class="waves-effect waves-teal btn-flat btn-flat-medium right hide-on-small-and-down" id="print">
<i class="material-icons center">print</i>
</a>
</div>
{% endfor %}
</h5>
{% endif %}
</div>
<div class="row">
{% if smart %}
{# Show if smart #}
{# Toggle button to regular and smart plan badge #}
<div class="row s12 m6 left">
<span class="badge new primary-color left smart-plan-badge">SMART PLAN</span>
{# Show print button only if not on mobile #}
<div class="col s4 m6 l4 xl3 right align-right no-print">
<a class="waves-effect waves-teal btn-flat btn-flat-medium right hide-on-small-and-down" id="print">
<i class="material-icons center">print</i>
</a>
</div>
</div>
<div class="row">
{% if smart %}
{# Show if smart #}
{# Toggle button to regular and smart plan badge #}
<div class="row s12 m6 left">
<span class="badge new primary-color left smart-plan-badge">SMART PLAN</span>
<a class="waves-effect waves-light btn-flat no-print" style="padding-left: 3px; padding-right: 3px;"
href="{% url "timetable_regular_plan" raw_type id "regular" %}">
<i class="material-icons left">slideshow</i>
REGELPLAN ANZEIGEN
</a>
</div>
<a class="waves-effect waves-light btn-flat no-print" style="padding-left: 3px; padding-right: 3px;"
href="#{# url "timetable_regular_plan" raw_type id "regular" #}">
<i class="material-icons left">slideshow</i>
REGELPLAN ANZEIGEN
</a>
</div>
{# Week select #}
<div class="col s12 m6 right">
<div class="col s2 no-print">
<a class="waves-effect waves-teal btn-flat btn-flat-medium right" id="week-before">
<i class="material-icons center">navigate_before</i>
</a>
</div>
<div class="input-field col s8 no-margin hide-on-med-and-up">
<select id="calendar-week-1">
{% for week in weeks %}
<option value="{{ week.calendar_week }}" {% if week.calendar_week == selected_week %}
selected {% endif %}> KW {{ week.calendar_week }}
({{ week.first_day|date:"j.n" }}–{{ week.last_day|date:"j.n" }})
</option>
{% endfor %}
</select>
</div>
<div class="input-field col s8 no-margin hide-on-med-and-down">
<select id="calendar-week-2">
{% for week in weeks %}
<option value="{{ week.calendar_week }}" {% if week.calendar_week == selected_week %}
selected {% endif %}> KW {{ week.calendar_week }} ({{ week.first_day|date:"j.n.Y" }}–{{ week.last_day|date:"j.n.Y" }})
</option>
{% endfor %}
</select>
</div>
<div class="input-field col s8 no-margin hide-on-small-and-down hide-on-large-only">
<select id="calendar-week-3">
{% for week in weeks %}
<option value="{{ week.calendar_week }}" {% if week.calendar_week == selected_week %}
selected {% endif %}> KW {{ week.calendar_week }}
({{ week.first_day|date:"j.n" }}–{{ week.last_day|date:"j.n.Y" }})
</option>
{% endfor %}
</select>
</div>
<div class="col s2 no-print">
<a class="waves-effect waves-teal btn-flat btn-flat-medium left" id="week-next">
<i class="material-icons center">navigate_next</i>
</a>
</div>
</div>
{# Week select #}
<div class="col s12 m6 right">
<div class="col s2 no-print">
<a class="waves-effect waves-teal btn-flat btn-flat-medium right" id="week-before">
<i class="material-icons center">navigate_before</i>
</a>
</div>
<div class="input-field col s8 no-margin hide-on-med-and-up">
<select id="calendar-week-1">
{% for week in weeks %}
<option value="{{ week.calendar_week }}" {% if week.calendar_week == selected_week %}
selected {% endif %}> KW {{ week.calendar_week }}
({{ week.first_day|date:"j.n" }}–{{ week.last_day|date:"j.n" }})
</option>
{% endfor %}
</select>
</div>
<div class="input-field col s8 no-margin hide-on-med-and-down">
<select id="calendar-week-2">
{% for week in weeks %}
<option value="{{ week.calendar_week }}" {% if week.calendar_week == selected_week %}
selected {% endif %}> KW {{ week.calendar_week }}
({{ week.first_day|date:"j.n.Y" }}–{{ week.last_day|date:"j.n.Y" }})
</option>
{% endfor %}
</select>
</div>
<div class="input-field col s8 no-margin hide-on-small-and-down hide-on-large-only">
<select id="calendar-week-3">
{% for week in weeks %}
<option value="{{ week.calendar_week }}" {% if week.calendar_week == selected_week %}
selected {% endif %}> KW {{ week.calendar_week }}
({{ week.first_day|date:"j.n" }}–{{ week.last_day|date:"j.n.Y" }})
</option>
{% endfor %}
</select>
</div>
<div class="col s2 no-print">
<a class="waves-effect waves-teal btn-flat btn-flat-medium left" id="week-next">
<i class="material-icons center">navigate_next</i>
</a>
</div>
</div>
{% else %}
{# Show if regular #}
<a class="waves-effect waves-light btn-flat no-print"
href="{% url "timetable_smart_plan" raw_type id %}">
<i class="material-icons left">slideshow</i>
SMART PLAN ANZEIGEN
</a>
{% endif %}
</div>
{% else %}
{# Show if regular #}
<a class="waves-effect waves-light btn-flat no-print"
href="{% url "timetable" type pk %}">
<i class="material-icons left">slideshow</i>
SMART PLAN ANZEIGEN
</a>
{% endif %}
</div>
{% include "timetable/hintsinplan.html" %}
{# {% include "chronos/hintsinplan.html" %}#}
{# show full timetable on tablets, laptops and pcs #}
<div class="timetable-plan hide-on-small-and-down">
{# show full timetable on tablets, laptops and pcs #}
<div class="timetable-plan hide-on-small-and-down">
{# Week days #}
<div class="row">
<div class="col s2">
{# Week days #}
<div class="row">
<div class="col s2">
</div>
{# Show short weekdays on tablets #}
{% for day in short_week_days|deepcopy %}
<div class="col s2 hide-on-large-only">
<div class="card timetable-title-card">
<div class="card-content">
</div>
{# Show short weekdays on tablets #}
{% for day in weekdays_short.items %}
<div class="col s2 hide-on-large-only">
<div class="card timetable-title-card">
<div class="card-content">
<span class="card-title">
{{ day.0 }}
{{ day.1 }}
</span>
{% if day.1 %}
<span class="badge new blue center-align holiday-badge">{{ day.1.0 }}</span>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{# Show long weekdays elsewere #}
{% for day in long_week_days|deepcopy %}
<div class="col s2 hide-on-med-only">
<div class="card timetable-title-card">
<div class="card-content">
{# {% if day.1 %}#}
{# <span class="badge new blue center-align holiday-badge">{{ day.1.0 }}</span>#}
{# {% endif %}#}
</div>
</div>
</div>
{% endfor %}
{# Show long weekdays elsewere #}
{% for day in weekdays.items %}
<div class="col s2 hide-on-med-only">
<div class="card timetable-title-card">
<div class="card-content">
<span class="card-title">
{{ day.0.0 }}
{{ day.1 }}
</span>
{% if day.1 %}
<span class="badge new blue center-align holiday-badge">{{ day.1.0 }}</span>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{# {% if day.1 %}#}
{# <span class="badge new blue center-align holiday-badge">{{ day.1.0 }}</span>#}
{# {% endif %}#}
</div>
</div>
</div>
{% endfor %}
</div>
{# Lessons #}
{% for row, time in plan|deepcopy %}
<div class="row">
<div class="col s2">
<div class="card timetable-title-card">
<div class="card-content">
{# Lessons #}
{% for period, lesson_periods_period in lesson_periods.items %}
{# Lesson number #}
<span class="card-title left">
{{ time.number_format }}
</span>
<div class="row">
<div class="col s2">
<div class="card timetable-title-card">
<div class="card-content">
{# Time dimension of lesson #}
<div class="right timetable-time grey-text text-darken-2">
<span>{{ time.start|date:"H:i" }}</span>
<br>
<span>{{ time.end|date:"H:i" }}</span>
</div>
</div>
</div>
{# Lesson number #}
<span class="card-title left">
{{ period }}.
</span>
</div>
{% for col in row %}
{# A lesson #}
<div class="col s2">
{% include "timetable/lesson.html" %}
</div>
{% endfor %}
{# Time dimension of lesson #}
<div class="right timetable-time grey-text text-darken-2">
{% with period_obj=periods|get_dict:period %}
<span>{{ period_obj.0|date:"H:i" }}</span>
<br>
<span>{{ period_obj.1|date:"H:i" }}</span>
{% endwith %}
</div>
</div>
</div>
</div>
{% for col in row %}
{# A lesson #}
<div class="col s2">
{% include "timetable/lesson.html" %}
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
{# show 5 seperate ones on mobiles #}
<div class="timetable-plan hide-on-med-and-up">
{% for day in long_week_days|deepcopy %}
<div class="card timetable-mobile-title-card">
<div class="card-content">
{# show 5 seperate ones on mobiles #}
<div class="timetable-plan hide-on-med-and-up">
{% for day in long_week_days %}
<div class="card timetable-mobile-title-card">
<div class="card-content">
<span class="card-title">
{{ day.0.0 }}
</span>
{% if day.1 %}
<span class="badge new blue center-align holiday-badge">{{ day.1.0 }}</span>
{% endif %}
&nbsp;
</div>
</div>
{% for row, time in plan|deepcopy %}
<div class="row">
<div class="col s4">
<div class="card timetable-title-card">
<div class="card-content">
{% if day.1 %}
<span class="badge new blue center-align holiday-badge">{{ day.1.0 }}</span>
{% endif %}
&nbsp;
</div>
</div>
{% for row, time in plan %}
<div class="row">
<div class="col s4">
<div class="card timetable-title-card">
<div class="card-content">
{# Lesson number #}
<span class="card-title left">
{# Lesson number #}
<span class="card-title left">
{{ time.number_format }}
</span>
{# Time dimension of lesson #}
<div class="right timetable-time grey-text text-darken-2">
<span>{{ time.start|date:"H:i" }}</span>
<br>
<span>{{ time.end|date:"H:i" }}</span>
</div>
</div>
</div>
</div>
{% for col in row|deepcopy %}
{% if forloop.counter0 == day.0.1 %}
<div class="col s8">
{# A lesson #}
{% include "timetable/lesson.html" %}
</div>
{% endif %}
{% endfor %}
{# Time dimension of lesson #}
<div class="right timetable-time grey-text text-darken-2">
<span>{{ time.start|date:"H:i" }}</span>
<br>
<span>{{ time.end|date:"H:i" }}</span>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
</div>
{% for col in row %}
{% if forloop.counter0 == day.0.1 %}
<div class="col s8">
{# A lesson #}
{% include "timetable/lesson.html" %}
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endblock %}
......@@ -23,7 +23,6 @@ from .util import CalendarWeek
@login_required
def all(request: HttpRequest) -> HttpResponse:
context = {}
teachers = Person.objects.annotate(lessons_count=Count("lessons_as_teacher")).filter(lessons_count__gt=0)
......@@ -69,53 +68,61 @@ def timetable(
# return redirect(reverse("timetable") + "?teacher=%d" % request.user.person.pk)
# Regroup lesson periods per weekday
per_day = {}
per_period = {}
for lesson_period in lesson_periods:
per_day.setdefault(lesson_period.period.weekday, {})[
lesson_period.period.period
print(lesson_period.period)
per_period.setdefault(lesson_period.period.period, {})[
lesson_period.period.weekday
] = lesson_period
print(per_period)
# Determine overall first and last day and period
min_max = TimePeriod.objects.aggregate(
Min("period"), Max("period"), Min("weekday"), Max("weekday")
)
period_min = min_max.get("period__min", 1)
period_max = min_max.get("period__max", 7)
weekday_min = min_max.get("weekday__min", 0)
weekday_max = min_max.get("weekday__max", 6)
# Fill in empty lessons
for weekday_num in range(min_max.get("weekday__min", 0), min_max.get("weekday__max", 6) + 1):
for period_num in range(period_min, period_max + 1):
print(period_num)
# Fill in empty weekdays
if weekday_num not in per_day.keys():
per_day[weekday_num] = {}
if period_num not in per_period.keys():
per_period[period_num] = {}
# Fill in empty lessons on this workday
for period_num in range(min_max.get("period__min", 1), min_max.get("period__max", 7) + 1):
if period_num not in per_day[weekday_num].keys():
per_day[weekday_num][period_num] = None
for weekday_num in range(weekday_min, weekday_max + 1):
if weekday_num not in per_period[period_num].keys():
per_period[period_num][weekday_num] = None
# Order this weekday by periods
per_day[weekday_num] = OrderedDict(sorted(per_day[weekday_num].items()))
# Add a form to filter the view
select_form = SelectForm(request.GET or None)
per_period[period_num] = OrderedDict(sorted(per_period[period_num].items()))
context["current_head"] = _("Timetable")
context["lesson_periods"] = OrderedDict(sorted(per_day.items()))
print(lesson_periods)
context["lesson_periods"] = OrderedDict(sorted(per_period.items()))
context["periods"] = TimePeriod.get_times_dict()
context["weekdays"] = dict(TimePeriod.WEEKDAY_CHOICES)
context["weekdays"] = dict(TimePeriod.WEEKDAY_CHOICES[weekday_min:weekday_max + 1])
context["weekdays_short"] = dict(TimePeriod.WEEKDAY_CHOICES_SHORT[weekday_min:weekday_max + 1])
context["week"] = wanted_week
context["select_form"] = select_form
context["type"] = _type
context["pk"] = pk
week_prev = wanted_week - 1
week_next = wanted_week + 1
context["url_prev"] = "%s?%s" % (
reverse("timetable_by_week", args=[week_prev.year, week_prev.week]),
reverse("timetable_by_week", args=[_type, pk, week_prev.year, week_prev.week]),
request.GET.urlencode(),
)
context["url_next"] = "%s?%s" % (
reverse("timetable_by_week", args=[week_next.year, week_next.week]),
reverse("timetable_by_week", args=[_type, pk, week_next.year, week_next.week]),
request.GET.urlencode(),
)
return render(request, "chronos/tt_week.html", context)
return render(request, "chronos/plan.html", context)
@login_required
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment