Refactor code and add filtering to circle progress displays
This commit is contained in:
parent
b780061641
commit
10cd228d56
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
),
|
||||
),
|
||||
]
|
||||
Loading…
Reference in New Issue