diff --git a/aleksis/apps/chronos/managers.py b/aleksis/apps/chronos/managers.py index b963a600828d9059852f624091d03fee4139b43b..89e0599844e282b9a07c6c80d13abb008f946d89 100644 --- a/aleksis/apps/chronos/managers.py +++ b/aleksis/apps/chronos/managers.py @@ -209,7 +209,7 @@ class WeekQuerySetMixin: class GroupByPeriodsMixin: - def group_by_periods(self, is_person: bool = False) -> dict: + def group_by_periods(self, is_week: bool = False) -> dict: """Group a QuerySet of objects with attribute period by period numbers and weekdays.""" per_period = {} for obj in self: @@ -217,12 +217,12 @@ class GroupByPeriodsMixin: weekday = obj.period.weekday if period not in per_period: - per_period[period] = [] if is_person else {} + per_period[period] = [] if not is_week else {} - if not is_person and weekday not in per_period[period]: + if is_week and weekday not in per_period[period]: per_period[period][weekday] = [] - if is_person: + if not is_week: per_period[period].append(obj) else: per_period[period][weekday].append(obj) diff --git a/aleksis/apps/chronos/templates/chronos/my_timetable.html b/aleksis/apps/chronos/templates/chronos/my_timetable.html index 897aafdb448da7f282d349a004bc5efc59caa28b..10175bfa4530c7a8016c6397308c5727086eb7a7 100644 --- a/aleksis/apps/chronos/templates/chronos/my_timetable.html +++ b/aleksis/apps/chronos/templates/chronos/my_timetable.html @@ -13,7 +13,7 @@ {% block content %} <div class="row no-margin"> - <div class="col m12 s12 l6 xl4"> + <div class="col s12"> <h4> {% trans "My timetable" %} <i>{{ el }}</i> <span class="badge new primary-color ">{% trans "SMART PLAN" %}</span> @@ -24,36 +24,43 @@ </div> </div> - <div class="row nomargin"> + <div class="row nomargin hide-on-large-only"> <div class="col m12 s12 l6 xl4"> {% include "core/partials/announcements.html" with announcements=announcements %} </div> </div> - <div class="row"> - <div class="timetable-plan col s12 m12 xl4"> - - {# Date #} - - <div class="row"> - <div class="col s12"> - <div class="card timetable-title-card"> - <div class="card-content"> - <span class="card-title"> - {% include "chronos/partials/datepicker.html" with display_date_only=1 %} -{# {% if holiday %}#} -{# <span class="badge new blue center-align holiday-badge">{{ holiday.0 }}</span>#} -{# {% endif %}#} - </span> - </div> - </div> + <div class="row nomargin hide-on-large-med-and-down"> + <div class="col m12 s12 l6 xl4"> + {% include "core/partials/announcements.html" with announcements=week_announcements %} + </div> + </div> + <div class="row"> + <div class="col s12"> + <div class="card timetable-title-card"> + <div class="card-content"> + <span class="card-title"> + {% include "chronos/partials/datepicker.html" with display_date_only=1 %} + <span class="show-on-medium-and-down hide-on-large-only"> + {% if weekday.date == today %} + <br/> {% include "chronos/partials/today.html" %} + {% endif %} + </span> + </span> </div> </div> + </div> + </div> + + <div class="row hide-on-large-only"> + <div class="timetable-plan col s12 m12 xl4"> {# Lessons #} {% include "chronos/partials/lessons_col.html" with lesson_periods=lesson_periods %} - </div> </div> + <div class="row timetable-plan hide-on-med-and-down"> + {% include "chronos/partials/week_timetable.html" with timetable=week_timetable active_day=day today=today %} + </div> {% endblock %} diff --git a/aleksis/apps/chronos/templates/chronos/partials/elements.html b/aleksis/apps/chronos/templates/chronos/partials/elements.html index 82231b1b2bcfdb311ced7ea96d731b7ed9daf62b..825a3291b9d904f277223f5ededa05a301d1e86f 100644 --- a/aleksis/apps/chronos/templates/chronos/partials/elements.html +++ b/aleksis/apps/chronos/templates/chronos/partials/elements.html @@ -1,4 +1,4 @@ -<div class="card lesson-card"> +<div class="card lesson-card {% if week_day == active_day %} z-depth-5 active {% endif %}"> <div class="card-content"> {% for element in elements %} {% if element.label_ == "lesson_period" %} diff --git a/aleksis/apps/chronos/templates/chronos/partials/today.html b/aleksis/apps/chronos/templates/chronos/partials/today.html new file mode 100644 index 0000000000000000000000000000000000000000..8f3897c26b5de1d4c69d825d828e8df6630cf682 --- /dev/null +++ b/aleksis/apps/chronos/templates/chronos/partials/today.html @@ -0,0 +1,2 @@ +{% load i18n %} +<span class="badge new orange center-align holiday-badge">{% trans "Today" %}</span> diff --git a/aleksis/apps/chronos/templates/chronos/partials/week_timetable.html b/aleksis/apps/chronos/templates/chronos/partials/week_timetable.html new file mode 100644 index 0000000000000000000000000000000000000000..95ff53c309ac4e3676f2f51a3f062bc628f858d2 --- /dev/null +++ b/aleksis/apps/chronos/templates/chronos/partials/week_timetable.html @@ -0,0 +1,71 @@ +{# Week days #} +<div class="row"> + <div class="col s1"> + + </div> + {# Show short weekdays on tablets #} + {% for weekday in weekdays_short %} + <div class="col s2 hide-on-large-only"> + <div class="card timetable-title-card"> + <div class="card-content"> + <span class="card-title"> + {{ weekday.name }} + </span> + {% if smart %} + {{ weekday.date }} + {% if weekday.holiday %} + <br/>{% include "chronos/partials/holiday.html" with holiday=weekday.holiday %} + {% endif %} + {% if weekday.date == today %} + <br/> {% include "chronos/partials/today.html" %} + {% endif %} + {% endif %} + </div> + </div> + </div> + {% endfor %} + + {# Show long weekdays elsewere #} + {% for weekday in weekdays %} + <div class="col {% if weekday.date == active_day %} s3 {% else %} s2 {% endif %} hide-on-med-only"> + <div class="card timetable-title-card {% if weekday.date == active_day %} z-depth-5 {% endif %}"> + <div class="card-content"> + <span class="card-title"> + {{ weekday.name }} + </span> + {% if smart %} + {{ weekday.date }} + {% if weekday.holiday %} + <br/>{% include "chronos/partials/holiday.html" with holiday=weekday.holiday %} + {% endif %} + {% if weekday.date == today %} + <br/> {% include "chronos/partials/today.html" %} + {% endif %} + {% endif %} + </div> + </div> + </div> + {% endfor %} +</div> + +{# Lessons #} +{% for row in timetable %} +<div class="row"> + <div class="col s1"> + {% if row.type == "period" %} + {% include "chronos/partials/period_time.html" with period=row.period periods=periods %} + {% endif %} + </div> + + {% for col in row.cols %} + {# A lesson #} + <div class="col {% if forloop.counter0 == active_day.weekday %} s3 {% else %} s2 {% endif %}"> + {% if row.type == "period" %} + {% include "chronos/partials/elements.html" with elements=col week_day=forloop.counter0 active_day=active_day.weekday %} + {% else %} + {% include "chronos/partials/supervision.html" with supervision=col %} + {% endif %} + </div> + {% endfor %} +</div> +{% endfor %} \ No newline at end of file diff --git a/aleksis/apps/chronos/templates/chronos/timetable.html b/aleksis/apps/chronos/templates/chronos/timetable.html index eb0d3e165bd64459ae5f0c8e98cac81af9566bac..07b8402d8c770ba225a16d6f563d8276f0827021 100644 --- a/aleksis/apps/chronos/templates/chronos/timetable.html +++ b/aleksis/apps/chronos/templates/chronos/timetable.html @@ -73,72 +73,7 @@ {# 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"> - - </div> - {# Show short weekdays on tablets #} - {% for weekday in weekdays_short %} - <div class="col s2 hide-on-large-only"> - <div class="card timetable-title-card"> - <div class="card-content"> - <span class="card-title"> - {{ weekday.name }} - </span> - {% if smart %} - {{ weekday.date }} - {% if weekday.holiday %} - <br/>{% include "chronos/partials/holiday.html" with holiday=weekday.holiday %} - {% endif %} - {% endif %} - </div> - </div> - </div> - {% endfor %} - - {# Show long weekdays elsewere #} - {% for weekday in weekdays %} - <div class="col s2 hide-on-med-only"> - <div class="card timetable-title-card"> - <div class="card-content"> - <span class="card-title"> - {{ weekday.name }} - </span> - {% if smart %} - {{ weekday.date }} - {% if weekday.holiday %} - <br/>{% include "chronos/partials/holiday.html" with holiday=weekday.holiday %} - {% endif %} - {% endif %} - </div> - </div> - </div> - {% endfor %} - </div> - - {# Lessons #} - {% for row in timetable %} - <div class="row"> - <div class="col s2"> - {% if row.type == "period" %} - {% include "chronos/partials/period_time.html" with period=row.period periods=periods %} - {% endif %} - </div> - - {% for col in row.cols %} - {# A lesson #} - <div class="col s2"> - {% if row.type == "period" %} - {% include "chronos/partials/elements.html" with elements=col %} - {% else %} - {% include "chronos/partials/supervision.html" with supervision=col %} - {% endif %} - </div> - {% endfor %} - </div> - {% endfor %} + {% include "chronos/partials/week_timetable.html" %} </div> {# show 5 seperate ones on mobiles #} diff --git a/aleksis/apps/chronos/util/build.py b/aleksis/apps/chronos/util/build.py index 1ae528852b1b9734438afa3cee9ff68ad5bb3ee9..d7c189860c376c04a504a0769dcf7023f2b8ab86 100644 --- a/aleksis/apps/chronos/util/build.py +++ b/aleksis/apps/chronos/util/build.py @@ -33,45 +33,64 @@ def build_timetable( is_person = True type_ = obj.timetable_type + is_week = False + if type(date_ref) == CalendarWeek: + is_week = True + if type_ is None: return None # Get matching holidays - if is_person: - holiday = Holiday.on_day(date_ref) - else: + if is_week: holidays_per_weekday = Holiday.in_week(date_ref) + else: + holiday = Holiday.on_day(date_ref) # Get matching lesson periods + lesson_periods = LessonPeriod.objects + if is_week: + lesson_periods = lesson_periods.in_week(date_ref) + else: + lesson_periods = lesson_periods.on_day(date_ref) + if is_person: - lesson_periods = LessonPeriod.objects.daily_lessons_for_person(obj, date_ref) + lesson_periods = lesson_periods.filter_from_person(obj) else: - lesson_periods = LessonPeriod.objects.in_week(date_ref).filter_from_type(type_, obj) + lesson_periods = lesson_periods.filter_from_type(type_, obj) # Sort lesson periods in a dict - lesson_periods_per_period = lesson_periods.group_by_periods(is_person=is_person) + lesson_periods_per_period = lesson_periods.group_by_periods(is_week=is_week) # Get events + extra_lessons = ExtraLesson.objects + if is_week: + extra_lessons = extra_lessons.filter(week=date_ref.week, year=date_ref.year) + else: + extra_lessons = extra_lessons.on_day(date_ref) if is_person: - extra_lessons = ExtraLesson.objects.on_day(date_ref).filter_from_person(obj) + extra_lessons = extra_lessons.filter_from_person(obj) else: - extra_lessons = ExtraLesson.objects.filter( - week=date_ref.week, year=date_ref.year - ).filter_from_type(type_, obj) + extra_lessons = extra_lessons.filter_from_type(type_, obj) # Sort lesson periods in a dict - extra_lessons_per_period = extra_lessons.group_by_periods(is_person=is_person) + extra_lessons_per_period = extra_lessons.group_by_periods(is_week=is_week) # Get events + events = Event.objects + if is_week: + events = events.in_week(date_ref) + else: + events = events.on_day(date_ref) + if is_person: - events = Event.objects.on_day(date_ref).filter_from_person(obj) + events = events.filter_from_person(obj) else: - events = Event.objects.in_week(date_ref).filter_from_type(type_, obj) + events = events.filter_from_type(type_, obj) # Sort events in a dict events_per_period = {} for event in events: - if not is_person and event.date_start < date_ref[TimePeriod.weekday_min]: + if is_week and event.date_start < date_ref[TimePeriod.weekday_min]: # If start date not in current week, set weekday and period to min weekday_from = TimePeriod.weekday_min period_from_first_weekday = TimePeriod.period_min @@ -79,7 +98,7 @@ def build_timetable( weekday_from = event.date_start.weekday() period_from_first_weekday = event.period_from.period - if not is_person and event.date_end > date_ref[TimePeriod.weekday_max]: + if is_week and event.date_end > date_ref[TimePeriod.weekday_max]: # If end date not in current week, set weekday and period to max weekday_to = TimePeriod.weekday_max period_to_last_weekday = TimePeriod.period_max @@ -88,7 +107,7 @@ def build_timetable( period_to_last_weekday = event.period_to.period for weekday in range(weekday_from, weekday_to + 1): - if is_person and weekday != date_ref.weekday(): + if not is_week and weekday != date_ref.weekday(): # If daily timetable for person, skip other weekdays continue @@ -110,17 +129,17 @@ def build_timetable( if period not in events_per_period: events_per_period[period] = [] if is_person else {} - if not is_person and weekday not in events_per_period[period]: + if is_week and weekday not in events_per_period[period]: events_per_period[period][weekday] = [] - if is_person: + if not is_week: events_per_period[period].append(event) else: events_per_period[period][weekday].append(event) if type_ == TimetableType.TEACHER: # Get matching supervisions - if is_person: + if not is_week: week = CalendarWeek.from_date(date_ref) else: week = date_ref @@ -128,22 +147,21 @@ def build_timetable( Supervision.objects.in_week(week).all().annotate_week(week).filter_by_teacher(obj) ) - if is_person: + if not is_week: supervisions = supervisions.filter_by_weekday(date_ref.weekday()) supervisions_per_period_after = {} for supervision in supervisions: weekday = supervision.break_item.weekday period_after_break = supervision.break_item.before_period_number - print(supervision, weekday, period_after_break) if period_after_break not in needed_breaks: needed_breaks.append(period_after_break) - if not is_person and period_after_break not in supervisions_per_period_after: + if is_week and period_after_break not in supervisions_per_period_after: supervisions_per_period_after[period_after_break] = {} - if is_person: + if not is_week: supervisions_per_period_after[period_after_break] = supervision else: supervisions_per_period_after[period_after_break][weekday] = supervision @@ -163,7 +181,7 @@ def build_timetable( "time_end": break_.time_end, } - if not is_person: + if is_week: cols = [] for weekday in range(TimePeriod.weekday_min, TimePeriod.weekday_max + 1): @@ -193,7 +211,7 @@ def build_timetable( "time_end": break_.before_period.time_end, } - if not is_person: + if is_week: cols = [] for weekday in range(TimePeriod.weekday_min, TimePeriod.weekday_max + 1): col = [] diff --git a/aleksis/apps/chronos/views.py b/aleksis/apps/chronos/views.py index 15edc727ff73d47f618b00abcc5b8c94874e87ed..d4b275cfe0e5b0f40e4f72970d81da4f0d876dc1 100644 --- a/aleksis/apps/chronos/views.py +++ b/aleksis/apps/chronos/views.py @@ -71,12 +71,15 @@ def my_timetable( else: wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time()) + wanted_week = CalendarWeek.from_date(wanted_day) + if has_person(request.user): person = request.user.person type_ = person.timetable_type # Build timetable timetable = build_timetable("person", person, wanted_day) + week_timetable = build_timetable("person", person, wanted_week) if type_ is None: # If no student or teacher, redirect to all timetables @@ -85,16 +88,25 @@ def my_timetable( super_el = person.timetable_object context["timetable"] = timetable + context["week_timetable"] = week_timetable context["holiday"] = Holiday.on_day(wanted_day) context["super"] = {"type": type_, "el": super_el} context["type"] = type_ context["day"] = wanted_day + context["today"] = timezone.now().date() + context["week"] = wanted_week context["periods"] = TimePeriod.get_times_dict() context["smart"] = True context["announcements"] = ( Announcement.for_timetables().on_date(wanted_day).for_person(person) ) - + context["week_announcements"] = ( + Announcement.for_timetables() + .within_days(wanted_week[0], wanted_week[6]) + .for_person(person) + ) + context["weekdays"] = build_weekdays(TimePeriod.WEEKDAY_CHOICES, wanted_week) + context["weekdays_short"] = build_weekdays(TimePeriod.WEEKDAY_CHOICES_SHORT, wanted_week) context["url_prev"], context["url_next"] = TimePeriod.get_prev_next_by_day( wanted_day, "my_timetable_by_date" )