forked from github/plane
refactor: track cycles and modules for issue
This commit is contained in:
parent
7207d92d62
commit
67a1052b7b
@ -1,5 +1,9 @@
|
|||||||
|
# Python imports
|
||||||
|
import json
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.db.models import OuterRef, Func, F
|
from django.db.models import OuterRef, Func, F
|
||||||
|
from django.core import serializers
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
@ -11,6 +15,7 @@ from . import BaseViewSet
|
|||||||
from plane.api.serializers import CycleSerializer, CycleIssueSerializer
|
from plane.api.serializers import CycleSerializer, CycleIssueSerializer
|
||||||
from plane.api.permissions import ProjectEntityPermission
|
from plane.api.permissions import ProjectEntityPermission
|
||||||
from plane.db.models import Cycle, CycleIssue, Issue
|
from plane.db.models import Cycle, CycleIssue, Issue
|
||||||
|
from plane.bgtasks.issue_activites_task import issue_activity
|
||||||
|
|
||||||
|
|
||||||
class CycleViewSet(BaseViewSet):
|
class CycleViewSet(BaseViewSet):
|
||||||
@ -90,17 +95,26 @@ class CycleIssueViewSet(BaseViewSet):
|
|||||||
|
|
||||||
# Get all CycleIssues already created
|
# Get all CycleIssues already created
|
||||||
cycle_issues = list(CycleIssue.objects.filter(issue_id__in=issues))
|
cycle_issues = list(CycleIssue.objects.filter(issue_id__in=issues))
|
||||||
|
|
||||||
records_to_update = []
|
records_to_update = []
|
||||||
|
update_cycle_issue_activity = []
|
||||||
record_to_create = []
|
record_to_create = []
|
||||||
|
|
||||||
for issue in issues:
|
for issue in issues:
|
||||||
cycle_issue = [
|
cycle_issue = [
|
||||||
cycle_issue
|
cycle_issue
|
||||||
for cycle_issue in cycle_issues
|
for cycle_issue in cycle_issues
|
||||||
if cycle_issue.issue_id in issues
|
if str(cycle_issue.issue_id) in issues
|
||||||
]
|
]
|
||||||
|
# Update only when cycle changes
|
||||||
if len(cycle_issue):
|
if len(cycle_issue):
|
||||||
|
if cycle_issue[0].cycle_id != cycle_id:
|
||||||
|
update_cycle_issue_activity.append(
|
||||||
|
{
|
||||||
|
"old_cycle_id": str(cycle_issue[0].cycle_id),
|
||||||
|
"new_cycle_id": str(cycle_id),
|
||||||
|
"issue_id": str(cycle_issue[0].issue_id),
|
||||||
|
}
|
||||||
|
)
|
||||||
cycle_issue[0].cycle_id = cycle_id
|
cycle_issue[0].cycle_id = cycle_id
|
||||||
records_to_update.append(cycle_issue[0])
|
records_to_update.append(cycle_issue[0])
|
||||||
else:
|
else:
|
||||||
@ -126,9 +140,29 @@ class CycleIssueViewSet(BaseViewSet):
|
|||||||
batch_size=10,
|
batch_size=10,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Capture Issue Activity
|
||||||
|
issue_activity.delay(
|
||||||
|
{
|
||||||
|
"type": "issue.activity",
|
||||||
|
"requested_data": json.dumps({"cycles_list": issues}),
|
||||||
|
"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(
|
||||||
|
{
|
||||||
|
"updated_cycle_issues": update_cycle_issue_activity,
|
||||||
|
"created_cycle_issues": serializers.serialize(
|
||||||
|
"json", record_to_create
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
# Return all Cycle Issues
|
# Return all Cycle Issues
|
||||||
return Response(
|
return Response(
|
||||||
CycleIssueSerializer(self.get_queryset(), many=True).data, status=status.HTTP_200_OK
|
CycleIssueSerializer(self.get_queryset(), many=True).data,
|
||||||
|
status=status.HTTP_200_OK,
|
||||||
)
|
)
|
||||||
|
|
||||||
except Cycle.DoesNotExist:
|
except Cycle.DoesNotExist:
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
# Python imports
|
||||||
|
import json
|
||||||
|
|
||||||
# Django Imports
|
# Django Imports
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.db.models import Prefetch, F, OuterRef, Func
|
from django.db.models import Prefetch, F, OuterRef, Func
|
||||||
|
from django.core import serializers
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
@ -22,6 +26,7 @@ from plane.db.models import (
|
|||||||
Issue,
|
Issue,
|
||||||
ModuleLink,
|
ModuleLink,
|
||||||
)
|
)
|
||||||
|
from plane.bgtasks.issue_activites_task import issue_activity
|
||||||
|
|
||||||
|
|
||||||
class ModuleViewSet(BaseViewSet):
|
class ModuleViewSet(BaseViewSet):
|
||||||
@ -148,6 +153,7 @@ class ModuleIssueViewSet(BaseViewSet):
|
|||||||
|
|
||||||
module_issues = list(ModuleIssue.objects.filter(issue_id__in=issues))
|
module_issues = list(ModuleIssue.objects.filter(issue_id__in=issues))
|
||||||
|
|
||||||
|
update_module_issue_activity = []
|
||||||
records_to_update = []
|
records_to_update = []
|
||||||
record_to_create = []
|
record_to_create = []
|
||||||
|
|
||||||
@ -159,6 +165,14 @@ class ModuleIssueViewSet(BaseViewSet):
|
|||||||
]
|
]
|
||||||
|
|
||||||
if len(module_issue):
|
if len(module_issue):
|
||||||
|
if module_issue[0].cycle_id != module_id:
|
||||||
|
update_module_issue_activity.append(
|
||||||
|
{
|
||||||
|
"old_module_id": str(module_issue[0].cycle_id),
|
||||||
|
"new_module_id": str(module_id),
|
||||||
|
"issue_id": str(module_issue[0].issue_id),
|
||||||
|
}
|
||||||
|
)
|
||||||
module_issue[0].module_id = module_id
|
module_issue[0].module_id = module_id
|
||||||
records_to_update.append(module_issue[0])
|
records_to_update.append(module_issue[0])
|
||||||
else:
|
else:
|
||||||
@ -185,6 +199,25 @@ class ModuleIssueViewSet(BaseViewSet):
|
|||||||
batch_size=10,
|
batch_size=10,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Capture Issue Activity
|
||||||
|
issue_activity.delay(
|
||||||
|
{
|
||||||
|
"type": "issue.activity",
|
||||||
|
"requested_data": json.dumps({"cycles_list": issues}),
|
||||||
|
"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(
|
||||||
|
{
|
||||||
|
"updated_cycle_issues": update_module_issue_activity,
|
||||||
|
"created_cycle_issues": serializers.serialize(
|
||||||
|
"json", record_to_create
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
ModuleIssueSerializer(self.get_queryset(), many=True).data,
|
ModuleIssueSerializer(self.get_queryset(), many=True).data,
|
||||||
status=status.HTTP_200_OK,
|
status=status.HTTP_200_OK,
|
||||||
|
@ -6,7 +6,16 @@ from django_rq import job
|
|||||||
from sentry_sdk import capture_exception
|
from sentry_sdk import capture_exception
|
||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from plane.db.models import User, Issue, Project, Label, IssueActivity, State
|
from plane.db.models import (
|
||||||
|
User,
|
||||||
|
Issue,
|
||||||
|
Project,
|
||||||
|
Label,
|
||||||
|
IssueActivity,
|
||||||
|
State,
|
||||||
|
Cycle,
|
||||||
|
Module,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Track Chnages in name
|
# Track Chnages in name
|
||||||
@ -44,7 +53,6 @@ def track_parent(
|
|||||||
issue_activities,
|
issue_activities,
|
||||||
):
|
):
|
||||||
if current_instance.get("parent") != requested_data.get("parent"):
|
if current_instance.get("parent") != requested_data.get("parent"):
|
||||||
|
|
||||||
if requested_data.get("parent") == None:
|
if requested_data.get("parent") == None:
|
||||||
old_parent = Issue.objects.get(pk=current_instance.get("parent"))
|
old_parent = Issue.objects.get(pk=current_instance.get("parent"))
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
@ -134,7 +142,6 @@ def track_state(
|
|||||||
issue_activities,
|
issue_activities,
|
||||||
):
|
):
|
||||||
if current_instance.get("state") != requested_data.get("state"):
|
if current_instance.get("state") != requested_data.get("state"):
|
||||||
|
|
||||||
new_state = State.objects.get(pk=requested_data.get("state", None))
|
new_state = State.objects.get(pk=requested_data.get("state", None))
|
||||||
old_state = State.objects.get(pk=current_instance.get("state", None))
|
old_state = State.objects.get(pk=current_instance.get("state", None))
|
||||||
|
|
||||||
@ -167,7 +174,6 @@ def track_description(
|
|||||||
if current_instance.get("description_html") != requested_data.get(
|
if current_instance.get("description_html") != requested_data.get(
|
||||||
"description_html"
|
"description_html"
|
||||||
):
|
):
|
||||||
|
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
IssueActivity(
|
IssueActivity(
|
||||||
issue_id=issue_id,
|
issue_id=issue_id,
|
||||||
@ -274,7 +280,6 @@ def track_labels(
|
|||||||
):
|
):
|
||||||
# Label Addition
|
# Label Addition
|
||||||
if len(requested_data.get("labels_list")) > len(current_instance.get("labels")):
|
if len(requested_data.get("labels_list")) > len(current_instance.get("labels")):
|
||||||
|
|
||||||
for label in requested_data.get("labels_list"):
|
for label in requested_data.get("labels_list"):
|
||||||
if label not in current_instance.get("labels"):
|
if label not in current_instance.get("labels"):
|
||||||
label = Label.objects.get(pk=label)
|
label = Label.objects.get(pk=label)
|
||||||
@ -296,7 +301,6 @@ def track_labels(
|
|||||||
|
|
||||||
# Label Removal
|
# Label Removal
|
||||||
if len(requested_data.get("labels_list")) < len(current_instance.get("labels")):
|
if len(requested_data.get("labels_list")) < len(current_instance.get("labels")):
|
||||||
|
|
||||||
for label in current_instance.get("labels"):
|
for label in current_instance.get("labels"):
|
||||||
if label not in requested_data.get("labels_list"):
|
if label not in requested_data.get("labels_list"):
|
||||||
label = Label.objects.get(pk=label)
|
label = Label.objects.get(pk=label)
|
||||||
@ -326,12 +330,10 @@ def track_assignees(
|
|||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
):
|
):
|
||||||
|
|
||||||
# Assignee Addition
|
# Assignee Addition
|
||||||
if len(requested_data.get("assignees_list")) > len(
|
if len(requested_data.get("assignees_list")) > len(
|
||||||
current_instance.get("assignees")
|
current_instance.get("assignees")
|
||||||
):
|
):
|
||||||
|
|
||||||
for assignee in requested_data.get("assignees_list"):
|
for assignee in requested_data.get("assignees_list"):
|
||||||
if assignee not in current_instance.get("assignees"):
|
if assignee not in current_instance.get("assignees"):
|
||||||
assignee = User.objects.get(pk=assignee)
|
assignee = User.objects.get(pk=assignee)
|
||||||
@ -354,7 +356,6 @@ def track_assignees(
|
|||||||
if len(requested_data.get("assignees_list")) < len(
|
if len(requested_data.get("assignees_list")) < len(
|
||||||
current_instance.get("assignees")
|
current_instance.get("assignees")
|
||||||
):
|
):
|
||||||
|
|
||||||
for assignee in current_instance.get("assignees"):
|
for assignee in current_instance.get("assignees"):
|
||||||
if assignee not in requested_data.get("assignees_list"):
|
if assignee not in requested_data.get("assignees_list"):
|
||||||
assignee = User.objects.get(pk=assignee)
|
assignee = User.objects.get(pk=assignee)
|
||||||
@ -386,7 +387,6 @@ def track_blocks(
|
|||||||
if len(requested_data.get("blocks_list")) > len(
|
if len(requested_data.get("blocks_list")) > len(
|
||||||
current_instance.get("blocked_issues")
|
current_instance.get("blocked_issues")
|
||||||
):
|
):
|
||||||
|
|
||||||
for block in requested_data.get("blocks_list"):
|
for block in requested_data.get("blocks_list"):
|
||||||
if (
|
if (
|
||||||
len(
|
len(
|
||||||
@ -418,7 +418,6 @@ def track_blocks(
|
|||||||
if len(requested_data.get("blocks_list")) < len(
|
if len(requested_data.get("blocks_list")) < len(
|
||||||
current_instance.get("blocked_issues")
|
current_instance.get("blocked_issues")
|
||||||
):
|
):
|
||||||
|
|
||||||
for blocked in current_instance.get("blocked_issues"):
|
for blocked in current_instance.get("blocked_issues"):
|
||||||
if blocked.get("block") not in requested_data.get("blocks_list"):
|
if blocked.get("block") not in requested_data.get("blocks_list"):
|
||||||
issue = Issue.objects.get(pk=blocked.get("block"))
|
issue = Issue.objects.get(pk=blocked.get("block"))
|
||||||
@ -450,7 +449,6 @@ def track_blockings(
|
|||||||
if len(requested_data.get("blockers_list")) > len(
|
if len(requested_data.get("blockers_list")) > len(
|
||||||
current_instance.get("blocker_issues")
|
current_instance.get("blocker_issues")
|
||||||
):
|
):
|
||||||
|
|
||||||
for block in requested_data.get("blockers_list"):
|
for block in requested_data.get("blockers_list"):
|
||||||
if (
|
if (
|
||||||
len(
|
len(
|
||||||
@ -482,7 +480,6 @@ def track_blockings(
|
|||||||
if len(requested_data.get("blockers_list")) < len(
|
if len(requested_data.get("blockers_list")) < len(
|
||||||
current_instance.get("blocker_issues")
|
current_instance.get("blocker_issues")
|
||||||
):
|
):
|
||||||
|
|
||||||
for blocked in current_instance.get("blocker_issues"):
|
for blocked in current_instance.get("blocker_issues"):
|
||||||
if blocked.get("blocked_by") not in requested_data.get("blockers_list"):
|
if blocked.get("blocked_by") not in requested_data.get("blockers_list"):
|
||||||
issue = Issue.objects.get(pk=blocked.get("blocked_by"))
|
issue = Issue.objects.get(pk=blocked.get("blocked_by"))
|
||||||
@ -502,6 +499,116 @@ def track_blockings(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def track_cycles(
|
||||||
|
requested_data,
|
||||||
|
current_instance,
|
||||||
|
issue_id,
|
||||||
|
project,
|
||||||
|
actor,
|
||||||
|
issue_activities,
|
||||||
|
):
|
||||||
|
# Updated Records:
|
||||||
|
updated_records = current_instance.get("updated_cycle_issues", [])
|
||||||
|
created_records = json.loads(current_instance.get("created_cycle_issues", []))
|
||||||
|
|
||||||
|
for updated_record in updated_records:
|
||||||
|
old_cycle = Cycle.objects.filter(
|
||||||
|
pk=updated_record.get("old_cycle_id", None)
|
||||||
|
).first()
|
||||||
|
new_cycle = Cycle.objects.filter(
|
||||||
|
pk=updated_record.get("new_cycle_id", None)
|
||||||
|
).first()
|
||||||
|
|
||||||
|
issue_activities.append(
|
||||||
|
IssueActivity(
|
||||||
|
issue_id=updated_record.get("issue_id"),
|
||||||
|
actor=actor,
|
||||||
|
verb="updated",
|
||||||
|
old_value=old_cycle.name,
|
||||||
|
new_value=new_cycle.name,
|
||||||
|
field="cycles",
|
||||||
|
project=project,
|
||||||
|
workspace=project.workspace,
|
||||||
|
comment=f"{actor.email} updated cycle from {old_cycle.name} to {new_cycle.name}",
|
||||||
|
old_identifier=old_cycle.id,
|
||||||
|
new_identifier=new_cycle.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for created_record in created_records:
|
||||||
|
cycle = Cycle.objects.filter(pk=created_record.cycle_id).first()
|
||||||
|
issue_activities.append(
|
||||||
|
IssueActivity(
|
||||||
|
issue_id=created_record.issue_id,
|
||||||
|
actor=actor,
|
||||||
|
verb="created",
|
||||||
|
old_value="",
|
||||||
|
new_value=cycle.name,
|
||||||
|
field="cycles",
|
||||||
|
project=project,
|
||||||
|
workspace=project.workspace,
|
||||||
|
comment=f"{actor.email} added cycle {cycle.name}",
|
||||||
|
old_identifier="",
|
||||||
|
new_identifier=cycle.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def track_modules(
|
||||||
|
requested_data,
|
||||||
|
current_instance,
|
||||||
|
issue_id,
|
||||||
|
project,
|
||||||
|
actor,
|
||||||
|
issue_activities,
|
||||||
|
):
|
||||||
|
# Updated Records:
|
||||||
|
updated_records = current_instance.get("updated_module_issues", [])
|
||||||
|
created_records = json.loads(current_instance.get("created_module_issues", []))
|
||||||
|
|
||||||
|
for updated_record in updated_records:
|
||||||
|
old_module = Module.objects.filter(
|
||||||
|
pk=updated_record.get("old_module_id", None)
|
||||||
|
).first()
|
||||||
|
new_module = Module.objects.filter(
|
||||||
|
pk=updated_record.get("new_module_id", None)
|
||||||
|
).first()
|
||||||
|
|
||||||
|
issue_activities.append(
|
||||||
|
IssueActivity(
|
||||||
|
issue_id=updated_record.get("issue_id"),
|
||||||
|
actor=actor,
|
||||||
|
verb="updated",
|
||||||
|
old_value=old_module.name,
|
||||||
|
new_value=new_module.name,
|
||||||
|
field="modules",
|
||||||
|
project=project,
|
||||||
|
workspace=project.workspace,
|
||||||
|
comment=f"{actor.email} updated module from {old_module.name} to {new_module.name}",
|
||||||
|
old_identifier=old_module.id,
|
||||||
|
new_identifier=new_module.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for created_record in created_records:
|
||||||
|
module = Module.objects.filter(pk=created_record.module_id).first()
|
||||||
|
issue_activities.append(
|
||||||
|
IssueActivity(
|
||||||
|
issue_id=created_record.issue_id,
|
||||||
|
actor=actor,
|
||||||
|
verb="created",
|
||||||
|
old_value="",
|
||||||
|
new_value=module.name,
|
||||||
|
field="modules",
|
||||||
|
project=project,
|
||||||
|
workspace=project.workspace,
|
||||||
|
comment=f"{actor.email} added module {module.name}",
|
||||||
|
old_identifier="",
|
||||||
|
new_identifier=module.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Receive message from room group
|
# Receive message from room group
|
||||||
@job("default")
|
@job("default")
|
||||||
def issue_activity(event):
|
def issue_activity(event):
|
||||||
@ -510,7 +617,7 @@ def issue_activity(event):
|
|||||||
|
|
||||||
requested_data = json.loads(event.get("requested_data"))
|
requested_data = json.loads(event.get("requested_data"))
|
||||||
current_instance = json.loads(event.get("current_instance"))
|
current_instance = json.loads(event.get("current_instance"))
|
||||||
issue_id = event.get("issue_id")
|
issue_id = event.get("issue_id", None)
|
||||||
actor_id = event.get("actor_id")
|
actor_id = event.get("actor_id")
|
||||||
project_id = event.get("project_id")
|
project_id = event.get("project_id")
|
||||||
|
|
||||||
@ -530,6 +637,8 @@ def issue_activity(event):
|
|||||||
"assignees_list": track_assignees,
|
"assignees_list": track_assignees,
|
||||||
"blocks_list": track_blocks,
|
"blocks_list": track_blocks,
|
||||||
"blockers_list": track_blockings,
|
"blockers_list": track_blockings,
|
||||||
|
"cycles_list": track_cycles,
|
||||||
|
"modules_list": track_modules,
|
||||||
}
|
}
|
||||||
|
|
||||||
for key in requested_data:
|
for key in requested_data:
|
||||||
|
Loading…
Reference in New Issue
Block a user