diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue index 9685fe60ee7dff92c4c2b725c77119e37b7c5b55..6ced8cee9ee0256b357c70b3416b2cba0bfc6827 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue @@ -16,9 +16,18 @@ <template #additionalActions="{ attrs, on }"> <coursebook-filters :page-type="pageType" v-model="filters" /> <v-expand-transition> - <v-card outlined class="full-width" v-show="pageType === 'absences' && selectedParticipations.length"> + <v-card + outlined + class="full-width" + v-show="pageType === 'absences' && selectedParticipations.length" + > <v-card-text> - {{ $tc('alsijil.coursebook.absences.action_for_selected', selectedParticipations.length) }} + {{ + $tc( + "alsijil.coursebook.absences.action_for_selected", + selectedParticipations.length, + ) + }} </v-card-text> <v-card-actions> <absence-reason-buttons @@ -32,7 +41,13 @@ </template> <template #item="{ item, lastQuery }"> - <component :is="itemComponent" :documentation="item" :affectedQuery="lastQuery" @select="addSelectedParticipation" @deselect="removeSelectedParticipation" /> + <component + :is="itemComponent" + :documentation="item" + :affectedQuery="lastQuery" + @select="addSelectedParticipation" + @deselect="removeSelectedParticipation" + /> </template> <template #loading> @@ -203,7 +218,7 @@ export default { }, }, itemComponent() { - if (this.pageType === 'documentations') { + if (this.pageType === "documentations") { return "DocumentationModal"; } else { return "DocumentationAbsencesModal"; @@ -212,17 +227,23 @@ export default { }, methods: { addSelectedParticipation(participation) { - this.selectedParticipations = [...new Set([...this.selectedParticipations, participation])]; + this.selectedParticipations = [ + ...new Set([...this.selectedParticipations, participation]), + ]; }, removeSelectedParticipation(participation) { const index = this.selectedParticipations.indexOf(participation); - if (index>=0) { + if (index >= 0) { this.selectedParticipations.splice(index, 1); } }, handleMultipleAction(absenceReasonId) { this.loadSelectedParticiptions = true; - this.sendToServer(this.selectedParticipations, "absenceReason", absenceReasonId); + this.sendToServer( + this.selectedParticipations, + "absenceReason", + absenceReasonId, + ); this.$once("save", this.resetMultipleAction); }, resetMultipleAction() { diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/CoursebookFilters.vue b/aleksis/apps/alsijil/frontend/components/coursebook/CoursebookFilters.vue index d67a388eaf932f2bb5bd0a28aea90cb98777a7e2..ee867e83134a874dfbb2d76b739059ad0e9cabe1 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/CoursebookFilters.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/CoursebookFilters.vue @@ -146,7 +146,10 @@ export default { }, togglePageType() { this.$emit("input", { - pageType: this.value.pageType === "documentations" ? "absences" : "documentations", + pageType: + this.value.pageType === "documentations" + ? "absences" + : "documentations", objType: this.value.objType, objId: this.value.objId, }); diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue index 12f1ad9191ceb41f72d198d310802407cc1c01ff..d9013806dba3bafb5a47dbbc2e39ca255a2d963d 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue @@ -14,7 +14,12 @@ <lesson-information v-if="compact" v-bind="documentationPartProps" /> <v-spacer /> <lesson-notes v-bind="documentationPartProps" /> - <participation-list :include-present="false" class="participation-list" v-bind="documentationPartProps" v-on="selectListeners" /> + <participation-list + :include-present="false" + class="participation-list" + v-bind="documentationPartProps" + v-on="selectListeners" + /> </v-card-text> <v-spacer /> <v-divider /> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsencesModal.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsencesModal.vue index 86403a0227597fa6abb32bbf56c798c4ec577612..92bd289b5479cc9e0b7a78fb106b51c692b61083 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsencesModal.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsencesModal.vue @@ -4,11 +4,20 @@ <mobile-fullscreen-dialog v-model="popup" max-width="500px"> <template #activator="activator"> <!-- list view -> activate dialog --> - <documentation-absences compact v-bind="$attrs" :dialog-activator="activator" v-on="selectListeners" /> + <documentation-absences + compact + v-bind="$attrs" + :dialog-activator="activator" + v-on="selectListeners" + /> </template> <!-- dialog view -> deactivate dialog --> <!-- cancel | save (through lesson-summary) --> - <documentation-absences v-bind="$attrs" @close="popup = false" v-on="selectListeners" /> + <documentation-absences + v-bind="$attrs" + @close="popup = false" + v-on="selectListeners" + /> </mobile-fullscreen-dialog> </template> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ParticipationList.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ParticipationList.vue index 223ba0097cef80274a7a6145bd42443efdcacff9..3c0d1c0190baacd41ed6a22f8f176d48fa0cf0f3 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ParticipationList.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ParticipationList.vue @@ -20,18 +20,22 @@ import documentationPartMixin from "../documentation/documentationPartMixin"; > <template #default="{ active }"> <v-list-item-action> - <v-checkbox :input-value="active" @change="handleParticipationSelect($event, participation)" /> + <v-checkbox + :input-value="active" + @change="handleParticipationSelect($event, participation)" + /> </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" /> + <absence-reason-chip + small + :absence-reason="participation.absenceReason" + /> </v-list-item-subtitle> <v-list-item-action> - <v-icon> - mdi-chevron-right - </v-icon> + <v-icon> mdi-chevron-right </v-icon> </v-list-item-action> </template> </v-list-item> @@ -42,8 +46,7 @@ import documentationPartMixin from "../documentation/documentationPartMixin"; <mobile-fullscreen-dialog v-model="participationDialogs" max-width="500px"> test </mobile-fullscreen-dialog> - - + <!--<template #expandedItem="{ item, close }">--> <!-- <v-card-title>--> <!-- <v-tooltip bottom>--> @@ -90,7 +93,9 @@ export default { computed: { filteredParticipations() { if (!this.includePresent) { - return this.documentation.participations.filter((p) => !!p.absenceReason); + return this.documentation.participations.filter( + (p) => !!p.absenceReason, + ); } else { return this.documentation.participations; } @@ -104,6 +109,6 @@ export default { this.handleDeselect(participation.id); } }, - } + }, }; -</script> \ No newline at end of file +</script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/selectParticipationMixin.js b/aleksis/apps/alsijil/frontend/components/coursebook/absences/selectParticipationMixin.js index 0dc139db32bd3a491a85da007b493b428cebe326..2d6d522692690c6def6aaa53e2dc0e7835019681 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/selectParticipationMixin.js +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/selectParticipationMixin.js @@ -1,6 +1,6 @@ /** * Mixin to provide passing through functionality for the events emitted when (de)selecting participations on the absence overview page -*/ + */ export default { emits: ["select", "deselect"], methods: { @@ -14,9 +14,9 @@ export default { computed: { /** - * All necessary listeners bundled together to easily pass to child components - * @returns {{select: Function, deselect: Function}} - */ + * All necessary listeners bundled together to easily pass to child components + * @returns {{select: Function, deselect: Function}} + */ selectListeners() { return { select: this.handleSelect, diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/updateParticipationMixin.js b/aleksis/apps/alsijil/frontend/components/coursebook/absences/updateParticipationMixin.js index 6aab0c9bf83d097916fc4c866b8cf836d9d9c87e..ca44b374f9264a8df5d84c8f1efd29af6f12276b 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/updateParticipationMixin.js +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/updateParticipationMixin.js @@ -1,6 +1,6 @@ /** * Mixin to provide shared functionality needed to update participations -*/ + */ import { updateParticipationStatuses } from "./participationStatus.graphql"; import mutateMixin from "aleksis.core/mixins/mutateMixin.js"; import documentationPartMixin from "../documentation/documentationPartMixin"; @@ -10,12 +10,14 @@ export default { methods: { sendToServer(participations, field, value) { if (field !== "absenceReason") return; - + this.mutate( updateParticipationStatuses, { input: participations.map((participation) => ({ - id: Object.hasOwn(participation, "id") ? participation.id : participation, + id: Object.hasOwn(participation, "id") + ? participation.id + : participation, absenceReason: value === "present" ? null : value, })), }, @@ -23,7 +25,7 @@ export default { const documentation = storedDocumentations.find( (doc) => doc.id === this.documentation.id, ); - + incomingStatuses.forEach((newStatus) => { const participationStatus = documentation.participations.find( (part) => part.id === newStatus.id, @@ -31,7 +33,7 @@ export default { participationStatus.absenceReason = newStatus.absenceReason; participationStatus.isOptimistic = newStatus.isOptimistic; }); - + return storedDocumentations; }, // { diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue index 880e92f4c03eb41a042f1ace474611de0ab5617e..72781ec627a7a74e1931f3c42ef176be5706fa18 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue @@ -7,16 +7,14 @@ import AbsenceReasonChip from "aleksis.apps.kolego/components/AbsenceReasonChip. class="d-flex align-center justify-space-between justify-md-end flex-wrap gap" > <v-chip dense color="success" outlined v-if="total > 0"> - {{ $t("alsijil.coursebook.present_number", { present, total })}} + {{ $t("alsijil.coursebook.present_number", { present, total }) }} </v-chip> <absence-reason-chip v-for="participation in absences" :absence-reason="participation.absenceReason" dense > - <template #prepend> - {{ participation.person.fullName }}: - </template> + <template #prepend> {{ participation.person.fullName }}: </template> </absence-reason-chip> <manage-students-trigger v-bind="documentationPartProps" /> @@ -36,11 +34,15 @@ export default { return this.documentation.participations.length; }, present() { - return this.documentation.participations.filter(p => p.absenceReason === null).length; + return this.documentation.participations.filter( + (p) => p.absenceReason === null, + ).length; }, absences() { // Get all course attendants who have an absence reason - return this.documentation.participations.filter(p => p.absenceReason !== null); + return this.documentation.participations.filter( + (p) => p.absenceReason !== null, + ); }, }, }; diff --git a/aleksis/apps/alsijil/frontend/index.js b/aleksis/apps/alsijil/frontend/index.js index 6f1ec9b3d931278b17a5f54e5303ee21df17bdc0..a1dfdf84d9ec32cdb15b077c2b0da7eac3941eaa 100644 --- a/aleksis/apps/alsijil/frontend/index.js +++ b/aleksis/apps/alsijil/frontend/index.js @@ -63,7 +63,7 @@ export default { name: "alsijil.coursebook", params: { filterType: "my", - pageType: "documentations" + pageType: "documentations", }, hash: "#" + DateTime.now().toISODate(), }; diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index 94c1a1f88c056cac23e186043d4cac5e01fda8ab..b30c8d7949b5730304a80ed03033cdcd077d7898 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -551,7 +551,13 @@ class Documentation(CalendarEvent): if existing_documentations.exists(): doc = existing_documentations.first() - if (incomplete and doc.topic) or (absences_exist and (not doc.participations.exists or not doc.participations.filter(absence_reason__isnull=False).exists())): + if (incomplete and doc.topic) or ( + absences_exist + and ( + not doc.participations.exists + or not doc.participations.filter(absence_reason__isnull=False).exists() + ) + ): continue docs.append(doc) elif not absences_exist: diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py index c46fbc45f402c88f62a07a3cf31a0abc0b568113..7ddf37b68b612aa04b552fbb4dd12e8802332028 100644 --- a/aleksis/apps/alsijil/schema/__init__.py +++ b/aleksis/apps/alsijil/schema/__init__.py @@ -36,7 +36,7 @@ class Query(graphene.ObjectType): date_start=graphene.Date(required=True), date_end=graphene.Date(required=True), incomplete=graphene.Boolean(required=False), - absences_exist=graphene.Boolean(required=False) + absences_exist=graphene.Boolean(required=False), ) groups_by_person = FilterOrderList(GroupType, person=graphene.ID()) @@ -110,7 +110,9 @@ class Query(graphene.ObjectType): ) # Lookup or create documentations and return them all. - docs, dummies = Documentation.get_documentations_for_events(events, incomplete, absences_exist) + docs, dummies = Documentation.get_documentations_for_events( + events, incomplete, absences_exist + ) return docs + dummies @staticmethod