-
-
{{ "Some title " }}}
-
-
+
+
+
+
+
diff --git a/client/src/pages/learningPath/selfEvaluationPage/SelfEvaluation.vue b/client/src/pages/learningPath/selfEvaluationPage/SelfEvaluation.vue
index d9d61d04..0f8de6c8 100644
--- a/client/src/pages/learningPath/selfEvaluationPage/SelfEvaluation.vue
+++ b/client/src/pages/learningPath/selfEvaluationPage/SelfEvaluation.vue
@@ -51,6 +51,13 @@ const showExitButton = computed(
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") {
+ courseCompletionData.markCompletion(currentQuestion.value, "UNKNOWN");
+ }
+
if (questionIndex.value + 1 < numPages.value) {
log.debug("increment questionIndex", questionIndex.value);
questionIndex.value += 1;
diff --git a/client/src/pages/learningPath/selfEvaluationPage/SelfEvaluationRequestFeedback.vue b/client/src/pages/learningPath/selfEvaluationPage/SelfEvaluationRequestFeedback.vue
index d2f174f9..dbeb9396 100644
--- a/client/src/pages/learningPath/selfEvaluationPage/SelfEvaluationRequestFeedback.vue
+++ b/client/src/pages/learningPath/selfEvaluationPage/SelfEvaluationRequestFeedback.vue
@@ -15,7 +15,10 @@ const props = defineProps<{
criteria: LearningUnitPerformanceCriteria[];
}>();
-const selfEvaluationFeedback = useSelfEvaluationFeedback(props.learningUnit.id);
+const selfEvaluationFeedback = useSelfEvaluationFeedback(
+ props.learningUnit.id,
+ "requester"
+);
const storedFeedback = computed(() => selfEvaluationFeedback.feedback.value);
const isStoredFeedbackLoading = computed(() => selfEvaluationFeedback.loading.value);
diff --git a/client/src/services/selfEvaluationFeedback.ts b/client/src/services/selfEvaluationFeedback.ts
index c80f6f0a..f5d33125 100644
--- a/client/src/services/selfEvaluationFeedback.ts
+++ b/client/src/services/selfEvaluationFeedback.ts
@@ -1,11 +1,13 @@
import { useCSRFFetch } from "@/fetchHelpers";
import type { User } from "@/types";
import type { Ref } from "vue";
-import { computed, onMounted, ref, toValue } from "vue";
+import { computed, onMounted, ref } from "vue";
export interface FeedbackRequest {
+ feedback_id: string;
learning_unit_id: number;
circle_name: string;
+ title: string;
// submitted => provider submitted (released) his/her feedback
feedback_submitted: boolean;
feedback_requester_user: User;
@@ -13,26 +15,31 @@ export interface FeedbackRequest {
criteria: Criterion[];
}
-interface Criterion {
+export interface Criterion {
course_completion_id: string;
title: string;
self_assessment: "FAIL" | "SUCCESS" | "UNKNOWN";
feedback_assessment: "FAIL" | "SUCCESS" | "UNKNOWN";
}
-export function useSelfEvaluationFeedback(learningUnitId: Ref
| string) {
+/** To keep the backend permissions model simple, we have two endpoints:
+ * 1. /requester/: for the user who requested the feedback
+ * 2. /provider/: for the user who provides the feedback
+ */
+export function useSelfEvaluationFeedback(
+ learningUnitId: Ref | string,
+ feedbackRole: "requester" | "provider"
+) {
const feedback = ref();
const loading = ref(false);
const error = ref();
const url = computed(
- () => `/api/self-evaluation-feedback/requester/${toValue(learningUnitId)}/feedback`
+ () => `/api/self-evaluation-feedback/${feedbackRole}/${learningUnitId}/feedback`
);
- const fetchSelfEvaluationFeedback = async () => {
- feedback.value = undefined;
+ const fetch = async () => {
error.value = undefined;
-
loading.value = true;
const { data, statusCode, error: _error } = await useCSRFFetch(url.value).json();
loading.value = false;
@@ -50,11 +57,50 @@ export function useSelfEvaluationFeedback(learningUnitId: Ref | string)
}
};
- onMounted(fetchSelfEvaluationFeedback);
+ const addFeedbackAssessment = async (
+ courseCompletionId: string,
+ assessment: "FAIL" | "SUCCESS"
+ ) => {
+ if (feedbackRole !== "provider" || !feedback.value) {
+ console.warn("Cannot add feedback assessment");
+ return;
+ }
+
+ await useCSRFFetch(
+ `/api/self-evaluation-feedback/provider/feedback/${feedback.value.feedback_id}/add-assessment`
+ ).put({
+ course_completion_id: courseCompletionId,
+ feedback_assessment: assessment,
+ });
+
+ // KISS: the backend is our "store" so just
+ // re-fetch e whole feedback from the backend
+ await fetch();
+ };
+
+ const releaseFeedback = async () => {
+ if (feedbackRole !== "provider" || !feedback.value) {
+ console.warn("Cannot release feedback");
+ return;
+ }
+
+ await useCSRFFetch(
+ `/api/self-evaluation-feedback/provider/feedback/${feedback.value.feedback_id}/release`
+ ).put({});
+
+ // KISS: the backend is our "store" so just
+ // re-fetch e whole feedback from the backend
+ await fetch();
+ };
+
+ onMounted(fetch);
return {
feedback,
error,
loading,
+ // feedback provider actions
+ addFeedbackAssessment,
+ releaseFeedback,
};
}
diff --git a/server/vbv_lernwelt/learning_mentor/content/self_evaluation_feedback.py b/server/vbv_lernwelt/learning_mentor/content/self_evaluation_feedback.py
index c8e138f7..8f5750d1 100644
--- a/server/vbv_lernwelt/learning_mentor/content/self_evaluation_feedback.py
+++ b/server/vbv_lernwelt/learning_mentor/content/self_evaluation_feedback.py
@@ -37,6 +37,7 @@ def create_blank_completions_non_requesters(
status=MentorCompletionStatus.UNKNOWN,
user_id=non_requester_user.id,
last_name=non_requester_user.last_name,
+ url="",
)
)
diff --git a/server/vbv_lernwelt/self_evaluation_feedback/serializers.py b/server/vbv_lernwelt/self_evaluation_feedback/serializers.py
index d2cb9a44..fd24d363 100644
--- a/server/vbv_lernwelt/self_evaluation_feedback/serializers.py
+++ b/server/vbv_lernwelt/self_evaluation_feedback/serializers.py
@@ -18,9 +18,7 @@ class SelfEvaluationFeedbackSerializer(serializers.ModelSerializer):
learning_unit_id = serializers.PrimaryKeyRelatedField(
read_only=True, source="learning_unit"
)
- feedback_id = serializers.PrimaryKeyRelatedField(
- read_only=True, source="course_completion_feedback"
- )
+ feedback_id = serializers.PrimaryKeyRelatedField(read_only=True, source="id")
circle_name = serializers.SerializerMethodField()
title = serializers.CharField(source="learning_unit.title")
diff --git a/server/vbv_lernwelt/self_evaluation_feedback/tests/test_api.py b/server/vbv_lernwelt/self_evaluation_feedback/tests/test_api.py
index 550f3a28..fde8f288 100644
--- a/server/vbv_lernwelt/self_evaluation_feedback/tests/test_api.py
+++ b/server/vbv_lernwelt/self_evaluation_feedback/tests/test_api.py
@@ -370,7 +370,7 @@ class SelfEvaluationFeedbackAPI(APITestCase):
feedback.feedback_assessment, CourseCompletionStatus.FAIL.value
)
- def test_submit_self_evaluation_feedback(self):
+ def test_release_self_evaluation_feedback(self):
# GIVEN
learning_unit = create_learning_unit(course=self.course, circle=self.circle)
self_evaluation_feedback = create_self_evaluation_feedback(
@@ -385,7 +385,7 @@ class SelfEvaluationFeedbackAPI(APITestCase):
# WHEN
response = self.client.put(
reverse(
- "submit_self_evaluation_feedback", args=[self_evaluation_feedback.id]
+ "release_self_evaluation_feedback", args=[self_evaluation_feedback.id]
),
)
diff --git a/server/vbv_lernwelt/self_evaluation_feedback/urls.py b/server/vbv_lernwelt/self_evaluation_feedback/urls.py
index c3a3efe0..0b0514de 100644
--- a/server/vbv_lernwelt/self_evaluation_feedback/urls.py
+++ b/server/vbv_lernwelt/self_evaluation_feedback/urls.py
@@ -4,8 +4,8 @@ from vbv_lernwelt.self_evaluation_feedback.views import (
add_provider_self_evaluation_feedback,
get_self_evaluation_feedback_as_provider,
get_self_evaluation_feedback_as_requester,
+ release_provider_self_evaluation_feedback,
start_self_evaluation_feedback,
- submit_provider_self_evaluation_feedback,
)
urlpatterns = [
@@ -25,9 +25,9 @@ urlpatterns = [
name="get_self_evaluation_feedback_as_provider",
),
path(
- "provider/feedback//submit",
- submit_provider_self_evaluation_feedback,
- name="submit_self_evaluation_feedback",
+ "provider/feedback//release",
+ release_provider_self_evaluation_feedback,
+ name="release_self_evaluation_feedback",
),
path(
"provider/feedback//add-assessment",
diff --git a/server/vbv_lernwelt/self_evaluation_feedback/views.py b/server/vbv_lernwelt/self_evaluation_feedback/views.py
index 521a6161..e6842b3f 100644
--- a/server/vbv_lernwelt/self_evaluation_feedback/views.py
+++ b/server/vbv_lernwelt/self_evaluation_feedback/views.py
@@ -48,7 +48,7 @@ def start_self_evaluation_feedback(request, learning_unit_id):
@api_view(["PUT"])
@permission_classes([IsAuthenticated])
-def submit_provider_self_evaluation_feedback(request, feedback_id):
+def release_provider_self_evaluation_feedback(request, feedback_id):
feedback = get_object_or_404(
SelfEvaluationFeedback, id=feedback_id, feedback_provider_user=request.user
)
@@ -56,6 +56,8 @@ def submit_provider_self_evaluation_feedback(request, feedback_id):
feedback.feedback_submitted = True
feedback.save()
+ # TODO: Create notification for feedback_requester_user
+
return Response({"success": True})