diff --git a/apiserver/plane/app/urls/issue.py b/apiserver/plane/app/urls/issue.py index 910eb91078..564725e839 100644 --- a/apiserver/plane/app/urls/issue.py +++ b/apiserver/plane/app/urls/issue.py @@ -42,7 +42,7 @@ urlpatterns = [ ), # updated v2 paginated issues path( - "workspaces//v2/issues/", + "workspaces//projects//v2/issues/", IssuePaginatedViewSet.as_view({"get": "list"}), name="project-issues-paginated", ), diff --git a/apiserver/plane/app/views/issue/base.py b/apiserver/plane/app/views/issue/base.py index 8adc5a8420..eca14018ff 100644 --- a/apiserver/plane/app/views/issue/base.py +++ b/apiserver/plane/app/views/issue/base.py @@ -741,17 +741,12 @@ class DeletedIssuesListViewSet(BaseAPIView): class IssuePaginatedViewSet(BaseViewSet): def get_queryset(self): workspace_slug = self.kwargs.get("slug") - - # getting the project_id from the request params - project_id = self.request.GET.get("project_id", None) + project_id = self.kwargs.get("project_id") issue_queryset = Issue.issue_objects.filter( - workspace__slug=workspace_slug + workspace__slug=workspace_slug, project_id=project_id ) - if project_id: - issue_queryset = issue_queryset.filter(project_id=project_id) - return ( issue_queryset.select_related( "workspace", "project", "state", "parent" @@ -793,8 +788,8 @@ class IssuePaginatedViewSet(BaseViewSet): return paginated_data - def list(self, request, slug): - project_id = self.request.GET.get("project_id", None) + @allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST]) + def list(self, request, slug, project_id): cursor = request.GET.get("cursor", None) is_description_required = request.GET.get("description", False) updated_at = request.GET.get("updated_at__gt", None) @@ -833,14 +828,26 @@ class IssuePaginatedViewSet(BaseViewSet): required_fields.append("description_html") # querying issues - base_queryset = Issue.issue_objects.filter(workspace__slug=slug) - - if project_id: - base_queryset = base_queryset.filter(project_id=project_id) + base_queryset = Issue.issue_objects.filter( + workspace__slug=slug, project_id=project_id + ) base_queryset = base_queryset.order_by("updated_at") queryset = self.get_queryset().order_by("updated_at") + # validation for guest user + project = Project.objects.get(pk=project_id, workspace__slug=slug) + project_member = ProjectMember.objects.filter( + workspace__slug=slug, + project_id=project_id, + member=request.user, + role=5, + is_active=True, + ) + if project_member.exists() and not project.guest_view_all_features: + base_queryset = base_queryset.filter(created_by=request.user) + queryset = queryset.filter(created_by=request.user) + # filtering issues by greater then updated_at given by the user if updated_at: base_queryset = base_queryset.filter(updated_at__gt=updated_at) diff --git a/packages/ui/src/dropdowns/custom-search-select.tsx b/packages/ui/src/dropdowns/custom-search-select.tsx index 81d33df6ea..7842f1531d 100644 --- a/packages/ui/src/dropdowns/custom-search-select.tsx +++ b/packages/ui/src/dropdowns/custom-search-select.tsx @@ -1,7 +1,7 @@ import React, { useRef, useState } from "react"; import { usePopper } from "react-popper"; import { Combobox } from "@headlessui/react"; -import { Check, ChevronDown, Search } from "lucide-react"; +import { Check, ChevronDown, Info, Search } from "lucide-react"; import { createPortal } from "react-dom"; // plane helpers import { useOutsideClickDetector } from "@plane/helpers"; @@ -11,6 +11,8 @@ import { useDropdownKeyDown } from "../hooks/use-dropdown-key-down"; import { cn } from "../../helpers"; // types import { ICustomSearchSelectProps } from "./helper"; +// local components +import { Tooltip } from "../tooltip"; export const CustomSearchSelect = (props: ICustomSearchSelectProps) => { const { @@ -95,11 +97,10 @@ export const CustomSearchSelect = (props: ICustomSearchSelectProps) => {