From 5214a2158fae35c5178a357395e51dcbb190df30 Mon Sep 17 00:00:00 2001
From: Hangzhi Yu <hangzhi@protonmail.com>
Date: Fri, 31 May 2024 16:41:34 +0200
Subject: [PATCH] Add filter for incomplete substitutions

---
 .../frontend/components/SubstitutionOverview.vue     | 12 ++++++++++++
 .../chronos/frontend/components/amendLesson.graphql  |  2 ++
 aleksis/apps/chronos/frontend/messages/en.json       |  3 ++-
 aleksis/apps/chronos/models.py                       |  3 +++
 aleksis/apps/chronos/schema/__init__.py              |  5 +++--
 5 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/aleksis/apps/chronos/frontend/components/SubstitutionOverview.vue b/aleksis/apps/chronos/frontend/components/SubstitutionOverview.vue
index 4f4d08bf..04a20e63 100644
--- a/aleksis/apps/chronos/frontend/components/SubstitutionOverview.vue
+++ b/aleksis/apps/chronos/frontend/components/SubstitutionOverview.vue
@@ -41,6 +41,16 @@ import {
         @input="changeSelection"
         @click:clear="changeSelection"
       />
+      <v-switch
+        :loading="$apollo.queries.groups.loading"
+        :label="$t('chronos.substitutions.overview.filter.missing')"
+        v-model="incomplete"
+        dense
+        inset
+        hide-details
+        class="ml-6"
+      />
+
       <v-alert type="info" outlined dense class="full-width">
         <v-row align="center" no-gutters>
           <v-col class="grow">
@@ -115,6 +125,7 @@ export default {
       gqlQuery: amendedLessonsFromAbsences,
       gqlPatchMutation: createOrUpdateSubstitutions,
       groups: [],
+      incomplete: false,
     };
   },
   methods: {
@@ -136,6 +147,7 @@ export default {
     gqlQueryArgs() {
       return {
         objId: this.objId ? Number(this.objId) : null,
+        incomplete: !!this.incomplete,
       };
     },
     currentGroup() {
diff --git a/aleksis/apps/chronos/frontend/components/amendLesson.graphql b/aleksis/apps/chronos/frontend/components/amendLesson.graphql
index f36abe98..608acfd8 100644
--- a/aleksis/apps/chronos/frontend/components/amendLesson.graphql
+++ b/aleksis/apps/chronos/frontend/components/amendLesson.graphql
@@ -172,11 +172,13 @@ query amendedLessonsFromAbsences(
   $objId: ID
   $dateStart: Date!
   $dateEnd: Date!
+  $incomplete: Boolean
 ) {
   items: amendedLessonsFromAbsences(
     objId: $objId
     dateStart: $dateStart
     dateEnd: $dateEnd
+    incomplete: $incomplete
   ) {
     id
     oldId
diff --git a/aleksis/apps/chronos/frontend/messages/en.json b/aleksis/apps/chronos/frontend/messages/en.json
index 689c6834..87a05b7d 100644
--- a/aleksis/apps/chronos/frontend/messages/en.json
+++ b/aleksis/apps/chronos/frontend/messages/en.json
@@ -52,7 +52,8 @@
           "button": "Manage absences"
         },
         "filter": {
-          "groups": "Filter by groups"
+          "groups": "Filter by groups",
+          "missing": "Only show incomplete lessons"
         },
         "cancel": {
           "cancelled": "Cancelled",
diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py
index 59b886de..685544c7 100644
--- a/aleksis/apps/chronos/models.py
+++ b/aleksis/apps/chronos/models.py
@@ -1584,6 +1584,7 @@ class LessonEvent(CalendarEvent):
         request: HttpRequest,
         obj_type: Optional[str],
         obj_id: Optional[str],
+        incomplete: Optional[bool] = False,
     ) -> list:
         """Get all the amended lessons for an object and a time frame.
 
@@ -1638,6 +1639,8 @@ class LessonEvent(CalendarEvent):
                 )
 
                 if existing_substitutions.exists():
+                    if incomplete:
+                        continue
                     substitution = existing_substitutions.first()
                     substitutions.append(substitution)
 
diff --git a/aleksis/apps/chronos/schema/__init__.py b/aleksis/apps/chronos/schema/__init__.py
index d2f1c747..05edad1b 100644
--- a/aleksis/apps/chronos/schema/__init__.py
+++ b/aleksis/apps/chronos/schema/__init__.py
@@ -268,6 +268,7 @@ class Query(graphene.ObjectType):
         obj_id=graphene.ID(required=False),
         date_start=graphene.Date(required=True),
         date_end=graphene.Date(required=True),
+        incomplete=graphene.Boolean(required=False),
     )
 
     def resolve_timetable_teachers(self, info, **kwargs):
@@ -311,7 +312,7 @@ class Query(graphene.ObjectType):
         return all_timetables
 
     def resolve_amended_lessons_from_absences(
-        root, info, date_start, date_end, obj_type="GROUP", obj_id=None, **kwargs
+        root, info, date_start, date_end, obj_type="GROUP", obj_id=None, incomplete=False, **kwargs
     ):
         datetime_start = datetime.combine(date_start, datetime.min.time())
         datetime_end = datetime.combine(date_end, datetime.max.time())
@@ -327,7 +328,7 @@ class Query(graphene.ObjectType):
             raise PermissionDenied()
 
         return LessonEvent.get_for_substitution_overview(
-            datetime_start, datetime_end, info.context, obj_type, obj_id
+            datetime_start, datetime_end, info.context, obj_type, obj_id, incomplete
         )
 
 
-- 
GitLab