Refactor learningPath views
This commit is contained in:
parent
7022827cf3
commit
cbbf4e42a2
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import * as d3 from 'd3'
|
||||
import * as _ from 'underscore'
|
||||
import * as d3 from 'd3';
|
||||
import { useLearningPathStore } from '../../stores/learningPath';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
|
@ -157,23 +157,31 @@ export default {
|
|||
type: Number,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const learningPathStore = useLearningPathStore()
|
||||
|
||||
return { learningPathStore }
|
||||
},
|
||||
computed: {
|
||||
viewBox() {
|
||||
return `0 0 ${this.width} ${this.height* 1.5}`
|
||||
},
|
||||
circles() {
|
||||
|
||||
let internalCircles = _.flatten(_.pluck(this.learningPathContents.topics, 'circles'))
|
||||
_.forEach(internalCircles, function (circle) {
|
||||
let pieWeights = new Array(Math.max(circle.learning_sequences.length, 1)).fill(1)
|
||||
if (this.learningPathStore.learningPath) {
|
||||
let internalCircles = this.learningPathStore.learningPath.topics.flatMap(topic => topic.circles);
|
||||
// console.log(internalCircles);
|
||||
internalCircles.forEach((circle) => {
|
||||
let pieWeights = new Array(Math.max(circle.learningSequences.length, 1)).fill(1)
|
||||
let pieGenerator = d3.pie()
|
||||
let pieData = pieGenerator(pieWeights)
|
||||
_.forEach(pieData, function (pie) {
|
||||
pie.done = circle.learning_sequences.length === 0 ? false : circle.learning_sequences[parseInt(pie.index)].done
|
||||
})
|
||||
// _.forEach(pieData, function(pie) {
|
||||
// pie.done = circle.learning_sequences.length === 0 ? false : circle.learning_sequences[parseInt(pie.index)].done
|
||||
// })
|
||||
circle.pieData = pieData
|
||||
})
|
||||
});
|
||||
return internalCircles
|
||||
}
|
||||
return [];
|
||||
},
|
||||
svg() {
|
||||
return d3.select('.learning-path-visualization')
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ import type {
|
|||
CircleChild,
|
||||
CircleCompletion,
|
||||
CircleGoal,
|
||||
CircleInterface,
|
||||
CircleJobSituation,
|
||||
LearningContent,
|
||||
LearningSequence,
|
||||
LearningUnit
|
||||
LearningUnit,
|
||||
LearningWagtailPage
|
||||
} from '@/types';
|
||||
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ export function parseLearningSequences (children: CircleChild[]): LearningSequen
|
|||
return result;
|
||||
}
|
||||
|
||||
export class Circle implements CircleInterface {
|
||||
export class Circle implements LearningWagtailPage {
|
||||
readonly type = 'learnpath.Circle';
|
||||
readonly learningSequences: LearningSequence[];
|
||||
readonly completed: boolean;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
import * as log from 'loglevel';
|
||||
|
||||
import {defineStore} from 'pinia'
|
||||
|
||||
import type {LearningPath, Topic} from '@/types'
|
||||
import {itGet} from '@/fetchHelpers';
|
||||
import {Circle} from '@/services/circle';
|
||||
|
||||
export type LearningPathStoreState = {
|
||||
learningPath: LearningPath;
|
||||
}
|
||||
|
||||
export const useLearningPathStore = defineStore({
|
||||
id: 'learningPath',
|
||||
state: () => {
|
||||
return {
|
||||
learningPath: undefined,
|
||||
} as LearningPathStoreState;
|
||||
},
|
||||
getters: {
|
||||
},
|
||||
actions: {
|
||||
async loadLearningPath(slug: string) {
|
||||
try {
|
||||
this.learningPath = await itGet(`/learnpath/api/learningpath/${slug}/`);
|
||||
this.learningPath.topics = [];
|
||||
const emptyTopic: Topic = {
|
||||
id: 0,
|
||||
title: '',
|
||||
slug: '',
|
||||
type: 'learnpath.Topic',
|
||||
translation_key: '',
|
||||
is_visible: false,
|
||||
circles: []
|
||||
}
|
||||
let topic = Object.assign({}, emptyTopic);
|
||||
this.learningPath.children.forEach((page) => {
|
||||
if (page.type === 'learnpath.Topic') {
|
||||
if (topic.id !== 0) {
|
||||
this.learningPath.topics.push(topic);
|
||||
}
|
||||
topic = Object.assign({}, emptyTopic, page);
|
||||
}
|
||||
if (page.type === 'learnpath.Circle') {
|
||||
const circle = Circle.fromJson(page);
|
||||
topic.circles.push(circle);
|
||||
}
|
||||
|
||||
this.learningPath.topics.push(topic);
|
||||
})
|
||||
console.log(this.learningPath);
|
||||
return this.learningPath;
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
return error
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import {parseLearningSequences} from '@/services/circle';
|
||||
import type {Circle} from '@/services/circle';
|
||||
|
||||
export interface LearningContentBlock {
|
||||
type: 'web-based-training' | 'competence' | 'exercise' | 'knowledge';
|
||||
|
|
@ -95,6 +95,20 @@ export interface WagtailCircle extends LearningWagtailPage {
|
|||
description: string;
|
||||
}
|
||||
|
||||
export interface Topic extends LearningWagtailPage {
|
||||
type: 'learnpath.Topic';
|
||||
is_visible: boolean;
|
||||
circles: Circle[];
|
||||
}
|
||||
|
||||
export type LearningPathChild = Topic | WagtailCircle;
|
||||
|
||||
export interface LearningPath extends LearningWagtailPage {
|
||||
type: 'learnpath.LearningPath';
|
||||
children: LearningPathChild[];
|
||||
topics: Topic[];
|
||||
}
|
||||
|
||||
export interface CircleCompletion {
|
||||
id: number;
|
||||
created_at: string;
|
||||
|
|
@ -107,17 +121,6 @@ export interface CircleCompletion {
|
|||
json_data: any;
|
||||
}
|
||||
|
||||
export interface CircleInterface extends LearningWagtailPage {
|
||||
readonly type: 'learnpath.Circle';
|
||||
readonly children: CircleChild[];
|
||||
readonly description: string;
|
||||
readonly goals: CircleGoal[];
|
||||
readonly job_situations: CircleJobSituation[];
|
||||
learningSequences: LearningSequence[];
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface CircleDiagramData {
|
||||
index: number
|
||||
title: string
|
||||
|
|
|
|||
|
|
@ -1,80 +1,40 @@
|
|||
<script>
|
||||
import axios from 'axios';
|
||||
<script setup lang="ts">
|
||||
|
||||
import * as log from 'loglevel';
|
||||
import { mapStores } from 'pinia';
|
||||
|
||||
import LearningPathDiagram from '../components/circle/LearningPathDiagram.vue';
|
||||
import { useUserStore } from '../stores/user';
|
||||
import {onMounted} from 'vue'
|
||||
import {useLearningPathStore} from '@/stores/learningPath';
|
||||
import {useUserStore} from '@/stores/user';
|
||||
|
||||
export default {
|
||||
import LearningPathDiagram from '@/components/circle/LearningPathDiagram.vue';
|
||||
|
||||
|
||||
components: {LearningPathDiagram},
|
||||
props: ['learningPathSlug',],
|
||||
data() {
|
||||
return {
|
||||
count: 0,
|
||||
learningPathData: {},
|
||||
learningPathContents: null,
|
||||
circles: [],
|
||||
learningSequences: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUserStore)
|
||||
},
|
||||
mounted() {
|
||||
log.debug('LearningPath mounted', this.learningPathSlug);
|
||||
axios({
|
||||
method: 'get',
|
||||
url: `/learnpath/api/learningpath/${this.learningPathSlug}/`,
|
||||
}).then((response) => {
|
||||
log.debug('LearningPathView created');
|
||||
|
||||
this.learningPathData = response.data
|
||||
const props = defineProps<{
|
||||
learningPathSlug: string
|
||||
}>()
|
||||
|
||||
let learningPathContents = {topics: []}
|
||||
let topic = {
|
||||
id: 0,
|
||||
title: '',
|
||||
slug: '',
|
||||
type: 'learnpath.Topic',
|
||||
translation_key: '',
|
||||
is_visible: false,
|
||||
cirlces: []
|
||||
}
|
||||
response.data.children.forEach((child) => {
|
||||
if (child.type === 'learnpath.Topic') {
|
||||
if (topic.id != 0) {
|
||||
learningPathContents.topics.push(child)
|
||||
}
|
||||
topic = child
|
||||
topic.circles = []
|
||||
}
|
||||
if (child.type === 'learnpath.Circle') {
|
||||
topic.circles.push(child)
|
||||
}
|
||||
});
|
||||
learningPathContents.topics.push(topic)
|
||||
this.learningPathContents = learningPathContents;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
const learningPathStore = useLearningPathStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
onMounted(async () => {
|
||||
log.info('LearningPathView mounted');
|
||||
await learningPathStore.loadLearningPath(props.learningPathSlug);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-gray-100" v-if="learningPathContents">
|
||||
<div class="bg-gray-100" v-if="learningPathStore.learningPath">
|
||||
|
||||
<div class="learningpath flex flex-col">
|
||||
<div class="flex flex-col h-max">
|
||||
<div class="bg-white h-80 pt-8">
|
||||
<LearningPathDiagram :learning-path-contents="learningPathContents"></LearningPathDiagram>
|
||||
<LearningPathDiagram></LearningPathDiagram>
|
||||
</div>
|
||||
|
||||
<h1 class="m-12">{{ learningPathData.title }}</h1>
|
||||
<h1 class="m-12">{{ learningPathStore.learningPath.title }}</h1>
|
||||
|
||||
<div class="bg-white m-12 p-8 flex flex-row justify-start">
|
||||
<div class="p-8 flex-auto">
|
||||
|
|
|
|||
Loading…
Reference in New Issue