From 83ad08b3dc19b57b2772c3f7f189a567c711f89f Mon Sep 17 00:00:00 2001
From: Hangzhi Yu <hangzhi@protonmail.com>
Date: Sat, 15 Jun 2024 21:01:52 +0200
Subject: [PATCH] Integrate absences overview into coursebook main component

---
 .../components/coursebook/Coursebook.vue      |  15 ++-
 .../coursebook/absences/AbsenceCard.vue       |   0
 .../absences/DocumentationAbsences.vue        |  14 ++-
 .../coursebook/absences/ParticipationList.vue | 114 ++++++++++++++++++
 4 files changed, 136 insertions(+), 7 deletions(-)
 delete mode 100644 aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCard.vue
 create mode 100644 aleksis/apps/alsijil/frontend/components/coursebook/absences/ParticipationList.vue

diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue
index d136fa81b..4185a32c3 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue
@@ -15,10 +15,15 @@
   >
     <template #additionalActions="{ attrs, on }">
       <coursebook-filters v-model="filters" />
+      <absence-reason-buttons
+        v-if="pageType === 'absences' && selectedParticipations.length"
+        allow-empty
+        empty-value="present"
+      />
     </template>
 
     <template #item="{ item, lastQuery }">
-      <component :is="itemComponent" :documentation="item" :affectedQuery="lastQuery" />
+      <component :is="itemComponent" :documentation="item" :affectedQuery="lastQuery" @selectParticipation="changeSelectedParticipations()" />
     </template>
 
     <template #loading>
@@ -49,6 +54,7 @@
 import InfiniteScrollingDateSortedCRUDIterator from "aleksis.core/components/generic/InfiniteScrollingDateSortedCRUDIterator.vue";
 import { DateTime, Interval } from "luxon";
 import { documentationsForCoursebook } from "./coursebook.graphql";
+import AbsenceReasonButtons from "aleksis.apps.kolego/components/AbsenceReasonButtons.vue";
 import CoursebookFilters from "./CoursebookFilters.vue";
 import CoursebookLoader from "./CoursebookLoader.vue";
 import CoursebookEmptyMessage from "./CoursebookEmptyMessage.vue";
@@ -118,6 +124,7 @@ export default {
       initDate: false,
       currentDate: "",
       hashUpdater: false,
+      selectedParticipations: [1],
     };
   },
   computed: {
@@ -182,6 +189,12 @@ export default {
       }
     },
   },
+  methods: {
+    changeSelectedParticipations(participations) {
+      console.log(participations);
+      this.selectedParticipations = participations;
+    }
+  },
 };
 </script>
 
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCard.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCard.vue
deleted file mode 100644
index e69de29bb..000000000
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue
index de3bac643..190692bc2 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue
@@ -12,13 +12,12 @@
       }"
     >
       <lesson-information v-if="compact" v-bind="documentationPartProps" />
-      <div>
-        <div v-for="participation in documentation.participations">
-          {{ participation }}
-        </div>
-      </div>
+      <v-spacer />
       <lesson-notes v-bind="documentationPartProps" />
     </v-card-text>
+    <v-card-text>
+      <participation-list v-bind="documentationPartProps" @select="$emit('selectParticipation', $event)" />
+    </v-card-text>
     <v-spacer />
     <v-divider />
     <v-card-actions v-if="!compact">
@@ -43,6 +42,7 @@
 </template>
 
 <script>
+import ParticipationList from "./ParticipationList.vue";
 import LessonInformation from "../documentation/LessonInformation.vue";
 import LessonNotes from "../documentation/LessonNotes.vue";
 
