mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
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:
parent
42ece0d784
commit
f4fa2e011a
@ -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(
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
)
|
||||||
|
@ -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,
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user