From f1a893607e3b2e6a24f112c56f0d78bdb671941f Mon Sep 17 00:00:00 2001
From: Hangzhi Yu <hangzhi@protonmail.com>
Date: Wed, 27 Mar 2024 20:41:25 +0100
Subject: [PATCH] Add success/error indicator for topic field

---
 .../components/coursebook/Coursebook.vue      |  2 +-
 .../components/coursebook/coursebook.graphql  |  2 ++
 .../documentation/LessonSummary.vue           | 25 +++++++++++++++++--
 aleksis/apps/alsijil/schema/documentation.py  |  2 ++
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue
index e2f56912c..3287360be 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue
@@ -49,7 +49,7 @@
           <v-list max-width="100%" class="pt-0 mt-n1">
             <v-list-item
               v-for="doc in day.slice(1)"
-              :key="'documentation-' + doc.id"
+              :key="'documentation-' + (doc.oldId || doc.id)"
             >
               <documentation-modal
                 :documentation="doc"
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql
index c47203625..0701a39f3 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql
@@ -58,6 +58,7 @@ query documentationsForCoursebook(
     datetimeEnd
     dateStart
     dateEnd
+    oldId
     canEdit
     canDelete
   }
@@ -70,6 +71,7 @@ mutation createOrUpdateDocumentations($input: [DocumentationInputType]!) {
       topic
       homework
       groupNote
+      oldId
     }
   }
 }
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue
index ad9a62649..168c7796d 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue
@@ -16,7 +16,13 @@
         @keydown.enter="saveAndBlur"
         :loading="loading"
         :readonly="!documentation.canEdit"
-      />
+        >
+        <template #append>
+          <v-scroll-x-transition>
+            <v-icon v-if="appendIcon" :color="appendIconColor">{{ appendIcon }}</v-icon>
+          </v-scroll-x-transition>
+        </template>
+      </v-text-field>
       <div :class="{ 'flex-grow-1 max-width': true, 'full-width': $vuetify.breakpoint.mobile }">
         <v-card
           v-bind="dialogActivator.attrs"
@@ -90,6 +96,7 @@ export default {
       topic: null,
       homework: null,
       groupNote: null,
+      appendIcon: null,
     };
   },
   methods: {
@@ -102,11 +109,16 @@ export default {
             (o) => o[itemId] === this.documentation.id,
           );
           // merged with the incoming partial documentation
-          cached[index] = { ...this.documentation, ...object };
+          // set ID of documentation currently being edited as oldID so that key in coursebook doesn't change
+          cached[index] = { ...this.documentation, ...object, oldId: this.documentation.id };
         }
         return cached;
       };
     },
+    handleAppendIconSuccess() {
+      this.appendIcon = "$success";
+      setTimeout(() => {this.appendIcon = ""}, 3000);
+    },
     save() {
       if (this.topic !== null || this.homework !== null || this.groupNote !== null) {
         const topic = this.topic !== null ? { topic: this.topic } : {};
@@ -131,6 +143,9 @@ export default {
       this.save();
       event.target.blur();
     },
+    handleError() {
+      this.appendIcon = "$error";
+    },
   },
   computed: {
     homeworkIcon() {
@@ -158,8 +173,14 @@ export default {
     },
     maxWidth() {
       return this.$vuetify.breakpoint.mobile ? "100%" : "20ch";
+    },
+    appendIconColor() {
+      return {"$success": "success", "$error": "error"}[this.appendIcon] || "primary";
     }
   },
+  mounted() {
+    this.$on("save", this.handleAppendIconSuccess);
+  },
 };
 </script>
 
diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py
index 43e958e91..b5168df07 100644
--- a/aleksis/apps/alsijil/schema/documentation.py
+++ b/aleksis/apps/alsijil/schema/documentation.py
@@ -50,6 +50,8 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp
     course = graphene.Field(CourseType, required=False)
     subject = graphene.Field(SubjectType, required=False)
 
+    old_id = graphene.ID(required=False)
+
     @staticmethod
     def resolve_teachers(root: Documentation, info, **kwargs):
         if not str(root.pk).startswith("DUMMY") and hasattr(root, "teachers"):
-- 
GitLab