vbv/client/src/services/selfEvaluationFeedback.ts

170 lines
4.3 KiB
TypeScript

import { useCSRFFetch } from "@/fetchHelpers";
import type { User } from "@/types";
import { toValue } from "@vueuse/core";
import { t } from "i18next";
import type { Ref } 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;
feedback_provider_user: User;
criteria: Criterion[];
}
export interface Criterion {
course_completion_id: string;
title: string;
self_assessment: "FAIL" | "SUCCESS" | "UNKNOWN";
feedback_assessment: "FAIL" | "SUCCESS" | "UNKNOWN";
}
/** 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
*
* Design decision: We generally just re-fetch the whole feedback from the backend
* after each action (e.g. request, release, add-assessment) to keep the frontend simple.
*/
export function useSelfEvaluationFeedback(
learningUnitId: Ref<string> | string,
feedbackRole: "requester" | "provider"
) {
const feedback = ref<FeedbackRequest>();
const loading = ref(false);
const error = ref();
const url = computed(
() => `/api/self-evaluation-feedback/${feedbackRole}/${learningUnitId}/feedback`
);
const fetch = async () => {
error.value = undefined;
loading.value = true;
console.log("Fetching feedback for learning unit", learningUnitId);
const { data, statusCode, error: _error } = await useCSRFFetch(url.value).json();
loading.value = false;
if (_error.value) {
error.value = _error;
feedback.value = undefined;
return;
}
if (statusCode.value === 404) {
feedback.value = undefined;
} else {
feedback.value = data.value;
}
};
const requestFeedback = async (fromProviderUserId: string) => {
if (feedbackRole !== "requester") {
console.warn("Cannot request feedback");
return;
}
const url = `/api/self-evaluation-feedback/requester/${toValue(
learningUnitId
)}/feedback/start`;
await useCSRFFetch(url).post({
feedback_provider_user_id: fromProviderUserId,
});
await fetch();
};
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,
});
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({});
await fetch();
};
onMounted(fetch);
return {
feedback,
error,
loading,
// feedback requester actions
requestFeedback,
// feedback provider actions
addFeedbackAssessment,
releaseFeedback,
};
}
export const getSmiley = (assessment: "FAIL" | "SUCCESS" | "UNKNOWN") => {
switch (assessment) {
case "SUCCESS":
return "it-icon-smiley-happy";
case "FAIL":
return "it-icon-smiley-thinking";
default:
return "it-icon-smiley-neutral";
}
};
export const getSelfEvaluationCaption = (
assessment: "FAIL" | "SUCCESS" | "UNKNOWN"
) => {
switch (assessment) {
case "SUCCESS":
return t("selfEvaluation.yes");
case "FAIL":
return t("selfEvaluation.no");
case "UNKNOWN":
return t("a.Nicht bewertet");
}
};
export const getFeedbackEvaluationCaption = (
assessment: "FAIL" | "SUCCESS" | "UNKNOWN",
requester: User
) => {
switch (assessment) {
case "SUCCESS":
return t("a.Ja, NAME kann das.", {
NAME: requester.first_name,
});
case "FAIL":
return t("a.Nein, NAME muss das nochmals anschauen.", {
NAME: requester.first_name,
});
case "UNKNOWN":
return t("a.Nicht bewertet");
}
};