93 lines
3.0 KiB
TypeScript
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]
|
|
}
|
|
}
|
|
}
|
|
}
|