From a665caf384778db7255e9d59fe498bb312836095 Mon Sep 17 00:00:00 2001
From: Julian Leucker <leuckerj@gmail.com>
Date: Tue, 21 May 2024 11:40:02 +0200
Subject: [PATCH] Manage extra marks of person in frontend

---
 .../personal_notes/ExtraMarkNoteCheckbox.vue  | 105 ++++++++++++++++++
 .../personal_notes/ExtraMarksNote.vue         |  39 +++++++
 .../personal_notes/PersonalNotes.vue          |   4 +
 .../personal_notes/personal_notes.graphql     |  45 ++++++++
 4 files changed, 193 insertions(+)
 create mode 100644 aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarkNoteCheckbox.vue
 create mode 100644 aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarksNote.vue
 create mode 100644 aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personal_notes.graphql

diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarkNoteCheckbox.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarkNoteCheckbox.vue
new file mode 100644
index 000000000..b9280724b
--- /dev/null
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarkNoteCheckbox.vue
@@ -0,0 +1,105 @@
+<script>
+import {
+  createPersonalNotes,
+  deletePersonalNotes,
+} from "./personal_notes.graphql";
+import personalNoteRelatedMixin from "./personalNoteRelatedMixin";
+import mutateMixin from "aleksis.core/mixins/mutateMixin.js";
+
+export default {
+  name: "ExtraMarkNoteCheckbox",
+  mixins: [mutateMixin, personalNoteRelatedMixin],
+  props: {
+    personalNote: {
+      type: Object,
+      default: null,
+    },
+    /**
+     * Extra Mark
+     */
+    value: {
+      type: Object,
+      required: true,
+    },
+  },
+  computed: {
+    model: {
+      get() {
+        return !!this.personalNote?.id;
+      },
+      set(newValue) {
+        if (newValue && !this.personalNote) {
+          // CREATE new personal note
+          this.mutate(
+            createPersonalNotes,
+            {
+              input: [
+                {
+                  documentation: this.documentation.id,
+                  person: this.participation.person.id,
+                  extraMark: this.value.id,
+                  note: "",
+                },
+              ],
+            },
+            (storedDocumentations, incomingPersonalNotes) => {
+              const note = incomingPersonalNotes[0];
+              const documentation = storedDocumentations.find(
+                (doc) => doc.id === this.documentation.id,
+              );
+              const participationStatus = documentation.participations.find(
+                (part) => part.id === this.participation.id,
+              );
+              participationStatus.notesWithExtraMark.push(note);
+
+              return storedDocumentations;
+            },
+          );
+        } else {
+          // DELETE personal note
+          this.mutate(
+            deletePersonalNotes,
+            {
+              ids: [this.personalNote.id],
+            },
+            (storedDocumentations) => {
+              const documentation = storedDocumentations.find(
+                (doc) => doc.id === this.documentation.id,
+              );
+              const participationStatus = documentation.participations.find(
+                (part) => part.id === this.participation.id,
+              );
+              const index = participationStatus.notesWithExtraMark.findIndex(
+                (n) => n.id === this.participation.id,
+              );
+              participationStatus.notesWithExtraMark.splice(index, 1);
+
+              return storedDocumentations;
+            },
+          );
+        }
+      },
+    },
+  },
+};
+</script>
+
+<template>
+  <v-checkbox
+    :label="value.name"
+    :value="value.id"
+    v-model="model"
+    :disabled="loading"
+    :true-value="true"
+    :false-value="false"
+  >
+    <template #append>
+      <v-progress-circular
+        v-if="loading"
+        indeterminate
+        :size="16"
+        :width="2"
+      ></v-progress-circular>
+    </template>
+  </v-checkbox>
+</template>
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarksNote.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarksNote.vue
new file mode 100644
index 000000000..8b9a04957
--- /dev/null
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarksNote.vue
@@ -0,0 +1,39 @@
+<script>
+import { extraMarks } from "../../extra_marks/extra_marks.graphql";
+import ExtraMarkNoteCheckbox from "./ExtraMarkNoteCheckbox.vue";
+import personalNoteRelatedMixin from "./personalNoteRelatedMixin";
+
+export default {
+  name: "ExtraMarksNote",
+  components: { ExtraMarkNoteCheckbox },
+  mixins: [personalNoteRelatedMixin],
+  props: {
+    value: {
+      type: Array,
+      required: true,
+    },
+  },
+  data() {
+    return {
+      extraMarks: [],
+    };
+  },
+  apollo: {
+    extraMarks: {
+      query: extraMarks,
+      update: (data) => data.items,
+    },
+  },
+};
+</script>
+
+<template>
+  <div>
+    <extra-mark-note-checkbox
+      v-for="extraMark in extraMarks"
+      v-bind="personalNoteRelatedProps"
+      :value="extraMark"
+      :personal-note="value.find((pn) => pn.extraMark.id === extraMark.id)"
+    />
+  </div>
+</template>
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/PersonalNotes.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/PersonalNotes.vue
index c74dc4d6b..0487e7084 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/PersonalNotes.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/PersonalNotes.vue
@@ -15,6 +15,10 @@ export default {
 <template>
   <div>
 
+    <extra-marks-note
+      v-bind="personalNoteRelatedProps"
+      :value="participation.notesWithExtraMark"
+    />
   </div>
 </template>
 
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personal_notes.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personal_notes.graphql
new file mode 100644
index 000000000..014178c13
--- /dev/null
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personal_notes.graphql
@@ -0,0 +1,45 @@
+query personalNotes($orderBy: [String], $filters: JSONString) {
+  items: personalNotes(orderBy: $orderBy, filters: $filters) {
+    id
+    note
+    extraMark {
+      id
+    }
+    canEdit
+    canDelete
+  }
+}
+
+mutation createPersonalNotes($input: [BatchCreatePersonalNoteInput]!) {
+  createPersonalNotes(input: $input) {
+    items: personalNotes {
+      id
+      note
+      extraMark {
+        id
+      }
+      canEdit
+      canDelete
+    }
+  }
+}
+
+mutation deletePersonalNotes($ids: [ID]!) {
+  deletePersonalNotes(ids: $ids) {
+    deletionCount
+  }
+}
+
+mutation updatePersonalNotes($input: [BatchPatchPersonalNoteInput]!) {
+  updatePersonalNotes(input: $input) {
+    items: personalNotes {
+      id
+      note
+      extraMark {
+        id
+      }
+      canEdit
+      canDelete
+    }
+  }
+}
-- 
GitLab