This repository has been archived on 2025-09-22. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
2025SELab2-project-Dwengo/frontend/src/views/learning-paths/learning-object/content/LearningObjectContentView.vue
2025-04-19 08:20:33 +00:00

90 lines
2.9 KiB
Vue

<script setup lang="ts">
import type { SubmissionData } from "@/views/learning-paths/learning-object/submission-data";
import { getGiftAdapterForType } from "@/views/learning-paths/gift-adapters/gift-adapters.ts";
import { computed, nextTick, onMounted, watch } from "vue";
import { copyArrayWith } from "@/utils/array-utils.ts";
const props = defineProps<{
learningObjectContent: Document;
submissionData?: SubmissionData;
}>();
const emit = defineEmits<(e: "update:submissionData", value: SubmissionData) => void>();
const submissionData = computed<SubmissionData | undefined>({
get: () => props.submissionData,
set: (v?: SubmissionData): void => {
if (v) emit("update:submissionData", v);
},
});
function forEachQuestion(
doAction: (questionIndex: number, questionName: string, questionType: string, questionElement: Element) => void,
): void {
const questions = document.querySelectorAll(".gift-question");
questions.forEach((question) => {
const name = question.id.match(/gift-q(\d+)/)?.[1];
const questionType = question.className
.split(" ")
.find((it) => it.startsWith("gift-question-type"))
?.match(/gift-question-type-([^ ]*)/)?.[1];
if (!name || isNaN(parseInt(name)) || !questionType) return;
const index = parseInt(name) - 1;
doAction(index, name, questionType, question);
});
}
function attachQuestionListeners(): void {
forEachQuestion((index, _name, type, element) => {
getGiftAdapterForType(type)?.installListener(element, (newAnswer) => {
submissionData.value = copyArrayWith(index, newAnswer, submissionData.value ?? []);
});
});
}
function setAnswers(answers: SubmissionData): void {
forEachQuestion((index, _name, type, element) => {
const answer = answers[index];
if (answer !== null && answer !== undefined) {
getGiftAdapterForType(type)?.setAnswer(element, answer);
} else if (answer === undefined) {
answers[index] = null;
}
});
submissionData.value = answers;
}
onMounted(async () =>
nextTick(() => {
attachQuestionListeners();
setAnswers(props.submissionData ?? []);
}),
);
watch(
() => props.learningObjectContent,
async () => {
await nextTick();
attachQuestionListeners();
},
);
watch(
() => props.submissionData,
async () => {
await nextTick();
setAnswers(props.submissionData ?? []);
},
);
</script>
<template>
<div
class="learning-object-container"
v-html="learningObjectContent.body.innerHTML"
></div>
</template>
<style scoped></style>