Add ts types for circle data
This commit is contained in:
parent
b6f26eaa61
commit
c1a7f4551d
|
|
@ -13,7 +13,6 @@ module.exports = {
|
|||
'vue/setup-compiler-macros': true
|
||||
},
|
||||
'rules': {
|
||||
'quotes': ['error', 'single'],
|
||||
'@typescript-eslint/no-unused-vars': ['warn'],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
import {describe, it} from 'vitest'
|
||||
import type {Circle} from '../circle';
|
||||
import {parseLearningSequences} from '../circle';
|
||||
|
||||
describe('circleService.parseLearningSequences', () => {
|
||||
it('can parse learning sequences from api response', () => {
|
||||
const input = {
|
||||
"id": 10,
|
||||
"title": "Analyse",
|
||||
"slug": "analyse",
|
||||
"type": "learnpath.Circle",
|
||||
"translation_key": "c9832aaf-02b2-47af-baeb-bde60d8ec1f5",
|
||||
"children": [
|
||||
{
|
||||
"id": 18,
|
||||
"title": "Anwenden",
|
||||
"slug": "anwenden",
|
||||
"type": "learnpath.LearningSequence",
|
||||
"translation_key": "2e4c431a-9602-4398-ad18-20dd4bb189fa",
|
||||
"icon": "it-icon-ls-apply"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"title": "Prämien einsparen",
|
||||
"slug": "pramien-einsparen",
|
||||
"type": "learnpath.LearningUnit",
|
||||
"translation_key": "75c1f31a-ae25-4d9c-9206-a4e7fdae8c13",
|
||||
"questions": []
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"title": "Versicherungsbedarf für Familien",
|
||||
"slug": "versicherungsbedarf-für-familien",
|
||||
"type": "learnpath.LearningContent",
|
||||
"translation_key": "2a422da3-a3ad-468a-831e-9141c122ffef",
|
||||
"minutes": 60,
|
||||
"contents": [
|
||||
{
|
||||
"type": "exercise",
|
||||
"value": {
|
||||
"description": "Beispiel Aufgabe"
|
||||
},
|
||||
"id": "ee0bcef7-702b-42f3-a891-88a0332fce6f"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"title": "Alles klar?",
|
||||
"slug": "alles-klar",
|
||||
"type": "learnpath.LearningContent",
|
||||
"translation_key": "7dc9d96d-07f9-4b9f-bec1-43ba67cf9010",
|
||||
"minutes": 60,
|
||||
"contents": [
|
||||
{
|
||||
"type": "exercise",
|
||||
"value": {
|
||||
"description": "Beispiel Aufgabe"
|
||||
},
|
||||
"id": "a556ebb2-f902-4d78-9b76-38b7933118b8"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"title": "Sich selbständig machen",
|
||||
"slug": "sich-selbstandig-machen",
|
||||
"type": "learnpath.LearningUnit",
|
||||
"translation_key": "c40d5266-3c94-4b9b-8469-9ac6b32a6231",
|
||||
"questions": []
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"title": "GmbH oder AG",
|
||||
"slug": "gmbh-oder-ag",
|
||||
"type": "learnpath.LearningContent",
|
||||
"translation_key": "59331843-9f52-4b41-9cd1-2293a8d90064",
|
||||
"minutes": 120,
|
||||
"contents": [
|
||||
{
|
||||
"type": "video",
|
||||
"value": {
|
||||
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam",
|
||||
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
||||
},
|
||||
"id": "a4974834-f404-4fb8-af94-a24c6db56bb8"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"title": "Tiertherapie Patrizia Feller",
|
||||
"slug": "tiertherapie-patrizia-feller",
|
||||
"type": "learnpath.LearningContent",
|
||||
"translation_key": "13f6d661-1d10-4b59-b8e5-01fcec47a38f",
|
||||
"minutes": 120,
|
||||
"contents": [
|
||||
{
|
||||
"type": "exercise",
|
||||
"value": {
|
||||
"description": "Beispiel Aufgabe"
|
||||
},
|
||||
"id": "5947c947-8656-44b5-826c-1787057c2df2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"title": "Auto verkaufen",
|
||||
"slug": "auto-verkaufen",
|
||||
"type": "learnpath.LearningUnit",
|
||||
"translation_key": "3b42e514-0bbe-4c23-9c88-3f5263e47cf9",
|
||||
"questions": []
|
||||
},
|
||||
],
|
||||
"description": "Nach dem Gespräch werten sie die Analyse aus...",
|
||||
"job_situations": [],
|
||||
"goals": [],
|
||||
"experts": []
|
||||
} as Circle;
|
||||
|
||||
const learningSequences = parseLearningSequences(input.children);
|
||||
|
||||
expect(learningSequences.length).toBe(4);
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
export interface LearningContentBlock {
|
||||
type: 'video' | 'web-based-training' | 'podcast' | 'competence' | 'exercise' | 'document' | 'knowledge';
|
||||
value: {
|
||||
description: string;
|
||||
url?: string;
|
||||
},
|
||||
id: string;
|
||||
}
|
||||
|
||||
|
||||
export interface CircleGoal {
|
||||
type: 'goal';
|
||||
value: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
|
||||
export interface CircleJobSituation {
|
||||
type: 'job_situation';
|
||||
value: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
|
||||
export interface LearningWagtailPage {
|
||||
id: number;
|
||||
title: string;
|
||||
slug: string;
|
||||
translation_key: string;
|
||||
}
|
||||
|
||||
|
||||
export interface LearningContent extends LearningWagtailPage {
|
||||
type: 'learnpath.LearningContent';
|
||||
minutes: number;
|
||||
contents: LearningContentBlock[];
|
||||
}
|
||||
|
||||
|
||||
export interface LearningUnit extends LearningWagtailPage {
|
||||
type: 'learnpath.LearningUnit';
|
||||
questions: [];
|
||||
learningContents: LearningContent[];
|
||||
minutes: number;
|
||||
}
|
||||
|
||||
|
||||
export interface LearningSequence extends LearningWagtailPage {
|
||||
type: 'learnpath.LearningSequence';
|
||||
icon: string;
|
||||
learningUnits: LearningUnit[];
|
||||
minutes: number;
|
||||
}
|
||||
|
||||
|
||||
type CircleChild = LearningContent | LearningUnit | LearningSequence;
|
||||
|
||||
export interface Circle extends LearningWagtailPage {
|
||||
type: 'learnpath.Circle';
|
||||
children: CircleChild[];
|
||||
description: string;
|
||||
}
|
||||
|
||||
function createEmptyLearningUnit(): LearningUnit {
|
||||
return {
|
||||
id: -1,
|
||||
title: '',
|
||||
slug: '',
|
||||
translation_key: '',
|
||||
type: 'learnpath.LearningUnit',
|
||||
questions: [],
|
||||
learningContents: [],
|
||||
minutes: 0,
|
||||
};
|
||||
}
|
||||
|
||||
export function parseLearningSequences (children: CircleChild[]): LearningSequence[] {
|
||||
let learningSequence:LearningSequence|null = null;
|
||||
let learningUnit:LearningUnit|null = null;
|
||||
const result:LearningSequence[] = [];
|
||||
|
||||
children.forEach((child) => {
|
||||
// FIXME add error detection if the data does not conform to expectations
|
||||
if (child.type === 'learnpath.LearningSequence') {
|
||||
if (learningSequence) {
|
||||
if (learningUnit) {
|
||||
learningSequence.learningUnits.push(learningUnit);
|
||||
}
|
||||
result.push(learningSequence);
|
||||
}
|
||||
learningSequence = Object.assign(child, {learningUnits: []});
|
||||
|
||||
// initialize empty learning unit if there will not come a learning unit next
|
||||
learningUnit = createEmptyLearningUnit();
|
||||
} else if (child.type === 'learnpath.LearningUnit') {
|
||||
if (learningSequence === null) {
|
||||
throw new Error('LearningUnit found before LearningSequence');
|
||||
}
|
||||
|
||||
if (learningUnit && learningUnit.learningContents.length) {
|
||||
learningSequence.learningUnits.push(learningUnit);
|
||||
}
|
||||
|
||||
learningUnit = Object.assign(child, {learningContents: []});
|
||||
} else if (child.type === 'learnpath.LearningContent') {
|
||||
if (learningUnit === null) {
|
||||
throw new Error('LearningContent found before LearningUnit');
|
||||
}
|
||||
|
||||
learningUnit.learningContents.push(child);
|
||||
}
|
||||
});
|
||||
|
||||
if (learningUnit && learningSequence) {
|
||||
(learningSequence as LearningSequence).learningUnits.push(learningUnit);
|
||||
result.push(learningSequence);
|
||||
} else {
|
||||
throw new Error('Finished with LearningContent but there is no LearningSequence and LearningUnit');
|
||||
}
|
||||
|
||||
// sum minutes
|
||||
result.forEach((learningSequence) => {
|
||||
learningSequence.minutes = 0;
|
||||
learningSequence.learningUnits.forEach((learningUnit) => {
|
||||
learningUnit.minutes = 0;
|
||||
learningUnit.learningContents.forEach((learningContent) => {
|
||||
learningUnit.minutes += learningContent.minutes;
|
||||
});
|
||||
learningSequence.minutes += learningUnit.minutes;
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import * as log from 'loglevel';
|
|||
import MainNavigationBar from '../components/MainNavigationBar.vue';
|
||||
import LearningSequence from '../components/circle/LearningSequence.vue';
|
||||
import { itGet, itPost } from '../fetchHelpers';
|
||||
import { parseLearningSequences } from '../services/circle';
|
||||
|
||||
export default {
|
||||
components: { LearningSequence, MainNavigationBar },
|
||||
|
|
@ -29,56 +30,13 @@ export default {
|
|||
this.completionData = data;
|
||||
});
|
||||
},
|
||||
createLearningSequences(circleData) {
|
||||
// aggregate wagtail data into LearningSequence > LearningUnit > LearningContent hierarchy
|
||||
let learningSequence = null;
|
||||
let learningUnit = null;
|
||||
circleData.children.forEach((child) => {
|
||||
// FIXME add error detection if the data does not conform to expectations
|
||||
if(child.type === 'learnpath.LearningSequence') {
|
||||
if(learningSequence) {
|
||||
if(learningUnit) {
|
||||
learningSequence.learningUnits.push(learningUnit);
|
||||
}
|
||||
this.learningSequences.push(learningSequence);
|
||||
}
|
||||
learningSequence = Object.assign({}, child, { learningUnits: [] });
|
||||
learningUnit = { id: null, title: '', learningContents: [] };
|
||||
} else if(child.type === 'learnpath.LearningUnit') {
|
||||
if(learningUnit && learningUnit.learningContents.length) {
|
||||
learningSequence.learningUnits.push(learningUnit);
|
||||
}
|
||||
learningUnit = Object.assign({}, child, { learningContents: [] });
|
||||
} else {
|
||||
learningUnit.learningContents.push(child);
|
||||
}
|
||||
});
|
||||
|
||||
if(learningUnit) {
|
||||
learningSequence.learningUnits.push(learningUnit);
|
||||
}
|
||||
this.learningSequences.push(learningSequence);
|
||||
|
||||
// sum minutes
|
||||
this.learningSequences.forEach((learningSequence) => {
|
||||
learningSequence.minutes = 0;
|
||||
learningSequence.learningUnits.forEach((learningUnit) => {
|
||||
learningUnit.minutes = 0;
|
||||
learningUnit.learningContents.forEach((learningContent) => {
|
||||
learningUnit.minutes += learningContent.minutes;
|
||||
});
|
||||
learningSequence.minutes += learningUnit.minutes;
|
||||
});
|
||||
});
|
||||
|
||||
log.debug(this.learningSequences);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
log.debug('CircleView mounted', this.circleSlug);
|
||||
itGet(`/learnpath/api/circle/${this.circleSlug}/`).then((data) => {
|
||||
this.circleData = data;
|
||||
this.createLearningSequences(data);
|
||||
this.learningSequences = parseLearningSequences(this.circleData.children);
|
||||
log.debug(this.learningSequences);
|
||||
|
||||
itGet(`/api/completion/circle/${this.circleData.translation_key}/`).then((completionData) => {
|
||||
this.completionData = completionData;
|
||||
|
|
|
|||
Loading…
Reference in New Issue