diff --git a/client/src/components/learningPath/LearningPathDiagram.vue b/client/src/components/learningPath/LearningPathDiagram.vue index 499b48b9..063a4382 100644 --- a/client/src/components/learningPath/LearningPathDiagram.vue +++ b/client/src/components/learningPath/LearningPathDiagram.vue @@ -4,6 +4,7 @@ import { useLearningPathStore } from "@/stores/learningPath"; import * as d3 from "d3"; import * as _ from "lodash"; import * as log from "loglevel"; +import { mapState } from "pinia"; export default { props: { @@ -16,10 +17,6 @@ export default { type: String, }, }, - setup() { - const learningPathStore = useLearningPathStore(); - return { learningPathStore }; - }, data() { return { width: 1640, @@ -27,6 +24,7 @@ export default { }; }, computed: { + ...mapState(useLearningPathStore, ["learningPath"]), viewBox() { return `0 0 ${this.width} ${this.height}`; }, @@ -47,9 +45,11 @@ export default { return false; } - if (this.learningPathStore.learningPath) { + if (this.learningPath) { + console.log("#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#"); + console.log(this.learningPath); const internalCircles = []; - this.learningPathStore.learningPath.circles.forEach((circle) => { + this.learningPath.circles.forEach((circle) => { const pieWeights = new Array( Math.max(circle.learningSequences.length, 1) ).fill(1); @@ -78,17 +78,20 @@ export default { return []; }, svg() { - return d3.select("#" + this.identifier); - }, - - learningPath() { - return Object.assign({}, this.learningPathStore.learningPath); + const result = d3.select("#" + this.identifier); + result.selectAll("*").remove(); + return result; }, }, mounted() { log.debug("LearningPathDiagram mounted"); + // clean old svg + d3.select("#" + this.identifier) + .selectAll("*") + .remove(); + const circleWidth = this.vertical ? 60 : 200; const radius = (circleWidth * 0.8) / 2; @@ -318,11 +321,7 @@ export default { .attr("transform", (d, i) => { return ( "translate(" + - getTopicHorizontalPosition( - i, - d, - this.learningPathStore.learningPath.topics - ) + + getTopicHorizontalPosition(i, d, this.learningPath.topics) + ",0)" ); }) diff --git a/client/src/components/learningPath/LearningPathViewVertical.vue b/client/src/components/learningPath/LearningPathViewVertical.vue index 9aea5c1d..4b03710e 100644 --- a/client/src/components/learningPath/LearningPathViewVertical.vue +++ b/client/src/components/learningPath/LearningPathViewVertical.vue @@ -1,6 +1,5 @@ @@ -25,6 +23,7 @@ const emits = defineEmits(["closemodal"]);
{ const itGetPromiseCache = new Map>(); -export function bustItGetCache() { - itGetPromiseCache.clear(); +export function bustItGetCache(key?: string) { + if (key) { + itGetPromiseCache.delete(key); + } else { + itGetPromiseCache.clear(); + } } -export const itGetCached = (url: RequestInfo): Promise => { - if (!itGetPromiseCache.has(url.toString())) { +export const itGetCached = ( + url: RequestInfo, + options = { + reload: false, + } +): Promise => { + if (!itGetPromiseCache.has(url.toString()) || options.reload) { itGetPromiseCache.set(url.toString(), itGet(url)); } diff --git a/client/src/stores/competence.ts b/client/src/stores/competence.ts index 5e09769f..2941774f 100644 --- a/client/src/stores/competence.ts +++ b/client/src/stores/competence.ts @@ -1,7 +1,7 @@ import { itGetCached } from "@/fetchHelpers"; import { useCompletionStore } from "@/stores/completion"; import type { - BaseCourseWagtailPage, + CircleLight, CompetencePage, CompetenceProfilePage, PerformanceCriteria, @@ -91,23 +91,17 @@ export const useCompetenceStore = defineStore({ }; }, async loadCompetenceProfilePage(slug: string, reload = false) { - if (this.competenceProfilePage && !reload) { - await this.parseCompletionData(); - return this.competenceProfilePage; - } - const competenceProfilePageData = await itGetCached(`/api/course/page/${slug}/`); + this.competenceProfilePage = await itGetCached(`/api/course/page/${slug}/`, { + reload: reload, + }); - if (!competenceProfilePageData) { + if (!this.competenceProfilePage) { throw `No competenceProfilePageData found with: ${slug}`; } - this.competenceProfilePage = competenceProfilePageData; - - const circles = competenceProfilePageData.circles.map( - (c: BaseCourseWagtailPage) => { - return { id: c.translation_key, name: `Circle: ${c.title}` }; - } - ); + const circles = this.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(); diff --git a/client/src/stores/completion.ts b/client/src/stores/completion.ts index 1dcaee26..3d422aa6 100644 --- a/client/src/stores/completion.ts +++ b/client/src/stores/completion.ts @@ -16,16 +16,14 @@ export const useCompletionStore = defineStore({ getters: {}, actions: { async loadCompletionData(courseId: number, reload = false) { - if (this.completionData && !reload) { - return this.completionData; - } - const completionData = await itGetCached(`/api/course/completion/${courseId}/`); + this.completionData = await itGetCached(`/api/course/completion/${courseId}/`, { + reload: reload, + }); - if (!completionData) { + if (!this.completionData) { throw `No completionData found with: ${courseId}`; } - this.completionData = completionData; return this.completionData || []; }, async markPage(page: BaseCourseWagtailPage) { diff --git a/client/src/stores/courseSessions.ts b/client/src/stores/courseSessions.ts index 6f73d5f0..5fd38b67 100644 --- a/client/src/stores/courseSessions.ts +++ b/client/src/stores/courseSessions.ts @@ -9,17 +9,13 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => { async function loadCourseSessionsData(reload = false) { log.debug("loadCourseSessionsData called"); - if (courseSessions.value && !reload) { - return courseSessions.value; - } - - const courseSessionsData = await itGetCached(`/api/course/sessions/`); - if (!courseSessionsData) { + courseSessions.value = await itGetCached(`/api/course/sessions/`, { + reload: reload, + }); + if (!courseSessions.value) { throw `No courseSessionData found for user`; } - - courseSessions.value = courseSessionsData; - return courseSessionsData || []; + return courseSessions.value; } return { courseSessions, loadCourseSessionsData }; diff --git a/client/src/stores/learningPath.ts b/client/src/stores/learningPath.ts index 6f57ae1f..5ecbba19 100644 --- a/client/src/stores/learningPath.ts +++ b/client/src/stores/learningPath.ts @@ -6,24 +6,31 @@ import { defineStore } from "pinia"; export type LearningPathStoreState = { learningPath: LearningPath | undefined; page: "INDEX" | "OVERVIEW"; + loading: boolean; }; +let lastSlug = ""; + export const useLearningPathStore = defineStore({ id: "learningPath", state: () => { return { learningPath: undefined, page: "INDEX", + loading: false, } as LearningPathStoreState; }, getters: {}, actions: { async loadLearningPath(slug: string, reload = false) { + this.loading = true; const completionStore = useCompletionStore(); - if (this.learningPath && !reload) { + if (this.learningPath && !reload && slug === lastSlug) { return this.learningPath; } + this.learningPath = undefined; const learningPathData = await itGetCached(`/api/course/page/${slug}/`); + lastSlug = slug; const completionData = await completionStore.loadCompletionData( learningPathData.course.id ); @@ -33,6 +40,7 @@ export const useLearningPathStore = defineStore({ } this.learningPath = LearningPath.fromJson(learningPathData, completionData); + this.loading = false; return this.learningPath; }, },