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

124 lines
3.5 KiB
Vue

<script setup lang="ts">
import ItTextarea from "@/components/ui/ItTextarea.vue";
import { useAssignmentStore } from "@/stores/assignmentStore";
import { useCourseSessionsStore } from "@/stores/courseSessions";
import type {
Assignment,
AssignmentCompletionData,
CourseSessionUser,
ExpertData,
} from "@/types";
import { useDebounceFn } from "@vueuse/core";
import * as log from "loglevel";
import { computed } from "vue";
const props = defineProps<{
assignmentUser: CourseSessionUser;
assignment: Assignment;
taskIndex: number;
}>();
log.debug("EvaluationTask setup", props.taskIndex);
const courseSessionStore = useCourseSessionsStore();
const assignmentStore = useAssignmentStore();
const task = computed(() => props.assignment.evaluation_tasks[props.taskIndex]);
const expertData = computed(() => {
const data = (assignmentStore.assignmentCompletion?.completion_data?.[task.value.id]
?.expert_data ?? {
points: 0,
text: "",
}) as ExpertData;
return data;
});
function changePoints(points: number) {
log.debug("changePoints", points);
evaluateAssignmentCompletion({
[task.value.id]: {
expert_data: { points, text: expertData.value.text },
},
});
}
function onUpdateText(value: string) {
// log.debug("onUpdateText", value);
evaluateAssignmentCompletionDebounced({
[task.value.id]: {
expert_data: {
text: value,
points: expertData.value.points,
},
},
});
}
async function evaluateAssignmentCompletion(completionData: AssignmentCompletionData) {
log.debug("evaluateAssignmentCompletion", completionData);
return assignmentStore.evaluateAssignmentCompletion({
assignment_user_id: Number(props.assignmentUser.user_id),
assignment_id: props.assignment.id,
course_session_id: courseSessionStore.currentCourseSession!.id,
completion_data: completionData,
completion_status: "evaluation_in_progress",
});
}
const evaluateAssignmentCompletionDebounced = useDebounceFn(
evaluateAssignmentCompletion,
300
);
</script>
<template>
<div>
<div class="text-bold mb-4 text-sm">
Beurteilungskriterium {{ taskIndex + 1 }} /
{{ props.assignment.evaluation_tasks.length }}
{{ task.value.title }}
</div>
<h3 class="default-wagtail-rich-text mb-8" v-html="task.value.description"></h3>
<fieldset>
<div>
<div
v-for="(subTask, index) in task.value.sub_tasks"
:key="index"
class="mb-4 flex items-center last:mb-0"
>
<input
:id="String(index)"
name="coursesessions"
type="radio"
:value="subTask.points"
:checked="expertData.points === subTask.points"
class="focus:ring-indigo-900 h-4 w-4 border-gray-300 text-blue-900"
@change="changePoints(subTask.points)"
/>
<label :for="String(index)" class="ml-4 block">
<div>{{ subTask.title }}</div>
<div
v-if="subTask.description"
class="default-wagtail-rich-text"
v-html="subTask.description"
></div>
<div class="text-sm text-gray-800">{{ subTask.points }} Punkte</div>
</label>
</div>
</div>
</fieldset>
<ItTextarea
class="mt-8"
:model-value="expertData.text ?? ''"
label="Begründung"
placeholder="Hier muss zwingend eine Begründung erfasst werden."
@update:model-value="onUpdateText($event)"
></ItTextarea>
</div>
</template>
<style lang="scss" scoped></style>