Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 28 additions & 181 deletions apps/api/plane/app/views/issue/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
from django.db.models import (
Count,
Exists,
F,
Func,
OuterRef,
Prefetch,
Q,
Expand Down Expand Up @@ -50,7 +48,6 @@
Issue,
IssueAssignee,
IssueLabel,
IssueLink,
IssueReaction,
IssueRelation,
IssueSubscriber,
Expand All @@ -76,6 +73,23 @@
from .. import BaseAPIView, BaseViewSet


def annotate_issue_cycle_and_counts(queryset):
return (
queryset.annotate(
cycle_id=Subquery(CycleIssue.objects.filter(issue=OuterRef("id"), deleted_at__isnull=True).values("cycle_id")[:1])
)
.annotate(link_count=Count("issue_link", distinct=True))
.annotate(
attachment_count=Count(
"assets",
filter=Q(assets__entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT),
distinct=True,
)
)
.annotate(sub_issues_count=Count("parent_issue", distinct=True))
)


class IssueListEndpoint(BaseAPIView):
filter_backends = (ComplexFilterBackend,)
filterset_class = IssueFilterSet
Expand Down Expand Up @@ -106,35 +120,7 @@ def get(self, request, slug, project_id):
)

# Add annotations
issue_queryset = (
issue_queryset.annotate(
cycle_id=Subquery(
CycleIssue.objects.filter(issue=OuterRef("id"), deleted_at__isnull=True).values("cycle_id")[:1]
)
)
.annotate(
link_count=IssueLink.objects.filter(issue=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
attachment_count=FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.distinct()
)
issue_queryset = annotate_issue_cycle_and_counts(issue_queryset).distinct()

order_by_param = request.GET.get("order_by", "-created_at")
# Issue queryset
Expand Down Expand Up @@ -210,42 +196,7 @@ def get_queryset(self):
return issues

def apply_annotations(self, issues):
issues = (
issues.annotate(
cycle_id=Subquery(
CycleIssue.objects.filter(issue=OuterRef("id"), deleted_at__isnull=True).values("cycle_id")[:1]
)
)
.annotate(
link_count=Subquery(
IssueLink.objects.filter(issue=OuterRef("id"))
.values("issue")
.annotate(count=Count("id"))
.values("count")
)
)
.annotate(
attachment_count=Subquery(
FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.values("issue_id")
.annotate(count=Count("id"))
.values("count")
)
)
.annotate(
sub_issues_count=Subquery(
Issue.issue_objects.filter(parent=OuterRef("id"))
.values("parent")
.annotate(count=Count("id"))
.values("count")
)
)
)

return issues
return annotate_issue_cycle_and_counts(issues)

@method_decorator(gzip_page)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
Expand Down Expand Up @@ -482,40 +433,14 @@ def retrieve(self, request, slug, project_id, pk=None):
project = Project.objects.get(pk=project_id, workspace__slug=slug)

issue = (
Issue.objects.filter(
project_id=self.kwargs.get("project_id"),
workspace__slug=self.kwargs.get("slug"),
pk=pk,
)
.select_related("state")
.annotate(cycle_id=Subquery(CycleIssue.objects.filter(issue=OuterRef("id")).values("cycle_id")[:1]))
.annotate(
link_count=Subquery(
IssueLink.objects.filter(issue=OuterRef("id"))
.values("issue")
.annotate(count=Count("id"))
.values("count")
)
)
.annotate(
attachment_count=Subquery(
FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.values("issue_id")
.annotate(count=Count("id"))
.values("count")
)
)
.annotate(
sub_issues_count=Subquery(
Issue.issue_objects.filter(parent=OuterRef("id"))
.values("parent")
.annotate(count=Count("id"))
.values("count")
annotate_issue_cycle_and_counts(
Issue.objects.filter(
project_id=self.kwargs.get("project_id"),
workspace__slug=self.kwargs.get("slug"),
pk=pk,
)
)
.select_related("state")
.annotate(
label_ids=Coalesce(
Subquery(
Expand Down Expand Up @@ -808,37 +733,7 @@ def get_queryset(self):

issue_queryset = Issue.issue_objects.filter(workspace__slug=workspace_slug, project_id=project_id)

return (
issue_queryset.select_related("state")
.annotate(cycle_id=Subquery(CycleIssue.objects.filter(issue=OuterRef("id")).values("cycle_id")[:1]))
.annotate(
link_count=Subquery(
IssueLink.objects.filter(issue=OuterRef("id"))
.values("issue")
.annotate(count=Count("id"))
.values("count")
)
)
.annotate(
attachment_count=Subquery(
FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.values("issue_id")
.annotate(count=Count("id"))
.values("count")
)
)
.annotate(
sub_issues_count=Subquery(
Issue.issue_objects.filter(parent=OuterRef("id"))
.values("parent")
.annotate(count=Count("id"))
.values("count")
)
)
)
return annotate_issue_cycle_and_counts(issue_queryset.select_related("state"))

def process_paginated_result(self, fields, results, timezone):
paginated_data = results.values(*fields)
Expand Down Expand Up @@ -966,32 +861,7 @@ class IssueDetailEndpoint(BaseAPIView):

def apply_annotations(self, issues):
return (
issues.annotate(
cycle_id=Subquery(
CycleIssue.objects.filter(issue=OuterRef("id"), deleted_at__isnull=True).values("cycle_id")[:1]
)
)
.annotate(
link_count=IssueLink.objects.filter(issue=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
attachment_count=FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
annotate_issue_cycle_and_counts(issues)
.prefetch_related(
Prefetch(
"issue_assignee",
Expand Down Expand Up @@ -1220,32 +1090,9 @@ def get(self, request, slug, project_identifier, issue_identifier):

# Fetch the issue
issue = (
Issue.objects.filter(project_id=project.id)
.filter(workspace__slug=slug)
annotate_issue_cycle_and_counts(Issue.objects.filter(project_id=project.id).filter(workspace__slug=slug))
.select_related("workspace", "project", "state", "parent")
.prefetch_related("assignees", "labels", "issue_module__module")
.annotate(cycle_id=Subquery(CycleIssue.objects.filter(issue=OuterRef("id")).values("cycle_id")[:1]))
.annotate(
link_count=IssueLink.objects.filter(issue=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
attachment_count=FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.filter(sequence_id=issue_identifier)
.annotate(
label_ids=Coalesce(
Expand Down
34 changes: 3 additions & 31 deletions apps/api/plane/app/views/issue/relation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# Django imports
from django.utils import timezone
from django.db.models import Q, OuterRef, F, Func, UUIDField, Value, CharField, Subquery
from django.db.models import Q, UUIDField, Value, CharField
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models.functions import Coalesce
from django.contrib.postgres.aggregates import ArrayAgg
Expand All @@ -25,13 +25,11 @@
Project,
IssueRelation,
Issue,
FileAsset,
IssueLink,
CycleIssue,
)
from plane.bgtasks.issue_activities_task import issue_activity
from plane.utils.issue_relation_mapper import get_actual_relation
from plane.utils.host import base_host
from .base import annotate_issue_cycle_and_counts


class IssueRelationViewSet(BaseViewSet):
Expand Down Expand Up @@ -100,35 +98,9 @@ def list(self, request, slug, project_id, issue_id):
)

queryset = (
Issue.issue_objects.filter(workspace__slug=slug)
annotate_issue_cycle_and_counts(Issue.issue_objects.filter(workspace__slug=slug))
.select_related("workspace", "project", "state", "parent")
.prefetch_related("assignees", "labels", "issue_module__module")
.annotate(
cycle_id=Subquery(
CycleIssue.objects.filter(issue=OuterRef("id"), deleted_at__isnull=True).values("cycle_id")[:1]
)
)
.annotate(
link_count=IssueLink.objects.filter(issue=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
attachment_count=FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
label_ids=Coalesce(
ArrayAgg(
Expand Down
33 changes: 4 additions & 29 deletions apps/api/plane/app/views/issue/sub_issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# Django imports
from django.utils import timezone
from django.db.models import OuterRef, Func, F, Q, Value, UUIDField, Subquery
from django.db.models import F, Q, Value, UUIDField
from django.utils.decorators import method_decorator
from django.views.decorators.gzip import gzip_page
from django.contrib.postgres.aggregates import ArrayAgg
Expand All @@ -22,12 +22,13 @@
from .. import BaseAPIView
from plane.app.serializers import IssueSerializer
from plane.app.permissions import ProjectEntityPermission
from plane.db.models import Issue, IssueLink, FileAsset, CycleIssue
from plane.db.models import Issue
from plane.bgtasks.issue_activities_task import issue_activity
from plane.utils.timezone_converter import user_timezone_converter
from collections import defaultdict
from plane.utils.host import base_host
from plane.utils.order_queryset import order_issue_queryset
from .base import annotate_issue_cycle_and_counts


class SubIssuesEndpoint(BaseAPIView):
Expand All @@ -36,35 +37,9 @@ class SubIssuesEndpoint(BaseAPIView):
@method_decorator(gzip_page)
def get(self, request, slug, project_id, issue_id):
sub_issues = (
Issue.issue_objects.filter(parent_id=issue_id, workspace__slug=slug)
annotate_issue_cycle_and_counts(Issue.issue_objects.filter(parent_id=issue_id, workspace__slug=slug))
.select_related("workspace", "project", "state", "parent")
.prefetch_related("assignees", "labels", "issue_module__module")
.annotate(
cycle_id=Subquery(
CycleIssue.objects.filter(issue=OuterRef("id"), deleted_at__isnull=True).values("cycle_id")[:1]
)
)
.annotate(
link_count=IssueLink.objects.filter(issue=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
attachment_count=FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
label_ids=Coalesce(
ArrayAgg(
Expand Down
Loading