Refactor data loading
This commit is contained in:
parent
376c206b29
commit
4111e26828
|
|
@ -4,6 +4,7 @@ import { useLearningPathStore } from "@/stores/learningPath";
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
import * as _ from "lodash";
|
import * as _ from "lodash";
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
|
import { mapState } from "pinia";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -16,10 +17,6 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
|
||||||
const learningPathStore = useLearningPathStore();
|
|
||||||
return { learningPathStore };
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
width: 1640,
|
width: 1640,
|
||||||
|
|
@ -27,6 +24,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapState(useLearningPathStore, ["learningPath"]),
|
||||||
viewBox() {
|
viewBox() {
|
||||||
return `0 0 ${this.width} ${this.height}`;
|
return `0 0 ${this.width} ${this.height}`;
|
||||||
},
|
},
|
||||||
|
|
@ -47,9 +45,11 @@ export default {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.learningPathStore.learningPath) {
|
if (this.learningPath) {
|
||||||
|
console.log("#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#");
|
||||||
|
console.log(this.learningPath);
|
||||||
const internalCircles = [];
|
const internalCircles = [];
|
||||||
this.learningPathStore.learningPath.circles.forEach((circle) => {
|
this.learningPath.circles.forEach((circle) => {
|
||||||
const pieWeights = new Array(
|
const pieWeights = new Array(
|
||||||
Math.max(circle.learningSequences.length, 1)
|
Math.max(circle.learningSequences.length, 1)
|
||||||
).fill(1);
|
).fill(1);
|
||||||
|
|
@ -78,17 +78,20 @@ export default {
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
svg() {
|
svg() {
|
||||||
return d3.select("#" + this.identifier);
|
const result = d3.select("#" + this.identifier);
|
||||||
},
|
result.selectAll("*").remove();
|
||||||
|
return result;
|
||||||
learningPath() {
|
|
||||||
return Object.assign({}, this.learningPathStore.learningPath);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
log.debug("LearningPathDiagram mounted");
|
log.debug("LearningPathDiagram mounted");
|
||||||
|
|
||||||
|
// clean old svg
|
||||||
|
d3.select("#" + this.identifier)
|
||||||
|
.selectAll("*")
|
||||||
|
.remove();
|
||||||
|
|
||||||
const circleWidth = this.vertical ? 60 : 200;
|
const circleWidth = this.vertical ? 60 : 200;
|
||||||
const radius = (circleWidth * 0.8) / 2;
|
const radius = (circleWidth * 0.8) / 2;
|
||||||
|
|
||||||
|
|
@ -318,11 +321,7 @@ export default {
|
||||||
.attr("transform", (d, i) => {
|
.attr("transform", (d, i) => {
|
||||||
return (
|
return (
|
||||||
"translate(" +
|
"translate(" +
|
||||||
getTopicHorizontalPosition(
|
getTopicHorizontalPosition(i, d, this.learningPath.topics) +
|
||||||
i,
|
|
||||||
d,
|
|
||||||
this.learningPathStore.learningPath.topics
|
|
||||||
) +
|
|
||||||
",0)"
|
",0)"
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useLearningPathStore } from "@/stores/learningPath";
|
import { useLearningPathStore } from "@/stores/learningPath";
|
||||||
import { useUserStore } from "@/stores/user";
|
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
|
|
||||||
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
||||||
|
|
@ -14,7 +13,6 @@ const props = defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const learningPathStore = useLearningPathStore();
|
const learningPathStore = useLearningPathStore();
|
||||||
const userStore = useUserStore();
|
|
||||||
|
|
||||||
const emits = defineEmits(["closemodal"]);
|
const emits = defineEmits(["closemodal"]);
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -25,6 +23,7 @@ const emits = defineEmits(["closemodal"]);
|
||||||
<div class="learningpath flex flex-col">
|
<div class="learningpath flex flex-col">
|
||||||
<div class="flex flex-col h-max">
|
<div class="flex flex-col h-max">
|
||||||
<LearningPathDiagram
|
<LearningPathDiagram
|
||||||
|
v-if="learningPathStore.learningPath"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
identifier="verticalVisualization"
|
identifier="verticalVisualization"
|
||||||
:vertical="true"
|
:vertical="true"
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,21 @@ export const itGet = (url: RequestInfo) => {
|
||||||
|
|
||||||
const itGetPromiseCache = new Map<string, Promise<any>>();
|
const itGetPromiseCache = new Map<string, Promise<any>>();
|
||||||
|
|
||||||
export function bustItGetCache() {
|
export function bustItGetCache(key?: string) {
|
||||||
itGetPromiseCache.clear();
|
if (key) {
|
||||||
|
itGetPromiseCache.delete(key);
|
||||||
|
} else {
|
||||||
|
itGetPromiseCache.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const itGetCached = (url: RequestInfo): Promise<any> => {
|
export const itGetCached = (
|
||||||
if (!itGetPromiseCache.has(url.toString())) {
|
url: RequestInfo,
|
||||||
|
options = {
|
||||||
|
reload: false,
|
||||||
|
}
|
||||||
|
): Promise<any> => {
|
||||||
|
if (!itGetPromiseCache.has(url.toString()) || options.reload) {
|
||||||
itGetPromiseCache.set(url.toString(), itGet(url));
|
itGetPromiseCache.set(url.toString(), itGet(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { itGetCached } from "@/fetchHelpers";
|
import { itGetCached } from "@/fetchHelpers";
|
||||||
import { useCompletionStore } from "@/stores/completion";
|
import { useCompletionStore } from "@/stores/completion";
|
||||||
import type {
|
import type {
|
||||||
BaseCourseWagtailPage,
|
CircleLight,
|
||||||
CompetencePage,
|
CompetencePage,
|
||||||
CompetenceProfilePage,
|
CompetenceProfilePage,
|
||||||
PerformanceCriteria,
|
PerformanceCriteria,
|
||||||
|
|
@ -91,23 +91,17 @@ export const useCompetenceStore = defineStore({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async loadCompetenceProfilePage(slug: string, reload = false) {
|
async loadCompetenceProfilePage(slug: string, reload = false) {
|
||||||
if (this.competenceProfilePage && !reload) {
|
this.competenceProfilePage = await itGetCached(`/api/course/page/${slug}/`, {
|
||||||
await this.parseCompletionData();
|
reload: reload,
|
||||||
return this.competenceProfilePage;
|
});
|
||||||
}
|
|
||||||
const competenceProfilePageData = await itGetCached(`/api/course/page/${slug}/`);
|
|
||||||
|
|
||||||
if (!competenceProfilePageData) {
|
if (!this.competenceProfilePage) {
|
||||||
throw `No competenceProfilePageData found with: ${slug}`;
|
throw `No competenceProfilePageData found with: ${slug}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.competenceProfilePage = competenceProfilePageData;
|
const circles = this.competenceProfilePage.circles.map((c: CircleLight) => {
|
||||||
|
return { id: c.translation_key, name: `Circle: ${c.title}` };
|
||||||
const circles = competenceProfilePageData.circles.map(
|
});
|
||||||
(c: BaseCourseWagtailPage) => {
|
|
||||||
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();
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,14 @@ export const useCompletionStore = defineStore({
|
||||||
getters: {},
|
getters: {},
|
||||||
actions: {
|
actions: {
|
||||||
async loadCompletionData(courseId: number, reload = false) {
|
async loadCompletionData(courseId: number, reload = false) {
|
||||||
if (this.completionData && !reload) {
|
this.completionData = await itGetCached(`/api/course/completion/${courseId}/`, {
|
||||||
return this.completionData;
|
reload: reload,
|
||||||
}
|
});
|
||||||
const completionData = await itGetCached(`/api/course/completion/${courseId}/`);
|
|
||||||
|
|
||||||
if (!completionData) {
|
if (!this.completionData) {
|
||||||
throw `No completionData found with: ${courseId}`;
|
throw `No completionData found with: ${courseId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.completionData = completionData;
|
|
||||||
return this.completionData || [];
|
return this.completionData || [];
|
||||||
},
|
},
|
||||||
async markPage(page: BaseCourseWagtailPage) {
|
async markPage(page: BaseCourseWagtailPage) {
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,13 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
|
|
||||||
async function loadCourseSessionsData(reload = false) {
|
async function loadCourseSessionsData(reload = false) {
|
||||||
log.debug("loadCourseSessionsData called");
|
log.debug("loadCourseSessionsData called");
|
||||||
if (courseSessions.value && !reload) {
|
courseSessions.value = await itGetCached(`/api/course/sessions/`, {
|
||||||
return courseSessions.value;
|
reload: reload,
|
||||||
}
|
});
|
||||||
|
if (!courseSessions.value) {
|
||||||
const courseSessionsData = await itGetCached(`/api/course/sessions/`);
|
|
||||||
if (!courseSessionsData) {
|
|
||||||
throw `No courseSessionData found for user`;
|
throw `No courseSessionData found for user`;
|
||||||
}
|
}
|
||||||
|
return courseSessions.value;
|
||||||
courseSessions.value = courseSessionsData;
|
|
||||||
return courseSessionsData || [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { courseSessions, loadCourseSessionsData };
|
return { courseSessions, loadCourseSessionsData };
|
||||||
|
|
|
||||||
|
|
@ -6,24 +6,31 @@ import { defineStore } from "pinia";
|
||||||
export type LearningPathStoreState = {
|
export type LearningPathStoreState = {
|
||||||
learningPath: LearningPath | undefined;
|
learningPath: LearningPath | undefined;
|
||||||
page: "INDEX" | "OVERVIEW";
|
page: "INDEX" | "OVERVIEW";
|
||||||
|
loading: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let lastSlug = "";
|
||||||
|
|
||||||
export const useLearningPathStore = defineStore({
|
export const useLearningPathStore = defineStore({
|
||||||
id: "learningPath",
|
id: "learningPath",
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
learningPath: undefined,
|
learningPath: undefined,
|
||||||
page: "INDEX",
|
page: "INDEX",
|
||||||
|
loading: false,
|
||||||
} as LearningPathStoreState;
|
} as LearningPathStoreState;
|
||||||
},
|
},
|
||||||
getters: {},
|
getters: {},
|
||||||
actions: {
|
actions: {
|
||||||
async loadLearningPath(slug: string, reload = false) {
|
async loadLearningPath(slug: string, reload = false) {
|
||||||
|
this.loading = true;
|
||||||
const completionStore = useCompletionStore();
|
const completionStore = useCompletionStore();
|
||||||
if (this.learningPath && !reload) {
|
if (this.learningPath && !reload && slug === lastSlug) {
|
||||||
return this.learningPath;
|
return this.learningPath;
|
||||||
}
|
}
|
||||||
|
this.learningPath = undefined;
|
||||||
const learningPathData = await itGetCached(`/api/course/page/${slug}/`);
|
const learningPathData = await itGetCached(`/api/course/page/${slug}/`);
|
||||||
|
lastSlug = slug;
|
||||||
const completionData = await completionStore.loadCompletionData(
|
const completionData = await completionStore.loadCompletionData(
|
||||||
learningPathData.course.id
|
learningPathData.course.id
|
||||||
);
|
);
|
||||||
|
|
@ -33,6 +40,7 @@ export const useLearningPathStore = defineStore({
|
||||||
}
|
}
|
||||||
|
|
||||||
this.learningPath = LearningPath.fromJson(learningPathData, completionData);
|
this.learningPath = LearningPath.fromJson(learningPathData, completionData);
|
||||||
|
this.loading = false;
|
||||||
return this.learningPath;
|
return this.learningPath;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue