[MOBIL-1096] dev: Implement intake search functionality #3837

This commit is contained in:
guru_sainath
2025-08-08 00:50:19 +05:30
committed by GitHub
parent 95b791ed93
commit c7c66fec2d
5 changed files with 128 additions and 2 deletions

View File

@@ -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,
)

View File

@@ -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

View File

@@ -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,

View 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)

View File

@@ -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