From 743ad0626083894377d6ea8093ef08dc5d14579c Mon Sep 17 00:00:00 2001 From: Livio Bieri Date: Fri, 27 Oct 2023 10:57:57 +0200 Subject: [PATCH] hack: make supervisor ephemeral expert of every circle in the course universe --- client/src/composables.ts | 3 - server/vbv_lernwelt/course/graphql/types.py | 132 ++++++++++++-------- 2 files changed, 78 insertions(+), 57 deletions(-) diff --git a/client/src/composables.ts b/client/src/composables.ts index 3ae4c089..295718f3 100644 --- a/client/src/composables.ts +++ b/client/src/composables.ts @@ -62,9 +62,6 @@ export function useCourseSessionDetailQuery(courSessionId?: string) { }, }); - // TODO: Why is this always empty??????!!!!! - // console.log(queryResult.data.value?.course_session); - const courseSessionDetail = computed(() => { return queryResult.data.value?.course_session as CourseSessionDetail | undefined; }); diff --git a/server/vbv_lernwelt/course/graphql/types.py b/server/vbv_lernwelt/course/graphql/types.py index d4328930..190f2f99 100644 --- a/server/vbv_lernwelt/course/graphql/types.py +++ b/server/vbv_lernwelt/course/graphql/types.py @@ -1,4 +1,4 @@ -from typing import Type +from typing import List, Type import graphene import structlog @@ -26,8 +26,10 @@ from vbv_lernwelt.course_session.models import ( CourseSessionAttendanceCourse, CourseSessionEdoniqTest, ) +from vbv_lernwelt.course_session_group.models import CourseSessionGroup from vbv_lernwelt.iam.permissions import has_course_access from vbv_lernwelt.learnpath.graphql.types import LearningPathObjectType +from vbv_lernwelt.learnpath.models import Circle logger = structlog.get_logger(__name__) @@ -109,50 +111,26 @@ class CourseSessionUserExpertCircleType(ObjectType): slug = graphene.String(required=True) -class CourseSessionUserObjectsType(DjangoObjectType): +class CourseSessionUserObjectsType(ObjectType): + """ + WORKAROUND: + Why is this no DjangoObjectType? It's because we have to "inject" + the supervisor into the list of users. This is done in the resolve_users + of the CourseSessionObjectType. And there we have to be able to construct + a CourseSessionUserObjectsType with the CIRCLES of the supervisor! + """ + + id = graphene.ID(required=True) user_id = graphene.UUID(required=True) first_name = graphene.String(required=True) last_name = graphene.String(required=True) email = graphene.String(required=True) avatar_url = graphene.String(required=True) - # role = graphene.String(required=True) + role = graphene.String(required=True) circles = graphene.List( graphene.NonNull(CourseSessionUserExpertCircleType), required=True ) - class Meta: - model = CourseSessionUser - fields = ( - "id", - "user_id", - "first_name", - "last_name", - "email", - "avatar_url", - "role", - ) - - def resolve_user_id(self, info): - return self.user.id - - def resolve_first_name(self, info): - return self.user.first_name - - def resolve_last_name(self, info): - return self.user.last_name - - def resolve_email(self, info): - return self.user.email - - def resolve_avatar_url(self, info): - return self.user.avatar_url - - def resolve_role(self, info): - return self.role - - def resolve_circles(self, info): - return self.expert.all().values("id", "title", "slug", "translation_key") - class CircleDocumentObjectType(DjangoObjectType): file_name = graphene.String() @@ -211,23 +189,69 @@ class CourseSessionObjectType(DjangoObjectType): return CourseSessionEdoniqTest.objects.filter(course_session=self) def resolve_users(self, info): - csu = list( - CourseSessionUser.objects.filter(course_session_id=self.id).distinct() - ) + course_session_users_resolved: List[CourseSessionUserObjectsType] = [] - # TODO remove or fix this - # HACK: This is an ugly hack to pretend supervisor is a course session expert - # if CourseSessionGroup.objects.filter( - # course_session=self.id, supervisor=info.context.user - # ).exists(): - # print() - # csu = [CourseSessionUser( - # id=info.context.user.id, - # user=info.context.user, - # role=CourseSessionUser.Role.EXPERT, - # )] + csu - # - # for user in csu: - # print(user.id) + # happy path, members and experts + for course_session_user in CourseSessionUser.objects.filter( + course_session_id=self.id + ).distinct(): + course_session_users_resolved.append( + CourseSessionUserObjectsType( + id=course_session_user.id, # noqa + user_id=course_session_user.user.id, # noqa + first_name=course_session_user.user.first_name, # noqa + last_name=course_session_user.user.last_name, # noqa + email=course_session_user.user.email, # noqa + avatar_url=course_session_user.user.avatar_url, # noqa + role=course_session_user.role, # noqa + circles=[ # noqa + CourseSessionUserExpertCircleType( # noqa + id=circle.id, # noqa + title=circle.title, # noqa + slug=circle.slug, # noqa + ) + for circle in course_session_user.expert.all() # noqa + ], + ) + ) - return csu + # workaround for supervisor + # add supervisor to the list of users (as expert) + course_session_id = self.id # noqa + user = info.context.user # noqa + + if CourseSessionGroup.objects.filter( + course_session=course_session_id, supervisor=user + ).exists(): + if course_session := CourseSession.objects.filter( + id=course_session_id + ).first(): + circles = ( + course_session.course.get_learning_path() + .get_descendants() + .live() + .specific() + .exact_type(Circle) + ) + + course_session_users_resolved.append( + CourseSessionUserObjectsType( + id=f"{user.id}-as-ephemeral-supervisor", # noqa + user_id=user.id, # noqa + first_name=user.first_name, # noqa + last_name=user.last_name, # noqa + email=user.email, # noqa + avatar_url=user.avatar_url, # noqa + role=CourseSessionUser.Role.EXPERT, # noqa + circles=[ # noqa + CourseSessionUserExpertCircleType( # noqa + id=circle.id, # noqa + title=circle.title, # noqa + slug=circle.slug, # noqa + ) + for circle in circles + ], + ) + ) + + return course_session_users_resolved