vbv/client/src/stores/circle.ts

180 lines
5.2 KiB
TypeScript

import * as log from "loglevel";
import type { Circle } from "@/services/circle";
import { useCompletionStore } from "@/stores/completion";
import { useLearningPathStore } from "@/stores/learningPath";
import { useUserStore } from "@/stores/user";
import type {
CourseCompletionStatus,
LearningContentInterface,
LearningUnit,
LearningUnitPerformanceCriteria,
PerformanceCriteria,
} from "@/types";
import { defineStore } from "pinia";
export type CircleStoreState = {
circle: Circle | undefined;
page: "INDEX" | "OVERVIEW";
};
function createLearningUnitHash(learningUnit: LearningUnit | undefined) {
const luSlug = learningUnit?.slug;
const circleSlug = learningUnit?.parentCircle?.slug;
if (luSlug && circleSlug) {
return "#" + luSlug.replace(`${circleSlug}-`, "");
}
return "";
}
export const useCircleStore = defineStore({
id: "circle",
state: () => {
return {
circle: undefined,
page: "INDEX",
} as CircleStoreState;
},
getters: {},
actions: {
async loadCircle(
courseSlug: string,
circleSlug: string,
userId: string | undefined = undefined
): Promise<Circle> {
if (!userId) {
const userStore = useUserStore();
userId = userStore.id;
}
this.circle = undefined;
const learningPathSlug = courseSlug + "-lp";
const learningPathStore = useLearningPathStore();
const learningPath = await learningPathStore.loadLearningPath(
learningPathSlug,
userId
);
if (learningPath) {
this.circle = learningPath.circles.find((circle) => {
return circle.slug.endsWith(circleSlug);
});
}
if (!this.circle) {
throw `No circle found with slug: ${circleSlug}`;
}
return this.circle;
},
async loadLearningContent(
courseSlug: string,
circleSlug: string,
learningContentSlug: string
) {
const circle = await this.loadCircle(courseSlug, circleSlug);
const result = circle.flatLearningContents.find((learningContent) => {
return learningContent.slug.endsWith(learningContentSlug);
});
if (!result) {
throw `No learning content found with slug: ${learningContentSlug}`;
}
return result;
},
async loadSelfEvaluation(
courseSlug: string,
circleSlug: string,
learningUnitSlug: string
) {
const circle = await this.loadCircle(courseSlug, circleSlug);
const learningUnit = circle.flatLearningUnits.find((child) => {
return child.slug.endsWith(learningUnitSlug);
});
if (!learningUnit) {
throw `No self evaluation found with slug: ${learningUnitSlug}`;
}
return learningUnit;
},
async markCompletion(
page:
| LearningContentInterface
| LearningUnitPerformanceCriteria
| PerformanceCriteria
| undefined,
completion_status: CourseCompletionStatus = "SUCCESS"
) {
const completionStore = useCompletionStore();
try {
if (page) {
page.completion_status = completion_status;
const completionData = await completionStore.markPage(page);
if (this.circle) {
this.circle.parseCompletionData(completionData);
}
}
} catch (error) {
log.error(error);
return error;
}
},
openLearningContent(learningContent: LearningContentInterface) {
this.router.push({
path: learningContent.frontend_url,
});
},
closeLearningContent(learningContent: LearningContentInterface) {
this.router.push({
path: `${this.circle?.frontend_url}`,
hash: createLearningUnitHash(learningContent.parentLearningUnit),
});
},
openSelfEvaluation(learningUnit: LearningUnit) {
this.router.push({
path: learningUnit.evaluate_url,
});
},
closeSelfEvaluation(learningUnit: LearningUnit) {
this.router.push({
path: `${this.circle?.frontend_url}`,
hash: createLearningUnitHash(learningUnit),
});
},
calcSelfEvaluationStatus(learningUnit: LearningUnit): CourseCompletionStatus {
if (learningUnit.children.length > 0) {
if (learningUnit.children.every((q) => q.completion_status === "SUCCESS")) {
return "SUCCESS";
}
if (
learningUnit.children.every(
(q) => q.completion_status === "FAIL" || q.completion_status === "SUCCESS"
)
) {
return "FAIL";
}
}
return "UNKNOWN";
},
continueFromLearningContent(currentLearningContent: LearningContentInterface) {
if (currentLearningContent) {
if (currentLearningContent.can_user_self_toggle_course_completion) {
this.markCompletion(currentLearningContent, "SUCCESS");
} else {
// reload completion data anyway
currentLearningContent.parentCircle?.parentLearningPath?.reloadCompletionData();
}
this.closeLearningContent(currentLearningContent);
} else {
log.error("currentLearningContent is undefined");
}
},
continueFromSelfEvaluation(learningUnit: LearningUnit) {
this.closeSelfEvaluation(learningUnit);
},
},
});