Skip to content
Snippets Groups Projects
Commit 82942c55 authored by Martin Juhás's avatar Martin Juhás
Browse files

Merge branch '258-rollback-the-api-rework' into 'main'

Resolve "Rollback the API rework"

Closes #258

See merge request inject/backend!245
parents 184ac4c0 af2bd673
No related branches found
No related tags found
No related merge requests found
import graphene
from django.db import models
from exercise.models import TeamQuestionnaireState
from running_exercise.models import LogType
......@@ -7,3 +8,21 @@ from user.models import User
QuestionnaireStateEnum = graphene.Enum.from_enum(TeamQuestionnaireState.Status)
GroupEnum = graphene.Enum.from_enum(User.AuthGroup)
LogTypeEnum = graphene.Enum.from_enum(LogType)
class ExerciseEventTypeEnum(models.TextChoices):
CREATE = "create"
MODIFY = "modify"
DELETE = "delete"
@staticmethod
def create() -> "ExerciseEventTypeEnum":
return ExerciseEventTypeEnum(ExerciseEventTypeEnum.CREATE)
@staticmethod
def modify() -> "ExerciseEventTypeEnum":
return ExerciseEventTypeEnum(ExerciseEventTypeEnum.MODIFY)
@staticmethod
def delete() -> "ExerciseEventTypeEnum":
return ExerciseEventTypeEnum(ExerciseEventTypeEnum.DELETE)
from typing import Any
import graphene
from django.db import models
from graphene_django import DjangoObjectType
from common_lib.schema.enums import (
GroupEnum,
LogTypeEnum,
QuestionnaireStateEnum,
LogTypeEnum,
)
from common_lib.schema.simple_types import Simple
from exercise.models import (
Exercise,
Team,
......@@ -28,6 +24,7 @@ from exercise_definition.models import (
Inject,
Response,
FileInfo,
Role,
Content,
Control,
Channel,
......@@ -41,78 +38,75 @@ from running_exercise.models import (
ActionLog,
EmailThread,
Email,
ThreadParticipant,
ToolDetails,
InjectDetails,
CustomInjectDetails,
QuestionnaireAnswer,
ThreadParticipant,
)
from user.models import InstructorOfExercise, User, Tag
from user.models import User, Tag, InstructorOfExercise
def select_by_group(user: User, all: Any, some: Any) -> Any:
if user.group >= User.AuthGroup.INSTRUCTOR:
return all
return some
class RestrictedUser(DjangoObjectType):
class Meta:
model = User
exclude = ("definitions", "exercises", "teams", "password")
group = graphene.Field(GroupEnum)
class RestrictedExercise(DjangoObjectType):
id = graphene.ID(source="id")
uuid = graphene.UUID(source="uuid")
class Meta:
model = Exercise
fields = ()
class RestrictedTeam(DjangoObjectType):
class Meta:
model = Team
fields = ("id", "exercise", "name", "role", "email_address")
class ExerciseDefinitionType(graphene.ObjectType):
id = graphene.Int()
name = graphene.String()
class ToolType(DjangoObjectType):
class Meta:
model = Tool
exclude = ["responses"]
definition = graphene.Field(Simple.DefinitionType, required=True)
definition = graphene.Field(ExerciseDefinitionType)
class DefinitionType(DjangoObjectType):
class Meta:
model = Definition
exclude = ["milestones"]
files = graphene.List(graphene.NonNull(Simple.FileInfoType), required=True)
learning_objectives = graphene.List(
graphene.NonNull(Simple.LearningObjectiveType),
required=True,
)
addresses = graphene.List(
graphene.NonNull(Simple.EmailAddressType), required=True
)
injects = graphene.List(
graphene.NonNull(Simple.DefinitionInjectType), required=True
)
tools = graphene.List(graphene.NonNull(Simple.ToolType), required=True)
roles = graphene.List(
graphene.NonNull(Simple.DefinitionRoleType), required=True
)
channels = graphene.List(
graphene.NonNull(Simple.DefinitionChannelType), required=True
)
questionnaires = graphene.List(
graphene.NonNull(Simple.QuestionnaireType), required=True
)
exercises = graphene.List(
graphene.NonNull(Simple.ExerciseType), required=True
)
user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
tools = graphene.List(graphene.NonNull(ToolType), required=True)
user_set = graphene.List(RestrictedUser)
def resolve_user_set(self, info):
return self.user_set.all()
class DefinitionRoleType(DjangoObjectType):
class Meta:
model = Role
class ExerciseType(DjangoObjectType):
class Meta:
model = Exercise
definition = graphene.Field(Simple.DefinitionType)
teams = graphene.List(graphene.NonNull(Simple.TeamType), required=True)
email_participants = graphene.List(
graphene.NonNull(Simple.EmailParticipantType), required=True
)
user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
threads = graphene.List(
graphene.NonNull(Simple.EmailThreadType), required=True
)
def resolve_definition(self, info):
return select_by_group(info.context.user, self.definition, None)
# change the definition field type to hide some definition fields
definition = graphene.Field(ExerciseDefinitionType)
user_set = graphene.List(RestrictedUser)
def resolve_teams(self, info):
user = info.context.user
......@@ -128,43 +122,21 @@ class ExerciseType(DjangoObjectType):
# trainee or instructor assigned to specific team
return self.teams.filter(users__user=user)
def resolve_email_participants(self, info):
return select_by_group(
info.context.user,
self.email_participants.all(),
self.email_participants.filter(
team__in=info.context.user.teams.all()
),
)
def resolve_user_set(self, info):
return select_by_group(
info.context.user, self.user_set.all(), User.objects.none()
)
def resolve_threads(self, info):
return select_by_group(
info.context.user,
self.threads.all(),
self.threads.filter(
participants__team__in=info.context.user.teams.all()
),
)
if info.context.user.group == User.AuthGroup.TRAINEE:
return User.objects.none()
return self.user_set.all()
class TeamType(DjangoObjectType):
class Meta:
model = Team
exercise = graphene.Field(Simple.ExerciseType, required=True)
email_address = graphene.Field(Simple.EmailAddressType, required=True)
team_questionnaire_states = graphene.List(
graphene.NonNull(Simple.TeamQuestionnaireStateType), required=True
)
logs = graphene.List(graphene.NonNull(Simple.ActionLogType), required=True)
user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
user_set = graphene.List(RestrictedUser)
def resolve_user_set(self, info):
if info.context.user.group == User.AuthGroup.TRAINEE:
return User.objects.none()
return self.user_set.all()
......@@ -172,8 +144,6 @@ class ContentType(DjangoObjectType):
class Meta:
model = Content
file_info = graphene.Field(Simple.FileInfoType, required=True)
class ControlType(DjangoObjectType):
class Meta:
......@@ -189,53 +159,45 @@ class ToolDetailsType(DjangoObjectType):
class Meta:
model = ToolDetails
tool = graphene.Field(Simple.ToolType, required=True)
content = graphene.Field(ContentType, required=True)
user = graphene.Field(Simple.UserType)
user = graphene.Field(RestrictedUser)
tool = graphene.Field(ToolType, required=True)
class InjectDetailsType(DjangoObjectType):
class Meta:
model = InjectDetails
inject = graphene.Field(Simple.DefinitionInjectType, required=True)
class CustomInjectDetailsType(DjangoObjectType):
class Meta:
model = CustomInjectDetails
user = graphene.Field(Simple.UserType)
user = graphene.Field(RestrictedUser)
class EmailType(DjangoObjectType):
class Meta:
model = Email
thread = graphene.Field(Simple.EmailThreadType, required=True)
sender = graphene.Field(Simple.EmailParticipantType, required=True)
user = graphene.Field(Simple.UserType)
user = graphene.Field(RestrictedUser)
class QuestionType(DjangoObjectType):
class Meta:
model = Question
questionnaire = graphene.Field(Simple.QuestionnaireType, required=True)
def resolve_correct(self, info):
return select_by_group(info.context.user, self.correct, 0)
user = info.context.user
if user.group == User.AuthGroup.TRAINEE:
return 0
return self.correct
class QuestionnaireType(DjangoObjectType):
class Meta:
model = Questionnaire
definition = graphene.Field(Simple.DefinitionType, required=True)
team_questionnaire_states = graphene.List(
graphene.NonNull(Simple.TeamQuestionnaireStateType), required=True
)
class ActionLogDetails(graphene.Union):
class Meta:
......@@ -253,112 +215,88 @@ class ActionLogType(DjangoObjectType):
model = ActionLog
exclude = ["details_id"]
team = graphene.Field(Simple.TeamType, required=True)
channel = graphene.Field(Simple.DefinitionChannelType, required=True)
type = graphene.Field(LogTypeEnum, required=True)
details = graphene.Field(ActionLogDetails, required=True)
type = graphene.Field(LogTypeEnum, required=True)
class MilestoneType(DjangoObjectType):
class Meta:
model = Milestone
definition = graphene.Field(Simple.DefinitionType, required=True)
milestone_states = graphene.List(
graphene.NonNull(Simple.MilestoneStateType), required=True
)
activity = graphene.Field(Simple.LearningActivityType, required=True)
exclude = ["milestone_states", "definition"]
class MilestoneStateType(DjangoObjectType):
class Meta:
model = MilestoneState
milestone = graphene.Field(MilestoneType, required=True)
activity = graphene.Field(Simple.TeamLearningActivityType, required=True)
team_ids = graphene.List(graphene.NonNull(graphene.ID), required=True)
team_ids = graphene.List(graphene.ID)
def resolve_team_ids(self, info):
return [team.id for team in self.team_state.teams.all()]
class ThreadParticipantType(DjangoObjectType):
class Meta:
model = ThreadParticipant
class EmailThreadType(DjangoObjectType):
class Meta:
model = EmailThread
participants = graphene.List(
graphene.NonNull(Simple.EmailParticipantType), required=True
)
exercise = graphene.Field(Simple.ExerciseType, required=True)
emails = graphene.List(graphene.NonNull(EmailType), required=True)
last_email = graphene.Field(EmailType, required=False)
def resolve_participants(self, info):
return self.participants.all()
def resolve_last_email(self, info):
return self.emails.order_by("timestamp").last()
class ExtendedToolType(DjangoObjectType):
class Meta:
model = Tool
definition = graphene.Field(ExerciseDefinitionType)
class ToolResponseType(DjangoObjectType):
class Meta:
model = Response
tool = graphene.Field(Simple.ToolType, required=True)
class EmailAddressType(DjangoObjectType):
class Meta:
model = EmailAddress
definition = graphene.Field(Simple.DefinitionType, required=True)
definition = graphene.Field(ExerciseDefinitionType)
class EmailTemplateType(DjangoObjectType):
class Meta:
model = EmailTemplate
exclude = ["email_address"]
sender = graphene.String()
email_address = graphene.Field(Simple.EmailAddressType, required=True)
def resolve_sender(self, info):
return self.email_address.address
class ThreadParticipantType(DjangoObjectType):
class Meta:
model = ThreadParticipant
class EmailParticipantType(DjangoObjectType):
class Meta:
model = EmailParticipant
exercise = graphene.Field(Simple.ExerciseType, required=True)
definition_address = graphene.Field(Simple.EmailAddressType)
team = graphene.Field(Simple.TeamType)
threads = graphene.List(
graphene.NonNull(Simple.EmailThreadType), required=True
)
emails = graphene.List(graphene.NonNull(Simple.EmailType), required=True)
class DefinitionInjectType(DjangoObjectType):
class Meta:
model = Inject
exclude = ["alternatives"]
definition = graphene.Field(Simple.DefinitionType, required=True)
exclude = ["definition", "alternatives"]
class FileInfoType(DjangoObjectType):
class Meta:
model = FileInfo
definition = graphene.Field(Simple.DefinitionType, required=True)
class ExerciseConfigType(graphene.ObjectType):
class GrapheneConfig(graphene.ObjectType):
exercise_duration = graphene.Int()
email_between_teams = graphene.Boolean()
show_exercise_time = graphene.Boolean()
......@@ -367,19 +305,15 @@ class ExerciseConfigType(graphene.ObjectType):
class UserType(DjangoObjectType):
definitions = graphene.List(ExerciseDefinitionType)
exercises = graphene.List(RestrictedExercise)
teams = graphene.List(RestrictedTeam)
group = graphene.Field(GroupEnum)
class Meta:
model = User
exclude = ["password"]
definitions = graphene.List(
graphene.NonNull(Simple.DefinitionType), required=True
)
exercises = graphene.List(
graphene.NonNull(Simple.ExerciseType), required=True
)
teams = graphene.List(graphene.NonNull(Simple.TeamType), required=True)
group = graphene.Field(GroupEnum, required=True)
def resolve_definitions(self, info):
return self.definitions.all()
......@@ -393,95 +327,60 @@ class UserType(DjangoObjectType):
class TagType(DjangoObjectType):
class Meta:
model = Tag
exclude_fields = ["user_set"]
class ExerciseEventTypeEnum(models.TextChoices):
CREATE = "create"
MODIFY = "modify"
DELETE = "delete"
@staticmethod
def create() -> "ExerciseEventTypeEnum":
return ExerciseEventTypeEnum(ExerciseEventTypeEnum.CREATE)
@staticmethod
def modify() -> "ExerciseEventTypeEnum":
return ExerciseEventTypeEnum(ExerciseEventTypeEnum.MODIFY)
@staticmethod
def delete() -> "ExerciseEventTypeEnum":
return ExerciseEventTypeEnum(ExerciseEventTypeEnum.DELETE)
exclude_fields = ("user_set",)
class DefinitionChannelType(DjangoObjectType):
class Meta:
model = Channel
definition = graphene.Field(Simple.DefinitionType, required=True)
class TeamQuestionnaireStateType(DjangoObjectType):
class Meta:
model = TeamQuestionnaireState
status = graphene.Field(QuestionnaireStateEnum)
class QuestionnaireAnswerType(DjangoObjectType):
class Meta:
model = QuestionnaireAnswer
team_questionnaire_state = graphene.Field(
Simple.TeamQuestionnaireStateType, required=True
)
def resolve_is_correct(self, info):
return select_by_group(info.context.user, self.is_correct, None)
class TeamQuestionnaireStateType(DjangoObjectType):
class Meta:
model = TeamQuestionnaireState
user = info.context.user
if user.is_anonymous:
return self.is_correct
status = graphene.Field(QuestionnaireStateEnum, required=True)
team = graphene.Field(Simple.TeamType, required=True)
questionnaire = graphene.Field(Simple.QuestionnaireType, required=True)
answers = graphene.List(
graphene.NonNull(QuestionnaireAnswerType), required=True
)
if user.group == User.AuthGroup.TRAINEE:
return None
return self.is_correct
class LearningObjectiveType(DjangoObjectType):
class Meta:
model = LearningObjective
definition = graphene.Field(Simple.DefinitionType, required=True)
class LearningActivityType(DjangoObjectType):
class Meta:
model = LearningActivity
objective = graphene.Field(Simple.LearningObjectiveType, required=True)
class TeamLearningObjectiveType(DjangoObjectType):
reached = graphene.Boolean()
class Meta:
model = TeamLearningObjective
objective = graphene.Field(Simple.LearningObjectiveType, required=True)
reached = graphene.Boolean()
def resolve_reached(self, info):
return self.reached()
class TeamLearningActivityType(DjangoObjectType):
reached = graphene.Boolean()
class Meta:
model = TeamLearningActivity
team_objective = graphene.Field(
Simple.TeamLearningObjectiveType, required=True
)
activity = graphene.Field(Simple.LearningActivityType, required=True)
milestone_states = graphene.List(
graphene.NonNull(Simple.MilestoneStateType), required=True
)
reached = graphene.Boolean()
def resolve_reached(self, info):
return self.reached()
from typing import Any
import graphene
from django.db import models
from graphene_django import DjangoObjectType
from common_lib.schema.enums import (
GroupEnum,
LogTypeEnum,
QuestionnaireStateEnum,
)
from common_lib.schema.simple_types import Simple
from exercise.models import (
Exercise,
Team,
MilestoneState,
EmailParticipant,
TeamQuestionnaireState,
TeamLearningObjective,
TeamLearningActivity,
)
from exercise_definition.models import (
Milestone,
Definition,
Tool,
EmailAddress,
EmailTemplate,
Inject,
Response,
FileInfo,
Content,
Control,
Channel,
Overlay,
Questionnaire,
Question,
LearningObjective,
LearningActivity,
)
from running_exercise.models import (
ActionLog,
EmailThread,
Email,
ToolDetails,
InjectDetails,
CustomInjectDetails,
QuestionnaireAnswer,
ThreadParticipant,
)
from user.models import InstructorOfExercise, User, Tag
def select_by_group(user: User, all: Any, some: Any) -> Any:
if user.group >= User.AuthGroup.INSTRUCTOR:
return all
return some
class ToolType(DjangoObjectType):
class Meta:
model = Tool
definition = graphene.Field(Simple.DefinitionType, required=True)
class DefinitionType(DjangoObjectType):
class Meta:
model = Definition
files = graphene.List(graphene.NonNull(Simple.FileInfoType), required=True)
learning_objectives = graphene.List(
graphene.NonNull(Simple.LearningObjectiveType),
required=True,
)
addresses = graphene.List(
graphene.NonNull(Simple.EmailAddressType), required=True
)
injects = graphene.List(
graphene.NonNull(Simple.DefinitionInjectType), required=True
)
tools = graphene.List(graphene.NonNull(Simple.ToolType), required=True)
roles = graphene.List(
graphene.NonNull(Simple.DefinitionRoleType), required=True
)
channels = graphene.List(
graphene.NonNull(Simple.DefinitionChannelType), required=True
)
questionnaires = graphene.List(
graphene.NonNull(Simple.QuestionnaireType), required=True
)
exercises = graphene.List(
graphene.NonNull(Simple.ExerciseType), required=True
)
user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
def resolve_user_set(self, info):
return self.user_set.all()
class ExerciseType(DjangoObjectType):
class Meta:
model = Exercise
definition = graphene.Field(Simple.DefinitionType)
teams = graphene.List(graphene.NonNull(Simple.TeamType), required=True)
email_participants = graphene.List(
graphene.NonNull(Simple.EmailParticipantType), required=True
)
user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
threads = graphene.List(
graphene.NonNull(Simple.EmailThreadType), required=True
)
def resolve_definition(self, info):
return select_by_group(info.context.user, self.definition, None)
def resolve_teams(self, info):
user = info.context.user
if user.group == User.AuthGroup.ADMIN:
return self.teams.all()
if (
user.group == User.AuthGroup.INSTRUCTOR
and InstructorOfExercise.objects.filter(
exercise=self, user=user
).exists()
): # Instructor is assigned as an instructor of the exercise
return self.teams.all()
# trainee or instructor assigned to specific team
return self.teams.filter(users__user=user)
def resolve_email_participants(self, info):
return select_by_group(
info.context.user,
self.email_participants.all(),
self.email_participants.filter(
team__in=info.context.user.teams.all()
),
)
def resolve_user_set(self, info):
return select_by_group(
info.context.user, self.user_set.all(), User.objects.none()
)
def resolve_threads(self, info):
return select_by_group(
info.context.user,
self.threads.all(),
self.threads.filter(
participants__team__in=info.context.user.teams.all()
),
)
class TeamType(DjangoObjectType):
class Meta:
model = Team
exercise = graphene.Field(Simple.ExerciseType, required=True)
email_address = graphene.Field(Simple.EmailAddressType, required=True)
team_questionnaire_states = graphene.List(
graphene.NonNull(Simple.TeamQuestionnaireStateType), required=True
)
logs = graphene.List(graphene.NonNull(Simple.ActionLogType), required=True)
user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
def resolve_user_set(self, info):
return self.user_set.all()
class ContentType(DjangoObjectType):
class Meta:
model = Content
file_info = graphene.Field(Simple.FileInfoType, required=True)
class ControlType(DjangoObjectType):
class Meta:
model = Control
class OverlayType(DjangoObjectType):
class Meta:
model = Overlay
class ToolDetailsType(DjangoObjectType):
class Meta:
model = ToolDetails
tool = graphene.Field(Simple.ToolType, required=True)
content = graphene.Field(ContentType, required=True)
user = graphene.Field(Simple.UserType)
class InjectDetailsType(DjangoObjectType):
class Meta:
model = InjectDetails
inject = graphene.Field(Simple.DefinitionInjectType, required=True)
class CustomInjectDetailsType(DjangoObjectType):
class Meta:
model = CustomInjectDetails
user = graphene.Field(Simple.UserType)
class EmailType(DjangoObjectType):
class Meta:
model = Email
thread = graphene.Field(Simple.EmailThreadType, required=True)
sender = graphene.Field(Simple.EmailParticipantType, required=True)
user = graphene.Field(Simple.UserType)
class QuestionType(DjangoObjectType):
class Meta:
model = Question
questionnaire = graphene.Field(Simple.QuestionnaireType, required=True)
def resolve_correct(self, info):
return select_by_group(info.context.user, self.correct, 0)
class QuestionnaireType(DjangoObjectType):
class Meta:
model = Questionnaire
definition = graphene.Field(Simple.DefinitionType, required=True)
team_questionnaire_states = graphene.List(
graphene.NonNull(Simple.TeamQuestionnaireStateType), required=True
)
class ActionLogDetails(graphene.Union):
class Meta:
types = [
ToolDetailsType,
InjectDetailsType,
CustomInjectDetailsType,
EmailType,
QuestionnaireType,
]
class ActionLogType(DjangoObjectType):
class Meta:
model = ActionLog
exclude = ["details_id"]
team = graphene.Field(Simple.TeamType, required=True)
channel = graphene.Field(Simple.DefinitionChannelType, required=True)
type = graphene.Field(LogTypeEnum, required=True)
details = graphene.Field(ActionLogDetails, required=True)
class MilestoneType(DjangoObjectType):
class Meta:
model = Milestone
definition = graphene.Field(Simple.DefinitionType, required=True)
milestone_states = graphene.List(
graphene.NonNull(Simple.MilestoneStateType), required=True
)
activity = graphene.Field(Simple.LearningActivityType, required=True)
class MilestoneStateType(DjangoObjectType):
class Meta:
model = MilestoneState
milestone = graphene.Field(MilestoneType, required=True)
activity = graphene.Field(Simple.TeamLearningActivityType, required=True)
team_ids = graphene.List(graphene.NonNull(graphene.ID), required=True)
def resolve_team_ids(self, info):
return [team.id for team in self.team_state.teams.all()]
class ThreadParticipantType(DjangoObjectType):
class Meta:
model = ThreadParticipant
class EmailThreadType(DjangoObjectType):
class Meta:
model = EmailThread
participants = graphene.List(
graphene.NonNull(Simple.EmailParticipantType), required=True
)
exercise = graphene.Field(Simple.ExerciseType, required=True)
emails = graphene.List(graphene.NonNull(EmailType), required=True)
last_email = graphene.Field(EmailType, required=False)
def resolve_participants(self, info):
return self.participants.all()
def resolve_last_email(self, info):
return self.emails.order_by("timestamp").last()
class ToolResponseType(DjangoObjectType):
class Meta:
model = Response
tool = graphene.Field(Simple.ToolType, required=True)
class EmailAddressType(DjangoObjectType):
class Meta:
model = EmailAddress
definition = graphene.Field(Simple.DefinitionType, required=True)
class EmailTemplateType(DjangoObjectType):
class Meta:
model = EmailTemplate
sender = graphene.String()
email_address = graphene.Field(Simple.EmailAddressType, required=True)
def resolve_sender(self, info):
return self.email_address.address
class EmailParticipantType(DjangoObjectType):
class Meta:
model = EmailParticipant
exercise = graphene.Field(Simple.ExerciseType, required=True)
definition_address = graphene.Field(Simple.EmailAddressType)
team = graphene.Field(Simple.TeamType)
threads = graphene.List(
graphene.NonNull(Simple.EmailThreadType), required=True
)
emails = graphene.List(graphene.NonNull(Simple.EmailType), required=True)
class DefinitionInjectType(DjangoObjectType):
class Meta:
model = Inject
exclude = ["alternatives"]
definition = graphene.Field(Simple.DefinitionType, required=True)
class FileInfoType(DjangoObjectType):
class Meta:
model = FileInfo
definition = graphene.Field(Simple.DefinitionType, required=True)
class ExerciseConfigType(graphene.ObjectType):
exercise_duration = graphene.Int()
email_between_teams = graphene.Boolean()
show_exercise_time = graphene.Boolean()
enable_roles = graphene.Boolean()
custom_email_suffix = graphene.String()
class UserType(DjangoObjectType):
class Meta:
model = User
exclude = ["password"]
definitions = graphene.List(
graphene.NonNull(Simple.DefinitionType), required=True
)
exercises = graphene.List(
graphene.NonNull(Simple.ExerciseType), required=True
)
teams = graphene.List(graphene.NonNull(Simple.TeamType), required=True)
group = graphene.Field(GroupEnum, required=True)
def resolve_definitions(self, info):
return self.definitions.all()
def resolve_exercises(self, info):
return self.exercises.all()
def resolve_teams(self, info):
return self.teams.all()
class TagType(DjangoObjectType):
class Meta:
model = Tag
exclude_fields = ["user_set"]
class ExerciseEventTypeEnum(models.TextChoices):
CREATE = "create"
MODIFY = "modify"
DELETE = "delete"
@staticmethod
def create() -> "ExerciseEventTypeEnum":
return ExerciseEventTypeEnum(ExerciseEventTypeEnum.CREATE)
@staticmethod
def modify() -> "ExerciseEventTypeEnum":
return ExerciseEventTypeEnum(ExerciseEventTypeEnum.MODIFY)
@staticmethod
def delete() -> "ExerciseEventTypeEnum":
return ExerciseEventTypeEnum(ExerciseEventTypeEnum.DELETE)
class DefinitionChannelType(DjangoObjectType):
class Meta:
model = Channel
definition = graphene.Field(Simple.DefinitionType, required=True)
class QuestionnaireAnswerType(DjangoObjectType):
class Meta:
model = QuestionnaireAnswer
team_questionnaire_state = graphene.Field(
Simple.TeamQuestionnaireStateType, required=True
)
def resolve_is_correct(self, info):
return select_by_group(info.context.user, self.is_correct, None)
class TeamQuestionnaireStateType(DjangoObjectType):
class Meta:
model = TeamQuestionnaireState
status = graphene.Field(QuestionnaireStateEnum, required=True)
team = graphene.Field(Simple.TeamType, required=True)
questionnaire = graphene.Field(Simple.QuestionnaireType, required=True)
answers = graphene.List(
graphene.NonNull(QuestionnaireAnswerType), required=True
)
class LearningObjectiveType(DjangoObjectType):
class Meta:
model = LearningObjective
definition = graphene.Field(Simple.DefinitionType, required=True)
class LearningActivityType(DjangoObjectType):
class Meta:
model = LearningActivity
objective = graphene.Field(Simple.LearningObjectiveType, required=True)
class TeamLearningObjectiveType(DjangoObjectType):
class Meta:
model = TeamLearningObjective
objective = graphene.Field(Simple.LearningObjectiveType, required=True)
reached = graphene.Boolean()
def resolve_reached(self, info):
return self.reached()
class TeamLearningActivityType(DjangoObjectType):
class Meta:
model = TeamLearningActivity
team_objective = graphene.Field(
Simple.TeamLearningObjectiveType, required=True
)
activity = graphene.Field(Simple.LearningActivityType, required=True)
milestone_states = graphene.List(
graphene.NonNull(Simple.MilestoneStateType), required=True
)
reached = graphene.Boolean()
def resolve_reached(self, info):
return self.reached()
from typing import List
from common_lib.schema.types import ExerciseEventTypeEnum
from common_lib.schema.enums import ExerciseEventTypeEnum
from common_lib.utils import get_subscription_group
from exercise.models import (
Team,
......
......@@ -8,7 +8,7 @@ from rest_framework.request import Request
from common_lib.exceptions import ExerciseOperationException
from common_lib.logger import logger, log_user_msg
from common_lib.schema.types import ExerciseEventTypeEnum
from common_lib.schema.enums import ExerciseEventTypeEnum
from common_lib.subscription_handler import SubscriptionHandler
from common_lib.utils import get_model
from exercise.graphql_inputs import CreateExerciseInput, ConfigOverrideInput
......
......@@ -11,6 +11,8 @@ from common_lib.schema.types import (
MilestoneType,
FileInfoType,
DefinitionChannelType,
LearningObjectiveType,
QuestionnaireType,
)
from common_lib.utils import get_model
from exercise.models import Exercise
......@@ -20,6 +22,8 @@ from exercise_definition.models import (
Milestone,
FileInfo,
Channel,
LearningObjective,
Questionnaire,
)
from user.models import User
......@@ -94,6 +98,17 @@ class Query(graphene.ObjectType):
description="Retrieve all channels for an exercise",
)
learning_objectives = graphene.List(
LearningObjectiveType,
exercise_id=graphene.ID(required=True),
description="Retrieve all learning objectives for an exercise",
)
questionnaires = graphene.List(
QuestionnaireType,
exercise_id=graphene.ID(required=True),
description="Retrieve all questionnaires for an exercise",
)
@protected(User.AuthGroup.TRAINEE)
def resolve_exercises(
self,
......@@ -186,3 +201,21 @@ class Query(graphene.ObjectType):
) -> List[Channel]:
exercise_access(info.context, int(exercise_id))
return Channel.objects.filter(definition__exercises__in=[exercise_id])
@protected(User.AuthGroup.INSTRUCTOR)
def resolve_learning_objectives(
self, info, exercise_id: str
) -> List[LearningObjective]:
exercise_access(info.context, int(exercise_id))
return LearningObjective.objects.filter(
definition__exercises__in=[exercise_id]
)
@protected(User.AuthGroup.INSTRUCTOR)
def resolve_questionnaires(
self, info, exercise_id: str
) -> List[Questionnaire]:
exercise_access(info.context, int(exercise_id))
return Questionnaire.objects.filter(
definition__exercises__in=[exercise_id]
)
......@@ -2,7 +2,7 @@ import channels_graphql_ws
import graphene
from aai.decorators import protected
from common_lib.schema.types import ExerciseEventTypeEnum
from common_lib.schema.enums import ExerciseEventTypeEnum
from common_lib.schema.types import ExerciseType
from user.models import User
......
......@@ -2,7 +2,7 @@ import time
from threading import Thread
from common_lib.logger import logger
from common_lib.schema.types import ExerciseEventTypeEnum
from common_lib.schema.enums import ExerciseEventTypeEnum
from common_lib.subscription_handler import SubscriptionHandler
from common_lib.utils import get_model
from exercise.models import Exercise
......
......@@ -16,10 +16,10 @@ from common_lib.schema.types import (
EmailParticipantType,
EmailTemplateType,
TeamType,
ExerciseConfigType,
GrapheneConfig,
TeamQuestionnaireStateType,
ExtendedToolType,
)
from common_lib.schema.simple_types import Simple
from common_lib.utils import get_model, has_role
from exercise.models import (
Team,
......@@ -54,7 +54,7 @@ class Query(graphene.ObjectType):
description="Retrieve all team roles for the running exercise",
)
team_tools = graphene.List(
Simple.ToolType,
ExtendedToolType,
team_id=graphene.ID(required=True),
description="Retrieve all tools available to the specific team",
)
......@@ -79,6 +79,11 @@ class Query(graphene.ObjectType):
channel_id=graphene.ID(required=True),
description="Retrieve all team action logs for the specific channel",
)
team_milestone = graphene.Field(
MilestoneStateType,
milestone_state_id=graphene.ID(required=True),
description="Retrieve a specific milestone state",
)
team_milestones = graphene.List(
MilestoneStateType,
team_id=graphene.ID(required=True),
......@@ -150,7 +155,7 @@ class Query(graphene.ObjectType):
description="Retrieve the amount of time left in the running exercise in seconds"
)
exercise_config = graphene.Field(
ExerciseConfigType,
GrapheneConfig,
exercise_id=graphene.ID(required=True),
description="Retrieve the config for the current running exercise",
)
......@@ -259,6 +264,14 @@ class Query(graphene.ObjectType):
team_access(info.context, int(team_id))
return ActionLog.objects.filter(team_id=team_id, channel_id=channel_id)
@protected(User.AuthGroup.INSTRUCTOR)
def resolve_team_milestone(
self, info, milestone_state_id: str
) -> MilestoneState:
milestone_state = get_model(MilestoneState, id=int(milestone_state_id))
exercise_access(info.context, milestone_state.team_state.exercise_id)
return milestone_state
@protected(User.AuthGroup.INSTRUCTOR)
def resolve_team_milestones(
self, info, team_id: str, visible_only: bool = True
......@@ -371,14 +384,12 @@ class Query(graphene.ObjectType):
return max(0, exercise_duration_s - int(running_exercise.elapsed_s))
@protected(User.AuthGroup.TRAINEE)
def resolve_exercise_config(
self, info, exercise_id: str
) -> ExerciseConfigType:
def resolve_exercise_config(self, info, exercise_id: str) -> GrapheneConfig:
exercise_access(info.context, int(exercise_id))
exercise = get_model(Exercise, id=int(exercise_id))
config: Config = exercise.config
return ExerciseConfigType(
return GrapheneConfig(
exercise_duration=config.exercise_duration,
email_between_teams=config.has_enabled(
Feature.email_between_teams()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment