feat: leave project and workspace endpoint (#2042)

* feat: leave project and workspace endpoint

* fix: argument error

* dev: update endpoint status
This commit is contained in:
Nikhil 2023-09-01 15:55:06 +05:30 committed by GitHub
parent 42ece0d784
commit f4fa2e011a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 105 additions and 16 deletions

View File

@ -51,6 +51,7 @@ from plane.api.views import (
WorkspaceUserProfileEndpoint, WorkspaceUserProfileEndpoint,
WorkspaceUserProfileIssuesEndpoint, WorkspaceUserProfileIssuesEndpoint,
WorkspaceLabelsEndpoint, WorkspaceLabelsEndpoint,
LeaveWorkspaceEndpoint,
## End Workspaces ## End Workspaces
# File Assets # File Assets
FileAssetEndpoint, FileAssetEndpoint,
@ -68,6 +69,7 @@ from plane.api.views import (
UserProjectInvitationsViewset, UserProjectInvitationsViewset,
ProjectIdentifierEndpoint, ProjectIdentifierEndpoint,
ProjectFavoritesViewSet, ProjectFavoritesViewSet,
LeaveProjectEndpoint,
## End Projects ## End Projects
# Issues # Issues
IssueViewSet, IssueViewSet,
@ -441,6 +443,11 @@ urlpatterns = [
WorkspaceLabelsEndpoint.as_view(), WorkspaceLabelsEndpoint.as_view(),
name="workspace-labels", name="workspace-labels",
), ),
path(
"workspaces/<str:slug>/members/leave/",
LeaveWorkspaceEndpoint.as_view(),
name="workspace-labels",
),
## End Workspaces ## ## End Workspaces ##
# Projects # Projects
path( path(
@ -554,6 +561,11 @@ urlpatterns = [
), ),
name="project", name="project",
), ),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/members/leave/",
LeaveProjectEndpoint.as_view(),
name="project",
),
# End Projects # End Projects
# States # States
path( path(

View File

@ -16,6 +16,7 @@ from .project import (
ProjectDeployBoardPublicSettingsEndpoint, ProjectDeployBoardPublicSettingsEndpoint,
ProjectMemberEndpoint, ProjectMemberEndpoint,
WorkspaceProjectDeployBoardEndpoint, WorkspaceProjectDeployBoardEndpoint,
LeaveProjectEndpoint,
) )
from .user import ( from .user import (
UserEndpoint, UserEndpoint,
@ -52,6 +53,7 @@ from .workspace import (
WorkspaceUserProfileIssuesEndpoint, WorkspaceUserProfileIssuesEndpoint,
WorkspaceLabelsEndpoint, WorkspaceLabelsEndpoint,
WorkspaceMembersEndpoint, WorkspaceMembersEndpoint,
LeaveWorkspaceEndpoint,
) )
from .state import StateViewSet from .state import StateViewSet
from .view import IssueViewViewSet, ViewIssuesEndpoint, IssueViewFavoriteViewSet from .view import IssueViewViewSet, ViewIssuesEndpoint, IssueViewFavoriteViewSet

View File

@ -11,14 +11,8 @@ from django.db.models import (
OuterRef, OuterRef,
Func, Func,
F, F,
Max,
CharField,
Func, Func,
Subquery, Subquery,
Prefetch,
When,
Case,
Value,
) )
from django.core.validators import validate_email from django.core.validators import validate_email
from django.conf import settings from django.conf import settings
@ -47,6 +41,7 @@ from plane.api.permissions import (
ProjectBasePermission, ProjectBasePermission,
ProjectEntityPermission, ProjectEntityPermission,
ProjectMemberPermission, ProjectMemberPermission,
ProjectLitePermission,
) )
from plane.db.models import ( from plane.db.models import (
@ -71,16 +66,9 @@ from plane.db.models import (
ModuleMember, ModuleMember,
Inbox, Inbox,
ProjectDeployBoard, ProjectDeployBoard,
Issue,
IssueReaction,
IssueLink,
IssueAttachment,
Label,
) )
from plane.bgtasks.project_invitation_task import project_invitation from plane.bgtasks.project_invitation_task import project_invitation
from plane.utils.grouper import group_results
from plane.utils.issue_filters import issue_filters
class ProjectViewSet(BaseViewSet): class ProjectViewSet(BaseViewSet):
@ -629,7 +617,7 @@ class ProjectMemberViewSet(BaseViewSet):
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
except ProjectMember.DoesNotExist: except ProjectMember.DoesNotExist:
return Response( return Response(
{"error": "Project Member does not exist"}, status=status.HTTP_400 {"error": "Project Member does not exist"}, status=status.HTTP_400_BAD_REQUEST
) )
except Exception as e: except Exception as e:
capture_exception(e) capture_exception(e)
@ -1144,8 +1132,9 @@ class ProjectDeployBoardPublicSettingsEndpoint(BaseAPIView):
class WorkspaceProjectDeployBoardEndpoint(BaseAPIView): class WorkspaceProjectDeployBoardEndpoint(BaseAPIView):
permission_classes = [
permission_classes = [AllowAny,] AllowAny,
]
def get(self, request, slug): def get(self, request, slug):
try: try:
@ -1176,3 +1165,48 @@ class WorkspaceProjectDeployBoardEndpoint(BaseAPIView):
{"error": "Something went wrong please try again later"}, {"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST, status=status.HTTP_400_BAD_REQUEST,
) )
class LeaveProjectEndpoint(BaseAPIView):
permission_classes = [
ProjectLitePermission,
]
def delete(self, request, slug, project_id):
try:
project_member = ProjectMember.objects.get(
workspace__slug=slug,
member=request.user,
project_id=project_id,
)
# Only Admin case
if (
project_member.role == 20
and ProjectMember.objects.filter(
workspace__slug=slug,
role=20,
project_id=project_id,
).count()
== 1
):
return Response(
{
"error": "You cannot leave the project since you are the only admin of the project you should delete the project"
},
status=status.HTTP_400_BAD_REQUEST,
)
# Delete the member from workspace
project_member.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
except ProjectMember.DoesNotExist:
return Response(
{"error": "Workspace member does not exists"},
status=status.HTTP_400_BAD_REQUEST,
)
except Exception as e:
capture_exception(e)
return Response(
{"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST,
)

View File

@ -1473,3 +1473,44 @@ class WorkspaceMembersEndpoint(BaseAPIView):
{"error": "Something went wrong please try again later"}, {"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST, status=status.HTTP_400_BAD_REQUEST,
) )
class LeaveWorkspaceEndpoint(BaseAPIView):
permission_classes = [
WorkspaceEntityPermission,
]
def delete(self, request, slug):
try:
workspace_member = WorkspaceMember.objects.get(
workspace__slug=slug, member=request.user
)
# Only Admin case
if (
workspace_member.role == 20
and WorkspaceMember.objects.filter(
workspace__slug=slug, role=20
).count()
== 1
):
return Response(
{
"error": "You cannot leave the workspace since you are the only admin of the workspace you should delete the workspace"
},
status=status.HTTP_400_BAD_REQUEST,
)
# Delete the member from workspace
workspace_member.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
except WorkspaceMember.DoesNotExist:
return Response(
{"error": "Workspace member does not exists"},
status=status.HTTP_400_BAD_REQUEST,
)
except Exception as e:
capture_exception(e)
return Response(
{"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST,
)