From 86408fcd4682e3c4e9ea7cd19015d2679325f377 Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Wed, 29 Nov 2023 20:26:43 +0530 Subject: [PATCH] chore: replaced v3 issues endpoints (#2945) * chore: removed v3 endpoints * chore: replace v3 issues to normal issues endpoints * build-error: Bulid error is new issue structure --------- Co-authored-by: NarayanBavisetti --- apiserver/plane/app/urls/cycle.py | 6 - apiserver/plane/app/urls/issue.py | 12 -- apiserver/plane/app/urls/module.py | 6 - apiserver/plane/app/urls/views.py | 8 +- apiserver/plane/app/urls/workspace.py | 6 - apiserver/plane/app/views/__init__.py | 6 - apiserver/plane/app/views/cycle.py | 74 +------- apiserver/plane/app/views/issue.py | 159 ++---------------- apiserver/plane/app/views/module.py | 73 +------- apiserver/plane/app/views/view.py | 69 +------- apiserver/plane/app/views/workspace.py | 67 +------- .../core/modals/bulk-delete-issues-modal.tsx | 4 +- .../inbox/modals/select-duplicate.tsx | 2 +- web/services/cycle.service.ts | 17 +- web/services/issue/issue.service.ts | 12 +- web/services/issue/issue_archive.service.ts | 12 +- web/services/issue/issue_draft.service.tsx | 13 +- web/services/module.service.ts | 12 +- web/services/user.service.ts | 21 +-- web/store/cycle/cycles.store.ts | 2 +- web/store/issue/issue_draft.store.ts | 2 +- web/store/issues/global/issue.store.ts | 2 +- web/store/issues/profile/issue.store.ts | 2 +- .../project-issues/archived/issue.store.ts | 2 +- .../project-issues/cycle/issue.store.ts | 2 +- .../project-issues/draft/issue.store.ts | 2 +- .../project-issues/module/issue.store.ts | 2 +- .../project-view/issue.store.ts | 2 +- .../project-issues/project/issue.store.ts | 2 +- 29 files changed, 47 insertions(+), 552 deletions(-) diff --git a/apiserver/plane/app/urls/cycle.py b/apiserver/plane/app/urls/cycle.py index 0e786e291..46e6a5e84 100644 --- a/apiserver/plane/app/urls/cycle.py +++ b/apiserver/plane/app/urls/cycle.py @@ -7,7 +7,6 @@ from plane.app.views import ( CycleDateCheckEndpoint, CycleFavoriteViewSet, TransferCycleIssueEndpoint, - CycleIssueGroupedEndpoint, ) @@ -44,11 +43,6 @@ urlpatterns = [ ), name="project-issue-cycle", ), - path( - "v3/workspaces//projects//cycles//cycle-issues/", - CycleIssueGroupedEndpoint.as_view(), - name="project-issue-cycle", - ), path( "workspaces//projects//cycles//cycle-issues//", CycleIssueViewSet.as_view( diff --git a/apiserver/plane/app/urls/issue.py b/apiserver/plane/app/urls/issue.py index 9aa189288..971fbc395 100644 --- a/apiserver/plane/app/urls/issue.py +++ b/apiserver/plane/app/urls/issue.py @@ -3,8 +3,6 @@ from django.urls import path from plane.app.views import ( IssueViewSet, - IssueListEndpoint, - IssueListGroupedEndpoint, LabelViewSet, BulkCreateIssueLabelsEndpoint, BulkDeleteIssuesEndpoint, @@ -37,16 +35,6 @@ urlpatterns = [ ), name="project-issue", ), - path( - "v2/workspaces//projects//issues/", - IssueListEndpoint.as_view(), - name="project-issue", - ), - path( - "v3/workspaces//projects//issues/", - IssueListGroupedEndpoint.as_view(), - name="project-issue", - ), path( "workspaces//projects//issues//", IssueViewSet.as_view( diff --git a/apiserver/plane/app/urls/module.py b/apiserver/plane/app/urls/module.py index 20c9d9e35..5507b3a37 100644 --- a/apiserver/plane/app/urls/module.py +++ b/apiserver/plane/app/urls/module.py @@ -7,7 +7,6 @@ from plane.app.views import ( ModuleLinkViewSet, ModuleFavoriteViewSet, BulkImportModulesEndpoint, - ModuleIssueGroupedEndpoint, ) @@ -44,11 +43,6 @@ urlpatterns = [ ), name="project-module-issues", ), - path( - "v3/workspaces//projects//modules//module-issues/", - ModuleIssueGroupedEndpoint.as_view(), - name="project-issue-cycle", - ), path( "workspaces//projects//modules//module-issues//", ModuleIssueViewSet.as_view( diff --git a/apiserver/plane/app/urls/views.py b/apiserver/plane/app/urls/views.py index b2d8917b2..3d45b627a 100644 --- a/apiserver/plane/app/urls/views.py +++ b/apiserver/plane/app/urls/views.py @@ -5,8 +5,7 @@ from plane.app.views import ( IssueViewViewSet, GlobalViewViewSet, GlobalViewIssuesViewSet, - IssueViewFavoriteViewSet, - GlobalViewIssuesGroupedEndpoint + IssueViewFavoriteViewSet, ) @@ -64,11 +63,6 @@ urlpatterns = [ ), name="global-view-issues", ), - path( - "v3/workspaces//issues/", - GlobalViewIssuesGroupedEndpoint.as_view(), - name="global-view-issues", - ), path( "workspaces//projects//user-favorite-views/", IssueViewFavoriteViewSet.as_view( diff --git a/apiserver/plane/app/urls/workspace.py b/apiserver/plane/app/urls/workspace.py index c449c0fcc..739d17c55 100644 --- a/apiserver/plane/app/urls/workspace.py +++ b/apiserver/plane/app/urls/workspace.py @@ -18,7 +18,6 @@ from plane.app.views import ( WorkspaceUserProfileEndpoint, WorkspaceUserProfileIssuesEndpoint, WorkspaceLabelsEndpoint, - WorkspaceUserProfileIssuesGroupedEndpoint ) @@ -190,11 +189,6 @@ urlpatterns = [ WorkspaceUserProfileIssuesEndpoint.as_view(), name="workspace-user-profile-issues", ), - path( - "v3/workspaces//user-issues//", - WorkspaceUserProfileIssuesGroupedEndpoint.as_view(), - name="workspace-user-profile-issues", - ), path( "workspaces//labels/", WorkspaceLabelsEndpoint.as_view(), diff --git a/apiserver/plane/app/views/__init__.py b/apiserver/plane/app/views/__init__.py index 85d708a38..d86023458 100644 --- a/apiserver/plane/app/views/__init__.py +++ b/apiserver/plane/app/views/__init__.py @@ -44,7 +44,6 @@ from .workspace import ( WorkspaceUserProfileEndpoint, WorkspaceUserProfileIssuesEndpoint, WorkspaceLabelsEndpoint, - WorkspaceUserProfileIssuesGroupedEndpoint ) from .state import StateViewSet from .view import ( @@ -52,7 +51,6 @@ from .view import ( GlobalViewIssuesViewSet, IssueViewViewSet, IssueViewFavoriteViewSet, - GlobalViewIssuesGroupedEndpoint ) from .cycle import ( CycleViewSet, @@ -60,13 +58,10 @@ from .cycle import ( CycleDateCheckEndpoint, CycleFavoriteViewSet, TransferCycleIssueEndpoint, - CycleIssueGroupedEndpoint, ) from .asset import FileAssetEndpoint, UserAssetsEndpoint, FileAssetViewSet from .issue import ( IssueViewSet, - IssueListEndpoint, - IssueListGroupedEndpoint, WorkSpaceIssuesEndpoint, IssueActivityEndpoint, IssueCommentViewSet, @@ -108,7 +103,6 @@ from .module import ( ModuleIssueViewSet, ModuleLinkViewSet, ModuleFavoriteViewSet, - ModuleIssueGroupedEndpoint, ) from .api import ApiTokenEndpoint diff --git a/apiserver/plane/app/views/cycle.py b/apiserver/plane/app/views/cycle.py index b0fec588c..d2f82d75b 100644 --- a/apiserver/plane/app/views/cycle.py +++ b/apiserver/plane/app/views/cycle.py @@ -539,9 +539,8 @@ class CycleIssueViewSet(WebhookMixin, BaseViewSet): @method_decorator(gzip_page) def list(self, request, slug, project_id, cycle_id): + fields = [field for field in request.GET.get("fields", "").split(",") if field] order_by = request.GET.get("order_by", "created_at") - group_by = request.GET.get("group_by", False) - sub_group_by = request.GET.get("sub_group_by", False) filters = issue_filters(request.query_params, "GET") issues = ( Issue.issue_objects.filter(issue_cycle__cycle_id=cycle_id) @@ -576,24 +575,9 @@ class CycleIssueViewSet(WebhookMixin, BaseViewSet): ) ) - issues_data = IssueStateSerializer(issues, many=True).data - - if sub_group_by and sub_group_by == group_by: - return Response( - {"error": "Group by and sub group by cannot be same"}, - status=status.HTTP_400_BAD_REQUEST, - ) - - if group_by: - grouped_results = group_results(issues_data, group_by, sub_group_by) - return Response( - grouped_results, - status=status.HTTP_200_OK, - ) - - return Response( - issues_data, status=status.HTTP_200_OK - ) + issues = IssueStateSerializer(issues, many=True, fields=fields if fields else None).data + issue_dict = {str(issue["id"]): issue for issue in issues} + return Response(issue_dict, status=status.HTTP_200_OK) def create(self, request, slug, project_id, cycle_id): issues = request.data.get("issues", []) @@ -709,56 +693,6 @@ class CycleIssueViewSet(WebhookMixin, BaseViewSet): return Response(status=status.HTTP_204_NO_CONTENT) -class CycleIssueGroupedEndpoint(BaseAPIView): - - permission_classes = [ - ProjectEntityPermission, - ] - - def get(self, request, slug, project_id, cycle_id): - filters = issue_filters(request.query_params, "GET") - fields = [field for field in request.GET.get("fields", "").split(",") if field] - - issues = ( - Issue.issue_objects.filter(issue_cycle__cycle_id=cycle_id) - .annotate( - sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .annotate(bridge_id=F("issue_cycle__id")) - .filter(project_id=project_id) - .filter(workspace__slug=slug) - .select_related("project") - .select_related("workspace") - .select_related("state") - .select_related("parent") - .prefetch_related("assignees") - .prefetch_related("labels") - .filter(**filters) - .annotate( - link_count=IssueLink.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .annotate( - attachment_count=IssueAttachment.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - ) - - issues = IssueStateSerializer(issues, many=True, fields=fields if fields else None).data - issue_dict = {str(issue["id"]): issue for issue in issues} - return Response( - issue_dict, - status=status.HTTP_200_OK, - ) - - class CycleDateCheckEndpoint(BaseAPIView): permission_classes = [ ProjectEntityPermission, diff --git a/apiserver/plane/app/views/issue.py b/apiserver/plane/app/views/issue.py index a819d56f0..d489629ba 100644 --- a/apiserver/plane/app/views/issue.py +++ b/apiserver/plane/app/views/issue.py @@ -133,6 +133,7 @@ class IssueViewSet(WebhookMixin, BaseViewSet): @method_decorator(gzip_page) def list(self, request, slug, project_id): + fields = [field for field in request.GET.get("fields", "").split(",") if field] filters = issue_filters(request.query_params, "GET") # Custom ordering for priority and state @@ -216,25 +217,9 @@ class IssueViewSet(WebhookMixin, BaseViewSet): else: issue_queryset = issue_queryset.order_by(order_by_param) - issues = IssueLiteSerializer(issue_queryset, many=True).data - - ## Grouping the results - group_by = request.GET.get("group_by", False) - sub_group_by = request.GET.get("sub_group_by", False) - if sub_group_by and sub_group_by == group_by: - return Response( - {"error": "Group by and sub group by cannot be same"}, - status=status.HTTP_400_BAD_REQUEST, - ) - - if group_by: - grouped_results = group_results(issues, group_by, sub_group_by) - return Response( - grouped_results, - status=status.HTTP_200_OK, - ) - - return Response(issues, status=status.HTTP_200_OK) + issues = IssueLiteSerializer(issue_queryset, many=True, fields=fields if fields else None).data + issue_dict = {str(issue["id"]): issue for issue in issues} + return Response(issue_dict, status=status.HTTP_200_OK) def create(self, request, slug, project_id): project = Project.objects.get(pk=project_id) @@ -312,114 +297,6 @@ class IssueViewSet(WebhookMixin, BaseViewSet): return Response(status=status.HTTP_204_NO_CONTENT) -class IssueListEndpoint(BaseAPIView): - permission_classes = [ - ProjectEntityPermission, - ] - - def get(self, request, slug, project_id): - fields = [field for field in request.GET.get("fields", "").split(",") if field] - filters = issue_filters(request.query_params, "GET") - - issue_queryset = ( - Issue.objects.filter(workspace__slug=slug, project_id=project_id) - .select_related("project") - .select_related("workspace") - .select_related("state") - .select_related("parent") - .prefetch_related("assignees") - .prefetch_related("labels") - .prefetch_related( - Prefetch( - "issue_reactions", - queryset=IssueReaction.objects.select_related("actor"), - ) - ) - .filter(**filters) - .annotate(cycle_id=F("issue_cycle__cycle_id")) - .annotate(module_id=F("issue_module__module_id")) - .annotate( - link_count=IssueLink.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .annotate( - attachment_count=IssueAttachment.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .distinct() - ) - - serializer = IssueLiteSerializer( - issue_queryset, many=True, fields=fields if fields else None - ) - - return Response(serializer.data, status=status.HTTP_200_OK) - - -class IssueListGroupedEndpoint(BaseAPIView): - - permission_classes = [ - ProjectEntityPermission, - ] - - def get(self, request, slug, project_id): - filters = issue_filters(request.query_params, "GET") - archive = request.GET.get("archived", False) - draft = request.GET.get("draft", False) - fields = [field for field in request.GET.get("fields", "").split(",") if field] - - issue_queryset = ( - Issue.objects.filter(workspace__slug=slug, project_id=project_id) - .select_related("project") - .select_related("workspace") - .select_related("state") - .select_related("parent") - .prefetch_related("assignees") - .prefetch_related("labels") - .prefetch_related( - Prefetch( - "issue_reactions", - queryset=IssueReaction.objects.select_related("actor"), - ) - ) - .filter(**filters) - .filter(is_draft=bool(draft)) - .filter(~Q(archived_at__isnull=bool(archive))) - .filter( - models.Q(issue_inbox__status=1) - | models.Q(issue_inbox__status=-1) - | models.Q(issue_inbox__status=2) - | models.Q(issue_inbox__isnull=True) - ) - .annotate(cycle_id=F("issue_cycle__cycle_id")) - .annotate(module_id=F("issue_module__module_id")) - .annotate( - link_count=IssueLink.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .annotate( - attachment_count=IssueAttachment.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .distinct() - ) - - issues = IssueLiteSerializer(issue_queryset, many=True, fields=fields if fields else None).data - issue_dict = {str(issue["id"]): issue for issue in issues} - return Response( - issue_dict, - status=status.HTTP_200_OK, - ) - - class UserWorkSpaceIssues(BaseAPIView): @method_decorator(gzip_page) def get(self, request, slug): @@ -1094,6 +971,7 @@ class IssueArchiveViewSet(BaseViewSet): @method_decorator(gzip_page) def list(self, request, slug, project_id): + fields = [field for field in request.GET.get("fields", "").split(",") if field] filters = issue_filters(request.query_params, "GET") show_sub_issues = request.GET.get("show_sub_issues", "true") @@ -1184,14 +1062,9 @@ class IssueArchiveViewSet(BaseViewSet): else issue_queryset.filter(parent__isnull=True) ) - issues = IssueLiteSerializer(issue_queryset, many=True).data - - ## Grouping the results - group_by = request.GET.get("group_by", False) - if group_by: - return Response(group_results(issues, group_by), status=status.HTTP_200_OK) - - return Response(issues, status=status.HTTP_200_OK) + issues = IssueLiteSerializer(issue_queryset, many=True, fields=fields if fields else None).data + issue_dict = {str(issue["id"]): issue for issue in issues} + return Response(issue_dict, status=status.HTTP_200_OK) def retrieve(self, request, slug, project_id, pk=None): issue = Issue.objects.get( @@ -1591,6 +1464,7 @@ class IssueDraftViewSet(BaseViewSet): @method_decorator(gzip_page) def list(self, request, slug, project_id): filters = issue_filters(request.query_params, "GET") + fields = [field for field in request.GET.get("fields", "").split(",") if field] # Custom ordering for priority and state priority_order = ["urgent", "high", "medium", "low", "none"] @@ -1673,18 +1547,9 @@ class IssueDraftViewSet(BaseViewSet): else: issue_queryset = issue_queryset.order_by(order_by_param) - issues = IssueLiteSerializer(issue_queryset, many=True).data - - ## Grouping the results - group_by = request.GET.get("group_by", False) - if group_by: - grouped_results = group_results(issues, group_by) - return Response( - grouped_results, - status=status.HTTP_200_OK, - ) - - return Response(issues, status=status.HTTP_200_OK) + issues = IssueLiteSerializer(issue_queryset, many=True, fields=fields if fields else None).data + issue_dict = {str(issue["id"]): issue for issue in issues} + return Response(issue_dict, status=status.HTTP_200_OK) def create(self, request, slug, project_id): project = Project.objects.get(pk=project_id) diff --git a/apiserver/plane/app/views/module.py b/apiserver/plane/app/views/module.py index 3a9968bfd..a8a8655c3 100644 --- a/apiserver/plane/app/views/module.py +++ b/apiserver/plane/app/views/module.py @@ -324,9 +324,8 @@ class ModuleIssueViewSet(WebhookMixin, BaseViewSet): @method_decorator(gzip_page) def list(self, request, slug, project_id, module_id): + fields = [field for field in request.GET.get("fields", "").split(",") if field] order_by = request.GET.get("order_by", "created_at") - group_by = request.GET.get("group_by", False) - sub_group_by = request.GET.get("sub_group_by", False) filters = issue_filters(request.query_params, "GET") issues = ( Issue.issue_objects.filter(issue_module__module_id=module_id) @@ -360,24 +359,9 @@ class ModuleIssueViewSet(WebhookMixin, BaseViewSet): .values("count") ) ) - issues_data = IssueStateSerializer(issues, many=True).data - - if sub_group_by and sub_group_by == group_by: - return Response( - {"error": "Group by and sub group by cannot be same"}, - status=status.HTTP_400_BAD_REQUEST, - ) - - if group_by: - grouped_results = group_results(issues_data, group_by, sub_group_by) - return Response( - grouped_results, - status=status.HTTP_200_OK, - ) - - return Response( - issues_data, status=status.HTTP_200_OK - ) + issues = IssueStateSerializer(issues, many=True, fields=fields if fields else None).data + issue_dict = {str(issue["id"]): issue for issue in issues} + return Response(issue_dict, status=status.HTTP_200_OK) def create(self, request, slug, project_id, module_id): issues = request.data.get("issues", []) @@ -482,55 +466,6 @@ class ModuleIssueViewSet(WebhookMixin, BaseViewSet): return Response(status=status.HTTP_204_NO_CONTENT) -class ModuleIssueGroupedEndpoint(BaseAPIView): - - permission_classes = [ - ProjectEntityPermission, - ] - - def get(self, request, slug, project_id, module_id): - filters = issue_filters(request.query_params, "GET") - fields = [field for field in request.GET.get("fields", "").split(",") if field] - - issues = ( - Issue.issue_objects.filter(issue_module__module_id=module_id) - .annotate( - sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .annotate(bridge_id=F("issue_module__id")) - .filter(project_id=project_id) - .filter(workspace__slug=slug) - .select_related("project") - .select_related("workspace") - .select_related("state") - .select_related("parent") - .prefetch_related("assignees") - .prefetch_related("labels") - .filter(**filters) - .annotate( - link_count=IssueLink.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .annotate( - attachment_count=IssueAttachment.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - ) - - issues = IssueStateSerializer(issues, many=True, fields=fields if fields else None).data - issue_dict = {str(issue["id"]): issue for issue in issues} - return Response( - issue_dict, - status=status.HTTP_200_OK, - ) - class ModuleLinkViewSet(BaseViewSet): permission_classes = [ ProjectEntityPermission, diff --git a/apiserver/plane/app/views/view.py b/apiserver/plane/app/views/view.py index 56770a99d..eb76407b7 100644 --- a/apiserver/plane/app/views/view.py +++ b/apiserver/plane/app/views/view.py @@ -95,6 +95,7 @@ class GlobalViewIssuesViewSet(BaseViewSet): @method_decorator(gzip_page) def list(self, request, slug): filters = issue_filters(request.query_params, "GET") + fields = [field for field in request.GET.get("fields", "").split(",") if field] # Custom ordering for priority and state priority_order = ["urgent", "high", "medium", "low", "none"] @@ -177,73 +178,6 @@ class GlobalViewIssuesViewSet(BaseViewSet): ) else: issue_queryset = issue_queryset.order_by(order_by_param) - issues = IssueLiteSerializer(issue_queryset, many=True).data - - ## Grouping the results - group_by = request.GET.get("group_by", False) - sub_group_by = request.GET.get("sub_group_by", False) - if sub_group_by and sub_group_by == group_by: - return Response( - {"error": "Group by and sub group by cannot be same"}, - status=status.HTTP_400_BAD_REQUEST, - ) - - if group_by: - grouped_results = group_results(issues, group_by, sub_group_by) - return Response( - grouped_results, - status=status.HTTP_200_OK, - ) - - return Response(issues, status=status.HTTP_200_OK) - - -class GlobalViewIssuesGroupedEndpoint(BaseAPIView): - permission_classes = [ - WorkspaceEntityPermission, - ] - - def get(self, request, slug): - filters = issue_filters(request.query_params, "GET") - fields = [field for field in request.GET.get("fields", "").split(",") if field] - - issue_queryset = ( - 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") - ) - .filter(workspace__slug=self.kwargs.get("slug")) - .filter(project__project_projectmember__member=self.request.user) - .filter(**filters) - .select_related("project") - .select_related("workspace") - .select_related("state") - .select_related("parent") - .prefetch_related("assignees") - .prefetch_related("labels") - .prefetch_related( - Prefetch( - "issue_reactions", - queryset=IssueReaction.objects.select_related("actor"), - ) - ) - .annotate(cycle_id=F("issue_cycle__cycle_id")) - .annotate(module_id=F("issue_module__module_id")) - .annotate( - link_count=IssueLink.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .annotate( - attachment_count=IssueAttachment.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - ) issues = IssueLiteSerializer(issue_queryset, many=True, fields=fields if fields else None).data issue_dict = {str(issue["id"]): issue for issue in issues} @@ -252,6 +186,7 @@ class GlobalViewIssuesGroupedEndpoint(BaseAPIView): status=status.HTTP_200_OK, ) + class IssueViewViewSet(BaseViewSet): serializer_class = IssueViewSerializer model = IssueView diff --git a/apiserver/plane/app/views/workspace.py b/apiserver/plane/app/views/workspace.py index 5c5d0751c..108b89f21 100644 --- a/apiserver/plane/app/views/workspace.py +++ b/apiserver/plane/app/views/workspace.py @@ -1207,6 +1207,7 @@ class WorkspaceUserProfileIssuesEndpoint(BaseAPIView): ] def get(self, request, slug, user_id): + fields = [field for field in request.GET.get("fields", "").split(",") if field] filters = issue_filters(request.query_params, "GET") # Custom ordering for priority and state @@ -1308,75 +1309,11 @@ class WorkspaceUserProfileIssuesEndpoint(BaseAPIView): else: issue_queryset = issue_queryset.order_by(order_by_param) - issues = IssueLiteSerializer(issue_queryset, many=True).data - - ## Grouping the results - group_by = request.GET.get("group_by", False) - if group_by: - grouped_results = group_results(issues, group_by) - return Response( - grouped_results, - status=status.HTTP_200_OK, - ) - - return Response(issues, status=status.HTTP_200_OK) - - -class WorkspaceUserProfileIssuesGroupedEndpoint(BaseAPIView): - permission_classes = [ - WorkspaceViewerPermission, - ] - - def get(self, request, slug, user_id): - filters = issue_filters(request.query_params, "GET") - fields = [field for field in request.GET.get("fields", "").split(",") if field] - - issue_queryset = ( - Issue.issue_objects.filter( - Q(assignees__in=[user_id]) - | Q(created_by_id=user_id) - | Q(issue_subscribers__subscriber_id=user_id), - workspace__slug=slug, - project__project_projectmember__member=request.user, - ) - .filter(**filters) - .annotate( - sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .select_related("project", "workspace", "state", "parent") - .prefetch_related("assignees", "labels") - .prefetch_related( - Prefetch( - "issue_reactions", - queryset=IssueReaction.objects.select_related("actor"), - ) - ) - .order_by("-created_at") - .annotate( - link_count=IssueLink.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - .annotate( - attachment_count=IssueAttachment.objects.filter(issue=OuterRef("id")) - .order_by() - .annotate(count=Func(F("id"), function="Count")) - .values("count") - ) - ).distinct() - issues = IssueLiteSerializer( issue_queryset, many=True, fields=fields if fields else None ).data issue_dict = {str(issue["id"]): issue for issue in issues} - return Response( - issue_dict, - status=status.HTTP_200_OK, - ) + return Response(issue_dict, status=status.HTTP_200_OK) class WorkspaceLabelsEndpoint(BaseAPIView): diff --git a/web/components/core/modals/bulk-delete-issues-modal.tsx b/web/components/core/modals/bulk-delete-issues-modal.tsx index a70a722a2..4a80b1fe1 100644 --- a/web/components/core/modals/bulk-delete-issues-modal.tsx +++ b/web/components/core/modals/bulk-delete-issues-modal.tsx @@ -101,8 +101,8 @@ export const BulkDeleteIssuesModal: React.FC = (props) => { const filteredIssues: IIssue[] = query === "" - ? issues ?? [] - : issues?.filter( + ? Object.values(issues ?? {}) + : Object.values(issues ?? {})?.filter( (issue) => issue.name.toLowerCase().includes(query.toLowerCase()) || `${issue.project_detail.identifier}-${issue.sequence_id}`.toLowerCase().includes(query.toLowerCase()) diff --git a/web/components/inbox/modals/select-duplicate.tsx b/web/components/inbox/modals/select-duplicate.tsx index e746d0df8..9bd9fcb08 100644 --- a/web/components/inbox/modals/select-duplicate.tsx +++ b/web/components/inbox/modals/select-duplicate.tsx @@ -40,7 +40,7 @@ export const SelectDuplicateInboxIssueModal: React.FC = (props) => { ? () => issueService .getIssues(workspaceSlug as string, projectId as string) - .then((res) => res.filter((issue) => issue.id !== issueId)) + .then((res) => Object.values(res ?? {}).filter((issue) => issue.id !== issueId)) : null ); diff --git a/web/services/cycle.service.ts b/web/services/cycle.service.ts index 93dbd8635..c0adedde2 100644 --- a/web/services/cycle.service.ts +++ b/web/services/cycle.service.ts @@ -51,27 +51,12 @@ export class CycleService extends APIService { }); } - async getV3CycleIssues( - workspaceSlug: string, - projectId: string, - cycleId: string, - queries?: any - ): Promise { - return this.get(`/api/v3/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`, { - params: queries, - }) - .then((response) => response?.data) - .catch((error) => { - throw error?.response?.data; - }); - } - async getCycleIssuesWithParams( workspaceSlug: string, projectId: string, cycleId: string, queries?: any - ): Promise { + ): Promise { return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`, { params: queries, }) diff --git a/web/services/issue/issue.service.ts b/web/services/issue/issue.service.ts index 7b3ef0624..577f4c5a2 100644 --- a/web/services/issue/issue.service.ts +++ b/web/services/issue/issue.service.ts @@ -19,16 +19,8 @@ export class IssueService extends APIService { }); } - async getIssues(workspaceSlug: string, projectId: string): Promise { - return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/`) - .then((response) => response?.data) - .catch((error) => { - throw error?.response?.data; - }); - } - - async getV3Issues(workspaceSlug: string, projectId: string, queries?: any): Promise { - return this.get(`/api/v3/workspaces/${workspaceSlug}/projects/${projectId}/issues/`, { + async getIssues(workspaceSlug: string, projectId: string, queries?: any): Promise { + return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/`, { params: queries, }) .then((response) => response?.data) diff --git a/web/services/issue/issue_archive.service.ts b/web/services/issue/issue_archive.service.ts index a21a98fbc..3337f23ce 100644 --- a/web/services/issue/issue_archive.service.ts +++ b/web/services/issue/issue_archive.service.ts @@ -9,17 +9,7 @@ export class IssueArchiveService extends APIService { async getArchivedIssues(workspaceSlug: string, projectId: string, queries?: any): Promise { return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/`, { - params: queries, - }) - .then((response) => response?.data) - .catch((error) => { - throw error?.response?.data; - }); - } - - async getV3ArchivedIssues(workspaceSlug: string, projectId: string, queries?: any): Promise { - return this.get(`/api/v3/workspaces/${workspaceSlug}/projects/${projectId}/issues/`, { - params: { ...queries, archived: true }, + params: { ...queries }, }) .then((response) => response?.data) .catch((error) => { diff --git a/web/services/issue/issue_draft.service.tsx b/web/services/issue/issue_draft.service.tsx index 5634e3bfe..f5cbb4331 100644 --- a/web/services/issue/issue_draft.service.tsx +++ b/web/services/issue/issue_draft.service.tsx @@ -1,24 +1,15 @@ import { APIService } from "services/api.service"; // helpers import { API_BASE_URL } from "helpers/common.helper"; +import { IIssueResponse } from "store/issues/types"; export class IssueDraftService extends APIService { constructor() { super(API_BASE_URL); } - async getDraftIssues(workspaceSlug: string, projectId: string, params?: any): Promise { + async getDraftIssues(workspaceSlug: string, projectId: string, query?: any): Promise { return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/`, { - params, - }) - .then((response) => response?.data) - .catch((error) => { - throw error?.response; - }); - } - - async getV3DraftIssues(workspaceSlug: string, projectId: string, query?: any): Promise { - return this.get(`/api/v3/workspaces/${workspaceSlug}/projects/${projectId}/issues/?draft=true`, { params: { ...query }, }) .then((response) => response?.data) diff --git a/web/services/module.service.ts b/web/services/module.service.ts index aaac5f146..cbb76237f 100644 --- a/web/services/module.service.ts +++ b/web/services/module.service.ts @@ -63,21 +63,13 @@ export class ModuleService extends APIService { }); } - async getModuleIssues(workspaceSlug: string, projectId: string, moduleId: string): Promise { - return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-issues/`) - .then((response) => response?.data) - .catch((error) => { - throw error?.response?.data; - }); - } - - async getV3ModuleIssues( + async getModuleIssues( workspaceSlug: string, projectId: string, moduleId: string, queries?: any ): Promise { - return this.get(`/api/v3/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-issues/`, { + return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-issues/`, { params: queries, }) .then((response) => response?.data) diff --git a/web/services/user.service.ts b/web/services/user.service.ts index f5619a2f8..95231be26 100644 --- a/web/services/user.service.ts +++ b/web/services/user.service.ts @@ -152,16 +152,7 @@ export class UserService extends APIService { }); } - async getUserProfileIssues( - workspaceSlug: string, - userId: string, - params: any - ): Promise< - | { - [key: string]: IIssue[]; - } - | IIssue[] - > { + async getUserProfileIssues(workspaceSlug: string, userId: string, params: any): Promise { return this.get(`/api/workspaces/${workspaceSlug}/user-issues/${userId}/`, { params, }) @@ -171,16 +162,6 @@ export class UserService extends APIService { }); } - async getV3UserProfileIssues(workspaceSlug: string, userId: string, params: any): Promise { - return this.get(`/api/v3/workspaces/${workspaceSlug}/user-issues/${userId}/`, { - params, - }) - .then((response) => response?.data) - .catch((error) => { - throw error?.response?.data; - }); - } - async deactivateAccount() { return this.delete(`/api/users/me/`) .then((response) => response?.data) diff --git a/web/store/cycle/cycles.store.ts b/web/store/cycle/cycles.store.ts index 048326841..8e233c8f8 100644 --- a/web/store/cycle/cycles.store.ts +++ b/web/store/cycle/cycles.store.ts @@ -233,7 +233,7 @@ export class CycleStore implements ICycleStore { const _activeCycleIssues = { ...this.active_cycle_issues, - [cycleId]: _cycleIssues as IIssue[], + [cycleId]: Object.values(_cycleIssues) as IIssue[], }; runInAction(() => { diff --git a/web/store/issue/issue_draft.store.ts b/web/store/issue/issue_draft.store.ts index 76faacb7e..0aadcc430 100644 --- a/web/store/issue/issue_draft.store.ts +++ b/web/store/issue/issue_draft.store.ts @@ -39,7 +39,7 @@ export class DraftIssuesStore { const issues = Array.isArray(issuesResponse) ? { allIssues: issuesResponse } : issuesResponse; runInAction(() => { - this.issues = issues; + this.issues = Object.values(issues) as any; this.isIssuesLoading = false; }); } catch (error) { diff --git a/web/store/issues/global/issue.store.ts b/web/store/issues/global/issue.store.ts index c5a193dc6..b6f9177dd 100644 --- a/web/store/issues/global/issue.store.ts +++ b/web/store/issues/global/issue.store.ts @@ -159,7 +159,7 @@ export class GlobalIssuesStore extends IssueBaseStore implements IGlobalIssuesSt else if (this.currentUserIssueTab === "subscribed") params = params ? { ...params, subscriber: userId } : { subscriber: userId }; - const response = await this.userService.getV3UserProfileIssues(workspaceSlug, userId, params); + const response = await this.userService.getUserProfileIssues(workspaceSlug, userId, params); if (!this.currentUserIssueTab) return; diff --git a/web/store/issues/profile/issue.store.ts b/web/store/issues/profile/issue.store.ts index 96f3976e0..37b9f3085 100644 --- a/web/store/issues/profile/issue.store.ts +++ b/web/store/issues/profile/issue.store.ts @@ -173,7 +173,7 @@ export class ProfileIssuesStore extends IssueBaseStore implements IProfileIssues else if (this.currentUserIssueTab === "subscribed") params = params ? { ...params, subscriber: userId } : { subscriber: userId }; - const response = await this.userService.getV3UserProfileIssues(workspaceSlug, userId, params); + const response = await this.userService.getUserProfileIssues(workspaceSlug, userId, params); if (!this.currentUserIssueTab) return; diff --git a/web/store/issues/project-issues/archived/issue.store.ts b/web/store/issues/project-issues/archived/issue.store.ts index 6e1abab8e..69a397edd 100644 --- a/web/store/issues/project-issues/archived/issue.store.ts +++ b/web/store/issues/project-issues/archived/issue.store.ts @@ -100,7 +100,7 @@ export class ProjectArchivedIssuesStore extends IssueBaseStore implements IProje this.loader = loadType; const params = this.rootStore?.projectArchivedIssuesFilter?.appliedFilters; - const response = await this.archivedIssueService.getV3ArchivedIssues(workspaceSlug, projectId, params); + const response = await this.archivedIssueService.getArchivedIssues(workspaceSlug, projectId, params); const _issues = { ...this.issues, [projectId]: { ...response } }; diff --git a/web/store/issues/project-issues/cycle/issue.store.ts b/web/store/issues/project-issues/cycle/issue.store.ts index a82839b8d..341013ce4 100644 --- a/web/store/issues/project-issues/cycle/issue.store.ts +++ b/web/store/issues/project-issues/cycle/issue.store.ts @@ -168,7 +168,7 @@ export class CycleIssuesStore extends IssueBaseStore implements ICycleIssuesStor this.currentProjectId = projectId; const params = this.rootStore?.cycleIssuesFilter?.appliedFilters; - const response = await this.cycleService.getV3CycleIssues(workspaceSlug, projectId, cycleId, params); + const response = await this.cycleService.getCycleIssuesWithParams(workspaceSlug, projectId, cycleId, params); const _issues = { ...this.issues, [cycleId]: { ...response } }; diff --git a/web/store/issues/project-issues/draft/issue.store.ts b/web/store/issues/project-issues/draft/issue.store.ts index f3565c9e9..0333c066c 100644 --- a/web/store/issues/project-issues/draft/issue.store.ts +++ b/web/store/issues/project-issues/draft/issue.store.ts @@ -107,7 +107,7 @@ export class ProjectDraftIssuesStore extends IssueBaseStore implements IProjectD this.loader = loadType; const params = this.rootStore?.projectDraftIssuesFilter?.appliedFilters; - const response = await this.issueDraftService.getV3DraftIssues(workspaceSlug, projectId, params); + const response = await this.issueDraftService.getDraftIssues(workspaceSlug, projectId, params); const _issues = { ...this.issues, [projectId]: { ...response } }; diff --git a/web/store/issues/project-issues/module/issue.store.ts b/web/store/issues/project-issues/module/issue.store.ts index 2e78ae625..feaba7f56 100644 --- a/web/store/issues/project-issues/module/issue.store.ts +++ b/web/store/issues/project-issues/module/issue.store.ts @@ -166,7 +166,7 @@ export class ModuleIssuesStore extends IssueBaseStore implements IModuleIssuesSt this.loader = loadType; const params = this.rootStore?.moduleIssuesFilter?.appliedFilters; - const response = await this.moduleService.getV3ModuleIssues(workspaceSlug, projectId, moduleId, params); + const response = await this.moduleService.getModuleIssues(workspaceSlug, projectId, moduleId, params); const _issues = { ...this.issues, [moduleId]: { ...response } }; diff --git a/web/store/issues/project-issues/project-view/issue.store.ts b/web/store/issues/project-issues/project-view/issue.store.ts index a1dfb6d0b..c1f201be8 100644 --- a/web/store/issues/project-issues/project-view/issue.store.ts +++ b/web/store/issues/project-issues/project-view/issue.store.ts @@ -112,7 +112,7 @@ export class ViewIssuesStore extends IssueBaseStore implements IViewIssuesStore this.loader = loadType; const params = this.rootStore?.viewIssuesFilter?.appliedFilters; - const response = await this.issueService.getV3Issues(workspaceSlug, projectId, params); + const response = await this.issueService.getIssues(workspaceSlug, projectId, params); const _issues = { ...this.issues, [projectId]: { ...response } }; diff --git a/web/store/issues/project-issues/project/issue.store.ts b/web/store/issues/project-issues/project/issue.store.ts index 5e89ae712..e2c2b8ad6 100644 --- a/web/store/issues/project-issues/project/issue.store.ts +++ b/web/store/issues/project-issues/project/issue.store.ts @@ -112,7 +112,7 @@ export class ProjectIssuesStore extends IssueBaseStore implements IProjectIssues this.loader = loadType; const params = this.rootStore?.projectIssuesFilter?.appliedFilters; - const response = await this.issueService.getV3Issues(workspaceSlug, projectId, params); + const response = await this.issueService.getIssues(workspaceSlug, projectId, params); const _issues = { ...this.issues, [projectId]: { ...response } };