vbv/client/src/services/learningPath.ts

93 lines
3.0 KiB
TypeScript

import * as _ from 'lodash'
import type { CircleCompletion, LearningContent, LearningPathChild, CourseWagtailPage, 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 CourseWagtailPage {
readonly type = 'learnpath.LearningPath'
public topics: Topic[]
public circles: Circle[]
public nextLearningContent?: LearningContent
public static fromJson(json: any, completionData: CircleCompletion[]): LearningPath {
return new LearningPath(json.id, json.slug, json.title, json.translation_key, json.children, completionData)
}
constructor(
public readonly id: number,
public readonly slug: string,
public readonly title: string,
public readonly translation_key: string,
public children: LearningPathChild[],
completionData?: any
) {
// parse children
this.topics = []
this.circles = []
let topic: Topic | undefined
this.children.forEach((page) => {
if (page.type === 'learnpath.Topic') {
if (topic) {
this.topics.push(topic)
}
topic = Object.assign(page, { circles: [] })
}
if (page.type === 'learnpath.Circle') {
const circle = Circle.fromJson(page, this)
circle.parseCompletionData(completionData)
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)
}
})
if (topic) {
this.topics.push(topic)
}
this.calcNextLearningContent(completionData)
}
public calcNextLearningContent(completionData: CircleCompletion[]): void {
this.nextLearningContent = undefined
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 {
if (this.circles[0]) {
this.nextLearningContent = this.circles[0].flatLearningContents[0]
}
}
}
}