diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNote.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNote.vue index d5f35b553e32cadb8c7e8c2ac61d712f440770a6..380a0f4a01ef0b6f911b3b00e6a8c7bb982834e3 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNote.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNote.vue @@ -1,13 +1,16 @@ <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"; export default { name: "TextNote", + components: { DeleteDialog }, mixins: [mutateMixin, personalNoteRelatedMixin], props: { value: { @@ -21,43 +24,17 @@ export default { return this.value.note; }, set(newValue) { - const input = (extras) => ({ - input: [ - { - note: newValue, - ...extras, - }, - ], - }); - - const updater = - (replace) => (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, - ); - if (replace) { - const index = participationStatus.notesWithNote.findIndex( - (n) => n.id === this.participation.id, - ); - participationStatus.notesWithNote.splice(index, 1, note); - } else { - participationStatus.notesWithNote.push(note); - - this.$emit("create"); - } - - return storedDocumentations; - }; - + if (!newValue) { + // this is a DELETE action, show the dialog, ... + this.showDeleteConfirm = true; + return; + } const create = !this.value.id; this.mutate( create ? createPersonalNotes : updatePersonalNotes, - input( + this.getInput( + newValue, create ? { documentation: this.documentation.id, @@ -68,11 +45,66 @@ export default { id: this.value.id, }, ), - updater(!create), + this.getUpdater(create ? "create" : "update"), ); }, }, }, + methods: { + getInput(newValue, extras) { + return { + input: [ + { + note: 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": case "delete": { + const updateIndex = participationStatus.notesWithNote.findIndex( + (n) => n.id === this.value.id, + ); + if (mode === "update") { + participationStatus.notesWithNote.splice(updateIndex, 1, note); + } else { + participationStatus.notesWithNote.splice(updateIndex, 1); + } + + break; + } + + case "create": + participationStatus.notesWithNote.push(note); + + this.$emit("create"); + break; + + default: + console.error("Invalid mode in getUpdater():", mode); + break; + } + + return storedDocumentations; + }; + }, + }, + data() { + return { + showDeleteConfirm: false, + deletePersonalNotes, + }; + }, }; </script> @@ -83,10 +115,38 @@ export default { outlined hide-details class="mb-4" - clearable :label="$t('alsijil.personal_notes.note')" :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> + {{ + $t("alsijil.personal_notes.confirm_delete_explanation", { + note: value.note, + name: participation.person.fullName, + }) + }} + </template> + </delete-dialog> + </template> + </v-textarea> </template>