Load stuff
This commit is contained in:
parent
8621d4af07
commit
8544898bbf
|
|
@ -1,15 +1,15 @@
|
|||
<script setup lang="ts">
|
||||
import LearningPathCircle from "@/pages/learningPath/learningPathPage/LearningPathCircle.vue";
|
||||
import { calculateCircleSectorData } from "@/pages/learningPath/learningPathPage/utils";
|
||||
import type { LearningPath } from "@/services/learningPath";
|
||||
import { computed } from "vue";
|
||||
import type { LearningPathType } from "@/types";
|
||||
import { flatCircles } from "@/composables";
|
||||
|
||||
export type DiagramType = "horizontal" | "horizontalSmall" | "singleSmall";
|
||||
|
||||
export interface Props {
|
||||
diagramType?: DiagramType;
|
||||
learningPath: LearningPath;
|
||||
// set to undefined (default) to show all circles
|
||||
learningPath: LearningPathType;
|
||||
showCircleSlugs?: string[];
|
||||
}
|
||||
|
||||
|
|
@ -20,11 +20,11 @@ const props = withDefaults(defineProps<Props>(), {
|
|||
|
||||
const circles = computed(() => {
|
||||
if (props.showCircleSlugs?.length) {
|
||||
return props.learningPath.circles.filter(
|
||||
return flatCircles(props.learningPath).filter(
|
||||
(c) => props.showCircleSlugs?.includes(c.slug) ?? true
|
||||
);
|
||||
}
|
||||
return props.learningPath.circles;
|
||||
return flatCircles(props.learningPath);
|
||||
});
|
||||
|
||||
const wrapperClasses = computed(() => {
|
||||
|
|
|
|||
|
|
@ -1,31 +1,25 @@
|
|||
<script setup lang="ts">
|
||||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import * as log from "loglevel";
|
||||
|
||||
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
||||
import type { LearningPath } from "@/services/learningPath";
|
||||
import { ref } from "vue";
|
||||
import { useLearningPathWithCompletion } from "@/composables";
|
||||
|
||||
log.debug("LearningPathDiagramSmall created");
|
||||
|
||||
const props = defineProps<{
|
||||
courseSlug: string;
|
||||
courseSessionId: string;
|
||||
}>();
|
||||
|
||||
const learningPathData = ref<LearningPath | undefined>(undefined);
|
||||
|
||||
const learningPathStore = useLearningPathStore();
|
||||
|
||||
learningPathStore
|
||||
.loadLearningPath(props.courseSlug + "-lp", undefined, false, false)
|
||||
.then((data) => {
|
||||
learningPathData.value = data;
|
||||
});
|
||||
const lpQueryResult = useLearningPathWithCompletion(
|
||||
props.courseSlug,
|
||||
props.courseSessionId
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<LearningPathDiagram
|
||||
v-if="learningPathData"
|
||||
:learning-path="learningPathData"
|
||||
v-if="lpQueryResult.learningPath.value"
|
||||
:learning-path="lpQueryResult.learningPath.value"
|
||||
diagram-type="horizontalSmall"
|
||||
></LearningPathDiagram>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { COURSE_SESSION_DETAIL_QUERY, LEARNING_PATH_QUERY } from "@/graphql/queries";
|
||||
import { circleFlatChildren } from "@/services/circle";
|
||||
import { circleFlatChildren, circleFlatLearningContents } from "@/services/circle";
|
||||
import { useCompletionStore } from "@/stores/completion";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
|
|
@ -133,6 +133,10 @@ export function useCourseSessionDetailQuery(courSessionId?: string) {
|
|||
};
|
||||
}
|
||||
|
||||
export function flatCircles(learningPath: LearningPathType) {
|
||||
return learningPath.topics.flatMap((t) => t.circles);
|
||||
}
|
||||
|
||||
export function useLearningPathQuery(courseSlug: string) {
|
||||
const queryResult = useQuery({
|
||||
query: LEARNING_PATH_QUERY,
|
||||
|
|
@ -147,7 +151,7 @@ export function useLearningPathQuery(courseSlug: string) {
|
|||
|
||||
const circles = computed(() => {
|
||||
if (learningPath.value) {
|
||||
return learningPath.value.topics.flatMap((t) => t.circles);
|
||||
return flatCircles(learningPath.value);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
|
@ -158,7 +162,20 @@ export function useLearningPathQuery(courseSlug: string) {
|
|||
});
|
||||
}
|
||||
|
||||
return { ...queryResult, learningPath, circles, findCircle };
|
||||
const dataLoaded = ref(false);
|
||||
|
||||
function waitForData() {
|
||||
return new Promise((resolve) => {
|
||||
watchEffect(() => {
|
||||
if (queryResult.data.value) {
|
||||
dataLoaded.value = true;
|
||||
resolve(queryResult.data.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return { ...queryResult, waitForData, learningPath, circles, findCircle };
|
||||
}
|
||||
|
||||
export function useLearningPathWithCompletion(
|
||||
|
|
@ -178,6 +195,7 @@ export function useLearningPathWithCompletion(
|
|||
|
||||
const lpQueryResult = useLearningPathQuery(courseSlug);
|
||||
const completionStore = useCompletionStore();
|
||||
const nextLearningContent = ref<LearningContentWithCompletion | null>(null);
|
||||
|
||||
function updateCompletionData() {
|
||||
if (userId && courseSessionId) {
|
||||
|
|
@ -209,6 +227,13 @@ export function useLearningPathWithCompletion(
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
// FIXME calculate nextLearningContent
|
||||
if (lpQueryResult.circles.value?.length) {
|
||||
nextLearningContent.value = circleFlatLearningContents(
|
||||
lpQueryResult.circles.value[0]
|
||||
)[0];
|
||||
}
|
||||
}
|
||||
|
||||
async function markCompletion(
|
||||
|
|
@ -226,5 +251,10 @@ export function useLearningPathWithCompletion(
|
|||
}
|
||||
}
|
||||
|
||||
return { ...lpQueryResult, updateCompletionData, markCompletion };
|
||||
return {
|
||||
...lpQueryResult,
|
||||
updateCompletionData,
|
||||
markCompletion,
|
||||
nextLearningContent,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ const getNextStepLink = (courseSession: CourseSession) => {
|
|||
<LearningPathDiagramSmall
|
||||
class="mb-4"
|
||||
:course-slug="courseSession.course.slug"
|
||||
:course-session-id="courseSession.id"
|
||||
></LearningPathDiagramSmall>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
import LearningPathCircleListTile from "@/pages/learningPath/learningPathPage/LearningPathCircleListTile.vue";
|
||||
import type { OldCircle } from "@/services/oldCircle";
|
||||
import type { LearningPath } from "@/services/learningPath";
|
||||
import { computed } from "vue";
|
||||
import type { LearningPathType } from "@/types";
|
||||
|
||||
const props = defineProps<{
|
||||
learningPath: LearningPath | undefined;
|
||||
learningPath: LearningPathType | undefined;
|
||||
}>();
|
||||
|
||||
const topics = computed(() => props.learningPath?.topics ?? []);
|
||||
|
|
|
|||
|
|
@ -6,19 +6,16 @@ import CircleProgress from "@/pages/learningPath/learningPathPage/LearningPathPr
|
|||
import LearningPathTopics from "@/pages/learningPath/learningPathPage/LearningPathTopics.vue";
|
||||
import type { ViewType } from "@/pages/learningPath/learningPathPage/LearningPathViewSwitch.vue";
|
||||
import LearningPathViewSwitch from "@/pages/learningPath/learningPathPage/LearningPathViewSwitch.vue";
|
||||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core";
|
||||
import * as log from "loglevel";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { useLearningPathWithCompletion } from "@/composables";
|
||||
import { someFinishedInLearningSequence } from "@/services/circle";
|
||||
|
||||
const props = defineProps<{
|
||||
courseSlug: string;
|
||||
}>();
|
||||
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind);
|
||||
const learningPathStore = useLearningPathStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
// Layout state
|
||||
const useMobileLayout = breakpoints.smaller("sm");
|
||||
|
|
@ -26,38 +23,20 @@ const selectedView = ref<ViewType>(
|
|||
(window.localStorage.getItem("learningPathView") as ViewType) || "path"
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
log.debug("LearningPathPage mounted");
|
||||
const lpQueryResult = useLearningPathWithCompletion(props.courseSlug);
|
||||
|
||||
try {
|
||||
await learningPathStore.loadLearningPath(props.courseSlug + "-lp");
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
const learningPath = computed(() => {
|
||||
if (userStore.loggedIn && learningPathStore.state.learningPaths.size > 0) {
|
||||
const learningPathKey = `${props.courseSlug}-lp-${userStore.id}`;
|
||||
return learningPathStore.state.learningPaths.get(learningPathKey);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const learningPath = computed(() => lpQueryResult.learningPath.value);
|
||||
|
||||
const circlesCount = computed(() => {
|
||||
if (learningPath.value) {
|
||||
return learningPath.value.circles.length;
|
||||
}
|
||||
return 0;
|
||||
return lpQueryResult.circles.value?.length ?? 0;
|
||||
});
|
||||
|
||||
const inProgressCirclesCount = computed(() => {
|
||||
if (learningPath.value) {
|
||||
return learningPath.value.circles.filter(
|
||||
if (lpQueryResult.circles.value?.length) {
|
||||
return lpQueryResult.circles.value.filter(
|
||||
(circle) =>
|
||||
circle.learningSequences.filter((ls) =>
|
||||
circle.someFinishedInLearningSequence(ls.translation_key)
|
||||
).length
|
||||
circle.learning_sequences.filter((ls) => someFinishedInLearningSequence(ls))
|
||||
.length
|
||||
).length;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
import LearningPathCircleColumn from "@/pages/learningPath/learningPathPage/LearningPathCircleColumn.vue";
|
||||
import LearningPathScrollButton from "@/pages/learningPath/learningPathPage/LearningPathScrollButton.vue";
|
||||
import type { OldCircle } from "@/services/oldCircle";
|
||||
import type { LearningPath } from "@/services/learningPath";
|
||||
import { useScroll } from "@vueuse/core";
|
||||
import { ref } from "vue";
|
||||
import type { LearningPathType } from "@/types";
|
||||
|
||||
const props = defineProps<{
|
||||
learningPath: LearningPath | undefined;
|
||||
learningPath: LearningPathType | undefined;
|
||||
useMobileLayout: boolean;
|
||||
hideButtons?: boolean;
|
||||
overrideCircleUrlBase?: string;
|
||||
|
|
|
|||
|
|
@ -2,14 +2,18 @@ import type {
|
|||
CircleSectorData,
|
||||
CircleSectorProgress,
|
||||
} from "@/pages/learningPath/learningPathPage/LearningPathCircle.vue";
|
||||
import type { OldCircle } from "@/services/oldCircle";
|
||||
import {
|
||||
allFinishedInLearningSequence,
|
||||
someFinishedInLearningSequence,
|
||||
} from "@/services/circle";
|
||||
import type { CircleType } from "@/types";
|
||||
|
||||
export function calculateCircleSectorData(circle: OldCircle): CircleSectorData[] {
|
||||
return circle.learningSequences.map((ls) => {
|
||||
export function calculateCircleSectorData(circle: CircleType): CircleSectorData[] {
|
||||
return circle.learning_sequences.map((ls) => {
|
||||
let progress: CircleSectorProgress = "none";
|
||||
if (circle.allFinishedInLearningSequence(ls.translation_key)) {
|
||||
if (allFinishedInLearningSequence(ls)) {
|
||||
progress = "finished";
|
||||
} else if (circle.someFinishedInLearningSequence(ls.translation_key)) {
|
||||
} else if (someFinishedInLearningSequence(ls)) {
|
||||
progress = "in_progress";
|
||||
}
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import { useLearningPathQuery } from "@/composables";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import type { CircleLight, CourseSessionUser, ExpertSessionUser } from "@/types";
|
||||
import log from "loglevel";
|
||||
|
|
@ -12,7 +12,6 @@ export type CockpitStoreState = {
|
|||
courseSessionMembers: CourseSessionUser[] | undefined;
|
||||
circles: CircleCockpit[] | undefined;
|
||||
currentCircle: CircleCockpit | undefined;
|
||||
currentCourseSlug: string | undefined;
|
||||
};
|
||||
|
||||
export const useCockpitStore = defineStore({
|
||||
|
|
@ -22,7 +21,6 @@ export const useCockpitStore = defineStore({
|
|||
courseSessionMembers: undefined,
|
||||
circles: [],
|
||||
currentCircle: undefined,
|
||||
currentCourseSlug: undefined,
|
||||
} as CockpitStoreState;
|
||||
},
|
||||
actions: {
|
||||
|
|
@ -31,21 +29,8 @@ export const useCockpitStore = defineStore({
|
|||
currentCourseSessionUser: CourseSessionUser | undefined
|
||||
) {
|
||||
log.debug("loadCircles called", courseSlug);
|
||||
this.currentCourseSlug = courseSlug;
|
||||
|
||||
const circles = await courseCircles(
|
||||
this.currentCourseSlug,
|
||||
currentCourseSessionUser
|
||||
);
|
||||
|
||||
this.circles = circles.map((c) => {
|
||||
return {
|
||||
id: c.id,
|
||||
slug: c.slug,
|
||||
title: c.title,
|
||||
name: c.title,
|
||||
} as const;
|
||||
});
|
||||
this.circles = await courseCircles(courseSlug, currentCourseSessionUser);
|
||||
|
||||
if (this.circles?.length) {
|
||||
await this.setCurrentCourseCircle(this.circles[0].slug);
|
||||
|
|
@ -64,28 +49,27 @@ async function courseCircles(
|
|||
courseSlug: string,
|
||||
currentCourseSessionUser: CourseSessionUser | undefined
|
||||
) {
|
||||
const userStore = useUserStore();
|
||||
const userId = userStore.id;
|
||||
|
||||
if (currentCourseSessionUser && currentCourseSessionUser.role === "EXPERT") {
|
||||
const expert = currentCourseSessionUser as ExpertSessionUser;
|
||||
return expert.circles;
|
||||
return expert.circles.map((c) => {
|
||||
return { ...c, name: c.title };
|
||||
});
|
||||
}
|
||||
|
||||
const userStore = useUserStore();
|
||||
// Return all circles from learning path for admin users
|
||||
if (userStore.is_superuser) {
|
||||
const learningPathStore = useLearningPathStore();
|
||||
const learningPathCircles = learningPathStore
|
||||
.learningPathForUser(courseSlug, userId)
|
||||
?.circles.map((c) => {
|
||||
const lpQueryResult = useLearningPathQuery(courseSlug);
|
||||
await lpQueryResult.waitForData();
|
||||
|
||||
return (lpQueryResult.circles.value ?? []).map((c) => {
|
||||
return {
|
||||
id: c.id,
|
||||
title: c.title,
|
||||
slug: c.slug,
|
||||
translation_key: c.translation_key,
|
||||
};
|
||||
title: c.title,
|
||||
name: c.title,
|
||||
} as const;
|
||||
});
|
||||
return learningPathCircles || [];
|
||||
}
|
||||
|
||||
return [];
|
||||
|
|
|
|||
Loading…
Reference in New Issue