Add proof of concept implementation for the profile filter

This commit is contained in:
Ramon Wenger 2024-07-04 09:45:18 +02:00 committed by Christian Cueni
parent c84b25cc32
commit dd1d1ff6fe
7 changed files with 62 additions and 11 deletions

View File

@ -356,6 +356,7 @@ type CircleObjectType implements CoursePageInterface {
frontend_url: String!
course: CourseObjectType
learning_sequences: [LearningSequenceObjectType!]!
profiles: [String]!
}
type LearningSequenceObjectType implements CoursePageInterface {

View File

@ -298,6 +298,7 @@ export const COURSE_QUERY = graphql(`
circles {
description
goals
profiles
...CoursePageFields
learning_sequences {
icon

View File

@ -12,7 +12,6 @@ import {
useCourseDataWithCompletion,
useCurrentCourseSession,
} from "@/composables";
import CourseSessionDueDatesList from "@/components/dueDates/CourseSessionDueDatesList.vue";
const props = defineProps<{
courseSlug: string;
@ -33,6 +32,8 @@ const course = computed(() => lpQueryResult.course.value);
const courseSession = useCurrentCourseSession();
const filter = ref("");
const { inProgressCirclesCount, circlesCount } = useCourseCircleProgress(
lpQueryResult.circles
);
@ -66,10 +67,15 @@ const changeViewType = (viewType: ViewType) => {
<!-- Right -->
<div v-if="!useMobileLayout" class="flex-grow">
<CourseSessionDueDatesList
:course-session-id="courseSession.id"
:max-count="2"
></CourseSessionDueDatesList>
<p>Zulassungsprofil</p>
<div>
<button class="btn-primary" @click="filter = 'nonlife'">Nichtleben</button>
<button class="btn-secondary" @click="filter = 'life'">Leben</button>
<button class="btn-secondary" @click="filter = 'sick'">
Krankenzusatzversicherung
</button>
</div>
<p><a href="#" @click="filter = ''">Alle anzeigen (Allbranche)</a></p>
</div>
</div>
@ -101,6 +107,7 @@ const changeViewType = (viewType: ViewType) => {
<LearningPathPathView
:learning-path="learningPath"
:use-mobile-layout="useMobileLayout"
:filter="filter"
:next-learning-content="lpQueryResult.nextLearningContent.value"
></LearningPathPathView>
</div>

View File

@ -3,7 +3,11 @@ import LearningPathCircleColumn from "@/pages/learningPath/learningPathPage/Lear
import LearningPathScrollButton from "@/pages/learningPath/learningPathPage/LearningPathScrollButton.vue";
import { useScroll } from "@vueuse/core";
import { ref } from "vue";
import type { LearningContentWithCompletion, LearningPathType } from "@/types";
import type {
LearningContentWithCompletion,
LearningPathType,
TopicType,
} from "@/types";
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
const props = defineProps<{
@ -12,6 +16,7 @@ const props = defineProps<{
useMobileLayout: boolean;
hideButtons?: boolean;
overrideCircleUrlBase?: string;
filter?: string;
}>();
const scrollIncrement = 600;
@ -33,6 +38,14 @@ const scrollLeft = () => scrollLearnPathDiagram(-scrollIncrement);
const scrollLearnPathDiagram = (offset: number) => {
x.value += offset;
};
const filterCircles = (topic: TopicType) => {
// return [];
if (props.filter) {
return topic.circles.filter((circle) => circle.profiles.indexOf(props.filter) > -1);
}
return topic.circles;
};
</script>
<template>
@ -65,7 +78,7 @@ const scrollLearnPathDiagram = (offset: number) => {
</p>
<div class="flex flex-row pt-6">
<LearningPathCircleColumn
v-for="(circle, circleIndex) in topic.circles"
v-for="(circle, circleIndex) in filterCircles(topic)"
:key="circle.id"
:circle="circle"
:next-learning-content="props.nextLearningContent"

View File

@ -285,6 +285,10 @@ class CourseSessionUser(models.Model):
)
optional_attendance = models.BooleanField(default=False)
chosen_profile = models.ForeignKey(
"learnpath.CourseProfile", on_delete=models.SET_NULL, blank=True, null=True
)
class Meta:
constraints = [
UniqueConstraint(

View File

@ -1,3 +1,5 @@
import random
import graphene
import structlog
from graphene_django import DjangoObjectType
@ -299,14 +301,12 @@ class CircleObjectType(DjangoObjectType):
learning_sequences = graphene.List(
graphene.NonNull(LearningSequenceObjectType), required=True
)
profiles = graphene.List(graphene.String, required=True)
class Meta:
model = Circle
interfaces = (CoursePageInterface,)
fields = [
"description",
"goals",
]
fields = ["description", "goals"]
def resolve_learning_sequences(self: Circle, info, **kwargs):
circle_descendants = None
@ -335,6 +335,10 @@ class CircleObjectType(DjangoObjectType):
if descendant.specific_class == LearningSequence
]
def resolve_profiles(self, info, **kwargs):
choices = ["life", "nonlife", "sick"]
return [random.choice(choices)]
class TopicObjectType(DjangoObjectType):
circles = graphene.List(graphene.NonNull(CircleObjectType), required=True)

View File

@ -66,6 +66,16 @@ class Topic(CourseBasePage):
return f"{self.title}"
class CourseProfile(models.Model):
title = models.CharField(max_length=255)
class CourseProfileToCircle(models.Model):
# this connects the course profile to a circle, because a circle can be in multiple profiles
# todo: to we even need a through model?
pass
class Circle(CourseBasePage):
parent_page_types = ["learnpath.LearningPath"]
subpage_types = [
@ -95,6 +105,17 @@ class Circle(CourseBasePage):
goals = RichTextField(features=DEFAULT_RICH_TEXT_FEATURES_WITH_HEADER)
profiles = models.ManyToManyField(CourseProfile, related_name="circles")
# profile = models.ForeignKey(
# ApprovalProfile,
# null=True,
# blank=True,
# on_delete=models.SET_NULL,
# related_name="circles",
# help_text="Zulassungsprofil",
# )
content_panels = Page.content_panels + [
FieldPanel("description"),
FieldPanel("goals"),