vbv/client/src/components/learningPath/LearningPathDiagram.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>