80 lines
2.2 KiB
Vue
80 lines
2.2 KiB
Vue
<script setup lang="ts">
|
|
import LearningPathCircle from "@/pages/learningPath/learningPathPage/LearningPathCircle.vue";
|
|
import { calculateCircleSectorData } from "@/pages/learningPath/learningPathPage/utils";
|
|
import { computed } from "vue";
|
|
import { useCourseCircleProgress, useCourseDataWithCompletion } from "@/composables";
|
|
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
|
|
|
|
export type DiagramType = "horizontal" | "horizontalSmall" | "singleSmall";
|
|
|
|
export interface Props {
|
|
showCircleSlugs?: string[];
|
|
courseSlug: string;
|
|
courseSessionId: string;
|
|
userId?: string;
|
|
diagramType?: DiagramType;
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
diagramType: "horizontal",
|
|
showCircleSlugs: undefined,
|
|
userId: undefined,
|
|
});
|
|
|
|
const lpQueryResult = useCourseDataWithCompletion(
|
|
props.courseSlug,
|
|
props.userId,
|
|
props.courseSessionId
|
|
);
|
|
|
|
const circles = computed(() => {
|
|
if (props.showCircleSlugs?.length) {
|
|
return (lpQueryResult.circles.value ?? []).filter(
|
|
(c) => props.showCircleSlugs?.includes(c.slug) ?? true
|
|
);
|
|
}
|
|
return lpQueryResult.circles.value ?? [];
|
|
});
|
|
|
|
const wrapperClasses = computed(() => {
|
|
let classes = "flex";
|
|
if (props.diagramType === "horizontal") {
|
|
classes += " flex-row h-8 space-x-2";
|
|
} else if (props.diagramType === "horizontalSmall") {
|
|
classes += " flex-row h-5 space-x-1";
|
|
} else if (props.diagramType === "singleSmall") {
|
|
classes += " h-8";
|
|
}
|
|
return classes;
|
|
});
|
|
|
|
const { inProgressCirclesCount, circlesCount } = useCourseCircleProgress(
|
|
lpQueryResult.circles
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div v-if="circlesCount > 0">
|
|
<h4 v-if="diagramType === 'horizontal'" class="mb-4 font-bold">
|
|
{{
|
|
$t("learningPathPage.progressText", {
|
|
inProgressCount: inProgressCirclesCount,
|
|
allCount: circlesCount,
|
|
})
|
|
}}
|
|
</h4>
|
|
<div :class="wrapperClasses">
|
|
<LearningPathCircle
|
|
v-for="circle in circles"
|
|
:key="circle.id"
|
|
:sectors="calculateCircleSectorData(circle)"
|
|
></LearningPathCircle>
|
|
</div>
|
|
</div>
|
|
<div v-else class="flex justify-center">
|
|
<LoadingSpinner />
|
|
</div>
|
|
</div>
|
|
</template>
|