204 lines
7.0 KiB
Vue
204 lines
7.0 KiB
Vue
<script setup lang="ts">
|
|
import { useCircleStore } from "@/stores/circle";
|
|
import type {
|
|
CircleType,
|
|
CourseCompletionStatus,
|
|
LearningUnit,
|
|
LearningUnitPerformanceCriteria,
|
|
} from "@/types";
|
|
import * as log from "loglevel";
|
|
|
|
import { useCourseDataWithCompletion, useCurrentCourseSession } from "@/composables";
|
|
import LearningContentContainer from "@/pages/learningPath/learningContentPage/LearningContentContainer.vue";
|
|
import LearningContentMultiLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentMultiLayout.vue";
|
|
import SelfEvaluationRequestFeedbackPage from "@/pages/learningPath/selfEvaluationPage/SelfEvaluationRequestFeedbackPage.vue";
|
|
import { getPreviousRoute } from "@/router/history";
|
|
import eventBus from "@/utils/eventBus";
|
|
import { getCompetenceNaviUrl } from "@/utils/utils";
|
|
import { useRouteQuery } from "@vueuse/router";
|
|
import { computed, onUnmounted } from "vue";
|
|
|
|
log.debug("LearningContent.vue setup");
|
|
|
|
const props = defineProps<{
|
|
learningUnit: LearningUnit;
|
|
circle: CircleType;
|
|
}>();
|
|
|
|
const circleStore = useCircleStore();
|
|
const courseSession = useCurrentCourseSession();
|
|
const courseCompletionData = useCourseDataWithCompletion();
|
|
|
|
// if we have preview rights, we can only preview the learning content -> read only
|
|
const isReadOnly = computed(() => courseSession.value.actions.includes("preview"));
|
|
|
|
const questions = computed(() => props.learningUnit?.performance_criteria ?? []);
|
|
const numPages = computed(() => {
|
|
if (learningUnitHasFeedbackPage.value) {
|
|
return questions.value.length + 1;
|
|
} else {
|
|
return questions.value.length;
|
|
}
|
|
});
|
|
|
|
const questionIndex = useRouteQuery("step", "0", { transform: Number, mode: "push" });
|
|
const previousRoute = getPreviousRoute();
|
|
|
|
const learningUnitHasFeedbackPage = computed(
|
|
() =>
|
|
courseSession.value.course.configuration.enable_learning_mentor &&
|
|
courseSession.value.course.configuration.is_vv &&
|
|
!isReadOnly.value
|
|
);
|
|
|
|
const currentQuestion = computed(() => questions.value[questionIndex.value]);
|
|
const showPreviousButton = computed(() => questionIndex.value != 0);
|
|
|
|
const showNextButton = computed(
|
|
() => questionIndex.value + 1 < numPages.value && numPages.value > 1
|
|
);
|
|
|
|
const isLastStep = computed(
|
|
() => questions.value?.length === 1 || numPages.value == questionIndex.value + 1
|
|
);
|
|
|
|
function handleContinue() {
|
|
log.debug("handleContinue");
|
|
|
|
// not answering a question is allowed especially,
|
|
// nonetheless we want to still know this state in the backend!
|
|
if (currentQuestion.value && currentQuestion.value.completion_status === "UNKNOWN") {
|
|
markCompletion(currentQuestion.value, "UNKNOWN");
|
|
}
|
|
|
|
if (questionIndex.value + 1 < numPages.value) {
|
|
log.debug("increment questionIndex", questionIndex.value);
|
|
questionIndex.value += 1;
|
|
} else {
|
|
log.debug("continue to next learning content");
|
|
circleStore.continueFromSelfEvaluation(props.learningUnit, props.circle);
|
|
}
|
|
}
|
|
|
|
function markCompletion(
|
|
question: LearningUnitPerformanceCriteria,
|
|
status: CourseCompletionStatus
|
|
) {
|
|
if (isReadOnly.value) {
|
|
log.debug("We are in read only mode, so we do not mark the completion");
|
|
return;
|
|
} else {
|
|
log.debug("markCompletion", question, status);
|
|
courseCompletionData.markCompletion(question, status);
|
|
}
|
|
}
|
|
|
|
function handleBack() {
|
|
log.debug("handleBack");
|
|
if (questionIndex.value > 0 && questionIndex.value < numPages.value) {
|
|
questionIndex.value -= 1;
|
|
}
|
|
}
|
|
|
|
function handleFinishedLearningContent() {
|
|
circleStore.closeSelfEvaluation(props.learningUnit, props.circle, previousRoute);
|
|
}
|
|
|
|
eventBus.on("finishedLearningContent", handleFinishedLearningContent);
|
|
|
|
onUnmounted(() => {
|
|
eventBus.off("finishedLearningContent", handleFinishedLearningContent);
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div v-if="learningUnit">
|
|
<LearningContentContainer
|
|
@exit="
|
|
circleStore.closeSelfEvaluation(props.learningUnit, props.circle, previousRoute)
|
|
"
|
|
>
|
|
<LearningContentMultiLayout
|
|
:current-step="questionIndex"
|
|
:sub-title="$t('a.Selbsteinschätzung')"
|
|
:title="`${learningUnit.title}`"
|
|
icon="it-icon-lc-learning-module"
|
|
:steps-count="numPages"
|
|
:show-next-button="showNextButton"
|
|
:show-exit-button="isLastStep"
|
|
:show-start-button="false"
|
|
:show-previous-button="showPreviousButton"
|
|
:base-url="props.learningUnit.evaluate_url"
|
|
:close-button-variant="
|
|
learningUnitHasFeedbackPage || isReadOnly ? 'close' : 'mark_as_done'
|
|
"
|
|
:end-badge-text="
|
|
learningUnitHasFeedbackPage ? $t('general.submission') : undefined
|
|
"
|
|
@previous="handleBack()"
|
|
@next="handleContinue()"
|
|
>
|
|
<div v-if="currentQuestion" class="h-full">
|
|
<div class="mt-8">
|
|
<h3 class="heading-3">
|
|
{{ currentQuestion.title }}
|
|
</h3>
|
|
|
|
<div
|
|
class="mt-4 flex flex-col justify-between gap-8 lg:mt-8 lg:flex-row lg:gap-12"
|
|
>
|
|
<button
|
|
:disabled="isReadOnly"
|
|
class="inline-flex flex-1 items-center border p-4 text-left"
|
|
:class="{
|
|
'border-green-500': currentQuestion.completion_status === 'SUCCESS',
|
|
'border-2': currentQuestion.completion_status === 'SUCCESS',
|
|
}"
|
|
data-cy="success"
|
|
@click="markCompletion(currentQuestion, 'SUCCESS')"
|
|
>
|
|
<it-icon-smiley-happy class="mr-4 h-16 w-16"></it-icon-smiley-happy>
|
|
<span class="text-large font-bold">
|
|
{{ $t("selfEvaluation.yes") }}
|
|
</span>
|
|
</button>
|
|
<button
|
|
:disabled="isReadOnly"
|
|
class="inline-flex flex-1 items-center border p-4 text-left"
|
|
:class="{
|
|
'border-orange-500': currentQuestion.completion_status === 'FAIL',
|
|
'border-2': currentQuestion.completion_status === 'FAIL',
|
|
}"
|
|
data-cy="fail"
|
|
@click="markCompletion(currentQuestion, 'FAIL')"
|
|
>
|
|
<it-icon-smiley-thinking
|
|
class="mr-4 h-16 w-16"
|
|
></it-icon-smiley-thinking>
|
|
<span class="text-xl font-bold">{{ $t("selfEvaluation.no") }}</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="mt-6 lg:mt-12">
|
|
{{ $t("selfEvaluation.progressText") }}
|
|
<router-link
|
|
:to="getCompetenceNaviUrl(courseSession.course.slug)"
|
|
class="text-primary-500 underline"
|
|
>
|
|
{{ $t("selfEvaluation.progressLink") }}
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<SelfEvaluationRequestFeedbackPage
|
|
v-else-if="isLastStep && learningUnitHasFeedbackPage"
|
|
:learning-unit="props.learningUnit"
|
|
:criteria="questions"
|
|
/>
|
|
</LearningContentMultiLayout>
|
|
</LearningContentContainer>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped></style>
|