195 lines
5.7 KiB
Vue
195 lines
5.7 KiB
Vue
<script setup lang="ts">
|
|
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
|
import {
|
|
maxAssignmentPoints,
|
|
pointsToGrade,
|
|
userAssignmentPoints,
|
|
} from "@/services/assignmentService";
|
|
import { useAssignmentStore } from "@/stores/assignmentStore";
|
|
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
|
import type {
|
|
Assignment,
|
|
AssignmentCompletion,
|
|
AssignmentEvaluationTask,
|
|
CourseSessionUser,
|
|
} from "@/types";
|
|
import dayjs, { Dayjs } from "dayjs";
|
|
import * as log from "loglevel";
|
|
import { computed, reactive } from "vue";
|
|
|
|
const props = defineProps<{
|
|
assignmentUser: CourseSessionUser;
|
|
assignment: Assignment;
|
|
assignmentCompletion: AssignmentCompletion;
|
|
showEvaluationUser?: boolean;
|
|
dueDate?: Dayjs;
|
|
}>();
|
|
|
|
const emit = defineEmits(["editTask"]);
|
|
|
|
const state = reactive({
|
|
showSuccessInfo: false,
|
|
});
|
|
|
|
log.debug("EvaluationSummary setup");
|
|
|
|
const courseSessionsStore = useCourseSessionsStore();
|
|
const assignmentStore = useAssignmentStore();
|
|
|
|
async function submitEvaluation() {
|
|
log.debug("submitEvaluation");
|
|
await assignmentStore.evaluateAssignmentCompletion({
|
|
assignment_user_id: Number(props.assignmentUser.user_id),
|
|
assignment_id: props.assignment.id,
|
|
course_session_id: courseSessionsStore.currentCourseSession!.id,
|
|
completion_data: {},
|
|
completion_status: "evaluation_submitted",
|
|
evaluation_grade: grade.value ?? undefined,
|
|
evaluation_points: userPoints.value,
|
|
});
|
|
state.showSuccessInfo = true;
|
|
}
|
|
|
|
function subTaskByPoints(task: AssignmentEvaluationTask, points = 0) {
|
|
return task.value.sub_tasks.find((subTask) => subTask.points === points);
|
|
}
|
|
|
|
function evaluationForTask(task: AssignmentEvaluationTask) {
|
|
const expertData = props.assignmentCompletion.completion_data[task.id]?.expert_data;
|
|
if (!expertData) {
|
|
return {
|
|
points: 0,
|
|
text: "",
|
|
};
|
|
}
|
|
|
|
return expertData;
|
|
}
|
|
|
|
const maxPoints = computed(() => maxAssignmentPoints(props.assignment));
|
|
const userPoints = computed(() =>
|
|
userAssignmentPoints(props.assignment, props.assignmentCompletion)
|
|
);
|
|
const grade = computed(() => {
|
|
if (props.assignmentCompletion.completion_status === "evaluation_submitted") {
|
|
return props.assignmentCompletion.evaluation_grade;
|
|
}
|
|
return pointsToGrade(userPoints.value, maxPoints.value);
|
|
});
|
|
|
|
const evaluationUser = computed(() => {
|
|
if (props.assignmentCompletion.evaluation_user) {
|
|
return (courseSessionsStore.currentCourseSession?.users ?? []).find(
|
|
(user) => user.user_id === Number(props.assignmentCompletion.evaluation_user)
|
|
) as CourseSessionUser;
|
|
}
|
|
|
|
return undefined;
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<h3 v-if="evaluationUser && props.showEvaluationUser" class="mb-6">
|
|
Bewertung von {{ evaluationUser.first_name }} {{ evaluationUser.last_name }}
|
|
</h3>
|
|
<h3 v-else class="mb-6">Bewertung Freigabe</h3>
|
|
|
|
<section class="mb-6 border p-6">
|
|
<div class="text-lg font-bold">Note: {{ grade }}</div>
|
|
<div class="text-gray-900">
|
|
Gesamtpunktezahl {{ userPoints }} / {{ maxPoints }}
|
|
</div>
|
|
|
|
<p class="my-4">
|
|
Die Gesamtpunktzahl und die daraus resultierende Note wird auf Grund des
|
|
hinterlegeten Beurteilungsinstrument berechnet.
|
|
</p>
|
|
|
|
<p class="my-4">
|
|
<a
|
|
:href="props.assignment.evaluation_document_url"
|
|
class="link"
|
|
target="_blank"
|
|
>
|
|
Beurteilungsinstrument anzeigen
|
|
</a>
|
|
</p>
|
|
|
|
<div
|
|
v-if="props.assignmentCompletion.completion_status === 'evaluation_submitted'"
|
|
>
|
|
Freigabetermin:
|
|
{{
|
|
dayjs(props.assignmentCompletion.evaluation_submitted_at).format("DD.MM.YYYY")
|
|
}}
|
|
um
|
|
{{ dayjs(props.assignmentCompletion.evaluation_submitted_at).format("HH.mm") }}
|
|
Uhr
|
|
</div>
|
|
<div v-else>
|
|
<button class="btn-primary" @click="submitEvaluation()">
|
|
Bewertung freigeben
|
|
</button>
|
|
</div>
|
|
|
|
<div v-if="state.showSuccessInfo" class="mt-4">
|
|
<ItSuccessAlert
|
|
:text="`Deine Bewertung für ${props.assignmentUser.first_name} ${props.assignmentUser.last_name} wurde freigegeben.`"
|
|
></ItSuccessAlert>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<div v-for="(task, index) in props.assignment.evaluation_tasks" :key="task.id">
|
|
<article class="border-t py-4">
|
|
<div class="flex flex-row justify-between">
|
|
<div class="mb-4">
|
|
Bewertungskriterium {{ index + 1 }}: {{ task.value.title }}
|
|
</div>
|
|
<div
|
|
v-if="
|
|
props.assignmentCompletion.completion_status !== 'evaluation_submitted'
|
|
"
|
|
>
|
|
<button
|
|
class="link pl-2text-sm whitespace-nowrap"
|
|
@click="emit('editTask', task)"
|
|
>
|
|
{{ $t("assignment.edit") }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="default-wagtail-rich-text mb-2 font-bold"
|
|
v-html="task.value.description"
|
|
></div>
|
|
|
|
<section class="mb-4">
|
|
<div
|
|
v-html="subTaskByPoints(task, evaluationForTask(task).points)?.title"
|
|
></div>
|
|
<p
|
|
class="default-wagtail-rich-text"
|
|
v-html="
|
|
subTaskByPoints(task, evaluationForTask(task).points)?.description
|
|
"
|
|
></p>
|
|
<div class="text-sm text-gray-800">
|
|
{{ evaluationForTask(task).points }} Punkte
|
|
</div>
|
|
</section>
|
|
|
|
<div>
|
|
<span class="font-bold">Begründung:</span>
|
|
{{ evaluationForTask(task).text }}
|
|
</div>
|
|
</article>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped></style>
|