Skip to content

Commit

Permalink
Implement leave project
Browse files Browse the repository at this point in the history
  • Loading branch information
sudan45 authored and AdityaKhatri committed Dec 5, 2024
1 parent b265ccd commit 2fa7ef9
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 4 deletions.
18 changes: 15 additions & 3 deletions apps/project/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@
ProjectJoinRequest,
ProjectOrganization,
ProjectChangeLog,
ProjectPinned
ProjectPinned,
)

TRIGGER_LIMIT = 5


Expand Down Expand Up @@ -221,7 +220,20 @@ class ProjectMembershipAdmin(admin.ModelAdmin):
list_filter = (
AutocompleteFilterFactory('Project', 'project'),
)
list_display = ['project', 'member']
list_display = ['project', 'member', 'role', 'added_by']

def get_readonly_fields(self, request, obj=None):
# editing an existing object
if obj:
return self.readonly_fields + ('project', )
return self.readonly_fields


@admin.register(ProjectJoinRequest)
class ProjectJoinAdmin(admin.ModelAdmin):
search_fields = ['project__title']
autocomplete_fields = ('requested_by', 'responded_by', 'project')
list_display = ['project', 'requested_by', 'responded_by', 'status']

def get_readonly_fields(self, request, obj=None):
# editing an existing object
Expand Down
28 changes: 27 additions & 1 deletion apps/project/mutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
PsGrapheneMutation,
PsBulkGrapheneMutation,
DeleteMutation,
ProjectScopeMixin
)
from utils.graphene.error_types import mutation_is_not_valid, CustomErrorType

Expand Down Expand Up @@ -48,12 +49,14 @@
ProjectUserGroupMembershipGqlSerializer as ProjectUserGroupMembershipSerializer,
ProjectVizConfigurationSerializer,
UserPinnedProjectSerializer,
BulkProjectPinnedSerializer
BulkProjectPinnedSerializer,
UserProjectLeaveSerializer
)
from .schema import (
ProjectDetailType,
ProjectJoinRequestType,
ProjectMembershipType,
ProjectType,
ProjectUserGroupMembershipType,
ProjectVizDataType,
UserPinnedProjectType
Expand Down Expand Up @@ -106,6 +109,11 @@
serializer_class=BulkProjectPinnedSerializer,
)

UserProjectLeaveInputType = generate_input_type_for_serializer(
'UserProjectLeaveInputType',
serializer_class=UserProjectLeaveSerializer,
)


class CreateProject(GrapheneMutation):
class Arguments:
Expand Down Expand Up @@ -340,6 +348,23 @@ class Arguments:
permissions = []


class LeaveProject(ProjectScopeMixin, graphene.Mutation):
ok = graphene.Boolean()
result = graphene.Field(ProjectType)
errors = graphene.List(graphene.NonNull(CustomErrorType))
serializer_class = UserProjectLeaveSerializer
permissions = []

@classmethod
def mutate(cls, root, info, **kwargs):
project = info.context.active_project
serializer = UserProjectLeaveSerializer(data={}, context={'request': info.context.request})
if errors := mutation_is_not_valid(serializer):
return LeaveProject(errors=errors, ok=False)
serializer.save()
return LeaveProject(result=project, errors=None, ok=True)


class ProjectMutationType(
# --Begin Project Scoped Mutation
LeadMutation,
Expand Down Expand Up @@ -369,6 +394,7 @@ class Meta:
project_viz_configuration_update = UpdateProjectVizConfiguration.Field()
unified_connector = graphene.Field(UnifiedConnectorMutationType)
assisted_tagging = graphene.Field(AssistedTaggingMutationType)
leave_project = LeaveProject.Field()

@staticmethod
def get_custom_node(_, info, id):
Expand Down
24 changes: 24 additions & 0 deletions apps/project/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -959,3 +959,27 @@ def create(self, validated_data):

def update(self, instance, validated_data):
return super().update(instance, validated_data)


class UserProjectLeaveSerializer(ProjectPropertySerializerMixin, serializers.Serializer):

def validate(self, data):
membership = ProjectMembership.objects.filter(
project=self.project,
)
if membership.count() == 1:
raise serializers.ValidationError('Last member of project can\'t leave')

owner_memberships = membership.filter(role=ProjectRole.get_owner_role())
if (
owner_memberships.count() == 1 and
owner_memberships.filter(member=self.current_user)
):
raise serializers.ValidationError('Last owner of project can\'t leave')
return data

def create(self, data):
ProjectJoinRequest.objects.filter(project=self.project, requested_by=self.current_user).delete()
ProjectPinned.objects.filter(project=self.project, user=self.current_user).delete()
ProjectMembership.objects.filter(project=self.project, member=self.current_user).delete()
return data
7 changes: 7 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -4980,6 +4980,12 @@ type LeadsFilterDataType {
duplicatesOf: ID
}

type LeaveProject {
ok: Boolean
result: ProjectType
errors: [GenericScalar!]
}

type Login {
result: UserMeType
errors: [GenericScalar!]
Expand Down Expand Up @@ -5552,6 +5558,7 @@ type ProjectMutationType {
projectVizConfigurationUpdate(data: ProjectVizConfigurationInputType!): UpdateProjectVizConfiguration
unifiedConnector: UnifiedConnectorMutationType
assistedTagging: AssistedTaggingMutationType
leaveProject: LeaveProject
}

enum ProjectOrderingEnum {
Expand Down

0 comments on commit 2fa7ef9

Please sign in to comment.