Skip to content

Commit

Permalink
Allow filtering per date in the calendar view.
Browse files Browse the repository at this point in the history
  • Loading branch information
Theophile-Madet committed Oct 20, 2023
1 parent da62f7f commit cdae3ac
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 51 deletions.
10 changes: 1 addition & 9 deletions tapir/shifts/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def register_sidebar_links(cls):
shifts_group.add_link(
display_name=_("Shift calendar"),
material_icon="calendar_today",
url=reverse_lazy("shifts:calendar_future"),
url=reverse_lazy("shifts:calendar"),
ordering=1,
)

Expand All @@ -57,14 +57,6 @@ def register_sidebar_links(cls):
on_render=cls.get_link_display_name_abcd_calendar,
)

shifts_group.add_link(
display_name=_("Past shifts"),
material_icon="history",
url=reverse_lazy("shifts:calendar_past"),
required_permissions=[PERMISSION_SHIFTS_MANAGE],
ordering=4,
)

shifts_group.add_link(
display_name=_("Shift statistics"),
material_icon="calculate",
Expand Down
24 changes: 24 additions & 0 deletions tapir/shifts/templates/shifts/shift_calendar_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,30 @@ <h5 class="card-header">
</div>
{% shift_filters %}
</div>
<div class="card mb-2">
<h5 class="card-header">
{% translate "Date range" %}
</h5>
<div class="card-body d-flex gap-4">
<script>
function onFilter() {
let url = "{% url "shifts:calendar" %}";
url += "?date_from=" + document.getElementById("date-from").value;
url += "&date_to=" + document.getElementById("date-to").value;
window.location = url;
}
</script>
<div class="d-flex align-items-baseline gap-2">
<label for="date-from" class="form-label">{% translate "From" %}</label>
<input id="date-from" type="date" value="{{ date_from }}" class="form-control" style="max-width: 160px"/>
</div>
<div class="d-flex align-items-baseline gap-2">
<label for="date-to" class="form-label">{% translate "To" %}</label>
<input id="date-to" type="date" value="{{ date_to }}" class="form-control" style="max-width: 160px"/>
</div>
<button class="{% tapir_button_link %}" onclick="onFilter()">{% translate "Filter" %}</button>
</div>
</div>
{% for week, shifts_by_day in shifts_by_weeks_and_days.items %}
<div class="card mb-2">
{% with week_group=week_to_group|dictionary_get:week %}
Expand Down
10 changes: 3 additions & 7 deletions tapir/shifts/tests/test_calendars.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,10 @@
class TestCalendars(TapirFactoryTestBase):
# Minimal tests that the calendar views works, some of them were broken but the tests were still green.

def test_calendar_future_view_response_status_200(self):
def test_calendar_view_response_status_200(self):
self.login_as_normal_user()
response = self.client.get(reverse("shifts:calendar_future"))
self.assertEqual(response.status_code, 200)

def test_calendar_past_view_response_status_200(self):
self.login_as_member_office_user()
response = self.client.get(reverse("shifts:calendar_past"))
test = reverse("shifts:calendar")
response = self.client.get(reverse("shifts:calendar"))
self.assertEqual(response.status_code, 200)

def test_shift_template_overview_view_response_status_200(self):
Expand Down
9 changes: 2 additions & 7 deletions tapir/shifts/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,8 @@
),
path(
"calendar",
views.ShiftCalendarFutureView.as_view(),
name="calendar_future",
),
path(
"calendar_past",
views.ShiftCalendarPastView.as_view(),
name="calendar_past",
views.ShiftCalendarView.as_view(),
name="calendar",
),
path(
"shift_user_data/<int:pk>",
Expand Down
56 changes: 28 additions & 28 deletions tapir/shifts/views/calendars.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
from calendar import MONDAY
from collections import OrderedDict

from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse
from django.utils import timezone
from django.utils.safestring import mark_safe
from django.views.generic import TemplateView
from weasyprint import HTML

from tapir.coop.pdfs import CONTENT_TYPE_PDF
from tapir.settings import PERMISSION_SHIFTS_MANAGE
from tapir.shifts.models import (
Shift,
WEEKDAY_CHOICES,
Expand All @@ -24,29 +23,51 @@


class ShiftCalendarBaseView(TemplateView):
DATE_FORMAT = "%Y-%m-%d"

def get_context_data(self, *args, **kwargs):
context_data = super().get_context_data(**kwargs)

date_from = (
datetime.datetime.strptime(
self.request.GET["date_from"], self.DATE_FORMAT
).date()
if "date_from" in self.request.GET.keys()
else get_monday(timezone.now())
)
date_to = (
datetime.datetime.strptime(
self.request.GET["date_to"], self.DATE_FORMAT
).date()
if "date_to" in self.request.GET.keys()
else date_from + datetime.timedelta(days=60)
)
context_data["date_from"] = date_from.strftime(self.DATE_FORMAT)
context_data["date_to"] = date_to.strftime(self.DATE_FORMAT)

context_data["nb_days_for_self_unregister"] = Shift.NB_DAYS_FOR_SELF_UNREGISTER
# Because the shift views show a lot of shifts,
# we preload all related objects to avoid doing many database requests.
upcoming_shifts = (
self.get_queryset()
.prefetch_related("slots")
shifts = (
Shift.objects.prefetch_related("slots")
.prefetch_related("slots__attendances")
.prefetch_related("slots__attendances__user")
.prefetch_related("slots__slot_template")
.prefetch_related("slots__slot_template__attendance_template")
.prefetch_related("slots__slot_template__attendance_template__user")
.prefetch_related("shift_template")
.prefetch_related("shift_template__group")
.filter(
start_time__gte=date_from,
start_time__lt=date_to + datetime.timedelta(days=1),
)
)

# A nested dict containing weeks (indexed by the Monday of the week), then days, then a list of shifts
# OrderedDict[OrderedDict[list]]
shifts_by_weeks_and_days = OrderedDict()
week_to_group = {}
for shift in upcoming_shifts:
for shift in shifts:
shift_day = shift.start_time.date()
shift_week_monday = shift_day - datetime.timedelta(days=shift_day.weekday())

Expand All @@ -66,7 +87,7 @@ def get_context_data(self, *args, **kwargs):
return context_data


class ShiftCalendarFutureView(LoginRequiredMixin, ShiftCalendarBaseView):
class ShiftCalendarView(LoginRequiredMixin, ShiftCalendarBaseView):
template_name = "shifts/shift_calendar_future.html"

def get_queryset(self):
Expand All @@ -82,27 +103,6 @@ def get_queryset(self):
).order_by("start_time")


class ShiftCalendarPastView(
LoginRequiredMixin, PermissionRequiredMixin, ShiftCalendarBaseView
):
permission_required = PERMISSION_SHIFTS_MANAGE
template_name = "shifts/shift_calendar_past.html"

def get_queryset(self):
return Shift.objects.filter(
start_time__gte=datetime.date.today() - datetime.timedelta(days=8 * 7),
end_time__lt=datetime.date.today(),
).order_by("start_time")

def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
# We order by start time to get proper day and time ordering, but want to display weeks in reverse
context["shifts_by_weeks_and_days"] = OrderedDict(
reversed(context["shifts_by_weeks_and_days"].items())
)
return context


class ShiftTemplateOverview(LoginRequiredMixin, SelectedUserViewMixin, TemplateView):
template_name = "shifts/shift_template_overview.html"

Expand Down

0 comments on commit cdae3ac

Please sign in to comment.