From a32c8ccbff71374c34e28ea0f8daec8fb7e4eda6 Mon Sep 17 00:00:00 2001
From: Daniel Egger
Date: Tue, 30 Aug 2022 16:34:08 +0200
Subject: [PATCH] VBV-80: Refactor next learning content
---
client/package.json | 1 +
client/src/services/circle.ts | 20 ++++++++-
client/src/services/learningPath.ts | 37 +++++++++++++++-
client/src/stores/learningPath.ts | 63 ---------------------------
client/src/types.ts | 2 +
client/src/views/LearningPathView.vue | 16 +++----
client/vite.config.ts | 2 +-
7 files changed, 66 insertions(+), 75 deletions(-)
diff --git a/client/package.json b/client/package.json
index 09806947..91a7c6e4 100644
--- a/client/package.json
+++ b/client/package.json
@@ -15,6 +15,7 @@
"@headlessui/vue": "^1.6.7",
"axios": "^0.26.1",
"d3": "^7.6.1",
+ "lodash": "^4.17.21",
"loglevel": "^1.8.0",
"pinia": "^2.0.21",
"vue": "^3.2.38",
diff --git a/client/src/services/circle.ts b/client/src/services/circle.ts
index 09cd0e69..54e8eb46 100644
--- a/client/src/services/circle.ts
+++ b/client/src/services/circle.ts
@@ -24,7 +24,7 @@ function _createEmptyLearningUnit(parentLearningSequence: LearningSequence): Lea
}
}
-export function parseLearningSequences (children: CircleChild[]): LearningSequence[] {
+export function parseLearningSequences (circle: Circle, children: CircleChild[]): LearningSequence[] {
let learningSequence:LearningSequence | undefined;
let learningUnit:LearningUnit | undefined;
let learningContent:LearningContent | undefined;
@@ -69,6 +69,7 @@ export function parseLearningSequences (children: CircleChild[]): LearningSequen
previousLearningContent = learningContent;
learningContent = Object.assign(child, {
+ parentCircle: circle,
parentLearningSequence: learningSequence,
parentLearningUnit: learningUnit,
previousLearningContent: previousLearningContent,
@@ -111,6 +112,9 @@ export class Circle implements LearningWagtailPage {
readonly learningSequences: LearningSequence[];
readonly completed: boolean;
+ nextCircle?: Circle;
+ previousCircle?: Circle;
+
constructor(
public readonly id: number,
public readonly slug: string,
@@ -121,7 +125,7 @@ export class Circle implements LearningWagtailPage {
public goals: CircleGoal[],
public job_situations: CircleJobSituation[],
) {
- this.learningSequences = parseLearningSequences(this.children);
+ this.learningSequences = parseLearningSequences(this, this.children);
this.completed = false;
}
@@ -154,6 +158,18 @@ export class Circle implements LearningWagtailPage {
return result;
}
+ public get flatLearningContents(): LearningContent[] {
+ const result: LearningContent[] = [];
+ this.learningSequences.forEach((learningSequence) => {
+ learningSequence.learningUnits.forEach((learningUnit) => {
+ learningUnit.learningContents.forEach((learningContent) => {
+ result.push(learningContent);
+ });
+ });
+ });
+ return result;
+ }
+
public someFinishedInLearningSequence(translationKey: string): boolean {
if (translationKey) {
return this.flatChildren.filter((lc) => {
diff --git a/client/src/services/learningPath.ts b/client/src/services/learningPath.ts
index b902c71e..1c7c45ae 100644
--- a/client/src/services/learningPath.ts
+++ b/client/src/services/learningPath.ts
@@ -1,10 +1,19 @@
-import type { LearningPathChild, LearningWagtailPage, Topic } from '@/types'
+import * as _ from 'lodash'
+
+import type { CircleCompletion, LearningContent, LearningPathChild, LearningWagtailPage, Topic } from '@/types'
import { Circle } from '@/services/circle'
+function getLastCompleted(learningPathKey: string, completionData: CircleCompletion[]) {
+ return _.orderBy(completionData, ['updated_at'], 'desc').find((c: CircleCompletion) => {
+ return c.completed && c.learning_path_key === learningPathKey && c.page_type === 'learnpath.LearningContent'
+ })
+}
+
export class LearningPath implements LearningWagtailPage {
readonly type = 'learnpath.LearningPath'
public topics: Topic[]
public circles: Circle[]
+ public nextLearningContent?: LearningContent
public static fromJson(json: any, completionData: any): LearningPath {
return new LearningPath(json.id, json.slug, json.title, json.translation_key, json.children, completionData)
@@ -37,6 +46,11 @@ export class LearningPath implements LearningWagtailPage {
if (topic) {
topic.circles.push(circle)
}
+
+ circle.previousCircle = this.circles[this.circles.length - 1]
+ if (circle.previousCircle) {
+ circle.previousCircle.nextCircle = circle
+ }
this.circles.push(circle)
}
})
@@ -44,5 +58,26 @@ export class LearningPath implements LearningWagtailPage {
if (topic) {
this.topics.push(topic)
}
+
+ // find next learning content
+ const lastCompletedLearningContent = getLastCompleted(this.translation_key, completionData);
+
+ if (lastCompletedLearningContent) {
+ const lastCircle = this.circles.find(circle => circle.translation_key === lastCompletedLearningContent.circle_key);
+ if (lastCircle) {
+ const lastLearningContent = lastCircle.flatLearningContents.find(learningContent => learningContent.translation_key === lastCompletedLearningContent.page_key);
+ if (lastLearningContent && lastLearningContent.nextLearningContent) {
+ this.nextLearningContent = lastLearningContent.nextLearningContent;
+ } else {
+ if (lastCircle.nextCircle) {
+ this.nextLearningContent = lastCircle.nextCircle.flatLearningContents[0];
+ }
+ }
+ }
+ } else {
+ this.nextLearningContent = this.circles[0].flatLearningContents[0];
+ }
+
+ console.log('################# ', this.nextLearningContent);
}
}
diff --git a/client/src/stores/learningPath.ts b/client/src/stores/learningPath.ts
index 7b6ad0d4..9dcfb1a9 100644
--- a/client/src/stores/learningPath.ts
+++ b/client/src/stores/learningPath.ts
@@ -3,67 +3,16 @@ import * as log from 'loglevel'
import { defineStore } from 'pinia'
import { itGet } from '@/fetchHelpers'
import { LearningPath } from '@/services/learningPath'
-import {defineStore} from 'pinia'
-import * as _ from 'lodash';
-
-import type {LearningPath, Topic} from '@/types'
-import {itGet} from '@/fetchHelpers';
-import {Circle} from '@/services/circle';
-import learningPathDiagram from "@/components/circle/LearningPathDiagram.vue";
export type LearningPathStoreState = {
learningPath: LearningPath | undefined
}
-
-function getLastCompleted(completionData: any) {
- return _.filter(_.orderBy(completionData, ['updated_at'], 'desc'), c =>{return c.completed && c.page_type === "learnpath.LearningContent" })[0]
-}
-
-
-function getFirstLearningContent(lastCopleted, learningPathData) {
- const circles = _.filter(learningPathData.children, {'type': 'learnpath.Circle'})
-
- let currentCircle = Circle.fromJson(circles[0])
- const currentLearningUnit = currentCircle.flatChildren[0]
- let currentLearningSequence = currentLearningUnit.parentLearningSequence
- return [currentCircle, currentLearningSequence, currentLearningUnit]
-}
-
-function getNextLearningContent(lastCopleted, learningPathData) {
-
- let currentCircle, currentLearningSequence, currentLearningUnit
-
- currentLearningUnit = getFirstLearningContent(lastCopleted, learningPathData)
-
- if (lastCopleted) {
- const circles = _.filter(learningPathData.children, {'type': 'learnpath.Circle'})
- _.forEach(circles, circle => {
- _.forEach(Circle.fromJson(circle).learningSequences, learningSequence => {
- _.forEach(learningSequence.learningUnits, learningUnit => {
- _.forEach(learningUnit.learningContents, content => {
- if (lastCopleted.page_key === content.translation_key) {
- currentCircle = Circle.fromJson(circle)
- currentLearningSequence = learningSequence
- currentLearningUnit = content
-
- }
- })
- })
- })
- })
- currentLearningUnit = [currentCircle, currentLearningSequence, currentLearningUnit]
- }
- return currentLearningUnit
-}
-
-
export const useLearningPathStore = defineStore({
id: 'learningPath',
state: () => {
return {
learningPath: undefined,
-
} as LearningPathStoreState;
},
getters: {},
@@ -76,19 +25,7 @@ export const useLearningPathStore = defineStore({
const learningPathData = await itGet(`/learnpath/api/page/${slug}/`);
const completionData = await itGet(`/api/completion/learning_path/${learningPathData.translation_key}/`);
- this.learningPath = learningPathData;
-
-
if (learningPathData) {
- this.learningPath.lastCompleted = getLastCompleted(completionData)
- const nextLearningContent = getNextLearningContent(this.learningPath.lastCompleted, learningPathData)
-
- console.log('nextLearningContent', nextLearningContent)
- this.learningPath.nextCircle = nextLearningContent[0]
- this.learningPath.nextLearningSequence = nextLearningContent[1]
- this.learningPath.nextLearningUnit = nextLearningContent[2]
-
-
this.learningPath = LearningPath.fromJson(learningPathData, completionData);
}
return this.learningPath;
diff --git a/client/src/types.ts b/client/src/types.ts
index b349af30..420c1984 100644
--- a/client/src/types.ts
+++ b/client/src/types.ts
@@ -59,6 +59,7 @@ export interface LearningContent extends LearningWagtailPage {
type: 'learnpath.LearningContent';
minutes: number;
contents: (LearningContentBlock | VideoBlock | PodcastBlock | DocumentBlock)[];
+ parentCircle: Circle;
parentLearningSequence?: LearningSequence;
parentLearningUnit?: LearningUnit;
nextLearningContent?: LearningContent;
@@ -111,6 +112,7 @@ export interface CircleCompletion {
page_key: string;
page_type: string;
circle_key: string;
+ learning_path_key: string;
completed: boolean;
json_data: any;
}
diff --git a/client/src/views/LearningPathView.vue b/client/src/views/LearningPathView.vue
index d77d7470..ee0c80ec 100644
--- a/client/src/views/LearningPathView.vue
+++ b/client/src/views/LearningPathView.vue
@@ -2,7 +2,7 @@
import * as log from 'loglevel';
-import {computed, onMounted} from 'vue'
+import {onMounted} from 'vue'
import {useLearningPathStore} from '@/stores/learningPath';
import {useUserStore} from '@/stores/user';
@@ -20,10 +20,6 @@ const learningPathStore = useLearningPathStore();
const userStore = useUserStore();
-const continueRoute = computed(() => {
- return "/circle/" + learningPathStore.learningPath.nextCircle.slug + "/";
-})
-
onMounted(async () => {
log.info('LearningPathView mounted');
await learningPathStore.loadLearningPath(props.learningPathSlug);
@@ -72,10 +68,14 @@ onMounted(async () => {
-
+
Nächster Schirtt
-
{{ learningPathStore.learningPath.nextCircle.title }}: {{ learningPathStore.learningPath.nextLearningSequence.title }}
-
+ {{ learningPathStore.learningPath.nextLearningContent.parentCircle.title }}: {{ learningPathStore.learningPath.nextLearningContent.parentLearningSequence.title }}
+
Los geht's
diff --git a/client/vite.config.ts b/client/vite.config.ts
index 8fc64adf..36825c0d 100644
--- a/client/vite.config.ts
+++ b/client/vite.config.ts
@@ -43,7 +43,7 @@ export default defineConfig(({ mode }) => {
},
test: {
globals: true,
- environment: 'happy-dom',
+ environment: 'jsdom',
},
}
})