Refactor code and add filtering to circle progress displays

This commit is contained in:
Ramon Wenger 2024-07-25 20:31:07 +02:00 committed by Christian Cueni
parent b780061641
commit 10cd228d56
5 changed files with 90 additions and 35 deletions

View File

@ -1,6 +1,10 @@
<script setup lang="ts">
import LearningPathCircle from "@/pages/learningPath/learningPathPage/LearningPathCircle.vue";
import { calculateCircleSectorData } from "@/pages/learningPath/learningPathPage/utils";
import {
calculateCircleSectorData,
filterCircles,
useCourseFilter,
} from "@/pages/learningPath/learningPathPage/utils";
import { computed } from "vue";
import { useCourseCircleProgress, useCourseDataWithCompletion } from "@/composables";
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
@ -48,9 +52,13 @@ const wrapperClasses = computed(() => {
return classes;
});
const { inProgressCirclesCount, circlesCount } = useCourseCircleProgress(
lpQueryResult.circles
);
const { filter } = useCourseFilter(props.courseSlug, props.courseSessionId);
const filteredCircles = computed(() => {
return filterCircles(filter.value, circles.value);
});
const { inProgressCirclesCount, circlesCount } =
useCourseCircleProgress(filteredCircles);
</script>
<template>
@ -66,7 +74,7 @@ const { inProgressCirclesCount, circlesCount } = useCourseCircleProgress(
</h4>
<div :class="wrapperClasses">
<LearningPathCircle
v-for="circle in circles"
v-for="circle in filteredCircles"
:key="circle.id"
:sectors="calculateCircleSectorData(circle)"
></LearningPathCircle>

View File

@ -14,9 +14,9 @@ import {
useCurrentCourseSession,
} from "@/composables";
import CourseSessionDueDatesList from "@/components/dueDates/CourseSessionDueDatesList.vue";
import { useMutation, useQuery } from "@urql/vue";
import { useMutation } from "@urql/vue";
import { UPDATE_COURSE_PROFILE_MUTATION } from "@/graphql/mutations";
import { COURSE_QUERY } from "@/graphql/queries";
import { filterCircles, useCourseFilter } from "./utils";
const props = defineProps<{
courseSlug: string;
@ -37,25 +37,17 @@ const course = computed(() => lpQueryResult.course.value);
const courseSession = useCurrentCourseSession();
// todo: we do not use the courseStore, because the returned object has lost its reactivity and does not reflect cache changes. maybe this could be fixed in there, then we can use the same object here
// todo: this could maybe go somewhere else, but useQuery must be used inside of a setup function. is there a better place?
const courseReactiveResult = useQuery({
query: COURSE_QUERY,
variables: { slug: props.courseSlug },
});
const courseReactive = computed(() => courseReactiveResult.data.value?.course);
const courseSessionUser = computed(() => {
return courseReactive.value?.course_session_users.find(
(e) => e?.course_session.id === courseSession.value.id
);
});
const filter = computed(() => {
return courseSessionUser.value?.chosen_profile || "";
const { filter } = useCourseFilter(props.courseSlug);
const filteredCircles = computed(() => {
if (lpQueryResult.circles.value === undefined) {
return [];
}
return filterCircles(filter.value, lpQueryResult.circles.value);
});
const { inProgressCirclesCount, circlesCount } = useCourseCircleProgress(
lpQueryResult.circles
);
const { inProgressCirclesCount, circlesCount } =
useCourseCircleProgress(filteredCircles);
const updateCourseProfileMutation = useMutation(UPDATE_COURSE_PROFILE_MUTATION);

View File

@ -3,6 +3,7 @@ import { computed } from "vue";
import type { LearningContentWithCompletion, TopicType } from "@/types";
import LearningPathCircleColumn from "./LearningPathCircleColumn.vue";
import { COURSE_PROFILE_ALL_FILTER } from "@/constants";
import { filterCircles } from "./utils";
interface Props {
topic: TopicType;
@ -22,17 +23,7 @@ const isLastCircle = (circleIndex: number, numCircles: number) =>
props.isLastTopic && circleIndex === numCircles - 1;
const filteredCircles = computed(() => {
if (
props.filter === undefined ||
props.filter === "" ||
props.filter === COURSE_PROFILE_ALL_FILTER
) {
return props.topic.circles;
}
return props.topic.circles.filter(
(circle) =>
circle.profiles.indexOf(props.filter as string) > -1 || circle.is_base_circle
);
return filterCircles(props.filter, props.topic.circles);
});
</script>

View File

@ -1,3 +1,6 @@
import { useCurrentCourseSession } from "@/composables";
import { COURSE_PROFILE_ALL_FILTER } from "@/constants";
import { COURSE_QUERY } from "@/graphql/queries";
import type {
CircleSectorData,
CircleSectorProgress,
@ -7,6 +10,8 @@ import {
someFinishedInLearningSequence,
} from "@/services/circle";
import type { CircleType } from "@/types";
import { useQuery } from "@urql/vue";
import { computed } from "vue";
export function calculateCircleSectorData(circle: CircleType): CircleSectorData[] {
return circle.learning_sequences.map((ls) => {
@ -21,3 +26,42 @@ export function calculateCircleSectorData(circle: CircleType): CircleSectorData[
};
});
}
export function useCourseFilter(courseSlug: string, courseSessionId?: string) {
const csId = computed(() => {
if (courseSessionId) {
return courseSessionId;
}
// assume we're on a page with a current course session
const courseSession = useCurrentCourseSession();
return courseSession.value.id;
});
const courseReactiveResult = useQuery({
query: COURSE_QUERY,
variables: { slug: courseSlug },
});
const courseReactive = computed(() => courseReactiveResult.data.value?.course);
const courseSessionUser = computed(() => {
return courseReactive.value?.course_session_users.find(
(e) => e?.course_session.id === csId.value
);
});
const filter = computed(() => {
return courseSessionUser.value?.chosen_profile || "";
});
return {
filter,
courseReactive,
courseSessionUser,
};
}
export function filterCircles(filter: string | undefined, circles: CircleType[]) {
if (filter === undefined || filter === "" || filter === COURSE_PROFILE_ALL_FILTER) {
return circles;
}
return circles.filter(
(circle) => circle.profiles.indexOf(filter as string) > -1 || circle.is_base_circle
);
}

View File

@ -0,0 +1,20 @@
# Generated by Django 4.2.13 on 2024-07-25 14:27
from django.db import migrations
import modelcluster.fields
class Migration(migrations.Migration):
dependencies = [
("learnpath", "0020_auto_20240711_1736"),
]
operations = [
migrations.AlterField(
model_name="circle",
name="profiles",
field=modelcluster.fields.ParentalManyToManyField(
related_name="circles", to="learnpath.courseprofile"
),
),
]