mirror of
https://github.com/makeplane/plane.git
synced 2026-07-13 14:01:45 +02:00
[MOBIL-1096] dev: Implement intake search functionality #3837
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# Python imports
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
# Third Party Imports
|
||||
@@ -212,6 +213,7 @@ def get_intake_work_items(
|
||||
filters: Optional[JSON] = {},
|
||||
orderBy: Optional[str] = "-created_at",
|
||||
is_snoozed_work_items_required: Optional[bool] = False,
|
||||
search: Optional[str] = None,
|
||||
):
|
||||
base_query = intake_work_item_base_query(
|
||||
workspace_slug=workspace_slug, project_id=project_id, user_id=user_id
|
||||
@@ -226,6 +228,18 @@ def get_intake_work_items(
|
||||
| Q(snoozed_till__isnull=True)
|
||||
)
|
||||
|
||||
if search:
|
||||
q = Q()
|
||||
fields = ["issue__name", "issue__sequence_id", "issue__project__identifier"]
|
||||
for field in fields:
|
||||
if field == "issue__sequence_id":
|
||||
sequences = re.findall(r"\b\d+\b", search)
|
||||
for sequence_id in sequences:
|
||||
q |= Q(**{"issue__sequence_id": sequence_id})
|
||||
else:
|
||||
q |= Q(**{f"{field}__icontains": search})
|
||||
base_query = base_query.filter(q)
|
||||
|
||||
intakes = (
|
||||
base_query.filter(**filters)
|
||||
.select_related("workspace", "project", "issue")
|
||||
@@ -244,6 +258,7 @@ def get_intake_work_items_async(
|
||||
filters: Optional[JSON] = {},
|
||||
orderBy: Optional[str] = "-created_at",
|
||||
is_snoozed_work_items_required: Optional[bool] = False,
|
||||
search: Optional[str] = None,
|
||||
):
|
||||
return get_intake_work_items(
|
||||
workspace_slug=workspace_slug,
|
||||
@@ -252,6 +267,7 @@ def get_intake_work_items_async(
|
||||
filters=filters,
|
||||
orderBy=orderBy,
|
||||
is_snoozed_work_items_required=is_snoozed_work_items_required,
|
||||
search=search,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -3,3 +3,4 @@ from .attachment import IntakeWorkItemAttachmentQuery
|
||||
from .base import IntakeCountQuery, IntakeWorkItemQuery
|
||||
from .comment import IntakeWorkItemCommentQuery
|
||||
from .comment_reaction import IntakeWorkItemCommentReactionQuery
|
||||
from .search import IntakeSearchQuery
|
||||
|
||||
@@ -61,9 +61,26 @@ class IntakeCountQuery:
|
||||
workspace_slug=workspace_slug, project_id=project_id
|
||||
)
|
||||
|
||||
current_user_role = None
|
||||
project_member = await get_project_member(
|
||||
workspace_slug=workspace_slug, project_id=project_id, user_id=user_id
|
||||
workspace_slug=workspace_slug,
|
||||
project_id=project_id,
|
||||
user_id=user_id,
|
||||
raise_exception=False,
|
||||
)
|
||||
if not project_member:
|
||||
project_teamspace_filter = await project_member_filter_via_teamspaces_async(
|
||||
user_id=user_id,
|
||||
workspace_slug=workspace_slug,
|
||||
)
|
||||
teamspace_project_ids = project_teamspace_filter.teamspace_project_ids
|
||||
if project_id not in teamspace_project_ids:
|
||||
message = "You are not allowed to access this project"
|
||||
error_extensions = {"code": "FORBIDDEN", "statusCode": 403}
|
||||
raise GraphQLError(message, extensions=error_extensions)
|
||||
current_user_role = Roles.MEMBER.value
|
||||
else:
|
||||
current_user_role = project_member.role
|
||||
|
||||
filters = intake_filters(filters)
|
||||
|
||||
@@ -83,7 +100,7 @@ class IntakeCountQuery:
|
||||
is_snoozed_work_items_required = True
|
||||
|
||||
intake_work_items = await get_intake_work_items_async(
|
||||
user_id=user_id if project_member.role == Roles.GUEST.value else None,
|
||||
user_id=user_id if current_user_role == Roles.GUEST.value else None,
|
||||
workspace_slug=workspace_slug,
|
||||
project_id=project_id,
|
||||
filters=filters,
|
||||
|
||||
90
apps/api/plane/graphql/queries/intake/search.py
Normal file
90
apps/api/plane/graphql/queries/intake/search.py
Normal file
@@ -0,0 +1,90 @@
|
||||
# Python imports
|
||||
from typing import Optional
|
||||
|
||||
# Third-Party Imports
|
||||
import strawberry
|
||||
|
||||
# Strawberry Imports
|
||||
from strawberry.exceptions import GraphQLError
|
||||
from strawberry.permission import PermissionExtension
|
||||
from strawberry.types import Info
|
||||
|
||||
# Module Imports
|
||||
from plane.graphql.helpers import (
|
||||
get_intake_work_items_async,
|
||||
get_project,
|
||||
get_project_member,
|
||||
get_workspace,
|
||||
is_project_intakes_enabled_async,
|
||||
)
|
||||
from plane.graphql.helpers.teamspace import project_member_filter_via_teamspaces_async
|
||||
from plane.graphql.permissions.workspace import WorkspaceBasePermission
|
||||
from plane.graphql.types.intake.base import IntakeWorkItemType
|
||||
from plane.graphql.types.paginator import PaginatorResponse
|
||||
from plane.graphql.utils.paginator import paginate
|
||||
from plane.graphql.utils.roles import Roles
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class IntakeSearchQuery:
|
||||
@strawberry.field(
|
||||
extensions=[PermissionExtension(permissions=[WorkspaceBasePermission()])]
|
||||
)
|
||||
|
||||
# getting issue relation issues
|
||||
async def intake_search(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: str,
|
||||
search: Optional[str] = None,
|
||||
cursor: Optional[str] = None,
|
||||
) -> PaginatorResponse[IntakeWorkItemType]:
|
||||
user = info.context.user
|
||||
user_id = str(user.id)
|
||||
|
||||
# get the workspace
|
||||
workspace = await get_workspace(workspace_slug=slug)
|
||||
workspace_slug = workspace.slug
|
||||
|
||||
# get the project
|
||||
project_details = await get_project(
|
||||
workspace_slug=workspace_slug, project_id=project
|
||||
)
|
||||
project_id = str(project_details.id)
|
||||
|
||||
await is_project_intakes_enabled_async(
|
||||
workspace_slug=workspace_slug, project_id=project_id
|
||||
)
|
||||
|
||||
current_user_role = None
|
||||
project_member = await get_project_member(
|
||||
workspace_slug=workspace_slug,
|
||||
project_id=project_id,
|
||||
user_id=user_id,
|
||||
raise_exception=False,
|
||||
)
|
||||
if not project_member:
|
||||
project_teamspace_filter = await project_member_filter_via_teamspaces_async(
|
||||
user_id=user_id,
|
||||
workspace_slug=workspace_slug,
|
||||
)
|
||||
teamspace_project_ids = project_teamspace_filter.teamspace_project_ids
|
||||
if project_id not in teamspace_project_ids:
|
||||
message = "You are not allowed to access this project"
|
||||
error_extensions = {"code": "FORBIDDEN", "statusCode": 403}
|
||||
raise GraphQLError(message, extensions=error_extensions)
|
||||
current_user_role = Roles.MEMBER.value
|
||||
else:
|
||||
current_user_role = project_member.role
|
||||
|
||||
# get the intake work items
|
||||
intake_work_items = await get_intake_work_items_async(
|
||||
user_id=user_id if current_user_role == Roles.GUEST.value else None,
|
||||
workspace_slug=workspace_slug,
|
||||
project_id=project_id,
|
||||
is_snoozed_work_items_required=False,
|
||||
search=search,
|
||||
)
|
||||
|
||||
return paginate(results_object=intake_work_items, cursor=cursor)
|
||||
@@ -111,6 +111,7 @@ from .queries.intake import (
|
||||
IntakeWorkItemCommentQuery,
|
||||
IntakeWorkItemCommentReactionQuery,
|
||||
IntakeWorkItemQuery,
|
||||
IntakeSearchQuery,
|
||||
)
|
||||
from .queries.issue import (
|
||||
IssueCommentActivityQuery,
|
||||
@@ -283,6 +284,7 @@ class Query(
|
||||
IntakeWorkItemCommentQuery,
|
||||
IntakeWorkItemCommentReactionQuery,
|
||||
IntakeWorkItemAttachmentQuery,
|
||||
IntakeSearchQuery,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user