diff --git a/client/src/components/profile/GroupList.vue b/client/src/components/profile/GroupList.vue
index 89fc2c0e..254925e3 100644
--- a/client/src/components/profile/GroupList.vue
+++ b/client/src/components/profile/GroupList.vue
@@ -28,11 +28,16 @@
v-for="member in activeMembers">
{{ fullName(member) }}
{{ role(member) }}
-
-
-
-
-
+ Verlassen
+
+
+
+
+
diff --git a/client/src/graphql/gql/fragments/teamParts.gql b/client/src/graphql/gql/fragments/teamParts.gql
new file mode 100644
index 00000000..fcfebba8
--- /dev/null
+++ b/client/src/graphql/gql/fragments/teamParts.gql
@@ -0,0 +1,11 @@
+fragment TeamParts on TeamNode {
+ name
+ code
+ id
+ members {
+ firstName
+ lastName
+ id
+ isMe
+ }
+}
diff --git a/client/src/graphql/gql/mutations/createTeam.gql b/client/src/graphql/gql/mutations/createTeam.gql
index 95baaa07..a9ce574d 100644
--- a/client/src/graphql/gql/mutations/createTeam.gql
+++ b/client/src/graphql/gql/mutations/createTeam.gql
@@ -1,9 +1,9 @@
+#import "gql/fragments/teamParts.gql"
mutation CreateTeamMutation($input: CreateTeamInput!) {
createTeam(input: $input) {
success
team {
- name
- code
+ ...TeamParts
}
}
}
diff --git a/client/src/graphql/gql/mutations/joinTeam.gql b/client/src/graphql/gql/mutations/joinTeam.gql
index 91bbf233..e1759405 100644
--- a/client/src/graphql/gql/mutations/joinTeam.gql
+++ b/client/src/graphql/gql/mutations/joinTeam.gql
@@ -1,9 +1,9 @@
+#import "gql/fragments/teamParts.gql"
mutation JoinTeamMutation($input: JoinTeamInput!) {
joinTeam(input: $input) {
success
team {
- name
- code
+ ...TeamParts
}
}
}
diff --git a/client/src/graphql/gql/mutations/me/leaveTeam.gql b/client/src/graphql/gql/mutations/me/leaveTeam.gql
new file mode 100644
index 00000000..7cad3a8d
--- /dev/null
+++ b/client/src/graphql/gql/mutations/me/leaveTeam.gql
@@ -0,0 +1,5 @@
+mutation LeaveTeam {
+ leaveTeam {
+ success
+ }
+}
diff --git a/client/src/graphql/gql/queries/meQuery.gql b/client/src/graphql/gql/queries/meQuery.gql
index c76b2793..24ac8caf 100644
--- a/client/src/graphql/gql/queries/meQuery.gql
+++ b/client/src/graphql/gql/queries/meQuery.gql
@@ -1,16 +1,10 @@
#import "../fragments/userParts.gql"
+#import "../fragments/teamParts.gql"
query MeQuery {
me {
...UserParts
team {
- name
- code
- id
- members {
- firstName
- lastName
- id
- }
+ ...TeamParts
}
isTeacher
permissions
diff --git a/client/src/helpers/add-team.js b/client/src/helpers/add-team.js
new file mode 100644
index 00000000..9a2bbc8a
--- /dev/null
+++ b/client/src/helpers/add-team.js
@@ -0,0 +1,18 @@
+import ME_QUERY from 'gql/queries/meQuery';
+
+const addTeam = (store, team) => {
+ const query = ME_QUERY;
+ const data = store.readQuery({query});
+ store.writeQuery({
+ query,
+ data: {
+ ...data,
+ me: {
+ ...data.me,
+ team: team,
+ },
+ },
+ });
+};
+
+export default addTeam;
diff --git a/client/src/mixins/add-team.js b/client/src/mixins/add-team.js
deleted file mode 100644
index beaeb879..00000000
--- a/client/src/mixins/add-team.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default {
- methods: {
- addTeam(store, team) {
- // todo
- throw new Error('NotImplemented');
- }
- }
-};
diff --git a/client/src/mixins/team.js b/client/src/mixins/team.js
new file mode 100644
index 00000000..e69de29b
diff --git a/client/src/pages/me/createTeam.vue b/client/src/pages/me/createTeam.vue
index c0d81ed2..12930da0 100644
--- a/client/src/pages/me/createTeam.vue
+++ b/client/src/pages/me/createTeam.vue
@@ -13,18 +13,17 @@
diff --git a/server/schema.graphql b/server/schema.graphql
index efd42593..e673b4f2 100644
--- a/server/schema.graphql
+++ b/server/schema.graphql
@@ -388,6 +388,7 @@ type CustomMutation {
createTeam(input: CreateTeamInput!): CreateTeamPayload
joinTeam(input: JoinTeamInput!): JoinTeamPayload
updateTeam(input: UpdateTeamInput!): UpdateTeamPayload
+ leaveTeam: LeaveTeam
addProject(input: AddProjectInput!): AddProjectPayload
updateProject(input: UpdateProjectInput!): UpdateProjectPayload
deleteProject(input: DeleteProjectInput!): DeleteProjectPayload
@@ -614,6 +615,10 @@ type JoinTeamPayload {
clientMutationId: String
}
+type LeaveTeam {
+ success: Boolean
+}
+
type Logout {
success: Boolean
}
@@ -1436,6 +1441,7 @@ type UserNode implements Node {
isTeacher: Boolean
oldClasses(offset: Int, before: String, after: String, first: Int, last: Int, name: String): SchoolClassNodeConnection
recentModules(offset: Int, before: String, after: String, first: Int, last: Int, recentModules: [ID], orderBy: String): ModuleNodeConnection
+ isMe: Boolean
}
type UserNodeConnection {
diff --git a/server/users/mutations.py b/server/users/mutations.py
index 0b286e1b..433d8548 100644
--- a/server/users/mutations.py
+++ b/server/users/mutations.py
@@ -14,6 +14,7 @@ from users.serializers import PasswordSerialzer, AvatarUrlSerializer
logger = get_logger(__name__)
+
class CodeNotFoundException(Exception):
pass
@@ -281,6 +282,17 @@ class JoinTeam(TeacherOnlyMutation):
raise CodeNotFoundException('[CNV] Code ist nicht gültig') # CNV = Code Not Valid
+class LeaveTeam(graphene.Mutation):
+ success = graphene.Boolean()
+
+ @classmethod
+ def mutate(cls, root, info, **kwargs):
+ user = info.context.user
+ user.team = None
+ user.save()
+ return cls(success=True)
+
+
class UpdateOnboardingProgress(graphene.Mutation):
success = graphene.Boolean()
@@ -306,3 +318,4 @@ class ProfileMutations:
create_team = CreateTeam.Field()
join_team = JoinTeam.Field()
update_team = UpdateTeam.Field()
+ leave_team = LeaveTeam.Field()
diff --git a/server/users/schema.py b/server/users/schema.py
index 115cfd5a..e820e3a3 100644
--- a/server/users/schema.py
+++ b/server/users/schema.py
@@ -77,6 +77,7 @@ class UserNode(DjangoObjectType):
old_classes = DjangoFilterConnectionField(SchoolClassNode)
recent_modules = DjangoFilterConnectionField(ModuleNode, filterset_class=RecentModuleFilter)
team = graphene.Field(TeamNode)
+ is_me = graphene.Boolean()
class Meta:
model = User
@@ -120,6 +121,9 @@ class UserNode(DjangoObjectType):
def resolve_team(self, info, **kwargs):
return self.team
+ def resolve_is_me(self, info, **kwargs):
+ return info.context.user.pk == self.pk
+
class ClassMemberNode(ObjectType):
"""
diff --git a/server/users/tests/test_teams.py b/server/users/tests/test_teams.py
index 575f0d03..8354ec9c 100644
--- a/server/users/tests/test_teams.py
+++ b/server/users/tests/test_teams.py
@@ -7,7 +7,7 @@ from api.schema import schema
from api.utils import get_graphql_mutation
from core.factories import TeacherFactory, UserFactory
from users.factories import TeamFactory
-from users.models import Team
+from users.models import Team, User
ME_QUERY = """
query MeQuery {
@@ -23,6 +23,7 @@ ME_QUERY = """
CREATE_TEAM_MUTATION = get_graphql_mutation('createTeam.gql')
JOIN_TEAM_MUTATION = get_graphql_mutation('joinTeam.gql')
UPDATE_TEAM_MUTATION = get_graphql_mutation('updateTeam.gql')
+LEAVE_TEAM_MUTATION = get_graphql_mutation('me/leaveTeam.gql')
class TeamTest(TestCase):
@@ -169,3 +170,19 @@ class TeamTest(TestCase):
result = self.client.execute(JOIN_TEAM_MUTATION, context=context, variables=variables)
self.permission_error(result)
self.assertIsNone(self.student.team)
+
+ def test_leave_team(self):
+ self.student.team = self.team
+ self.student.save()
+ student_before = User.objects.get(pk=self.student.pk)
+ self.assertIsNotNone(student_before.team)
+ context = Context(user=student_before)
+ result = self.client.execute(LEAVE_TEAM_MUTATION, context=context)
+ self.no_error(result)
+ leave_team = result.get('data').get('leaveTeam')
+ success = leave_team.get('success')
+ self.assertTrue(success)
+
+ student_after = User.objects.get(pk=self.student.pk)
+ self.assertIsNone(student_after.team)
+