From c816eb507f485e74d7e601ddc5b5f12286482444 Mon Sep 17 00:00:00 2001 From: Julian Leucker <leuckerj@gmail.com> Date: Sat, 22 Jun 2024 01:04:09 +0200 Subject: [PATCH] Create initial draft of TardinessNote.vue --- .../personal_notes/TardinessNote.vue | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TardinessNote.vue diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TardinessNote.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TardinessNote.vue new file mode 100644 index 000000000..94d9d317e --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TardinessNote.vue @@ -0,0 +1,156 @@ +<script> +import { + createPersonalNotes, + deletePersonalNotes, + updatePersonalNotes, +} from "./personal_notes.graphql"; +import personalNoteRelatedMixin from "./personalNoteRelatedMixin"; +import mutateMixin from "aleksis.core/mixins/mutateMixin.js"; +import DeleteDialog from "aleksis.core/components/generic/dialogs/DeleteDialog.vue"; +import PositiveSmallIntegerField from "aleksis.core/components/generic/forms/PositiveSmallIntegerField.vue"; + +export default { + name: "TardinessNote", + components: { DeleteDialog, PositiveSmallIntegerField }, + mixins: [mutateMixin, personalNoteRelatedMixin], + computed: { + value() { + return this.participation.noteWithTardiness; + }, + lessonLength() { + // TODO: calculate lesson length in minutes + return 60; + }, + model: { + get() { + return this.value?.tardiness; + }, + set(newValue) { + if (!newValue) { + // this is a DELETE action, show the dialog, ... + this.showDeleteConfirm = true; + return; + } + const create = !this.value?.id; + + this.mutate( + create ? createPersonalNotes : updatePersonalNotes, + this.getInput( + newValue, + create + ? { + documentation: this.documentation.id, + person: this.participation.person.id, + } + : { + id: this.value.id, + }, + ), + this.getUpdater(create ? "create" : "update"), + ); + }, + }, + }, + methods: { + getInput(newValue, extras) { + return { + input: [ + { + tardiness: newValue, + ...extras, + }, + ], + }; + }, + getUpdater(mode) { + return (storedDocumentations, incomingPersonalNotes) => { + const note = incomingPersonalNotes?.[0] || undefined; + const documentation = storedDocumentations.find( + (doc) => doc.id === this.documentation.id, + ); + const participationStatus = documentation.participations.find( + (part) => part.id === this.participation.id, + ); + switch (mode.toLowerCase()) { + case "update": { + const oldNote = participationStatus.noteWithTardiness; + participationStatus.noteWithTardiness = { + ...oldNote, + ...note, + }; + break; + } + case "delete": { + participationStatus.noteWithTardiness = null; + break; + } + + case "create": + participationStatus.noteWithTardiness = note; + break; + + default: + console.error("Invalid mode in getUpdater():", mode); + break; + } + + return storedDocumentations; + }; + }, + lessonLengthRule(time) { + // FIXME: translation + return time <= lessonLength || this.$t("alsijil.personal_notes.lesson_length_exceeded"); + } + }, + data() { + return { + showDeleteConfirm: false, + deletePersonalNotes, + }; + }, +} +</script> + +<template> + <positive-small-integer-field + outlined + class="mt-1" + prepend-inner-icon="mdi-clock-alert-outline" + :suffix="$t('time.minutes')" + :label="$t('alsijil.personal_notes.tardiness')" + :rules="[lessonLengthRule]" + :value="model" + @change="model = $event" + :loading="loading" + > + <template #append> + <v-slide-x-reverse-transition> + <v-btn v-if="!!model" icon @click="showDeleteConfirm = true"> + <v-icon> $deleteContent </v-icon> + </v-btn> + </v-slide-x-reverse-transition> + + <delete-dialog + v-model="showDeleteConfirm" + :gql-delete-mutation="deletePersonalNotes" + :affected-query="affectedQuery" + item-attribute="fullName" + :items="[value]" + :custom-update="getUpdater('delete')" + > + <template #title> + {{ $t("alsijil.personal_notes.confirm_delete") }} + </template> + <template #body> + {{ + // TODO: Fix delete content + $t("alsijil.personal_notes.confirm_delete_explanation", { + note: value.note, + name: participation.person.fullName, + }) + }} + </template> + </delete-dialog> + </template> + </positive-small-integer-field> +</template> -- GitLab