From 95827733785753c4190e7030153e308c6eccdcbe Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Tue, 25 May 2021 23:30:19 +0200 Subject: [PATCH] Add 'Leave Team' action --- client/src/components/profile/GroupList.vue | 15 ++++++++++----- .../src/graphql/gql/fragments/teamParts.gql | 11 +++++++++++ .../src/graphql/gql/mutations/createTeam.gql | 4 ++-- client/src/graphql/gql/mutations/joinTeam.gql | 4 ++-- .../graphql/gql/mutations/me/leaveTeam.gql | 5 +++++ client/src/graphql/gql/queries/meQuery.gql | 10 ++-------- client/src/helpers/add-team.js | 18 ++++++++++++++++++ client/src/mixins/add-team.js | 8 -------- client/src/mixins/team.js | 0 client/src/pages/me/createTeam.vue | 12 ++++++------ client/src/pages/me/joinTeam.vue | 15 ++------------- client/src/pages/me/myTeam.vue | 19 +++++++++++++++---- server/schema.graphql | 6 ++++++ server/users/mutations.py | 13 +++++++++++++ server/users/schema.py | 4 ++++ server/users/tests/test_teams.py | 19 ++++++++++++++++++- 16 files changed, 114 insertions(+), 49 deletions(-) create mode 100644 client/src/graphql/gql/fragments/teamParts.gql create mode 100644 client/src/graphql/gql/mutations/me/leaveTeam.gql create mode 100644 client/src/helpers/add-team.js delete mode 100644 client/src/mixins/add-team.js create mode 100644 client/src/mixins/team.js 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) +