Compare commits

...

4 Commits

Author SHA1 Message Date
NarayanBavisetti
7a867a4884 fix: fixed the typo 2023-09-14 15:35:46 +05:30
NarayanBavisetti
57c1adfb41 fix: created seperated endpoints for issue drafts 2023-09-14 15:23:29 +05:30
NarayanBavisetti
41cd5b2668 Merge branch 'develop' of github.com:makeplane/plane into chore/issue_drafts 2023-09-14 13:28:09 +05:30
NarayanBavisetti
597a136908 chore: history logs for issue draft 2023-09-13 21:42:14 +05:30
4 changed files with 155 additions and 15 deletions

View File

@ -49,6 +49,7 @@ class IssueFlatSerializer(BaseSerializer):
"target_date", "target_date",
"sequence_id", "sequence_id",
"sort_order", "sort_order",
"is_draft",
] ]

View File

@ -1038,6 +1038,7 @@ urlpatterns = [
IssueDraftViewSet.as_view( IssueDraftViewSet.as_view(
{ {
"get": "list", "get": "list",
"post": "create",
} }
), ),
name="project-issue-draft", name="project-issue-draft",
@ -1047,6 +1048,7 @@ urlpatterns = [
IssueDraftViewSet.as_view( IssueDraftViewSet.as_view(
{ {
"get": "retrieve", "get": "retrieve",
"patch": "partial_update",
"delete": "destroy", "delete": "destroy",
} }
), ),

View File

@ -508,7 +508,7 @@ class IssueActivityEndpoint(BaseAPIView):
issue_activities = ( issue_activities = (
IssueActivity.objects.filter(issue_id=issue_id) IssueActivity.objects.filter(issue_id=issue_id)
.filter( .filter(
~Q(field__in=["comment", "vote", "reaction"]), ~Q(field__in=["comment", "vote", "reaction", "draft"]),
project__project_projectmember__member=self.request.user, project__project_projectmember__member=self.request.user,
) )
.select_related("actor", "workspace", "issue", "project") .select_related("actor", "workspace", "issue", "project")
@ -2358,6 +2358,47 @@ class IssueDraftViewSet(BaseViewSet):
serializer_class = IssueFlatSerializer serializer_class = IssueFlatSerializer
model = Issue 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): def get_queryset(self):
return ( return (
Issue.objects.annotate( Issue.objects.annotate(
@ -2383,6 +2424,7 @@ class IssueDraftViewSet(BaseViewSet):
) )
) )
@method_decorator(gzip_page) @method_decorator(gzip_page)
def list(self, request, slug, project_id): def list(self, request, slug, project_id):
try: 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): def retrieve(self, request, slug, project_id, pk=None):
try: try:
issue = Issue.objects.get( issue = Issue.objects.get(

View File

@ -396,16 +396,16 @@ def track_assignees(
def create_issue_activity( def create_issue_activity(
requested_data, current_instance, issue_id, project, actor, issue_activities requested_data, current_instance, issue_id, project, actor, issue_activities
): ):
issue_activities.append( issue_activities.append(
IssueActivity( IssueActivity(
issue_id=issue_id, issue_id=issue_id,
project=project, project=project,
workspace=project.workspace, workspace=project.workspace,
comment=f"created the issue", comment=f"created the issue",
verb="created", verb="created",
actor=actor, actor=actor,
)
) )
)
def track_estimate_points( def track_estimate_points(
@ -518,11 +518,6 @@ def update_issue_activity(
"closed_to": track_closed_to, "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
)
for key in requested_data: for key in requested_data:
func = ISSUE_ACTIVITY_MAPPER.get(key, None) func = ISSUE_ACTIVITY_MAPPER.get(key, None)
if func is not None: if func is not None:
@ -1095,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 draft 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 draft issue",
field="draft",
verb="deleted",
actor=actor,
)
)
# Receive message from room group # Receive message from room group
@shared_task @shared_task
def issue_activity( def issue_activity(
@ -1166,6 +1224,9 @@ def issue_activity(
"comment_reaction.activity.deleted": delete_comment_reaction_activity, "comment_reaction.activity.deleted": delete_comment_reaction_activity,
"issue_vote.activity.created": create_issue_vote_activity, "issue_vote.activity.created": create_issue_vote_activity,
"issue_vote.activity.deleted": delete_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) func = ACTIVITY_MAPPER.get(type)