fix: expose id on top-level; use name for dashboard config
This commit is contained in:
parent
d41bdf84e3
commit
49fdbd9648
|
|
@ -2,16 +2,14 @@ import graphene
|
||||||
|
|
||||||
from vbv_lernwelt.course.models import CourseSession, Course
|
from vbv_lernwelt.course.models import CourseSession, Course
|
||||||
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
||||||
from vbv_lernwelt.dashboard.graphql.types.dashboard import CourseStatisticsType, DashboardConfigType
|
from vbv_lernwelt.dashboard.graphql.types.dashboard import CourseStatisticsType, DashboardConfigType, DashboardType
|
||||||
from vbv_lernwelt.iam.permissions import can_view_course_session_group_statistics, can_view_course_session
|
from vbv_lernwelt.iam.permissions import can_view_course_session_group_statistics, can_view_course_session, \
|
||||||
|
can_view_course_session_progress
|
||||||
|
|
||||||
|
|
||||||
class DashboardQuery(graphene.ObjectType):
|
class DashboardQuery(graphene.ObjectType):
|
||||||
course_statistics = graphene.Field(CourseStatisticsType, course_id=graphene.ID(required=True))
|
course_statistics = graphene.Field(CourseStatisticsType, course_id=graphene.ID(required=True))
|
||||||
|
dashboard_config = graphene.List(DashboardConfigType, required=False)
|
||||||
dashboard_config = graphene.List(
|
|
||||||
DashboardConfigType
|
|
||||||
)
|
|
||||||
|
|
||||||
def resolve_course_statistics(root, info, course_id: str): # noqa
|
def resolve_course_statistics(root, info, course_id: str): # noqa
|
||||||
user = info.context.user
|
user = info.context.user
|
||||||
|
|
@ -27,7 +25,7 @@ class DashboardQuery(graphene.ObjectType):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
return CourseStatisticsType(course_id=course.id, course_title=course.title, # noqa
|
return CourseStatisticsType(id=course.id, course_title=course.title, # noqa
|
||||||
course_session_selection_ids=list(course_session_ids)) # noqa
|
course_session_selection_ids=list(course_session_ids)) # noqa
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -45,19 +43,27 @@ class DashboardQuery(graphene.ObjectType):
|
||||||
dashboards.append(
|
dashboards.append(
|
||||||
{
|
{
|
||||||
"id": str(course.id),
|
"id": str(course.id),
|
||||||
"title": course.title,
|
"name": course.title,
|
||||||
"dashboard_type": "StatisticsDashboard",
|
"dashboard_type": DashboardType.STATISTICS_DASHBOARD
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
for course_session in CourseSession.objects.exclude(course__in=course_index):
|
for course_session in CourseSession.objects.exclude(course__in=course_index):
|
||||||
if can_view_course_session(user=user, course_session=course_session):
|
|
||||||
course = course_session.course
|
course = course_session.course
|
||||||
|
if can_view_course_session(user=user, course_session=course_session):
|
||||||
dashboards.append(
|
dashboards.append(
|
||||||
{
|
{
|
||||||
"id": str(course.id),
|
"id": str(course.id),
|
||||||
"title": course.title,
|
"name": course.title,
|
||||||
"dashboard_type": "SimpleDashboard",
|
"dashboard_type": DashboardType.SIMPLE_LIST_DASHBOARD
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if can_view_course_session_progress(user=user, course_session=course_session):
|
||||||
|
dashboards.append(
|
||||||
|
{
|
||||||
|
"id": str(course.id),
|
||||||
|
"name": course.title,
|
||||||
|
"dashboard_type": DashboardType.PROGRESS_DASHBOARD
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,21 @@ from vbv_lernwelt.course.models import CourseCompletion, CourseCompletionStatus
|
||||||
|
|
||||||
|
|
||||||
class CompletionSummary(graphene.ObjectType):
|
class CompletionSummary(graphene.ObjectType):
|
||||||
success_total = graphene.Int()
|
success_total = graphene.Int(required=True)
|
||||||
fail_total = graphene.Int()
|
fail_total = graphene.Int(required=True)
|
||||||
|
|
||||||
|
|
||||||
class CompetencePerformance(graphene.ObjectType):
|
class CompetencePerformance(graphene.ObjectType):
|
||||||
course_session_id = graphene.ID()
|
course_session_id = graphene.ID(required=True)
|
||||||
generation = graphene.String()
|
generation = graphene.String(required=True)
|
||||||
circle_id = graphene.ID()
|
circle_id = graphene.ID(required=True)
|
||||||
success_count = graphene.Int()
|
success_count = graphene.Int(required=True)
|
||||||
fail_count = graphene.Int()
|
fail_count = graphene.Int(required=True)
|
||||||
|
|
||||||
|
|
||||||
class Competences(graphene.ObjectType):
|
class Competences(graphene.ObjectType):
|
||||||
performances = graphene.List(CompetencePerformance)
|
performances = graphene.List(CompetencePerformance, required=True)
|
||||||
summary = graphene.Field(CompletionSummary)
|
summary = graphene.Field(CompletionSummary, required=True)
|
||||||
|
|
||||||
|
|
||||||
def competences(
|
def competences(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import graphene
|
import graphene
|
||||||
|
from graphene import Enum
|
||||||
|
|
||||||
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
|
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
|
||||||
from vbv_lernwelt.dashboard.graphql.types.assignment import Assignments, assignments
|
from vbv_lernwelt.dashboard.graphql.types.assignment import Assignments, assignments
|
||||||
|
|
@ -15,14 +16,14 @@ from vbv_lernwelt.learnpath.models import Circle
|
||||||
|
|
||||||
|
|
||||||
class CourseSessionData(graphene.ObjectType):
|
class CourseSessionData(graphene.ObjectType):
|
||||||
session_id = graphene.ID()
|
session_id = graphene.ID(required=True)
|
||||||
session_title = graphene.String()
|
session_title = graphene.String(required=True)
|
||||||
|
|
||||||
|
|
||||||
class CircleData(graphene.ObjectType):
|
class CircleData(graphene.ObjectType):
|
||||||
circle_id = graphene.ID()
|
circle_id = graphene.ID(required=True)
|
||||||
circle_title = graphene.String()
|
circle_title = graphene.String(required=True)
|
||||||
experts = graphene.List(graphene.String)
|
experts = graphene.List(graphene.String, required=True)
|
||||||
|
|
||||||
|
|
||||||
class CourseSessionsSelectionMetrics(graphene.ObjectType):
|
class CourseSessionsSelectionMetrics(graphene.ObjectType):
|
||||||
|
|
@ -32,27 +33,35 @@ class CourseSessionsSelectionMetrics(graphene.ObjectType):
|
||||||
|
|
||||||
|
|
||||||
class CourseSessionProperties(graphene.ObjectType):
|
class CourseSessionProperties(graphene.ObjectType):
|
||||||
sessions = graphene.List(CourseSessionData)
|
sessions = graphene.List(CourseSessionData, required=True)
|
||||||
generations = graphene.List(graphene.String)
|
generations = graphene.List(graphene.String, required=True)
|
||||||
circles = graphene.List(CircleData)
|
circles = graphene.List(CircleData, required=True)
|
||||||
|
|
||||||
|
|
||||||
|
class DashboardType(Enum):
|
||||||
|
STATISTICS_DASHBOARD = "StatisticsDashboard"
|
||||||
|
PROGRESS_DASHBOARD = "ProgressDashboard"
|
||||||
|
SIMPLE_LIST_DASHBOARD = "SimpleListDashboard"
|
||||||
|
|
||||||
|
|
||||||
class DashboardConfigType(graphene.ObjectType):
|
class DashboardConfigType(graphene.ObjectType):
|
||||||
id = graphene.ID()
|
id = graphene.ID(required=True)
|
||||||
title = graphene.String()
|
name = graphene.String(required=True)
|
||||||
dashboard_type = graphene.String()
|
dashboard_type = graphene.Field(DashboardType, required=True)
|
||||||
|
|
||||||
|
|
||||||
class CourseStatisticsType(graphene.ObjectType):
|
class CourseStatisticsType(graphene.ObjectType):
|
||||||
course_id = graphene.ID()
|
id = graphene.ID(required=True)
|
||||||
course_title = graphene.String()
|
course_title = graphene.String(required=True)
|
||||||
course_session_properties = graphene.Field(CourseSessionProperties)
|
course_session_properties = graphene.Field(CourseSessionProperties, required=True)
|
||||||
course_session_selection_ids = graphene.List(graphene.ID)
|
course_session_selection_ids = graphene.List(graphene.ID, required=True)
|
||||||
course_session_selection_metrics = graphene.Field(CourseSessionsSelectionMetrics)
|
course_session_selection_metrics = graphene.Field(
|
||||||
attendance_day_presences = graphene.Field(AttendanceDayPresences)
|
CourseSessionsSelectionMetrics, required=True
|
||||||
feedback_responses = graphene.Field(FeedbackResponses)
|
)
|
||||||
assignments = graphene.Field(Assignments)
|
attendance_day_presences = graphene.Field(AttendanceDayPresences, required=True)
|
||||||
competences = graphene.Field(Competences)
|
feedback_responses = graphene.Field(FeedbackResponses, required=True)
|
||||||
|
assignments = graphene.Field(Assignments, required=True)
|
||||||
|
competences = graphene.Field(Competences, required=True)
|
||||||
|
|
||||||
def resolve_attendance_day_presences(root, info) -> AttendanceDayPresences:
|
def resolve_attendance_day_presences(root, info) -> AttendanceDayPresences:
|
||||||
return attendance_day_presences(root.course_session_selection_ids)
|
return attendance_day_presences(root.course_session_selection_ids)
|
||||||
|
|
@ -71,18 +80,18 @@ class CourseStatisticsType(graphene.ObjectType):
|
||||||
) -> CourseSessionsSelectionMetrics:
|
) -> CourseSessionsSelectionMetrics:
|
||||||
course_session_count = CourseSession.objects.filter(
|
course_session_count = CourseSession.objects.filter(
|
||||||
id__in=root.course_session_selection_ids,
|
id__in=root.course_session_selection_ids,
|
||||||
course_id=root.course_id,
|
course_id=root.id,
|
||||||
).count()
|
).count()
|
||||||
|
|
||||||
expert_count = CourseSession.objects.filter(
|
expert_count = CourseSession.objects.filter(
|
||||||
id__in=root.course_session_selection_ids,
|
id__in=root.course_session_selection_ids,
|
||||||
course_id=root.course_id,
|
course_id=root.id,
|
||||||
coursesessionuser__role=CourseSessionUser.Role.EXPERT,
|
coursesessionuser__role=CourseSessionUser.Role.EXPERT,
|
||||||
).count()
|
).count()
|
||||||
|
|
||||||
participant_count = CourseSession.objects.filter(
|
participant_count = CourseSession.objects.filter(
|
||||||
id__in=root.course_session_selection_ids,
|
id__in=root.course_session_selection_ids,
|
||||||
course_id=root.course_id,
|
course_id=root.id,
|
||||||
coursesessionuser__role=CourseSessionUser.Role.MEMBER,
|
coursesessionuser__role=CourseSessionUser.Role.MEMBER,
|
||||||
).count()
|
).count()
|
||||||
|
|
||||||
|
|
@ -99,7 +108,7 @@ class CourseStatisticsType(graphene.ObjectType):
|
||||||
|
|
||||||
course_sessions = CourseSession.objects.filter(
|
course_sessions = CourseSession.objects.filter(
|
||||||
id__in=root.course_session_selection_ids,
|
id__in=root.course_session_selection_ids,
|
||||||
course_id=root.course_id,
|
course_id=root.id,
|
||||||
)
|
)
|
||||||
|
|
||||||
for course_session in course_sessions:
|
for course_session in course_sessions:
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,22 @@ from vbv_lernwelt.feedback.utils import feedback_users
|
||||||
|
|
||||||
|
|
||||||
class FeedbackSummary(graphene.ObjectType):
|
class FeedbackSummary(graphene.ObjectType):
|
||||||
satisfaction_average = graphene.Float()
|
satisfaction_average = graphene.Float(required=True)
|
||||||
satisfaction_max = graphene.Int()
|
satisfaction_max = graphene.Int(required=True)
|
||||||
total_responses = graphene.Int()
|
total_responses = graphene.Int(required=True)
|
||||||
|
|
||||||
|
|
||||||
class FeedbackRecord(graphene.ObjectType):
|
class FeedbackRecord(graphene.ObjectType):
|
||||||
course_session_id = graphene.ID()
|
course_session_id = graphene.ID(required=True)
|
||||||
generation = graphene.String()
|
generation = graphene.String(required=True)
|
||||||
circle_id = graphene.ID()
|
circle_id = graphene.ID(required=True)
|
||||||
satisfaction_average = graphene.Float()
|
satisfaction_average = graphene.Float(required=True)
|
||||||
satisfaction_max = graphene.Int()
|
satisfaction_max = graphene.Int(required=True)
|
||||||
|
|
||||||
|
|
||||||
class FeedbackResponses(graphene.ObjectType):
|
class FeedbackResponses(graphene.ObjectType):
|
||||||
records = graphene.List(FeedbackRecord)
|
records = graphene.List(FeedbackRecord, required=True)
|
||||||
summary = graphene.Field(FeedbackSummary)
|
summary = graphene.Field(FeedbackSummary, required=True)
|
||||||
|
|
||||||
|
|
||||||
def feedback_responses(
|
def feedback_responses(
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ class DashboardCompetenceTestCase(GraphQLTestCase):
|
||||||
|
|
||||||
query = f"""query($course_id: ID!) {{
|
query = f"""query($course_id: ID!) {{
|
||||||
course_statistics(course_id: $course_id) {{
|
course_statistics(course_id: $course_id) {{
|
||||||
course_id
|
id
|
||||||
competences {{
|
competences {{
|
||||||
performances {{
|
performances {{
|
||||||
course_session_id
|
course_session_id
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
query = """query {
|
query = """query {
|
||||||
dashboard_config {
|
dashboard_config {
|
||||||
id
|
id
|
||||||
title
|
name
|
||||||
dashboard_type
|
dashboard_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -51,21 +51,21 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
self.assertResponseNoErrors(response)
|
self.assertResponseNoErrors(response)
|
||||||
|
|
||||||
dashboard_config = response.json()["data"]["dashboard_config"]
|
dashboard_config = response.json()["data"]["dashboard_config"]
|
||||||
self.assertEqual(len(dashboard_config), 2)
|
self.assertEqual(len(dashboard_config), 3)
|
||||||
|
|
||||||
course_1_config = find_dashboard_config_by_course_id(
|
course_1_config = find_dashboard_config_by_course_id(
|
||||||
dashboard_config, course_1.id
|
dashboard_config, course_1.id
|
||||||
)
|
)
|
||||||
self.assertIsNotNone(course_1_config)
|
self.assertIsNotNone(course_1_config)
|
||||||
self.assertEqual(course_1_config["title"], course_1.title)
|
self.assertEqual(course_1_config["name"], course_1.title)
|
||||||
self.assertEqual(course_1_config["dashboard_type"], "SimpleDashboard")
|
self.assertEqual(course_1_config["dashboard_type"], "SIMPLE_LIST_DASHBOARD")
|
||||||
|
|
||||||
course_2_config = find_dashboard_config_by_course_id(
|
course_2_config = find_dashboard_config_by_course_id(
|
||||||
dashboard_config, course_2.id
|
dashboard_config, course_2.id
|
||||||
)
|
)
|
||||||
self.assertIsNotNone(course_2_config)
|
self.assertIsNotNone(course_2_config)
|
||||||
self.assertEqual(course_2_config["title"], course_2.title)
|
self.assertEqual(course_2_config["name"], course_2.title)
|
||||||
self.assertEqual(course_2_config["dashboard_type"], "StatisticsDashboard")
|
self.assertEqual(course_2_config["dashboard_type"], "STATISTICS_DASHBOARD")
|
||||||
|
|
||||||
def test_course_statistics_deny_not_allowed_user(self):
|
def test_course_statistics_deny_not_allowed_user(self):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
|
|
@ -77,7 +77,7 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
|
|
||||||
query = f"""query($course_id: ID!) {{
|
query = f"""query($course_id: ID!) {{
|
||||||
course_statistics(course_id: $course_id) {{
|
course_statistics(course_id: $course_id) {{
|
||||||
course_id
|
id
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
@ -111,7 +111,7 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
|
|
||||||
query = f"""query($course_id: ID!) {{
|
query = f"""query($course_id: ID!) {{
|
||||||
course_statistics(course_id: $course_id) {{
|
course_statistics(course_id: $course_id) {{
|
||||||
course_id
|
id
|
||||||
course_title
|
course_title
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
@ -126,7 +126,7 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
|
|
||||||
course_statistics = response.json()["data"]["course_statistics"]
|
course_statistics = response.json()["data"]["course_statistics"]
|
||||||
|
|
||||||
self.assertEqual(course_statistics["course_id"], str(course_2.id))
|
self.assertEqual(course_statistics["id"], str(course_2.id))
|
||||||
self.assertEqual(course_statistics["course_title"], course_2.title)
|
self.assertEqual(course_statistics["course_title"], course_2.title)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ class DashboardFeedbackTestCase(GraphQLTestCase):
|
||||||
|
|
||||||
query = f"""query($course_id: ID!) {{
|
query = f"""query($course_id: ID!) {{
|
||||||
course_statistics(course_id: $course_id) {{
|
course_statistics(course_id: $course_id) {{
|
||||||
course_id
|
id
|
||||||
feedback_responses {{
|
feedback_responses {{
|
||||||
records {{
|
records {{
|
||||||
course_session_id
|
course_session_id
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,14 @@ def can_view_course_session_group_statistics(
|
||||||
return user in group.supervisor.all()
|
return user in group.supervisor.all()
|
||||||
|
|
||||||
|
|
||||||
|
def can_view_course_session_progress(user: User, course_session: CourseSession) -> bool:
|
||||||
|
return CourseSessionUser.objects.filter(
|
||||||
|
course_session=course_session,
|
||||||
|
user=user,
|
||||||
|
role=CourseSessionUser.Role.MEMBER,
|
||||||
|
).exists()
|
||||||
|
|
||||||
|
|
||||||
def can_view_course_session(user: User, course_session: CourseSession) -> bool:
|
def can_view_course_session(user: User, course_session: CourseSession) -> bool:
|
||||||
if user.is_superuser:
|
if user.is_superuser:
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue