170 lines
4.3 KiB
TypeScript
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");
|
|
}
|
|
};
|