vbv/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue

228 lines
6.6 KiB
Vue

<script setup lang="ts">
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
import {
maxAssignmentPoints,
userAssignmentPoints,
} from "@/services/assignmentService";
import type {
Assignment,
AssignmentCompletion,
AssignmentEvaluationTask,
CourseSessionUser,
} from "@/types";
import { useMutation } from "@urql/vue";
import dayjs, { Dayjs } from "dayjs";
import * as log from "loglevel";
import { computed, reactive } from "vue";
import RichText from "@/components/ui/RichText.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 courseSession = useCurrentCourseSession();
const upsertAssignmentCompletionMutation = useMutation(
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
);
async function submitEvaluation() {
upsertAssignmentCompletionMutation.executeMutation({
assignmentId: props.assignment.id,
courseSessionId: courseSession.value.id,
assignmentUserId: props.assignmentUser.user_id,
completionStatus: "EVALUATION_SUBMITTED",
completionDataString: JSON.stringify({}),
evaluationPoints: userPoints.value,
// next line used for urql
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
id: props.assignmentCompletion?.id,
});
log.debug("submitEvaluation");
state.showSuccessInfo = true;
}
function subTaskByPoints(task: AssignmentEvaluationTask, points = 0) {
return task.value.sub_tasks.find((subTask) => subTask.value.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 courseSessionDetailResult = useCourseSessionDetailQuery();
const evaluationUser = computed(() => {
if (props.assignmentCompletion.evaluation_user) {
return courseSessionDetailResult.findUser(
props.assignmentCompletion.evaluation_user?.id
);
}
return undefined;
});
</script>
<template>
<!-- eslint-disable vue/no-v-html -->
<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" data-cy="sub-title">{{ $t("a.Bewertung Freigabe") }}</h3>
<section class="mb-6 border p-6" data-cy="result-section">
<section class="flex items-center">
<div class="heading-1 py-4" data-cy="user-points">
{{ userPoints }}
</div>
<div class="pl-2" data-cy="total-points">
{{ $t("assignment.von x Punkten", { x: maxPoints }) }}
({{
(
((props.assignmentCompletion?.evaluation_points ?? 0) /
(props.assignmentCompletion?.evaluation_max_points ?? 1)) *
100
).toFixed(0)
}}%)
</div>
</section>
<div
v-if="
props.assignmentCompletion.completion_status === 'EVALUATION_SUBMITTED' &&
!props.assignmentCompletion.evaluation_passed
"
>
<span class="my-2 rounded-md bg-error-red-200 px-2.5 py-0.5">
{{ $t("a.Nicht Bestanden") }}
</span>
</div>
<p class="my-4">
{{ $t("assignment.evaluationInstrumentDescriptionText") }}
</p>
<p class="my-4">
<a
:href="props.assignment.evaluation_document_url"
class="link"
target="_blank"
>
{{ $t("a.Beurteilungsinstrument anzeigen") }}
</a>
</p>
<div
v-if="props.assignmentCompletion.completion_status === 'EVALUATION_SUBMITTED'"
>
{{ $t("assignment.dueDateEvaluation") }}:
{{
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 text-large"
data-cy="submit-evaluation"
@click="submitEvaluation()"
>
{{ $t("a.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 text-gray-900">
{{ $t("a.Beurteilungskriterium") }} {{ 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>
<RichText
class="mb-2 font-bold"
:content="task.value.description"
open-links-in-new-tab
/>
<section class="mb-4">
<div
v-html="
subTaskByPoints(task, evaluationForTask(task).points)?.value.title
"
></div>
<RichText
:content="
subTaskByPoints(task, evaluationForTask(task).points)?.value.description
"
open-links-in-new-tab
/>
<div class="text-sm text-gray-800">
{{ evaluationForTask(task).points }} Punkte
</div>
</section>
<div>
<span class="font-bold">{{ $t("a.Begründung") }}:</span>
{{ evaluationForTask(task).text }}
</div>
</article>
</div>
</section>
</div>
</template>
<style lang="scss" scoped></style>