mirror of
https://github.com/makeplane/plane.git
synced 2026-07-12 21:40:18 +02:00
Merge branch 'uat' of github.com:makeplane/plane-ee into preview
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
from .relation import IssueRelationMutation
|
||||
from .comment import IssueCommentMutation
|
||||
from .comment import IssueCommentMutation
|
||||
from .sub_issue import SubIssueMutation
|
||||
@@ -6,7 +6,6 @@ from strawberry.permission import PermissionExtension
|
||||
# Third-party imports
|
||||
from asgiref.sync import sync_to_async
|
||||
|
||||
|
||||
# Module imports
|
||||
from plane.graphql.permissions.project import ProjectBasePermission
|
||||
from plane.db.models import Workspace, IssueRelation
|
||||
|
||||
94
apiserver/plane/graphql/mutations/issues/sub_issue.py
Normal file
94
apiserver/plane/graphql/mutations/issues/sub_issue.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from typing import Optional
|
||||
|
||||
# Strawberry imports
|
||||
import strawberry
|
||||
from strawberry.types import Info
|
||||
from strawberry.permission import PermissionExtension
|
||||
|
||||
# Third-party imports
|
||||
from asgiref.sync import sync_to_async
|
||||
|
||||
# Module imports
|
||||
from plane.graphql.permissions.project import ProjectMemberPermission
|
||||
from plane.db.models import Issue
|
||||
from plane.graphql.types.issue import IssuesType
|
||||
|
||||
|
||||
# create methods
|
||||
@sync_to_async
|
||||
def get_sub_issues(sub_issue_ids):
|
||||
return list(Issue.issue_objects.filter(id__in=sub_issue_ids))
|
||||
|
||||
|
||||
@sync_to_async
|
||||
def bulk_update_issues(issues, fields):
|
||||
Issue.objects.bulk_update(issues, fields, batch_size=10)
|
||||
|
||||
|
||||
# remove methods
|
||||
@sync_to_async
|
||||
def get_sub_issue_details(
|
||||
issueId: strawberry.ID, parentIssueId: strawberry.ID
|
||||
):
|
||||
return Issue.issue_objects.get(id=issueId, parent=parentIssueId)
|
||||
|
||||
|
||||
@sync_to_async
|
||||
def update_issue_parent(
|
||||
issue: IssuesType, parentIssueId: Optional[strawberry.ID] = None
|
||||
):
|
||||
issue.parent = parentIssueId
|
||||
issue.save()
|
||||
return True
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class SubIssueMutation:
|
||||
# adding issue relation
|
||||
@strawberry.mutation(
|
||||
extensions=[
|
||||
PermissionExtension(permissions=[ProjectMemberPermission()])
|
||||
]
|
||||
)
|
||||
async def createSubIssue(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
parentIssueId: strawberry.ID,
|
||||
subIssueIds: list[strawberry.ID],
|
||||
) -> bool:
|
||||
try:
|
||||
sub_issues = await get_sub_issues(subIssueIds)
|
||||
|
||||
for sub_issue in sub_issues:
|
||||
sub_issue.parent_id = parentIssueId
|
||||
|
||||
await bulk_update_issues(sub_issues, ["parent"])
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
# removing issue relation
|
||||
@strawberry.mutation(
|
||||
extensions=[
|
||||
PermissionExtension(permissions=[ProjectMemberPermission()])
|
||||
]
|
||||
)
|
||||
async def removeSubIssue(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
parentIssueId: strawberry.ID,
|
||||
subIssueId: strawberry.ID,
|
||||
) -> bool:
|
||||
try:
|
||||
sub_issue = await get_sub_issue_details(subIssueId, parentIssueId)
|
||||
if not sub_issue:
|
||||
return False
|
||||
|
||||
await update_issue_parent(sub_issue, None)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
@@ -352,36 +352,6 @@ class WorkspaceIssuesQuery:
|
||||
return paginate(results_object=workspace_issues, cursor=cursor)
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class SubIssuesQuery:
|
||||
@strawberry.field(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def sub_issues(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
issue: strawberry.ID,
|
||||
cursor: Optional[str] = None,
|
||||
) -> PaginatorResponse[IssuesType]:
|
||||
sub_issues = await sync_to_async(list)(
|
||||
Issue.issue_objects.filter(
|
||||
workspace__slug=slug,
|
||||
parent_id=issue,
|
||||
)
|
||||
.filter(
|
||||
project__project_projectmember__member=info.context.user,
|
||||
project__project_projectmember__is_active=True,
|
||||
)
|
||||
.select_related("workspace", "project", "state", "parent")
|
||||
.prefetch_related("assignees", "labels")
|
||||
.order_by("-created_at")
|
||||
)
|
||||
|
||||
return paginate(results_object=sub_issues, cursor=cursor)
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class IssueTypesTypeQuery:
|
||||
@strawberry.field(
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
from .relation import IssueRelationQuery
|
||||
from .search import IssuesSearchQuery
|
||||
from .search import IssuesSearchQuery
|
||||
from .sub_issue import SubIssuesQuery
|
||||
@@ -37,10 +37,11 @@ class IssuesSearchQuery:
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: Optional[strawberry.ID] = None,
|
||||
module: Optional[strawberry.ID] = None,
|
||||
cycle: Optional[strawberry.ID] = None,
|
||||
issue: Optional[strawberry.ID] = None,
|
||||
relation_type: Optional[bool] = False,
|
||||
module: Optional[strawberry.ID] = False,
|
||||
cycle: Optional[bool] = False,
|
||||
relationType: Optional[bool] = False,
|
||||
subIssues: Optional[bool] = False,
|
||||
search: Optional[str] = None,
|
||||
) -> list[IssueLiteType]:
|
||||
issue_queryset = Issue.issue_objects.filter(
|
||||
@@ -56,16 +57,16 @@ class IssuesSearchQuery:
|
||||
|
||||
# module issues
|
||||
if module:
|
||||
issue_queryset = issue_queryset.filter(
|
||||
issue_module__module_id=module
|
||||
issue_queryset = issue_queryset.exclude(
|
||||
issue_module__module=module
|
||||
)
|
||||
|
||||
# cycle issues
|
||||
if cycle:
|
||||
issue_queryset = issue_queryset.filter(issue_cycle__cycle_id=cycle)
|
||||
issue_queryset = issue_queryset.exclude(issue_cycle__isnull=False)
|
||||
|
||||
# issue relation issues
|
||||
if relation_type and issue:
|
||||
if relationType and issue:
|
||||
issue_queryset = issue_queryset.filter(
|
||||
~Q(pk=issue),
|
||||
~Q(
|
||||
@@ -78,6 +79,19 @@ class IssuesSearchQuery:
|
||||
),
|
||||
)
|
||||
|
||||
# sub issues
|
||||
if subIssues and issue:
|
||||
current_issue = await sync_to_async(Issue.issue_objects.get)(
|
||||
pk=issue
|
||||
)
|
||||
issue_queryset = issue_queryset.filter(
|
||||
Q(parent__isNull=True), ~Q(parent=issue)
|
||||
)
|
||||
if current_issue.parent:
|
||||
issue_queryset = issue_queryset.filter(
|
||||
~Q(parent=current_issue.parent)
|
||||
)
|
||||
|
||||
# apply search filter
|
||||
q = Q()
|
||||
if search:
|
||||
|
||||
54
apiserver/plane/graphql/queries/issues/sub_issue.py
Normal file
54
apiserver/plane/graphql/queries/issues/sub_issue.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# Third-Party Imports
|
||||
import strawberry
|
||||
|
||||
# Python Standard Library Imports
|
||||
from asgiref.sync import sync_to_async
|
||||
from typing import Optional
|
||||
|
||||
# Strawberry Imports
|
||||
from strawberry.types import Info
|
||||
from strawberry.permission import PermissionExtension
|
||||
|
||||
|
||||
# Module Imports
|
||||
from plane.graphql.types.issue import (
|
||||
IssuesType,
|
||||
)
|
||||
from plane.db.models import (
|
||||
Issue,
|
||||
)
|
||||
|
||||
|
||||
from plane.graphql.permissions.project import ProjectBasePermission
|
||||
from plane.graphql.types.paginator import PaginatorResponse
|
||||
from plane.graphql.utils.paginator import paginate
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class SubIssuesQuery:
|
||||
@strawberry.field(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def sub_issues(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
issue: strawberry.ID,
|
||||
cursor: Optional[str] = None,
|
||||
) -> PaginatorResponse[IssuesType]:
|
||||
sub_issues = await sync_to_async(list)(
|
||||
Issue.issue_objects.filter(
|
||||
workspace__slug=slug,
|
||||
parent_id=issue,
|
||||
)
|
||||
.filter(
|
||||
project__project_projectmember__member=info.context.user,
|
||||
project__project_projectmember__is_active=True,
|
||||
)
|
||||
.select_related("workspace", "project", "state", "parent")
|
||||
.prefetch_related("assignees", "labels")
|
||||
.order_by("-created_at")
|
||||
)
|
||||
|
||||
return paginate(results_object=sub_issues, cursor=cursor)
|
||||
@@ -22,7 +22,6 @@ from .queries.issue import (
|
||||
IssueUserPropertyQuery,
|
||||
IssuePropertiesActivityQuery,
|
||||
IssueCommentActivityQuery,
|
||||
SubIssuesQuery,
|
||||
IssueTypesTypeQuery,
|
||||
)
|
||||
from .queries.page import PageQuery, UserPageQuery
|
||||
@@ -42,7 +41,11 @@ from .queries.search import GlobalSearchQuery
|
||||
from .queries.attachment import IssueAttachmentQuery
|
||||
from .queries.link import IssueLinkQuery
|
||||
from .queries.estimate import EstimatePointQuery
|
||||
from .queries.issues import IssueRelationQuery, IssuesSearchQuery
|
||||
from .queries.issues import (
|
||||
IssueRelationQuery,
|
||||
IssuesSearchQuery,
|
||||
SubIssuesQuery,
|
||||
)
|
||||
|
||||
# mutations
|
||||
from .mutations.workspace import WorkspaceMutation, WorkspaceInviteMutation
|
||||
@@ -72,7 +75,11 @@ from .mutations.module import (
|
||||
)
|
||||
from .mutations.link import IssueLinkMutation
|
||||
from .mutations.favorite import UserFavoriteMutation
|
||||
from .mutations.issues import IssueRelationMutation, IssueCommentMutation
|
||||
from .mutations.issues import (
|
||||
IssueRelationMutation,
|
||||
IssueCommentMutation,
|
||||
SubIssueMutation,
|
||||
)
|
||||
|
||||
|
||||
# combined query class for all
|
||||
@@ -147,6 +154,7 @@ class Mutation(
|
||||
ModuleIssueUserPropertyMutation,
|
||||
IssueRelationMutation,
|
||||
IssueCommentMutation,
|
||||
SubIssueMutation,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user