Refactor competenceStore to handle multiple users
This commit is contained in:
parent
c9ddefd82e
commit
7bddd43b65
|
|
@ -12,7 +12,8 @@ log.debug("CompetenceIndexPage created");
|
||||||
const competenceStore = useCompetenceStore();
|
const competenceStore = useCompetenceStore();
|
||||||
|
|
||||||
const failedCriteria = computed(() => {
|
const failedCriteria = computed(() => {
|
||||||
return competenceStore.flatPerformanceCriteria
|
return competenceStore
|
||||||
|
.flatPerformanceCriteria()
|
||||||
.filter((criteria) => {
|
.filter((criteria) => {
|
||||||
return criteria.completion_status === "fail";
|
return criteria.completion_status === "fail";
|
||||||
})
|
})
|
||||||
|
|
@ -21,7 +22,7 @@ const failedCriteria = computed(() => {
|
||||||
|
|
||||||
const lastUpdatedCompetences = computed(() => {
|
const lastUpdatedCompetences = computed(() => {
|
||||||
return _.orderBy(
|
return _.orderBy(
|
||||||
competenceStore.competences,
|
competenceStore.competences(),
|
||||||
[
|
[
|
||||||
(competence) => {
|
(competence) => {
|
||||||
let criteria = competence.children;
|
let criteria = competence.children;
|
||||||
|
|
@ -43,7 +44,7 @@ const lastUpdatedCompetences = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const countStatus = computed(() => {
|
const countStatus = computed(() => {
|
||||||
return competenceStore.calcStatusCount(competenceStore.flatPerformanceCriteria);
|
return competenceStore.calcStatusCount(competenceStore.flatPerformanceCriteria());
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ const competenceStore = useCompetenceStore();
|
||||||
</div>
|
</div>
|
||||||
<ul v-if="competenceStore.competenceProfilePage">
|
<ul v-if="competenceStore.competenceProfilePage">
|
||||||
<li
|
<li
|
||||||
v-for="competence in competenceStore.competences"
|
v-for="competence in competenceStore.competences()"
|
||||||
:key="competence.id"
|
:key="competence.id"
|
||||||
class="bg-white p-8 mb-8"
|
class="bg-white p-8 mb-8"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ interface MenuItem {
|
||||||
const competenceStore = useCompetenceStore();
|
const competenceStore = useCompetenceStore();
|
||||||
|
|
||||||
const shownCriteria = computed(() => {
|
const shownCriteria = computed(() => {
|
||||||
return competenceStore.flatPerformanceCriteria.filter((criteria) => {
|
return competenceStore.flatPerformanceCriteria().filter((criteria) => {
|
||||||
return criteria.completion_status === activeMenuItem.value.id;
|
return criteria.completion_status === activeMenuItem.value.id;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ import _ from "lodash";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
export type CompetenceStoreState = {
|
export type CompetenceStoreState = {
|
||||||
competenceProfilePage: CompetenceProfilePage | undefined;
|
competenceProfilePages: Map<number, CompetenceProfilePage>;
|
||||||
|
|
||||||
selectedCircle: { id: string; name: string };
|
selectedCircle: { id: string; name: string };
|
||||||
availableCircles: { id: string; name: string }[];
|
availableCircles: { id: string; name: string }[];
|
||||||
};
|
};
|
||||||
|
|
@ -20,60 +21,12 @@ export const useCompetenceStore = defineStore({
|
||||||
id: "competence",
|
id: "competence",
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
competenceProfilePage: undefined,
|
competenceProfilePages: new Map<number, CompetenceProfilePage>(),
|
||||||
selectedCircle: { id: "all", name: "Circle: Alle" },
|
selectedCircle: { id: "all", name: "Circle: Alle" },
|
||||||
availableCircles: [],
|
availableCircles: [],
|
||||||
} as CompetenceStoreState;
|
} as CompetenceStoreState;
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {},
|
||||||
flatPerformanceCriteria: (state) => {
|
|
||||||
if (!state.competenceProfilePage) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let criteria = _.orderBy(
|
|
||||||
state.competenceProfilePage.children.flatMap((competence) => {
|
|
||||||
return competence.children;
|
|
||||||
}),
|
|
||||||
["competence_id"],
|
|
||||||
["asc"]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (state.selectedCircle.id !== "all") {
|
|
||||||
criteria = criteria.filter(
|
|
||||||
(c) => c.circle.translation_key === state.selectedCircle.id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return criteria;
|
|
||||||
},
|
|
||||||
competences: (state) => {
|
|
||||||
if (state.competenceProfilePage?.children.length) {
|
|
||||||
return state.competenceProfilePage.children.filter((competence) => {
|
|
||||||
let criteria = competence.children;
|
|
||||||
if (state.selectedCircle.id != "all") {
|
|
||||||
criteria = criteria.filter((criteria) => {
|
|
||||||
return criteria.circle.translation_key === state.selectedCircle.id;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return criteria.length > 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
criteriaByCompetence: (state) => {
|
|
||||||
return (competence: CompetencePage) => {
|
|
||||||
return competence.children.filter((criteria) => {
|
|
||||||
if (state.selectedCircle.id != "all") {
|
|
||||||
return criteria.circle.translation_key === state.selectedCircle.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return competence.children;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
actions: {
|
actions: {
|
||||||
calcStatusCount(criteria: PerformanceCriteria[]) {
|
calcStatusCount(criteria: PerformanceCriteria[]) {
|
||||||
if (criteria) {
|
if (criteria) {
|
||||||
|
|
@ -91,36 +44,107 @@ export const useCompetenceStore = defineStore({
|
||||||
unknown: 0,
|
unknown: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async loadCompetenceProfilePage(slug: string, reload = false) {
|
criteriaByCompetence(competence: CompetencePage) {
|
||||||
this.competenceProfilePage = await itGetCached(`/api/course/page/${slug}/`, {
|
return competence.children.filter((criteria) => {
|
||||||
|
if (this.selectedCircle.id != "all") {
|
||||||
|
return criteria.circle.translation_key === this.selectedCircle.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return competence.children;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
flatPerformanceCriteria(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) {
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
const competenceProfilePage = await itGetCached(`/api/course/page/${slug}/`, {
|
||||||
reload: reload,
|
reload: reload,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!this.competenceProfilePage) {
|
if (!competenceProfilePage) {
|
||||||
throw `No competenceProfilePageData found with: ${slug}`;
|
throw `No competenceProfilePageData found with: ${slug}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const circles = this.competenceProfilePage.circles.map((c: CircleLight) => {
|
this.competenceProfilePages.set(userId, competenceProfilePage);
|
||||||
|
|
||||||
|
const circles = competenceProfilePage.circles.map((c: CircleLight) => {
|
||||||
return { id: c.translation_key, name: `Circle: ${c.title}` };
|
return { id: c.translation_key, name: `Circle: ${c.title}` };
|
||||||
});
|
});
|
||||||
this.availableCircles = [{ id: "all", name: "Circle: Alle" }, ...circles];
|
this.availableCircles = [{ id: "all", name: "Circle: Alle" }, ...circles];
|
||||||
|
|
||||||
await this.parseCompletionData();
|
await this.parseCompletionData(userId);
|
||||||
|
|
||||||
return this.competenceProfilePage;
|
return this.competenceProfilePages.get(userId);
|
||||||
},
|
},
|
||||||
async parseCompletionData() {
|
async parseCompletionData(userId: number) {
|
||||||
const userStore = useUserStore();
|
const competenceProfilePage = this.competenceProfilePages.get(userId);
|
||||||
|
if (competenceProfilePage) {
|
||||||
if (this.competenceProfilePage && userStore.loggedIn) {
|
|
||||||
const completionStore = useCompletionStore();
|
const completionStore = useCompletionStore();
|
||||||
const completionData = await completionStore.loadCompletionData(
|
const completionData = await completionStore.loadCompletionData(
|
||||||
this.competenceProfilePage.course.id,
|
competenceProfilePage.course.id,
|
||||||
userStore.id
|
userId
|
||||||
);
|
);
|
||||||
|
|
||||||
if (completionData) {
|
if (completionData) {
|
||||||
this.competenceProfilePage.children.forEach((competence) => {
|
competenceProfilePage.children.forEach((competence) => {
|
||||||
competence.children.forEach((performanceCriteria) => {
|
competence.children.forEach((performanceCriteria) => {
|
||||||
const completion = completionData.find(
|
const completion = completionData.find(
|
||||||
(c) => c.page_key === performanceCriteria.translation_key
|
(c) => c.page_key === performanceCriteria.translation_key
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,46 @@
|
||||||
import { bustItGetCache, itGetCached, itPost } from "@/fetchHelpers";
|
import { bustItGetCache, itGetCached, itPost } from "@/fetchHelpers";
|
||||||
|
import { useUserStore } from "@/stores/user";
|
||||||
import type { BaseCourseWagtailPage, CourseCompletion } from "@/types";
|
import type { BaseCourseWagtailPage, CourseCompletion } from "@/types";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
export type CompletionStoreState = {
|
|
||||||
completionStore: Map<number, CourseCompletion[]>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useCompletionStore = defineStore({
|
export const useCompletionStore = defineStore({
|
||||||
id: "completion",
|
id: "completion",
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {};
|
||||||
completionStore: new Map(),
|
|
||||||
} as CompletionStoreState;
|
|
||||||
},
|
},
|
||||||
getters: {},
|
getters: {},
|
||||||
actions: {
|
actions: {
|
||||||
async loadCompletionData(courseId: number, userId: number, reload = false) {
|
async loadCompletionData(courseId: number, userId: number, reload = false) {
|
||||||
const userCompletionData = await itGetCached(
|
const userCompletionData = (await itGetCached(
|
||||||
`/api/course/completion/${courseId}/${userId}/`,
|
`/api/course/completion/${courseId}/${userId}/`,
|
||||||
{
|
{
|
||||||
reload: reload,
|
reload: reload,
|
||||||
}
|
}
|
||||||
);
|
)) as CourseCompletion[];
|
||||||
|
|
||||||
if (userCompletionData === undefined) {
|
if (userCompletionData === undefined) {
|
||||||
throw `No completionData found with: ${courseId}, ${userId}`;
|
throw `No completionData found with: ${courseId}, ${userId}`;
|
||||||
}
|
}
|
||||||
|
return userCompletionData || [];
|
||||||
this.completionStore.set(userId, userCompletionData);
|
|
||||||
|
|
||||||
return this.completionStore.get(userId) || [];
|
|
||||||
},
|
},
|
||||||
async markPage(page: BaseCourseWagtailPage, userId: number) {
|
async markPage(
|
||||||
|
page: BaseCourseWagtailPage,
|
||||||
|
userId: number | undefined = undefined
|
||||||
|
) {
|
||||||
const completionData = await itPost("/api/course/completion/mark/", {
|
const completionData = await itPost("/api/course/completion/mark/", {
|
||||||
page_key: page.translation_key,
|
page_key: page.translation_key,
|
||||||
completion_status: page.completion_status,
|
completion_status: page.completion_status,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (completionData && completionData.length > 0) {
|
if (completionData && completionData.length > 0) {
|
||||||
this.completionStore.set(userId, completionData);
|
if (!userId) {
|
||||||
bustItGetCache(`/api/course/completion/${completionData[0].course}/`);
|
const userStore = useUserStore();
|
||||||
|
userId = userStore.id;
|
||||||
|
}
|
||||||
|
bustItGetCache(`/api/course/completion/${completionData[0].course}/${userId}/`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.completionStore.get(userId) || [];
|
return completionData as CourseCompletion[];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue