feat: wraps self evaluation feedback request member side
This commit is contained in:
parent
3a519e2220
commit
412172515f
|
|
@ -28,8 +28,8 @@ import type {
|
|||
import { useQuery } from "@urql/vue";
|
||||
import orderBy from "lodash/orderBy";
|
||||
import log from "loglevel";
|
||||
import type { ComputedRef } from "vue";
|
||||
import { computed, onMounted, ref, watchEffect } from "vue";
|
||||
import type { ComputedRef, Ref } from "vue";
|
||||
import { computed, onMounted, ref, toValue, watchEffect } from "vue";
|
||||
|
||||
export function useCurrentCourseSession() {
|
||||
/**
|
||||
|
|
@ -469,17 +469,52 @@ export function useFileUpload() {
|
|||
export function useLearningMentors() {
|
||||
const learningMentors = ref<LearningMentor[]>([]);
|
||||
const currentCourseSessionId = useCurrentCourseSession().value.id;
|
||||
const loading = ref(false);
|
||||
|
||||
const fetchMentors = async () => {
|
||||
loading.value = true;
|
||||
const { data } = await useCSRFFetch(
|
||||
`/api/mentor/${currentCourseSessionId}/mentors`
|
||||
).json();
|
||||
learningMentors.value = data.value;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
onMounted(fetchMentors);
|
||||
|
||||
return {
|
||||
learningMentors,
|
||||
loading,
|
||||
};
|
||||
}
|
||||
|
||||
export function useSelfEvaluationFeedback(learningUnitId: Ref<string> | string) {
|
||||
const feedback = ref({});
|
||||
const loading = ref(false);
|
||||
const exists = ref(false);
|
||||
|
||||
const url = `/api/self-evaluation-feedback/requester/${toValue(
|
||||
learningUnitId
|
||||
)}/feedback`;
|
||||
|
||||
const fetchSelfEvaluationFeedback = async () => {
|
||||
loading.value = true;
|
||||
const { data, statusCode } = await useCSRFFetch(url).json();
|
||||
loading.value = false;
|
||||
|
||||
if (statusCode.value === 404) {
|
||||
exists.value = false;
|
||||
return;
|
||||
} else {
|
||||
exists.value = true;
|
||||
feedback.value = data.value;
|
||||
}
|
||||
};
|
||||
onMounted(fetchSelfEvaluationFeedback);
|
||||
|
||||
return {
|
||||
feedback,
|
||||
exists,
|
||||
loading,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { useRouteQuery } from "@vueuse/router";
|
|||
import { computed, onUnmounted } from "vue";
|
||||
import { getPreviousRoute } from "@/router/history";
|
||||
import { getCompetenceNaviUrl } from "@/utils/utils";
|
||||
import SelfEvaluationSubmit from "@/pages/learningPath/selfEvaluationPage/SelfEvaluationSubmit.vue";
|
||||
import SelfEvaluationSubmit from "@/pages/learningPath/selfEvaluationPage/SelfEvaluationRequestFeedback.vue";
|
||||
|
||||
log.debug("LearningContent.vue setup");
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,170 @@
|
|||
<script setup lang="ts">
|
||||
import type { LearningUnit, LearningUnitPerformanceCriteria } from "@/types";
|
||||
import { useLearningMentors, useSelfEvaluationFeedback } from "@/composables";
|
||||
import { computed, ref } from "vue";
|
||||
import ItButton from "@/components/ui/ItButton.vue";
|
||||
import NoMentorInformationPanel from "@/components/mentor/NoMentorInformationPanel.vue";
|
||||
import { useCSRFFetch } from "@/fetchHelpers";
|
||||
|
||||
const props = defineProps<{
|
||||
learningUnit: LearningUnit;
|
||||
criteria: LearningUnitPerformanceCriteria[];
|
||||
}>();
|
||||
|
||||
const {
|
||||
feedback: storedFeedback,
|
||||
exists: isStoredFeedbackAvailable,
|
||||
loading: isStoredFeedbackLoading,
|
||||
} = useSelfEvaluationFeedback(props.learningUnit.id);
|
||||
|
||||
// if no feedback is stored "current session"
|
||||
// state management (mentor selection etc.)
|
||||
const { learningMentors, loading: isLearningMentorsLoading } = useLearningMentors();
|
||||
const isCurrentSessionFeedbackRequested = ref(false);
|
||||
const currentSessionRequestedMentor = ref();
|
||||
|
||||
const VisualState = {
|
||||
LOADING: "LOADING",
|
||||
NO_MENTOR: "NO_MENTOR",
|
||||
HAS_REQUESTED_FEEDBACK: "HAS_REQUESTED_FEEDBACK",
|
||||
HAS_NOT_REQUESTED_FEEDBACK: "HAS_NOT_REQUESTED_FEEDBACK",
|
||||
};
|
||||
|
||||
const currentVisualState = computed(() => {
|
||||
if (isLearningMentorsLoading.value || isStoredFeedbackLoading.value) {
|
||||
return VisualState.LOADING;
|
||||
} else if (learningMentors.value.length == 0) {
|
||||
return VisualState.NO_MENTOR;
|
||||
} else if (
|
||||
isStoredFeedbackAvailable.value ||
|
||||
isCurrentSessionFeedbackRequested.value
|
||||
) {
|
||||
return VisualState.HAS_REQUESTED_FEEDBACK;
|
||||
} else {
|
||||
return VisualState.HAS_NOT_REQUESTED_FEEDBACK;
|
||||
}
|
||||
});
|
||||
|
||||
const feedbackMentorName = computed(() => {
|
||||
const mentor = isStoredFeedbackAvailable.value
|
||||
? (storedFeedback.value as any).feedback_provider_user
|
||||
: isCurrentSessionFeedbackRequested.value
|
||||
? currentSessionRequestedMentor.value
|
||||
: null;
|
||||
return mentor ? `${mentor.first_name} ${mentor.last_name}` : "";
|
||||
});
|
||||
|
||||
const onSubmitForMentorFeedback = async () => {
|
||||
const url = `/api/self-evaluation-feedback/requester/${props.learningUnit.id}/feedback/start`;
|
||||
const { error } = await useCSRFFetch(url).post({
|
||||
feedback_provider_user_id: currentSessionRequestedMentor.value.id,
|
||||
});
|
||||
if (!error.value) {
|
||||
isCurrentSessionFeedbackRequested.value = true;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="currentVisualState != VisualState.LOADING" class="mb-10 w-full pt-8">
|
||||
<div class="w-full border border-gray-400">
|
||||
<div class="m-6 space-y-6">
|
||||
<h3 class="heading-3">
|
||||
{{ $t("a.Selbsteinschätzung teilen") }}
|
||||
</h3>
|
||||
<div v-if="currentVisualState == VisualState.NO_MENTOR">
|
||||
<NoMentorInformationPanel />
|
||||
</div>
|
||||
<div v-if="currentVisualState == VisualState.HAS_REQUESTED_FEEDBACK">
|
||||
<div class="flex space-x-2 bg-green-200 p-4">
|
||||
<it-icon-check class="it-icon h-6 w-6 text-green-700" />
|
||||
<div>
|
||||
{{
|
||||
$t(
|
||||
"a.Du hast deine Selbsteinschätzung erfolgreich mit FULL_NAME geteilt.",
|
||||
{
|
||||
FULL_NAME: feedbackMentorName,
|
||||
}
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-6">
|
||||
{{
|
||||
$t(
|
||||
"a.FULL_NAME wird eine Fremdeinschätzung für dich vornehmen. Du wirst per Benachrichtigung informiert, sobald die Fremdeinschätzung für dich freigegeben wurde.",
|
||||
{ FULL_NAME: feedbackMentorName }
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="currentVisualState == VisualState.HAS_NOT_REQUESTED_FEEDBACK">
|
||||
<p>
|
||||
{{
|
||||
$t(
|
||||
"a.Du kannst deine Selbsteinschätzung mit deiner Lernbegleitung teilen, damit sie eine Fremdeinschätzung vornimmt."
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
<select
|
||||
v-model="currentSessionRequestedMentor"
|
||||
data-cy="select-learning-mentor"
|
||||
>
|
||||
<option
|
||||
v-for="learningMentor in learningMentors"
|
||||
:key="learningMentor.id"
|
||||
:value="learningMentor.mentor"
|
||||
>
|
||||
{{ learningMentor.mentor.first_name }}
|
||||
{{ learningMentor.mentor.last_name }}
|
||||
</option>
|
||||
</select>
|
||||
<ItButton
|
||||
class="mt-6"
|
||||
variant="primary"
|
||||
size="large"
|
||||
:disabled="!currentSessionRequestedMentor"
|
||||
data-cy="submit-assignment"
|
||||
@click="onSubmitForMentorFeedback"
|
||||
>
|
||||
<p v-if="!currentSessionRequestedMentor">
|
||||
{{ $t("a.Selbsteinschätzung teilen") }}
|
||||
</p>
|
||||
<p v-else>
|
||||
{{
|
||||
$t("a.Selbsteinschätzung mit MENTOR_NAME teilen", {
|
||||
MENTOR_NAME: feedbackMentorName,
|
||||
})
|
||||
}}
|
||||
</p>
|
||||
</ItButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(completion, index) in criteria"
|
||||
:key="completion.id"
|
||||
class="flex flex-col space-y-4 border-t border-gray-400 py-8"
|
||||
>
|
||||
<div class="flex justify-between">
|
||||
<b>{{ completion.title }}</b>
|
||||
<router-link :to="`${learningUnit.evaluate_url}?step=${index}`" class="underline">
|
||||
{{ $t("a.Bearbeiten") }}
|
||||
</router-link>
|
||||
</div>
|
||||
<div
|
||||
v-if="completion.completion_status == 'SUCCESS'"
|
||||
class="flex flex-row items-center space-x-2"
|
||||
>
|
||||
<it-icon-smiley-happy class="h-6 w-6" />
|
||||
<span>{{ $t("selfEvaluation.yes") }}</span>
|
||||
</div>
|
||||
<div v-else class="flex flex-row items-center space-x-2">
|
||||
<it-icon-smiley-thinking class="h-6 w-6" />
|
||||
<span>{{ $t("selfEvaluation.no") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import type { LearningUnit, LearningUnitPerformanceCriteria } from "@/types";
|
||||
import { useLearningMentors } from "@/composables";
|
||||
import { ref } from "vue";
|
||||
import ItButton from "@/components/ui/ItButton.vue";
|
||||
import NoMentorInformationPanel from "@/components/mentor/NoMentorInformationPanel.vue";
|
||||
|
||||
defineProps<{
|
||||
learningUnit: LearningUnit;
|
||||
criteria: LearningUnitPerformanceCriteria[];
|
||||
}>();
|
||||
|
||||
const selectedLearningMentor = ref();
|
||||
const learningMentors = useLearningMentors().learningMentors;
|
||||
const onSubmitForMentorFeedback = async () => {
|
||||
try {
|
||||
console.log("submit for mentor feedback");
|
||||
} catch (error) {
|
||||
console.log("Could not submit assignment", error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mb-10 w-full pt-8">
|
||||
<div class="w-full border border-gray-400">
|
||||
<div class="m-6 space-y-6">
|
||||
<h3 class="heading-3">
|
||||
{{ $t("a.Selbsteinschätzung teilen") }}
|
||||
</h3>
|
||||
<div v-if="learningMentors?.length">
|
||||
<p>
|
||||
{{
|
||||
$t(
|
||||
"a.Du kannst deine Selbsteinschätzung mit deiner Lernbegleitung teilen, damit sie eine Fremdeinschätzung vornimmt."
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
<select v-model="selectedLearningMentor" data-cy="select-learning-mentor">
|
||||
<option
|
||||
v-for="learningMentor in learningMentors"
|
||||
:key="learningMentor.id"
|
||||
:value="learningMentor.mentor"
|
||||
>
|
||||
{{ learningMentor.mentor.first_name }}
|
||||
{{ learningMentor.mentor.last_name }}
|
||||
</option>
|
||||
</select>
|
||||
<ItButton
|
||||
class="mt-6"
|
||||
variant="primary"
|
||||
size="large"
|
||||
:disabled="!selectedLearningMentor"
|
||||
data-cy="submit-assignment"
|
||||
@click="onSubmitForMentorFeedback"
|
||||
>
|
||||
<p v-if="!selectedLearningMentor">
|
||||
{{ $t("a.Selbsteinschätzung teilen") }}
|
||||
</p>
|
||||
<p v-else>
|
||||
{{
|
||||
$t("a.Selbsteinschätzung mit MENTOR_NAME teilen", {
|
||||
MENTOR_NAME: selectedLearningMentor.first_name,
|
||||
})
|
||||
}}
|
||||
</p>
|
||||
</ItButton>
|
||||
</div>
|
||||
<div v-else>
|
||||
<NoMentorInformationPanel />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="(pc, index) in criteria"
|
||||
:key="pc.id"
|
||||
class="flex flex-col space-y-4 border-t border-gray-400 py-8"
|
||||
>
|
||||
<div class="flex justify-between">
|
||||
<b>{{ pc.title }}</b>
|
||||
<router-link :to="`${learningUnit.evaluate_url}?step=${index}`" class="underline">
|
||||
{{ $t("a.Bearbeiten") }}
|
||||
</router-link>
|
||||
</div>
|
||||
<div
|
||||
v-if="pc.completion_status == 'SUCCESS'"
|
||||
class="flex flex-row items-center space-x-2"
|
||||
>
|
||||
<it-icon-smiley-happy class="h-6 w-6" />
|
||||
<span>{{ $t("selfEvaluation.yes") }}</span>
|
||||
</div>
|
||||
<div v-else class="flex flex-row items-center space-x-2">
|
||||
<it-icon-smiley-thinking class="h-6 w-6" />
|
||||
<span>{{ $t("selfEvaluation.no") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -1,3 +1,49 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
from vbv_lernwelt.self_evaluation_feedback.models import (
|
||||
CourseCompletionFeedback,
|
||||
SelfEvaluationFeedback,
|
||||
)
|
||||
|
||||
|
||||
@admin.register(SelfEvaluationFeedback)
|
||||
class CourseSessionAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"feedback_submitted",
|
||||
"feedback_requester_user",
|
||||
"feedback_provider_user",
|
||||
"learning_unit",
|
||||
)
|
||||
list_filter = (
|
||||
"feedback_submitted",
|
||||
"feedback_requester_user",
|
||||
"feedback_provider_user",
|
||||
"learning_unit",
|
||||
)
|
||||
search_fields = (
|
||||
"feedback_submitted",
|
||||
"feedback_requester_user",
|
||||
"feedback_provider_user",
|
||||
"learning_unit",
|
||||
)
|
||||
|
||||
|
||||
@admin.register(CourseCompletionFeedback)
|
||||
class CourseSessionAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"feedback",
|
||||
"course_completion",
|
||||
"feedback_assessment",
|
||||
)
|
||||
list_filter = (
|
||||
"feedback",
|
||||
"course_completion",
|
||||
"feedback_assessment",
|
||||
)
|
||||
search_fields = (
|
||||
"feedback",
|
||||
"course_completion",
|
||||
"feedback_assessment",
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue