From 6f92da60a10709e2347814749e46323b73ca15ab Mon Sep 17 00:00:00 2001
From: Hangzhi Yu <hangzhi@protonmail.com>
Date: Mon, 29 Apr 2024 00:18:47 +0200
Subject: [PATCH] Use status-based chips for teachers

---
 .../substitutions/SubstitutionCard.vue        | 86 ++++++++++++++-----
 1 file changed, 63 insertions(+), 23 deletions(-)

diff --git a/aleksis/apps/chronos/frontend/components/substitutions/SubstitutionCard.vue b/aleksis/apps/chronos/frontend/components/substitutions/SubstitutionCard.vue
index 128581d5..de7617b7 100644
--- a/aleksis/apps/chronos/frontend/components/substitutions/SubstitutionCard.vue
+++ b/aleksis/apps/chronos/frontend/components/substitutions/SubstitutionCard.vue
@@ -31,16 +31,40 @@ import createOrPatchMixin from "aleksis.core/mixins/createOrPatchMixin.js";
         item-text="fullName"
         item-value="id"
         :disabled="loading"
-        @input="save"
+        @input="saveTeachers"
       >
         <template #prepend-inner>
           <v-chip
-            v-for="teacher in teachersWithStatus(substitution).filter(
+            v-for="teacher in teachersWithStatus.filter(
               (t) => t.status === 'removed',
             )"
-            class="text-decoration-line-through text--secondary mb-2"
-            >{{ teacher.fullName }}</v-chip
+            outlined
+            color="error"
+            class="mb-2"
+            close
+            close-icon="mdi-reload"
+            @click:close="addTeacher(teacher)"
           >
+            <v-icon left>
+              $cancel
+            </v-icon>
+            <div class="text-decoration-line-through">{{ teacher.fullName }}</div>
+          </v-chip>
+        </template>
+        <template #selection="data">
+          <v-chip
+            v-bind="data.attrs"
+            :input-value="data.selected"
+            close
+            :outlined="getTeacherStatus(data.item) === 'new'"
+            :color="getTeacherStatus(data.item) === 'new' ? 'success' : ''"
+            @click:close="removeTeacher(data.item)"
+          >
+            <v-icon left v-if="getTeacherStatus(data.item) === 'new'">
+              mdi-plus
+            </v-icon>
+            {{ data.item.fullName }}
+          </v-chip>
         </template>
       </v-autocomplete>
 
@@ -92,26 +116,21 @@ export default {
     },
   },
   methods: {
-    teachersWithStatus(lesson) {
-      let oldIds = lesson.amends.teachers.map((teacher) => teacher.id);
-      let newIds = lesson.teachers.map((teacher) => teacher.id);
-      let teachersWithStatus = lesson.amends.teachers
-        .concat(lesson.teachers)
-        .map((teacher) => {
-          let status = "regular";
-          if (newIds.includes(teacher.id) && !oldIds.includes(teacher.id)) {
-            status = "new";
-          } else if (
-            !newIds.includes(teacher.id) &&
-            oldIds.includes(teacher.id)
-          ) {
-            status = "removed";
-          }
-          return { ...teacher, status: status };
-        });
-      return teachersWithStatus;
+    getTeacherStatus(teacher) {
+      return this.teachersWithStatus.find((t) => t.id === teacher.id)?.status;
+    },
+    addTeacher(teacher) {
+      this.teachers.push(teacher.id);
+      this.saveTeachers();
     },
-    save() {
+    removeTeacher(teacher) {
+      const index = this.teachers.indexOf(teacher.id);
+      if (index >= 0) {
+        this.teachers.splice(index, 1);
+        this.saveTeachers();
+      }
+    },
+    saveTeachers() {
       this.createOrPatch([
         {
           id: this.substitution.id,
@@ -128,6 +147,27 @@ export default {
       ]);
     },
   },
+  computed: {
+    teachersWithStatus() {
+      const oldIds = this.substitution.amends.teachers.map((teacher) => teacher.id);
+      const newIds = this.substitution.teachers.map((teacher) => teacher.id);
+      const allTeachers = new Set(this.substitution.amends.teachers.concat(this.substitution.teachers));
+      let teachersWithStatus = Array.from(allTeachers)
+        .map((teacher) => {
+          let status = "regular";
+          if (newIds.includes(teacher.id) && !oldIds.includes(teacher.id)) {
+            status = "new";
+          } else if (
+            !newIds.includes(teacher.id) &&
+            oldIds.includes(teacher.id)
+          ) {
+            status = "removed";
+          }
+          return { ...teacher, status: status };
+        });
+      return teachersWithStatus;
+    },
+  },
   apollo: {
     amendableTeachers: gqlPersons,
   },
-- 
GitLab