mirror of
https://github.com/makeplane/plane
synced 2025-08-07 19:59:33 +00:00
[MOBIL-141] chore: added project and user details in inbox (#947)
* chore: added project and user details in inbox * chore: project detail * chore: cycle and module user properties queries and mutation * chore: typo in mutation * chore: created prjects in your work
This commit is contained in:
@@ -20,7 +20,13 @@ from plane.graphql.permissions.project import (
|
||||
ProjectMemberPermission,
|
||||
ProjectBasePermission,
|
||||
)
|
||||
from plane.db.models import CycleIssue, Cycle, UserFavorite
|
||||
from plane.db.models import (
|
||||
CycleIssue,
|
||||
Cycle,
|
||||
UserFavorite,
|
||||
CycleUserProperties,
|
||||
)
|
||||
from plane.graphql.types.cycle import CycleUserPropertyType
|
||||
from plane.graphql.bgtasks.issue_activity_task import issue_activity
|
||||
|
||||
|
||||
@@ -160,7 +166,6 @@ class CycleIssueMutation:
|
||||
|
||||
@strawberry.type
|
||||
class CycleFavoriteMutation:
|
||||
|
||||
@strawberry.mutation(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
@@ -199,3 +204,34 @@ class CycleFavoriteMutation:
|
||||
await sync_to_async(cycle_favorite.delete)()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class CycleIssueUserPropertyMutation:
|
||||
@strawberry.mutation(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def updateCycleUserProperties(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
cycle: strawberry.ID,
|
||||
filters: JSON,
|
||||
display_filters: JSON,
|
||||
display_properties: JSON,
|
||||
) -> CycleUserPropertyType:
|
||||
cycle_issue_properties = await sync_to_async(
|
||||
CycleUserProperties.objects.get
|
||||
)(
|
||||
workspace__slug=slug,
|
||||
project_id=project,
|
||||
cycle_id=cycle,
|
||||
user=info.context.user,
|
||||
)
|
||||
cycle_issue_properties.filters = filters
|
||||
cycle_issue_properties.display_filters = display_filters
|
||||
cycle_issue_properties.display_properties = display_properties
|
||||
|
||||
await sync_to_async(cycle_issue_properties.save)()
|
||||
return cycle_issue_properties
|
||||
|
||||
@@ -18,7 +18,13 @@ from plane.graphql.permissions.project import (
|
||||
ProjectMemberPermission,
|
||||
ProjectBasePermission,
|
||||
)
|
||||
from plane.db.models import Project, ModuleIssue, UserFavorite
|
||||
from plane.db.models import (
|
||||
Project,
|
||||
ModuleIssue,
|
||||
UserFavorite,
|
||||
ModuleUserProperties,
|
||||
)
|
||||
from plane.graphql.types.module import ModuleUserPropertyType
|
||||
from plane.graphql.bgtasks.issue_activity_task import issue_activity
|
||||
|
||||
|
||||
@@ -115,7 +121,6 @@ class ModuleIssueMutation:
|
||||
|
||||
@strawberry.type
|
||||
class ModuleFavoriteMutation:
|
||||
|
||||
@strawberry.mutation(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
@@ -154,3 +159,34 @@ class ModuleFavoriteMutation:
|
||||
await sync_to_async(module_favorite.delete)()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class ModuleIssueUserPropertyMutation:
|
||||
@strawberry.mutation(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def updateModuleUserProperties(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
module: strawberry.ID,
|
||||
filters: JSON,
|
||||
display_filters: JSON,
|
||||
display_properties: JSON,
|
||||
) -> ModuleUserPropertyType:
|
||||
module_issue_properties = await sync_to_async(
|
||||
ModuleUserProperties.objects.get
|
||||
)(
|
||||
workspace__slug=slug,
|
||||
project_id=project,
|
||||
module_id=module,
|
||||
user=info.context.user,
|
||||
)
|
||||
module_issue_properties.filters = filters
|
||||
module_issue_properties.display_filters = display_filters
|
||||
module_issue_properties.display_properties = display_properties
|
||||
|
||||
await sync_to_async(module_issue_properties.save)()
|
||||
return module_issue_properties
|
||||
|
||||
@@ -17,8 +17,8 @@ from strawberry.scalars import JSON
|
||||
from strawberry.permission import PermissionExtension
|
||||
|
||||
# Module Imports
|
||||
from plane.db.models import Cycle, Issue
|
||||
from plane.graphql.types.cycle import CycleType
|
||||
from plane.db.models import Cycle, Issue, CycleUserProperties
|
||||
from plane.graphql.types.cycle import CycleType, CycleUserPropertyType
|
||||
from plane.graphql.types.issue import (
|
||||
IssuesInformationType,
|
||||
IssuesInformationObjectType,
|
||||
@@ -84,6 +84,34 @@ class CycleQuery:
|
||||
return cycle
|
||||
|
||||
|
||||
# cycle issue user properties
|
||||
@strawberry.type
|
||||
class CycleIssueUserPropertyQuery:
|
||||
@strawberry.field(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def cycleIssueUserProperties(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
cycle: strawberry.ID,
|
||||
) -> CycleUserPropertyType:
|
||||
cycle_issue_property = await sync_to_async(
|
||||
lambda: CycleUserProperties.objects.filter(
|
||||
workspace__slug=slug, project_id=project, cycle_id=cycle
|
||||
)
|
||||
.filter(
|
||||
project__project_projectmember__member=info.context.user,
|
||||
project__project_projectmember__is_active=True,
|
||||
)
|
||||
.order_by("-created_at")
|
||||
.first()
|
||||
)()
|
||||
|
||||
return cycle_issue_property
|
||||
|
||||
|
||||
# cycle issues information query
|
||||
@strawberry.type
|
||||
class CycleIssuesInformationQuery:
|
||||
|
||||
@@ -364,16 +364,13 @@ class SubIssuesQuery:
|
||||
@strawberry.type
|
||||
class IssueTypesTypeQuery:
|
||||
@strawberry.field(
|
||||
extensions=[PermissionExtension(permissions=[WorkspaceBasePermission()])]
|
||||
extensions=[
|
||||
PermissionExtension(permissions=[WorkspaceBasePermission()])
|
||||
]
|
||||
)
|
||||
async def issueTypes(
|
||||
self, info: Info, slug: str
|
||||
) -> list[IssueTypesType]:
|
||||
async def issueTypes(self, info: Info, slug: str) -> list[IssueTypesType]:
|
||||
issue_types = await sync_to_async(list)(
|
||||
IssueType.objects.filter(
|
||||
workspace__slug=slug
|
||||
)
|
||||
.distinct()
|
||||
IssueType.objects.filter(workspace__slug=slug).distinct()
|
||||
)
|
||||
|
||||
return issue_types
|
||||
|
||||
@@ -13,8 +13,8 @@ from strawberry.scalars import JSON
|
||||
from strawberry.permission import PermissionExtension
|
||||
|
||||
# Module Imports
|
||||
from plane.db.models import Module, Issue
|
||||
from plane.graphql.types.module import ModuleType
|
||||
from plane.db.models import Module, Issue, ModuleUserProperties
|
||||
from plane.graphql.types.module import ModuleType, ModuleUserPropertyType
|
||||
from plane.graphql.types.issue import (
|
||||
IssuesInformationType,
|
||||
IssuesInformationObjectType,
|
||||
@@ -93,6 +93,34 @@ class ModuleQuery:
|
||||
return modules
|
||||
|
||||
|
||||
# module issue user properties
|
||||
@strawberry.type
|
||||
class ModuleIssueUserPropertyQuery:
|
||||
@strawberry.field(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def moduleIssueUserProperties(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
module: strawberry.ID,
|
||||
) -> ModuleUserPropertyType:
|
||||
module_issue_property = await sync_to_async(
|
||||
lambda: ModuleUserProperties.objects.filter(
|
||||
workspace__slug=slug, project_id=project, module_id=module
|
||||
)
|
||||
.filter(
|
||||
project__project_projectmember__member=info.context.user,
|
||||
project__project_projectmember__is_active=True,
|
||||
)
|
||||
.order_by("-created_at")
|
||||
.first()
|
||||
)()
|
||||
|
||||
return module_issue_property
|
||||
|
||||
|
||||
# module issues information query
|
||||
@strawberry.type
|
||||
class ModuleIssuesInformationQuery:
|
||||
|
||||
@@ -28,7 +28,6 @@ from typing import Optional, List
|
||||
|
||||
@strawberry.type
|
||||
class NotificationQuery:
|
||||
|
||||
@strawberry.field(
|
||||
extensions=[
|
||||
PermissionExtension(permissions=[WorkspaceBasePermission()])
|
||||
|
||||
@@ -71,6 +71,50 @@ class ProjectQuery:
|
||||
|
||||
return paginate(results_object=project, cursor=cursor)
|
||||
|
||||
@strawberry.field(
|
||||
extensions=[
|
||||
PermissionExtension(permissions=[WorkspaceBasePermission()])
|
||||
]
|
||||
)
|
||||
async def project(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
) -> Optional[ProjectType]:
|
||||
def get_project() -> Optional[ProjectType]:
|
||||
return (
|
||||
Project.objects.filter(
|
||||
workspace__slug=slug,
|
||||
pk=project,
|
||||
archived_at__isnull=True,
|
||||
)
|
||||
.annotate(
|
||||
is_favorite=Exists(
|
||||
UserFavorite.objects.filter(
|
||||
user=info.context.user,
|
||||
entity_identifier=OuterRef("pk"),
|
||||
entity_type="project",
|
||||
project_id=OuterRef("pk"),
|
||||
)
|
||||
)
|
||||
)
|
||||
.annotate(
|
||||
is_member=Exists(
|
||||
ProjectMember.objects.filter(
|
||||
member=info.context.user,
|
||||
project_id=OuterRef("pk"),
|
||||
workspace__slug=slug,
|
||||
is_active=True,
|
||||
)
|
||||
)
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
project = await sync_to_async(get_project)()
|
||||
return project
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class ProjectMembersQuery:
|
||||
|
||||
@@ -158,7 +158,8 @@ class YourWorkQuery:
|
||||
projects = await sync_to_async(list)(
|
||||
Project.objects.filter(workspace__slug=slug)
|
||||
.filter(
|
||||
Q(
|
||||
Q(created_by=info.context.user)
|
||||
& Q(
|
||||
project_projectmember__member=info.context.user,
|
||||
project_projectmember__is_active=True,
|
||||
)
|
||||
|
||||
@@ -30,11 +30,13 @@ from .queries.cycle import (
|
||||
CycleQuery,
|
||||
CycleIssuesInformationQuery,
|
||||
CycleIssueQuery,
|
||||
CycleIssueUserPropertyQuery,
|
||||
)
|
||||
from .queries.module import (
|
||||
ModuleQuery,
|
||||
ModuleIssuesInformationQuery,
|
||||
ModuleIssueQuery,
|
||||
ModuleIssueUserPropertyQuery,
|
||||
)
|
||||
from .queries.search import ProjectSearchQuery
|
||||
from .queries.attachment import IssueAttachmentQuery
|
||||
@@ -52,13 +54,21 @@ from .mutations.issue import (
|
||||
IssueMutation,
|
||||
IssueUserPropertyMutation,
|
||||
IssueAttachmentMutation,
|
||||
IssueSubscriptionMutation
|
||||
IssueSubscriptionMutation,
|
||||
)
|
||||
from .mutations.notification import NotificationMutation
|
||||
from .mutations.user import ProfileMutation
|
||||
from .mutations.page import PageFavoriteMutation
|
||||
from .mutations.cycle import CycleIssueMutation, CycleFavoriteMutation
|
||||
from .mutations.module import ModuleIssueMutation, ModuleFavoriteMutation
|
||||
from .mutations.cycle import (
|
||||
CycleIssueMutation,
|
||||
CycleFavoriteMutation,
|
||||
CycleIssueUserPropertyMutation,
|
||||
)
|
||||
from .mutations.module import (
|
||||
ModuleIssueMutation,
|
||||
ModuleFavoriteMutation,
|
||||
ModuleIssueUserPropertyMutation,
|
||||
)
|
||||
from .mutations.link import IssueLinkMutation
|
||||
from .mutations.favorite import UserFavoriteMutation
|
||||
|
||||
@@ -102,6 +112,8 @@ class Query(
|
||||
IssueTypesTypeQuery,
|
||||
EstimatePointQuery,
|
||||
UserPageQuery,
|
||||
CycleIssueUserPropertyQuery,
|
||||
ModuleIssueUserPropertyQuery,
|
||||
):
|
||||
pass
|
||||
|
||||
@@ -127,6 +139,8 @@ class Mutation(
|
||||
CycleFavoriteMutation,
|
||||
ModuleFavoriteMutation,
|
||||
UserFavoriteMutation,
|
||||
CycleIssueUserPropertyMutation,
|
||||
ModuleIssueUserPropertyMutation,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ from asgiref.sync import sync_to_async
|
||||
|
||||
|
||||
# Module Imports
|
||||
from plane.db.models import Cycle, Issue
|
||||
from plane.db.models import Cycle, Issue, CycleUserProperties
|
||||
from plane.graphql.types.users import UserType
|
||||
|
||||
|
||||
@@ -83,3 +83,31 @@ class CycleType:
|
||||
.count()
|
||||
)()
|
||||
return issue_assignees_count
|
||||
|
||||
|
||||
@strawberry_django.type(CycleUserProperties)
|
||||
class CycleUserPropertyType:
|
||||
display_filters: JSON
|
||||
display_properties: JSON
|
||||
filters: JSON
|
||||
id: strawberry.ID
|
||||
user: strawberry.ID
|
||||
workspace: strawberry.ID
|
||||
project: strawberry.ID
|
||||
cycle: strawberry.ID
|
||||
|
||||
@strawberry.field
|
||||
def user(self) -> int:
|
||||
return self.user_id
|
||||
|
||||
@strawberry.field
|
||||
def workspace(self) -> int:
|
||||
return self.workspace_id
|
||||
|
||||
@strawberry.field
|
||||
def project(self) -> int:
|
||||
return self.project_id
|
||||
|
||||
@strawberry.field
|
||||
def cycle(self) -> int:
|
||||
return self.cycle_id
|
||||
|
||||
@@ -9,7 +9,7 @@ from strawberry.types import Info
|
||||
from strawberry.scalars import JSON
|
||||
|
||||
# Module Imports
|
||||
from plane.db.models import Module, Issue
|
||||
from plane.db.models import Module, Issue, ModuleUserProperties
|
||||
from plane.graphql.types.users import UserType
|
||||
|
||||
# Third-party library imports
|
||||
@@ -85,3 +85,31 @@ class ModuleType:
|
||||
.count()
|
||||
)()
|
||||
return issue_assignees_count
|
||||
|
||||
|
||||
@strawberry_django.type(ModuleUserProperties)
|
||||
class ModuleUserPropertyType:
|
||||
display_filters: JSON
|
||||
display_properties: JSON
|
||||
filters: JSON
|
||||
id: strawberry.ID
|
||||
user: strawberry.ID
|
||||
workspace: strawberry.ID
|
||||
project: strawberry.ID
|
||||
module: strawberry.ID
|
||||
|
||||
@strawberry.field
|
||||
def user(self) -> int:
|
||||
return self.user_id
|
||||
|
||||
@strawberry.field
|
||||
def workspace(self) -> int:
|
||||
return self.workspace_id
|
||||
|
||||
@strawberry.field
|
||||
def project(self) -> int:
|
||||
return self.project_id
|
||||
|
||||
@strawberry.field
|
||||
def module(self) -> int:
|
||||
return self.module_id
|
||||
|
||||
@@ -9,6 +9,8 @@ from strawberry.scalars import JSON
|
||||
|
||||
# Module imports
|
||||
from plane.db.models import Notification
|
||||
from plane.graphql.types.users import UserType
|
||||
from plane.graphql.types.project import ProjectType
|
||||
|
||||
|
||||
@strawberry_django.type(Notification)
|
||||
@@ -19,7 +21,7 @@ class NotificationType:
|
||||
message_html = Optional[str]
|
||||
message_stripped = Optional[str]
|
||||
sender: str
|
||||
triggered_by: strawberry.ID
|
||||
triggered_by: Optional[UserType]
|
||||
receiver: strawberry.ID
|
||||
read_at: Optional[datetime]
|
||||
snoozed_till: Optional[datetime]
|
||||
@@ -28,7 +30,7 @@ class NotificationType:
|
||||
entity_identifier: strawberry.ID
|
||||
data: JSON
|
||||
workspace: strawberry.ID
|
||||
project: strawberry.ID
|
||||
project: Optional[ProjectType]
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
@@ -36,14 +38,6 @@ class NotificationType:
|
||||
def workspace(self) -> int:
|
||||
return self.workspace_id
|
||||
|
||||
@strawberry.field
|
||||
def project(self) -> int:
|
||||
return self.project_id
|
||||
|
||||
@strawberry.field
|
||||
def triggered_by(self) -> int:
|
||||
return self.triggered_by_id
|
||||
|
||||
@strawberry.field
|
||||
def receiver(self) -> int:
|
||||
return self.receiver_id
|
||||
|
||||
@@ -109,7 +109,7 @@ class UserFavoriteEntityData:
|
||||
class UserFavoriteType:
|
||||
id: strawberry.ID
|
||||
entity_type: str
|
||||
entity_identifier: str
|
||||
entity_identifier: Optional[str]
|
||||
name: Optional[str]
|
||||
is_folder: bool
|
||||
sequence: float
|
||||
@@ -214,7 +214,7 @@ class UserRecentVisitType:
|
||||
@strawberry.field
|
||||
def project(self) -> int:
|
||||
return self.project_id
|
||||
|
||||
|
||||
@strawberry.field
|
||||
def user(self) -> int:
|
||||
return self.user_id
|
||||
|
||||
Reference in New Issue
Block a user