Refactor data loading

This commit is contained in:
Daniel Egger 2022-11-09 18:33:35 +01:00
parent 376c206b29
commit 4111e26828
7 changed files with 55 additions and 52 deletions

View File

@ -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)"
); );
}) })

View File

@ -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"

View File

@ -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));
} }

View File

@ -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();

View File

@ -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) {

View File

@ -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 };

View File

@ -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;
}, },
}, },