diff --git a/apps/api/plane/api/views/issue.py b/apps/api/plane/api/views/issue.py index 6cd14ff13f..5c4ae71791 100644 --- a/apps/api/plane/api/views/issue.py +++ b/apps/api/plane/api/views/issue.py @@ -153,74 +153,6 @@ from plane.ee.bgtasks.entity_issue_state_progress_task import ( entity_issue_state_activity_task, ) -from plane.utils.openapi import ( - work_item_docs, - label_docs, - issue_link_docs, - issue_comment_docs, - issue_activity_docs, - issue_attachment_docs, - WORKSPACE_SLUG_PARAMETER, - PROJECT_IDENTIFIER_PARAMETER, - ISSUE_IDENTIFIER_PARAMETER, - PROJECT_ID_PARAMETER, - ISSUE_ID_PARAMETER, - LABEL_ID_PARAMETER, - COMMENT_ID_PARAMETER, - LINK_ID_PARAMETER, - ATTACHMENT_ID_PARAMETER, - ACTIVITY_ID_PARAMETER, - PROJECT_ID_QUERY_PARAMETER, - CURSOR_PARAMETER, - PER_PAGE_PARAMETER, - EXTERNAL_ID_PARAMETER, - EXTERNAL_SOURCE_PARAMETER, - ORDER_BY_PARAMETER, - SEARCH_PARAMETER, - SEARCH_PARAMETER_REQUIRED, - LIMIT_PARAMETER, - WORKSPACE_SEARCH_PARAMETER, - FIELDS_PARAMETER, - EXPAND_PARAMETER, - create_paginated_response, - # Request Examples - ISSUE_CREATE_EXAMPLE, - ISSUE_UPDATE_EXAMPLE, - ISSUE_UPSERT_EXAMPLE, - LABEL_CREATE_EXAMPLE, - LABEL_UPDATE_EXAMPLE, - ISSUE_LINK_CREATE_EXAMPLE, - ISSUE_LINK_UPDATE_EXAMPLE, - ISSUE_COMMENT_CREATE_EXAMPLE, - ISSUE_COMMENT_UPDATE_EXAMPLE, - ISSUE_ATTACHMENT_UPLOAD_EXAMPLE, - ATTACHMENT_UPLOAD_CONFIRM_EXAMPLE, - # Response Examples - ISSUE_EXAMPLE, - LABEL_EXAMPLE, - ISSUE_LINK_EXAMPLE, - ISSUE_COMMENT_EXAMPLE, - ISSUE_ATTACHMENT_EXAMPLE, - ISSUE_ATTACHMENT_NOT_UPLOADED_EXAMPLE, - ISSUE_SEARCH_EXAMPLE, - WORK_ITEM_NOT_FOUND_RESPONSE, - ISSUE_NOT_FOUND_RESPONSE, - PROJECT_NOT_FOUND_RESPONSE, - EXTERNAL_ID_EXISTS_RESPONSE, - DELETED_RESPONSE, - ADMIN_ONLY_RESPONSE, - LABEL_NOT_FOUND_RESPONSE, - LABEL_NAME_EXISTS_RESPONSE, - INVALID_REQUEST_RESPONSE, - LINK_NOT_FOUND_RESPONSE, - COMMENT_NOT_FOUND_RESPONSE, - ATTACHMENT_NOT_FOUND_RESPONSE, - BAD_SEARCH_REQUEST_RESPONSE, - UNAUTHORIZED_RESPONSE, - FORBIDDEN_RESPONSE, - WORKSPACE_NOT_FOUND_RESPONSE, -) - class WorkspaceIssueAPIEndpoint(BaseAPIView): """ @@ -634,115 +566,16 @@ class IssueDetailAPIEndpoint(BaseAPIView): Supports filtering, ordering, and field selection through query parameters. """ - external_id = request.GET.get("external_id") - external_source = request.GET.get("external_source") + issue = Issue.issue_objects.annotate( + sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id")) + .order_by() + .annotate(count=Func(F("id"), function="Count")) + .values("count") + ).get(workspace__slug=slug, project_id=project_id, pk=pk) - if external_id and external_source: - issue = Issue.objects.get( - external_id=external_id, - external_source=external_source, - workspace__slug=slug, - project_id=project_id, - ) - return Response( - IssueSerializer(issue, fields=self.fields, expand=self.expand).data, - status=status.HTTP_200_OK, - ) - - # Custom ordering for priority and state - priority_order = ["urgent", "high", "medium", "low", "none"] - state_order = ["backlog", "unstarted", "started", "completed", "cancelled"] - - order_by_param = request.GET.get("order_by", "-created_at") - - issue_queryset = ( - self.get_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") - ) - ) - - # Priority Ordering - if order_by_param == "priority" or order_by_param == "-priority": - priority_order = ( - priority_order if order_by_param == "priority" else priority_order[::-1] - ) - issue_queryset = issue_queryset.annotate( - priority_order=Case( - *[ - When(priority=p, then=Value(i)) - for i, p in enumerate(priority_order) - ], - output_field=CharField(), - ) - ).order_by("priority_order") - - # State Ordering - elif order_by_param in [ - "state__name", - "state__group", - "-state__name", - "-state__group", - ]: - state_order = ( - state_order - if order_by_param in ["state__name", "state__group"] - else state_order[::-1] - ) - issue_queryset = issue_queryset.annotate( - state_order=Case( - *[ - When(state__group=state_group, then=Value(i)) - for i, state_group in enumerate(state_order) - ], - default=Value(len(state_order)), - output_field=CharField(), - ) - ).order_by("state_order") - # assignee and label ordering - elif order_by_param in [ - "labels__name", - "-labels__name", - "assignees__first_name", - "-assignees__first_name", - ]: - issue_queryset = issue_queryset.annotate( - max_values=Max( - order_by_param[1::] - if order_by_param.startswith("-") - else order_by_param - ) - ).order_by( - "-max_values" if order_by_param.startswith("-") else "max_values" - ) - else: - issue_queryset = issue_queryset.order_by(order_by_param) - - return self.paginate( - request=request, - queryset=(issue_queryset), - on_results=lambda issues: IssueSerializer( - issues, many=True, fields=self.fields, expand=self.expand - ).data, + return Response( + IssueSerializer(issue, fields=self.fields, expand=self.expand).data, + status=status.HTTP_200_OK, ) @work_item_docs( @@ -2470,6 +2303,7 @@ class IssueAttachmentServerEndpoint(BaseAPIView): serializer_class = IssueAttachmentSerializer permission_classes = [ProjectEntityPermission] model = FileAsset + use_read_replica = True def post(self, request, slug, project_id, issue_id): name = request.data.get("name")