@@ -56,17 +56,19 @@ import documentationPartMixin from "../documentation/documentationPartMixin";
 export default {
   name: "DocumentationAbsences",
   components: {
+    ParticipationList,
     LessonInformation,
     LessonNotes,
     SaveButton,
     CancelButton,
   },
-  emits: ["open", "close"],
+  emits: ["open", "close", "selectParticipation"],
   mixins: [documentationPartMixin],
   data() {
     return {
       loading: false,
       documentationsMutation: createOrUpdateDocumentations,
+      selectedParticipations: [],
     };
   },
   methods: {
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ParticipationList.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ParticipationList.vue
new file mode 100644
index 000000000..ed1a74eee
--- /dev/null
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ParticipationList.vue
@@ -0,0 +1,114 @@
+<script setup>
+import MobileFullscreenDialog from "aleksis.core/components/generic/dialogs/MobileFullscreenDialog.vue";
+
+import AbsenceReasonChip from "aleksis.apps.kolego/components/AbsenceReasonChip.vue";
+import AbsenceReasonGroupSelect from "aleksis.apps.kolego/components/AbsenceReasonGroupSelect.vue";
+import documentationPartMixin from "../documentation/documentationPartMixin";
+</script>
+
+<template>
+  <v-list>
+    <v-divider v-if="filteredParticipations.length" />
+    <p v-else>no participations</p>
+    <v-list-item-group multiple v-model="selectedParticipations">
+      <template v-for="(participation, index) in filteredParticipations">
+        <v-list-item
+          :key="`documentation-${documentation.id}-participation-${participation.id}`"
+          :value="participation"
+          v-bind="$attrs"
+          v-on="$listeners"
+        >
+          <template :default="{ active }">
+            <v-list-item-action>
+              <v-checkbox :input-value="active" />
+            </v-list-item-action>
+            <v-list-item-title>
+              {{ participation.person.fullName }}
+            </v-list-item-title>
+            <v-list-item-subtitle v-if="participation.absenceReason">
+              <absence-reason-chip small :absence-reason="participation.absenceReason" />
+            </v-list-item-subtitle>
+            <v-list-item-action>
+              <v-icon>
+                mdi-chevron-right
+              </v-icon>
+            </v-list-item-action>
+          </template>
+        </v-list-item>
+        <v-divider
+          v-if="index < filteredParticipations.length - 1"
+          :key="index"
+        ></v-divider>
+        <mobile-fullscreen-dialog v-model="participationDialogs" max-width="500px">
+          test
+        </mobile-fullscreen-dialog>
+      </template>
+    </v-list-item-group>
+      
+  
+    <!--<template #expandedItem="{ item, close }">-->
+    <!--  <v-card-title>-->
+    <!--    <v-tooltip bottom>-->
+    <!--      <template #activator="{ on, attrs }">-->
+    <!--        <v-btn v-bind="attrs" v-on="on" icon @click="close">-->
+    <!--          <v-icon>$prev</v-icon>-->
+    <!--        </v-btn>-->
+    <!--      </template>-->
+    <!--      <span v-t="'actions.back_to_overview'" />-->
+    <!--    </v-tooltip>-->
+    <!--    {{ item.person.fullName }}-->
+    <!--  </v-card-title>-->
+    <!--  <v-card-text>-->
+    <!--    <absence-reason-group-select-->
+    <!--      allow-empty-->
+    <!--      empty-value="present"-->
+    <!--      :loadSelectedChip="loading"-->
+    <!--      :value="item.absenceReason?.id || 'present'"-->
+    <!--      @input="sendToServer([item], 'absenceReason', $event)"-->
+    <!--    />-->
+    <!--  </v-card-text>-->
+    <!--</template>-->
+  </v-list>
+</template>
+
+<script>
+export default {
+  name: "ParticipationList",
+  emits: ["select"],
+  mixins: [documentationPartMixin],
+  data() {
+    return {
+      loading: false,
+      selectedParticipations: [],
+      participationDialogs: false,
+      isExpanded: false,
+    };
+  },
+  props: {
+    includePresent: {
+      type: Boolean,
+      required: false,
+      default: true,
+    },
+  },
+  computed: {
+    filteredParticipations() {
+      if (!this.includePresent) {
+        return this.documentation.participations.filter((p) => !!p.absenceReason);
+      } else {
+        return this.documentation.participations;
+      }
+    },
+    selectedParticipationIDs() {
+      return this.selectedParticipations.map((p) => p.id);
+    },
+  },
+  watch: {
+    selectedParticipationIDs: {
+      handler() {
+        this.$emit("select", this.selectedParticipationIDs);
+      },
+    },
+  }
+};
+</script>
\ No newline at end of file
-- 
GitLab