201 lines
6.2 KiB
TypeScript
201 lines
6.2 KiB
TypeScript
import { itGetCached } from "@/fetchHelpers";
|
|
import { useCompletionStore } from "@/stores/completion";
|
|
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
|
import { useUserStore } from "@/stores/user";
|
|
import type {
|
|
CircleLight,
|
|
CompetencePage,
|
|
CompetenceProfilePage,
|
|
PerformanceCriteria,
|
|
} from "@/types";
|
|
import cloneDeep from "lodash/cloneDeep";
|
|
import groupBy from "lodash/groupBy";
|
|
import orderBy from "lodash/orderBy";
|
|
import { defineStore } from "pinia";
|
|
|
|
export type CompetenceStoreState = {
|
|
competenceProfilePages: Map<number, CompetenceProfilePage>;
|
|
|
|
selectedCircle: { id: string; name: string };
|
|
availableCircles: { id: string; name: string }[];
|
|
};
|
|
|
|
export const useCompetenceStore = defineStore({
|
|
id: "competence",
|
|
state: () => {
|
|
return {
|
|
competenceProfilePages: new Map<number, CompetenceProfilePage>(),
|
|
selectedCircle: { id: "all", name: "Circle: Alle" },
|
|
availableCircles: [],
|
|
} as CompetenceStoreState;
|
|
},
|
|
getters: {},
|
|
actions: {
|
|
calcStatusCount(criteria: PerformanceCriteria[]) {
|
|
if (criteria) {
|
|
const grouped = groupBy(criteria, "completion_status");
|
|
return {
|
|
fail: grouped?.fail?.length || 0,
|
|
success: grouped?.success?.length || 0,
|
|
unknown: grouped?.unknown?.length || 0,
|
|
};
|
|
}
|
|
|
|
return {
|
|
success: 0,
|
|
fail: 0,
|
|
unknown: 0,
|
|
};
|
|
},
|
|
criteriaByCompetence(competence: CompetencePage) {
|
|
return competence.children.filter((criteria) => {
|
|
if (this.selectedCircle.id != "all") {
|
|
return criteria.circle.translation_key === this.selectedCircle.id;
|
|
}
|
|
|
|
return competence.children;
|
|
});
|
|
},
|
|
competenceProfilePage(userId: number | undefined = undefined) {
|
|
if (!userId) {
|
|
const userStore = useUserStore();
|
|
userId = userStore.id;
|
|
}
|
|
|
|
return this.competenceProfilePages.get(userId);
|
|
},
|
|
flatPerformanceCriteria(
|
|
userId: number | undefined = undefined,
|
|
circleTranslationKeys: string[] | undefined = undefined
|
|
) {
|
|
if (!userId) {
|
|
const userStore = useUserStore();
|
|
userId = userStore.id;
|
|
}
|
|
|
|
if (this.competenceProfilePages.get(userId)) {
|
|
const competenceProfilePage = this.competenceProfilePages.get(userId);
|
|
if (competenceProfilePage) {
|
|
let criteria = orderBy(
|
|
competenceProfilePage.children.flatMap((competence) => {
|
|
return competence.children;
|
|
}),
|
|
["competence_id"],
|
|
["asc"]
|
|
);
|
|
|
|
if (this.selectedCircle.id !== "all") {
|
|
criteria = criteria.filter(
|
|
(c) => c.circle.translation_key === this.selectedCircle.id
|
|
);
|
|
}
|
|
|
|
if (circleTranslationKeys) {
|
|
criteria = criteria.filter((c) =>
|
|
circleTranslationKeys.includes(c.circle.translation_key)
|
|
);
|
|
}
|
|
|
|
return criteria;
|
|
}
|
|
}
|
|
|
|
return [];
|
|
},
|
|
competences(userId: number | undefined = undefined) {
|
|
if (!userId) {
|
|
const userStore = useUserStore();
|
|
userId = userStore.id;
|
|
}
|
|
|
|
if (this.competenceProfilePages.get(userId)) {
|
|
const competenceProfilePage = this.competenceProfilePages.get(userId);
|
|
|
|
if (competenceProfilePage?.children.length) {
|
|
return competenceProfilePage.children.filter((competence) => {
|
|
let criteria = competence.children;
|
|
if (this.selectedCircle.id != "all") {
|
|
criteria = criteria.filter((criteria) => {
|
|
return criteria.circle.translation_key === this.selectedCircle.id;
|
|
});
|
|
}
|
|
return criteria.length > 0;
|
|
});
|
|
}
|
|
}
|
|
|
|
return [];
|
|
},
|
|
async loadCompetenceProfilePage(
|
|
slug: string,
|
|
userId: number | undefined = undefined,
|
|
reload = false
|
|
) {
|
|
if (!userId) {
|
|
const userStore = useUserStore();
|
|
userId = userStore.id;
|
|
}
|
|
|
|
if (this.competenceProfilePages.has(userId) && !reload) {
|
|
const competenceProfilePage = this.competenceProfilePages.get(userId);
|
|
await this.parseCompletionData(userId);
|
|
return competenceProfilePage;
|
|
}
|
|
|
|
const competenceProfilePage = await itGetCached(`/api/course/page/${slug}/`, {
|
|
reload: reload,
|
|
});
|
|
|
|
if (!competenceProfilePage) {
|
|
throw `No competenceProfilePageData found with: ${slug}`;
|
|
}
|
|
|
|
this.competenceProfilePages.set(userId, cloneDeep(competenceProfilePage));
|
|
|
|
const circles = competenceProfilePage.circles.map((c: CircleLight) => {
|
|
return { id: c.translation_key, name: `Circle: ${c.title}` };
|
|
});
|
|
this.availableCircles = [{ id: "all", name: "Circle: Alle" }, ...circles];
|
|
|
|
await this.parseCompletionData(userId);
|
|
|
|
return this.competenceProfilePages.get(userId);
|
|
},
|
|
async parseCompletionData(userId: number) {
|
|
const competenceProfilePage = this.competenceProfilePages.get(userId);
|
|
if (competenceProfilePage) {
|
|
const completionStore = useCompletionStore();
|
|
|
|
const courseSessionsStore = useCourseSessionsStore();
|
|
const courseSession = courseSessionsStore.currentCourseSession;
|
|
if (courseSession) {
|
|
const completionData = await completionStore.loadCourseSessionCompletionData(
|
|
courseSession.id,
|
|
userId
|
|
);
|
|
|
|
if (completionData) {
|
|
competenceProfilePage.children.forEach((competence) => {
|
|
competence.children.forEach((performanceCriteria) => {
|
|
const completion = completionData.find(
|
|
(c) => c.page_key === performanceCriteria.translation_key
|
|
);
|
|
if (completion) {
|
|
performanceCriteria.completion_status = completion.completion_status;
|
|
performanceCriteria.completion_status_updated_at =
|
|
completion.updated_at;
|
|
} else {
|
|
performanceCriteria.completion_status = "unknown";
|
|
performanceCriteria.completion_status_updated_at = "";
|
|
}
|
|
});
|
|
});
|
|
|
|
this.competenceProfilePages.set(userId, competenceProfilePage);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
});
|