From 57c1adfb41de964a31f5a6d33adb908f886ebb0e Mon Sep 17 00:00:00 2001 From: NarayanBavisetti Date: Thu, 14 Sep 2023 15:23:29 +0530 Subject: [PATCH] fix: created seperated endpoints for issue drafts --- apiserver/plane/api/serializers/issue.py | 1 + apiserver/plane/api/urls.py | 2 + apiserver/plane/api/views/issue.py | 76 +++++++++++ .../plane/bgtasks/issue_activites_task.py | 121 +++++++++++------- 4 files changed, 155 insertions(+), 45 deletions(-) diff --git a/apiserver/plane/api/serializers/issue.py b/apiserver/plane/api/serializers/issue.py index 5888b759c..113b54d0e 100644 --- a/apiserver/plane/api/serializers/issue.py +++ b/apiserver/plane/api/serializers/issue.py @@ -49,6 +49,7 @@ class IssueFlatSerializer(BaseSerializer): "target_date", "sequence_id", "sort_order", + "is_draft", ] diff --git a/apiserver/plane/api/urls.py b/apiserver/plane/api/urls.py index 1d4a16eb6..2b83b0b94 100644 --- a/apiserver/plane/api/urls.py +++ b/apiserver/plane/api/urls.py @@ -1038,6 +1038,7 @@ urlpatterns = [ IssueDraftViewSet.as_view( { "get": "list", + "post": "create", } ), name="project-issue-draft", @@ -1047,6 +1048,7 @@ urlpatterns = [ IssueDraftViewSet.as_view( { "get": "retrieve", + "patch": "partial_update", "delete": "destroy", } ), diff --git a/apiserver/plane/api/views/issue.py b/apiserver/plane/api/views/issue.py index 54bf80259..16dce6f47 100644 --- a/apiserver/plane/api/views/issue.py +++ b/apiserver/plane/api/views/issue.py @@ -2358,6 +2358,47 @@ class IssueDraftViewSet(BaseViewSet): serializer_class = IssueFlatSerializer model = Issue + + def perform_update(self, serializer): + requested_data = json.dumps(self.request.data, cls=DjangoJSONEncoder) + current_instance = ( + self.get_queryset().filter(pk=self.kwargs.get("pk", None)).first() + ) + if current_instance is not None: + issue_activity.delay( + type="issue_draft.activity.updated", + requested_data=requested_data, + actor_id=str(self.request.user.id), + issue_id=str(self.kwargs.get("pk", None)), + project_id=str(self.kwargs.get("project_id", None)), + current_instance=json.dumps( + IssueSerializer(current_instance).data, cls=DjangoJSONEncoder + ), + ) + + return super().perform_update(serializer) + + + def perform_destroy(self, instance): + current_instance = ( + self.get_queryset().filter(pk=self.kwargs.get("pk", None)).first() + ) + if current_instance is not None: + issue_activity.delay( + type="issue_draft.activity.deleted", + requested_data=json.dumps( + {"issue_id": str(self.kwargs.get("pk", None))} + ), + actor_id=str(self.request.user.id), + issue_id=str(self.kwargs.get("pk", None)), + project_id=str(self.kwargs.get("project_id", None)), + current_instance=json.dumps( + IssueSerializer(current_instance).data, cls=DjangoJSONEncoder + ), + ) + return super().perform_destroy(instance) + + def get_queryset(self): return ( Issue.objects.annotate( @@ -2383,6 +2424,7 @@ class IssueDraftViewSet(BaseViewSet): ) ) + @method_decorator(gzip_page) def list(self, request, slug, project_id): try: @@ -2492,6 +2534,40 @@ class IssueDraftViewSet(BaseViewSet): ) + def create(self, request, slug, project_id): + try: + project = Project.objects.get(pk=project_id) + + serializer = IssueCreateSerializer( + data=request.data, + context={ + "project_id": project_id, + "workspace_id": project.workspace_id, + "default_assignee_id": project.default_assignee_id, + }, + ) + + if serializer.is_valid(): + serializer.save(is_draft=True) + + # Track the issue + issue_activity.delay( + type="issue_draft.activity.created", + requested_data=json.dumps(self.request.data, cls=DjangoJSONEncoder), + actor_id=str(request.user.id), + issue_id=str(serializer.data.get("id", None)), + project_id=str(project_id), + current_instance=None, + ) + return Response(serializer.data, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + except Project.DoesNotExist: + return Response( + {"error": "Project was not found"}, status=status.HTTP_404_NOT_FOUND + ) + + def retrieve(self, request, slug, project_id, pk=None): try: issue = Issue.objects.get( diff --git a/apiserver/plane/bgtasks/issue_activites_task.py b/apiserver/plane/bgtasks/issue_activites_task.py index 3ba76dd8c..c54211bfc 100644 --- a/apiserver/plane/bgtasks/issue_activites_task.py +++ b/apiserver/plane/bgtasks/issue_activites_task.py @@ -396,23 +396,6 @@ def track_assignees( def create_issue_activity( requested_data, current_instance, issue_id, project, actor, issue_activities ): - requested_data = json.loads(requested_data) if requested_data is not None else None - current_instance = ( - json.loads(current_instance) if current_instance is not None else None - ) - if(requested_data.get("is_draft") == True): - issue_activities.append( - IssueActivity( - issue_id=issue_id, - project=project, - workspace=project.workspace, - field="draft", - comment=f"drafted the issue", - verb="created", - actor=actor, - ) - ) - else: issue_activities.append( IssueActivity( issue_id=issue_id, @@ -535,35 +518,17 @@ def update_issue_activity( "closed_to": track_closed_to, } - requested_data = json.loads(requested_data) if requested_data is not None else None - current_instance = ( - json.loads(current_instance) if current_instance is not None else None - ) - - if requested_data.get("is_draft") == True: - issue_activities.append( - IssueActivity( - issue_id=issue_id, - project=project, - workspace=project.workspace, - field="draft", - comment=f"updated the drafted issue", - verb="updated", - actor=actor, - ) + for key in requested_data: + func = ISSUE_ACTIVITY_MAPPER.get(key, None) + if func is not None: + func( + requested_data, + current_instance, + issue_id, + project, + actor, + issue_activities, ) - else: - for key in requested_data: - func = ISSUE_ACTIVITY_MAPPER.get(key, None) - if func is not None: - func( - requested_data, - current_instance, - issue_id, - project, - actor, - issue_activities, - ) def delete_issue_activity( @@ -1125,6 +1090,69 @@ def delete_issue_relation_activity( ) +def create_draft_issue_activity( + requested_data, current_instance, issue_id, project, actor, issue_activities +): + issue_activities.append( + IssueActivity( + issue_id=issue_id, + project=project, + workspace=project.workspace, + comment=f"drafted the issue", + field="draft", + verb="created", + actor=actor, + ) + ) + + +def update_draft_issue_activity( + requested_data, current_instance, issue_id, project, actor, issue_activities +): + requested_data = json.loads(requested_data) if requested_data is not None else None + current_instance = ( + json.loads(current_instance) if current_instance is not None else None + ) + if requested_data.get("is_draft") is not None and requested_data.get("is_draft") == False: + issue_activities.append( + IssueActivity( + issue_id=issue_id, + project=project, + workspace=project.workspace, + comment=f"created the issue", + verb="updated", + actor=actor, + ) + ) + else: + issue_activities.append( + IssueActivity( + issue_id=issue_id, + project=project, + workspace=project.workspace, + comment=f"updated the drafted issue", + field="draft", + verb="updated", + actor=actor, + ) + ) + + + +def delete_draft_issue_activity( + requested_data, current_instance, issue_id, project, actor, issue_activities +): + issue_activities.append( + IssueActivity( + project=project, + workspace=project.workspace, + comment=f"deleted the drafted issue", + field="draft", + verb="deleted", + actor=actor, + ) + ) + # Receive message from room group @shared_task def issue_activity( @@ -1196,6 +1224,9 @@ def issue_activity( "comment_reaction.activity.deleted": delete_comment_reaction_activity, "issue_vote.activity.created": create_issue_vote_activity, "issue_vote.activity.deleted": delete_issue_vote_activity, + "issue_draft.activity.created": create_draft_issue_activity, + "issue_draft.activity.updated": update_draft_issue_activity, + "issue_draft.activity.deleted": delete_draft_issue_activity, } func = ACTIVITY_MAPPER.get(type)