diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue index 9aa082419edc04af6158e1cb492bb1fb21ca15a4..634471d0ce16a91c700e13541cfe44a02c32f2d7 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue @@ -56,7 +56,7 @@ :subjects="subjects" :documentation="item" :affected-query="lastQuery" - :value="(selectedParticipations[item.id] ??= [])" + :value="selectedParticipations[item.id] ??= []" @input="selectParticipation(item.id, $event)" /> </template> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/UpdateParticipations.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/UpdateParticipations.vue new file mode 100644 index 0000000000000000000000000000000000000000..1055c424275596d9f26fa87821434fb09abae630 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/UpdateParticipations.vue @@ -0,0 +1,44 @@ +<script> +import AbsenceReasonButtons from "aleksis.apps.kolego/components/AbsenceReasonButtons.vue"; +import updateParticipationMixin from "./updateParticipationMixin"; + +export default { + name: "UpdateParticipations", + components: { + AbsenceReasonButtons, + }, + mixins: [updateParticipationMixin], + props: { + participationStatuses: { + type: Array, + required: true, + }, + absenceReasons: { + type: Array, + required: true, + }, + }, + emits: ["update:participationStatuses"], + methods: { + afterSendToServer() { + this.$once("save", () => this.$emit("update:participationStatuses", [])); + }, + }, +}; +</script> + +<template> + <v-card> + <v-card-text> + <h4>{{ $t("alsijil.coursebook.participation_status") }}</h4> + <absence-reason-buttons + allow-empty + empty-value="present" + :custom-absence-reasons="absenceReasons" + @input="sendToServer(participationStatuses, 'absenceReason', $event)" + /> + </v-card-text> + </v-card> +</template> + +<style scoped></style> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/statistics/StatisticsForPersonPage.vue b/aleksis/apps/alsijil/frontend/components/coursebook/statistics/StatisticsForPersonPage.vue index c84bbfc7aa71f835d0e7eda3de27bc70532400fd..684e5dacc774e5891f771bd60da4cc39259edf17 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/statistics/StatisticsForPersonPage.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/statistics/StatisticsForPersonPage.vue @@ -42,151 +42,183 @@ </v-btn> </template> <template #default="{ items }"> - <v-expansion-panels focusable> - <v-expansion-panel - v-for="item in items" - :key="item.id" - ripple - :readonly="!showEdit(item)" - > - <v-expansion-panel-header - :hide-actions="!showEdit(item) && !showDelete(item)" - disable-icon-rotate + <v-expand-transition> + <update-participations + v-show="selected.length > 0" + class="mt-2" + :subjects="[]" + :absence-reasons="absenceReasons" + :participation-statuses.sync="selected" + :extra-marks="[]" + :affected-query="lastQuery" + :documentation="{}" + /> + </v-expand-transition> + + <v-item-group multiple v-model="selected" class="mt-2"> + <v-expansion-panels focusable> + <v-expansion-panel + v-for="item in items" + :key="item.id" + ripple + :readonly="!showEdit(item)" > - <template #actions> - <v-btn v-if="showEdit(item)" color="primary" icon> - <v-icon> $edit </v-icon> - </v-btn> - <delete-assigned-extra-mark - v-if="showDelete(item)" - :personal-note="item" - :participation="item.participation || {}" - :subjects="[]" - :absence-reasons="[]" - :extra-marks="[]" - :affected-query="lastQuery" - :documentation="item.relatedDocumentation" - :person="personName" - /> - </template> - <v-row class="mr-2"> - <v-col cols="12" md="6" class="pa-0"> - <v-list-item-content> - <v-list-item-title> - <!-- date & timeslot --> - <time - :datetime="item.relatedDocumentation.datetimeStart" - class="text-no-wrap" - > - {{ - $d( - $parseISODate( - item.relatedDocumentation.datetimeStart, - ), - "short", - ) - }} - </time> + <v-expansion-panel-header + :hide-actions="!showEdit(item) && !showDelete(item)" + disable-icon-rotate + > + <template #actions> + <v-btn v-if="showEdit(item)" color="primary" icon> + <v-icon> $edit </v-icon> + </v-btn> + <delete-assigned-extra-mark + v-if="showDelete(item)" + :personal-note="item" + :participation="item.participation || {}" + :subjects="[]" + :absence-reasons="[]" + :extra-marks="[]" + :affected-query="lastQuery" + :documentation="item.relatedDocumentation" + :person="personName" + /> + </template> + <v-row class="mr-2"> + <v-col cols="12" md="6" class="pa-0 d-flex"> + <v-list-item-avatar + v-if=" + mode === MODE.PARTICIPATIONS && + !$vuetify.breakpoint.mobile + " + > + <v-item v-slot="{ active, toggle }" :value="item.id"> + <v-simple-checkbox + :value="active" + @click="toggle" + /> + </v-item> + </v-list-item-avatar> + <v-list-item-content> + <v-list-item-title> + <!-- date & timeslot --> + <time + :datetime=" + item.relatedDocumentation.datetimeStart + " + class="text-no-wrap" + > + {{ + $d( + $parseISODate( + item.relatedDocumentation.datetimeStart, + ), + "short", + ) + }} + </time> - <time - :datetime="item.relatedDocumentation.datetimeStart" - class="text-no-wrap" - > - {{ - $d( - $parseISODate( - item.relatedDocumentation.datetimeStart, - ), - "shortTime", - ) - }} - </time> - <span>-</span> - <time - :datetime="item.relatedDocumentation.datetimeEnd" - class="text-no-wrap" - > - {{ - $d( - $parseISODate( - item.relatedDocumentation.datetimeEnd, - ), - "shortTime", - ) - }} - </time> - </v-list-item-title> - <v-list-item-subtitle class="overflow-scroll"> - <!-- teacher --> - <person-chip - v-for="teacher in item.relatedDocumentation - .teachers" - :key="teacher.id" - :person="teacher" - no-link - small + <time + :datetime=" + item.relatedDocumentation.datetimeStart + " + class="text-no-wrap" + > + {{ + $d( + $parseISODate( + item.relatedDocumentation.datetimeStart, + ), + "shortTime", + ) + }} + </time> + <span>-</span> + <time + :datetime="item.relatedDocumentation.datetimeEnd" + class="text-no-wrap" + > + {{ + $d( + $parseISODate( + item.relatedDocumentation.datetimeEnd, + ), + "shortTime", + ) + }} + </time> + </v-list-item-title> + <v-list-item-subtitle class="overflow-scroll"> + <!-- teacher --> + <person-chip + v-for="teacher in item.relatedDocumentation + .teachers" + :key="teacher.id" + :person="teacher" + no-link + small + /> + <!-- group --> + <span> + {{ item.groupShortName }} + </span> + <!-- subject --> + <subject-chip + :subject="item.relatedDocumentation.subject" + small + /> + </v-list-item-subtitle> + </v-list-item-content> + </v-col> + <v-col cols="12" md="6" class="pa-0"> + <v-list-item-action + class="flex-row full-width justify-md-end ma-0 align-center fill-height" + > + <!-- chips: absences & extraMarks --> + <absence-reason-chip + v-if="item.absenceReason" + :absence-reason="item.absenceReason" + /> + <tardiness-chip + v-if="item.tardiness" + :tardiness="item.tardiness" + class="ms-1" /> - <!-- group --> - <span> - {{ item.groupShortName }} - </span> - <!-- subject --> - <subject-chip - :subject="item.relatedDocumentation.subject" - small + <extra-mark-chip + v-if="item.extraMark" + :extra-mark="item.extraMark" /> - </v-list-item-subtitle> - </v-list-item-content> - </v-col> - <v-col cols="12" md="6" class="pa-0"> - <v-list-item-action - class="flex-row full-width justify-md-end ma-0 align-center fill-height" - > - <!-- chips: absences & extraMarks --> - <absence-reason-chip - v-if="item.absenceReason" - :absence-reason="item.absenceReason" - /> - <tardiness-chip - v-if="item.tardiness" - :tardiness="item.tardiness" - class="ms-1" - /> - <extra-mark-chip - v-if="item.extraMark" - :extra-mark="item.extraMark" - /> - <personal-note-chip v-if="item.note" :note="item" /> - </v-list-item-action> - </v-col> - </v-row> - </v-expansion-panel-header> - <v-expansion-panel-content> - <v-card-text class="pb-0"> - <text-note - v-if="item.note" - :value="item" - :participation="{}" - :person="personName" - :subjects="[]" - :absence-reasons="absenceReasons" - :extra-marks="[]" - :affected-query="lastQuery" - :documentation="item.relatedDocumentation" - /> - <update-participation - v-else - :participation="item" - :subjects="[]" - :absence-reasons="absenceReasons" - :extra-marks="[]" - :affected-query="lastQuery" - :documentation="item.relatedDocumentation" - /> - </v-card-text> - </v-expansion-panel-content> - </v-expansion-panel> - </v-expansion-panels> + <personal-note-chip v-if="item.note" :note="item" /> + </v-list-item-action> + </v-col> + </v-row> + </v-expansion-panel-header> + <v-expansion-panel-content> + <v-card-text class="pb-0"> + <text-note + v-if="item.note" + :value="item" + :participation="{}" + :person="personName" + :subjects="[]" + :absence-reasons="absenceReasons" + :extra-marks="[]" + :affected-query="lastQuery" + :documentation="item.relatedDocumentation" + /> + <update-participation + v-else + :participation="item" + :subjects="[]" + :absence-reasons="absenceReasons" + :extra-marks="[]" + :affected-query="lastQuery" + :documentation="item.relatedDocumentation" + /> + </v-card-text> + </v-expansion-panel-content> + </v-expansion-panel> + </v-expansion-panels> + </v-item-group> <v-divider></v-divider> </template> </c-r-u-d-iterator> @@ -243,10 +275,12 @@ import TextNote from "../personal_notes/TextNote.vue"; import UpdateParticipation from "../absences/UpdateParticipation.vue"; import TardinessChip from "../absences/TardinessChip.vue"; import DeleteAssignedExtraMark from "../personal_notes/DeleteExtraMarkPersonalNote.vue"; +import UpdateParticipations from "../absences/UpdateParticipations.vue"; export default { name: "StatisticsForPersonPage", components: { + UpdateParticipations, DeleteAssignedExtraMark, TardinessChip, UpdateParticipation, @@ -301,6 +335,7 @@ export default { statisticsBottomSheet: false, lastQuery: null, absenceReasons: [], + selected: [], }; }, computed: { @@ -324,6 +359,8 @@ export default { return; } + this.selected = []; + this.$router.push({ name: "alsijil.coursebook_statistics", params: {