mirror of
https://github.com/makeplane/plane.git
synced 2026-07-14 06:25:58 +02:00
[MOBIL-646] chore: add issue attachment mutations and update enums for workspace and project asset mutations (#2094)
* chore: issue attachements queries and mutations * chore: updated attachment id in Issue attachment
This commit is contained in:
@@ -24,7 +24,7 @@ from plane.settings.storage import S3Storage
|
||||
from plane.graphql.types.asset import (
|
||||
FileAssetType,
|
||||
AssetPresignedUrlResponseType,
|
||||
UserAssetFileEnumType,
|
||||
FileAssetAssetType,
|
||||
ProjectAssetEnumType,
|
||||
)
|
||||
from plane.bgtasks.storage_metadata_task import get_asset_object_metadata
|
||||
@@ -63,21 +63,18 @@ def get_entity_id_field(entity_type, entity_identifier):
|
||||
if entity_type == ProjectAssetEnumType.PROJECT_COVER.value:
|
||||
return {"project_id": entity_identifier}
|
||||
|
||||
if entity_type in [
|
||||
ProjectAssetEnumType.ISSUE_ATTACHMENT.value,
|
||||
ProjectAssetEnumType.ISSUE_DESCRIPTION.value,
|
||||
]:
|
||||
return {"issue_id": entity_identifier}
|
||||
|
||||
if entity_type == ProjectAssetEnumType.PAGE_DESCRIPTION.value:
|
||||
return {"page_id": entity_identifier}
|
||||
|
||||
if entity_type == ProjectAssetEnumType.COMMENT_DESCRIPTION.value:
|
||||
return {"comment_id": entity_identifier}
|
||||
if entity_type == ProjectAssetEnumType.ISSUE_DESCRIPTION.value:
|
||||
return {"issue_id": entity_identifier}
|
||||
|
||||
if entity_type == ProjectAssetEnumType.DRAFT_ISSUE_DESCRIPTION.value:
|
||||
return {"draft_issue_id": entity_identifier}
|
||||
|
||||
if entity_type == ProjectAssetEnumType.COMMENT_DESCRIPTION.value:
|
||||
return {"comment_id": entity_identifier}
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
@@ -131,11 +128,12 @@ class ProjectAssetMutation:
|
||||
# Checking if the entity type is valid
|
||||
if not entity_type or entity_type not in [
|
||||
ProjectAssetEnumType.PROJECT_COVER,
|
||||
ProjectAssetEnumType.ISSUE_ATTACHMENT,
|
||||
ProjectAssetEnumType.ISSUE_DESCRIPTION,
|
||||
ProjectAssetEnumType.COMMENT_DESCRIPTION,
|
||||
ProjectAssetEnumType.PAGE_DESCRIPTION,
|
||||
ProjectAssetEnumType.ISSUE_DESCRIPTION,
|
||||
ProjectAssetEnumType.DRAFT_ISSUE_DESCRIPTION,
|
||||
ProjectAssetEnumType.ISSUE_ATTACHMENT,
|
||||
ProjectAssetEnumType.DRAFT_ISSUE_ATTACHMENT,
|
||||
ProjectAssetEnumType.COMMENT_DESCRIPTION,
|
||||
]:
|
||||
message = "Invalid entity type."
|
||||
error_extensions = {"code": "INVALID_ENTITY_TYPE", "statusCode": 400}
|
||||
@@ -143,11 +141,11 @@ class ProjectAssetMutation:
|
||||
|
||||
# Checking if the file type is valid
|
||||
allowed_types = [
|
||||
UserAssetFileEnumType.IMAGE_JPEG.value,
|
||||
UserAssetFileEnumType.IMAGE_PNG.value,
|
||||
UserAssetFileEnumType.IMAGE_WEBP.value,
|
||||
UserAssetFileEnumType.IMAGE_JPG.value,
|
||||
UserAssetFileEnumType.IMAGE_GIF.value,
|
||||
FileAssetAssetType.IMAGE_JPEG.value,
|
||||
FileAssetAssetType.IMAGE_PNG.value,
|
||||
FileAssetAssetType.IMAGE_WEBP.value,
|
||||
FileAssetAssetType.IMAGE_JPG.value,
|
||||
FileAssetAssetType.IMAGE_GIF.value,
|
||||
]
|
||||
if type not in allowed_types:
|
||||
message = "Invalid file type. Only JPEG and PNG files are allowed."
|
||||
@@ -283,24 +281,24 @@ class ProjectAssetMutation:
|
||||
project_details = await get_project(project)
|
||||
await save_project_cover(project_details, asset.id)
|
||||
|
||||
if asset.entity_type == ProjectAssetEnumType.ISSUE_DESCRIPTION.value:
|
||||
for asset in assets:
|
||||
asset.issue_id = entity_id
|
||||
await sync_to_async(asset.save)(update_fields=["issue_id"])
|
||||
|
||||
if asset.entity_type == ProjectAssetEnumType.COMMENT_DESCRIPTION.value:
|
||||
for asset in assets:
|
||||
asset.comment_id = entity_id
|
||||
await sync_to_async(asset.save)(update_fields=["comment_id"])
|
||||
|
||||
if asset.entity_type == ProjectAssetEnumType.PAGE_DESCRIPTION.value:
|
||||
for asset in assets:
|
||||
asset.page_id = entity_id
|
||||
await sync_to_async(asset.save)(update_fields=["page_id"])
|
||||
|
||||
if asset.entity_type == ProjectAssetEnumType.ISSUE_DESCRIPTION.value:
|
||||
for asset in assets:
|
||||
asset.issue_id = entity_id
|
||||
await sync_to_async(asset.save)(update_fields=["issue_id"])
|
||||
|
||||
if asset.entity_type == ProjectAssetEnumType.DRAFT_ISSUE_DESCRIPTION.value:
|
||||
for asset in assets:
|
||||
asset.draft_issue_id = entity_id
|
||||
await sync_to_async(asset.save)(update_fields=["draft_issue_id"])
|
||||
|
||||
if asset.entity_type == ProjectAssetEnumType.COMMENT_DESCRIPTION.value:
|
||||
for asset in assets:
|
||||
asset.comment_id = entity_id
|
||||
await sync_to_async(asset.save)(update_fields=["comment_id"])
|
||||
|
||||
return True
|
||||
|
||||
@@ -23,7 +23,7 @@ from plane.settings.storage import S3Storage
|
||||
from plane.graphql.types.asset import (
|
||||
FileAssetType,
|
||||
AssetPresignedUrlResponseType,
|
||||
UserAssetFileEnumType,
|
||||
FileAssetAssetType,
|
||||
UserAssetEnumType,
|
||||
)
|
||||
from plane.bgtasks.storage_metadata_task import get_asset_object_metadata
|
||||
@@ -127,11 +127,11 @@ class UserAssetMutation:
|
||||
|
||||
# Checking if the file type is valid
|
||||
allowed_types = [
|
||||
UserAssetFileEnumType.IMAGE_JPEG.value,
|
||||
UserAssetFileEnumType.IMAGE_PNG.value,
|
||||
UserAssetFileEnumType.IMAGE_WEBP.value,
|
||||
UserAssetFileEnumType.IMAGE_JPG.value,
|
||||
UserAssetFileEnumType.IMAGE_GIF.value,
|
||||
FileAssetAssetType.IMAGE_JPEG.value,
|
||||
FileAssetAssetType.IMAGE_PNG.value,
|
||||
FileAssetAssetType.IMAGE_WEBP.value,
|
||||
FileAssetAssetType.IMAGE_JPG.value,
|
||||
FileAssetAssetType.IMAGE_GIF.value,
|
||||
]
|
||||
if type not in allowed_types:
|
||||
message = "Invalid file type. Only JPEG and PNG files are allowed."
|
||||
|
||||
@@ -24,7 +24,7 @@ from plane.settings.storage import S3Storage
|
||||
from plane.graphql.types.asset import (
|
||||
FileAssetType,
|
||||
AssetPresignedUrlResponseType,
|
||||
UserAssetFileEnumType,
|
||||
FileAssetAssetType,
|
||||
WorkspaceAssetEnumType,
|
||||
)
|
||||
from plane.bgtasks.storage_metadata_task import get_asset_object_metadata
|
||||
@@ -187,11 +187,11 @@ class WorkspaceAssetMutation:
|
||||
|
||||
# Checking if the file type is valid
|
||||
allowed_types = [
|
||||
UserAssetFileEnumType.IMAGE_JPEG.value,
|
||||
UserAssetFileEnumType.IMAGE_PNG.value,
|
||||
UserAssetFileEnumType.IMAGE_WEBP.value,
|
||||
UserAssetFileEnumType.IMAGE_JPG.value,
|
||||
UserAssetFileEnumType.IMAGE_GIF.value,
|
||||
FileAssetAssetType.IMAGE_JPEG.value,
|
||||
FileAssetAssetType.IMAGE_PNG.value,
|
||||
FileAssetAssetType.IMAGE_WEBP.value,
|
||||
FileAssetAssetType.IMAGE_JPG.value,
|
||||
FileAssetAssetType.IMAGE_GIF.value,
|
||||
]
|
||||
if type not in allowed_types:
|
||||
message = "Invalid file type. Only JPEG and PNG files are allowed."
|
||||
|
||||
@@ -439,48 +439,6 @@ class IssueUserPropertyMutation:
|
||||
return issue_properties
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class IssueAttachmentMutation:
|
||||
# @strawberry.mutation(
|
||||
# extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
# )
|
||||
# def upload_file(self, file: Upload, info: Info) -> bool:
|
||||
# content = file.read()
|
||||
# filename = file.filename
|
||||
# @strawberry.mutation(
|
||||
# extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
# )
|
||||
# async def upload_file(self, file: Upload, info: Info) -> bool:
|
||||
# content = await sync_to_async(file.read)()
|
||||
# filename = file.filename
|
||||
|
||||
# # Save the file using Django's file storage
|
||||
# await sync_to_async(default_storage.save)(filename, content)
|
||||
|
||||
# return True
|
||||
|
||||
@strawberry.mutation(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def deleteIssueAttachment(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
issue: strawberry.ID,
|
||||
attachment: strawberry.ID,
|
||||
) -> bool:
|
||||
issue_attachment = await sync_to_async(FileAsset.objects.get)(
|
||||
id=attachment,
|
||||
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
|
||||
entity_identifier=issue,
|
||||
project_id=project,
|
||||
workspace__slug=slug,
|
||||
)
|
||||
await sync_to_async(issue_attachment.delete)()
|
||||
return True
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class IssueSubscriptionMutation:
|
||||
@strawberry.mutation(
|
||||
|
||||
@@ -4,3 +4,4 @@ from .sub_issue import SubIssueMutation
|
||||
from .cycle import IssueCycleMutation
|
||||
from .module import IssueModuleMutation
|
||||
from .links import IssueLinkMutation
|
||||
from .attachment import IssueAttachmentMutation
|
||||
|
||||
235
apiserver/plane/graphql/mutations/issues/attachment.py
Normal file
235
apiserver/plane/graphql/mutations/issues/attachment.py
Normal file
@@ -0,0 +1,235 @@
|
||||
# Python imports
|
||||
import json
|
||||
import requests
|
||||
import uuid
|
||||
from typing import Optional
|
||||
|
||||
# Django imports
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
# Third-Party Imports
|
||||
import strawberry
|
||||
from strawberry.scalars import JSON
|
||||
from strawberry.exceptions import GraphQLError
|
||||
|
||||
# Python Standard Library Imports
|
||||
from asgiref.sync import sync_to_async
|
||||
|
||||
# Strawberry Imports
|
||||
from strawberry.types import Info
|
||||
from strawberry.permission import PermissionExtension
|
||||
|
||||
# Module Imports
|
||||
from plane.settings.storage import S3Storage
|
||||
from plane.db.models import FileAsset, Workspace
|
||||
from plane.graphql.types.asset import FileAssetType, FileAssetEntityType
|
||||
from plane.graphql.types.issues.attachment import (
|
||||
IssueAttachmentPresignedUrlResponseType,
|
||||
)
|
||||
from plane.graphql.permissions.project import ProjectBasePermission
|
||||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
from plane.bgtasks.storage_metadata_task import get_asset_object_metadata
|
||||
|
||||
|
||||
@sync_to_async
|
||||
def validate_feature_flag(slug: str, user_id: str, feature_key: str) -> bool:
|
||||
url = f"{settings.FEATURE_FLAG_SERVER_BASE_URL}/api/feature-flags/"
|
||||
json = {"workspace_slug": slug, "user_id": user_id, "flag_key": feature_key}
|
||||
headers = {
|
||||
"content-type": "application/json",
|
||||
"x-api-key": settings.FEATURE_FLAG_SERVER_AUTH_TOKEN,
|
||||
}
|
||||
response = requests.post(url, json=json, headers=headers)
|
||||
response.raise_for_status()
|
||||
return response.json().get("value", False)
|
||||
|
||||
|
||||
@sync_to_async
|
||||
def get_workspace(slug):
|
||||
try:
|
||||
return Workspace.objects.get(slug=slug)
|
||||
except Workspace.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
@sync_to_async
|
||||
def create_file_asset(
|
||||
workspace, project_id, issue_id, attributes, asset_key, size, user_id
|
||||
) -> FileAssetType:
|
||||
return FileAsset.objects.create(
|
||||
workspace=workspace,
|
||||
project_id=project_id,
|
||||
issue_id=issue_id,
|
||||
attributes=attributes,
|
||||
asset=asset_key,
|
||||
size=size,
|
||||
created_by_id=user_id,
|
||||
entity_type=FileAssetEntityType.ISSUE_ATTACHMENT.value,
|
||||
)
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class IssueAttachmentMutation:
|
||||
@strawberry.mutation(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def create_issue_attachment(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
issue: strawberry.ID,
|
||||
name: str,
|
||||
type: str,
|
||||
size: int,
|
||||
) -> IssueAttachmentPresignedUrlResponseType:
|
||||
user = info.context.user
|
||||
|
||||
# Checking if the file size is within the limit
|
||||
size_limit = min(size, settings.FILE_SIZE_LIMIT)
|
||||
if validate_feature_flag(
|
||||
slug=slug, user_id=str(user.id), feature_key="FILE_SIZE_LIMIT_PRO"
|
||||
):
|
||||
size_limit = min(size, settings.PRO_FILE_SIZE_LIMIT)
|
||||
|
||||
if type not in settings.ATTACHMENT_MIME_TYPES:
|
||||
message = "Invalid file type."
|
||||
error_extensions = {"code": "INVALID_FILE_TYPE", "statusCode": 400}
|
||||
raise GraphQLError(message, extensions=error_extensions)
|
||||
|
||||
# getting the workspace
|
||||
workspace = await get_workspace(slug=slug)
|
||||
if workspace is None:
|
||||
message = "Workspace not found."
|
||||
error_extensions = {"code": "WORKSPACE_NOT_FOUND", "statusCode": 404}
|
||||
raise GraphQLError(message, extensions=error_extensions)
|
||||
|
||||
# asset key
|
||||
asset_key = f"{workspace.id}/{uuid.uuid4().hex}-{name}"
|
||||
|
||||
# creating a file asset
|
||||
attachment = await create_file_asset(
|
||||
workspace=workspace,
|
||||
project_id=project,
|
||||
issue_id=issue,
|
||||
attributes={"name": name, "type": type, "size": size_limit},
|
||||
asset_key=asset_key,
|
||||
size=size_limit,
|
||||
user_id=user.id,
|
||||
)
|
||||
|
||||
# Get the presigned URL
|
||||
storage = S3Storage(request=info.context["request"])
|
||||
|
||||
# Generate a presigned URL to share an S3 object
|
||||
presigned_url_data = await sync_to_async(storage.generate_presigned_post)(
|
||||
object_name=asset_key, file_type=type, file_size=size_limit
|
||||
)
|
||||
|
||||
# Return the presigned URL
|
||||
return IssueAttachmentPresignedUrlResponseType(
|
||||
upload_data=presigned_url_data,
|
||||
attachment_id=str(attachment.id),
|
||||
asset_url=attachment.asset_url,
|
||||
)
|
||||
|
||||
@strawberry.mutation(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def update_issue_attachment(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
issue: strawberry.ID,
|
||||
attachment: strawberry.ID,
|
||||
attributes: Optional[JSON] = None,
|
||||
) -> FileAssetType:
|
||||
user = info.context.user
|
||||
issue_attachment = await sync_to_async(FileAsset.objects.get)(
|
||||
workspace__slug=slug,
|
||||
project_id=project,
|
||||
entity_type=FileAssetEntityType.ISSUE_ATTACHMENT.value,
|
||||
issue=issue,
|
||||
id=attachment,
|
||||
)
|
||||
|
||||
if not issue_attachment.is_uploaded:
|
||||
issue_activity.delay(
|
||||
type="attachment.activity.created",
|
||||
requested_data=None,
|
||||
actor_id=str(info.context.user.id),
|
||||
issue_id=str(issue),
|
||||
project_id=str(project),
|
||||
current_instance=json.dumps({"id": str(attachment)}),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=info.context.request.META.get("HTTP_ORIGIN"),
|
||||
)
|
||||
|
||||
issue_attachment.is_uploaded = True
|
||||
issue_attachment.created_by = user
|
||||
|
||||
# get the storage metadata
|
||||
if not issue_attachment.storage_metadata:
|
||||
get_asset_object_metadata.delay(asset_id=str(attachment))
|
||||
|
||||
# update the file asset attributes
|
||||
if attributes is not None:
|
||||
issue_attachment.attributes = attributes
|
||||
else:
|
||||
issue_attachment.attributes = issue_attachment.attributes
|
||||
|
||||
# save the file asset
|
||||
await sync_to_async(issue_attachment.save)(
|
||||
update_fields=["is_uploaded", "created_by", "attributes"]
|
||||
)
|
||||
|
||||
return issue_attachment
|
||||
|
||||
@strawberry.mutation(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def delete_issue_attachment(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
issue: strawberry.ID,
|
||||
attachment: strawberry.ID,
|
||||
) -> bool:
|
||||
issue_attachment = await sync_to_async(FileAsset.objects.get)(
|
||||
workspace__slug=slug,
|
||||
project_id=project,
|
||||
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
|
||||
issue=issue,
|
||||
id=attachment,
|
||||
)
|
||||
|
||||
if not issue_attachment:
|
||||
message = "Attachment not found."
|
||||
error_extensions = {"code": "ATTACHMENT_NOT_FOUND", "statusCode": 400}
|
||||
raise GraphQLError(message, extensions=error_extensions)
|
||||
|
||||
issue_attachment.is_deleted = True
|
||||
issue_attachment.deleted_at = timezone.now()
|
||||
|
||||
# save the file asset
|
||||
await sync_to_async(issue_attachment.save)(
|
||||
update_fields=["is_deleted", "deleted_at"]
|
||||
)
|
||||
|
||||
issue_activity.delay(
|
||||
type="attachment.activity.deleted",
|
||||
requested_data=None,
|
||||
actor_id=str(info.context.user.id),
|
||||
issue_id=str(issue),
|
||||
project_id=str(project),
|
||||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=info.context.request.META.get("HTTP_ORIGIN"),
|
||||
)
|
||||
|
||||
return True
|
||||
@@ -7,10 +7,11 @@ from asgiref.sync import sync_to_async
|
||||
# Strawberry Imports
|
||||
from strawberry.types import Info
|
||||
from strawberry.permission import PermissionExtension
|
||||
from strawberry.exceptions import GraphQLError
|
||||
|
||||
# Module Imports
|
||||
from plane.db.models import FileAsset
|
||||
from plane.graphql.types.issues.attachment import IssueAttachmentType
|
||||
from plane.graphql.types.asset import FileAssetType
|
||||
from plane.graphql.permissions.project import ProjectBasePermission
|
||||
|
||||
|
||||
@@ -21,14 +22,41 @@ class IssueAttachmentQuery:
|
||||
)
|
||||
async def issue_attachment(
|
||||
self, info: Info, slug: str, project: strawberry.ID, issue: strawberry.ID
|
||||
) -> list[IssueAttachmentType]:
|
||||
) -> list[FileAssetType]:
|
||||
issue_attachments = await sync_to_async(list)(
|
||||
FileAsset.objects.filter(
|
||||
workspace__slug=slug,
|
||||
project_id=project,
|
||||
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
|
||||
issue=issue,
|
||||
is_uploaded=True,
|
||||
)
|
||||
)
|
||||
|
||||
return issue_attachments
|
||||
|
||||
@strawberry.field(
|
||||
extensions=[PermissionExtension(permissions=[ProjectBasePermission()])]
|
||||
)
|
||||
async def issue_attachment_detail(
|
||||
self,
|
||||
info: Info,
|
||||
slug: str,
|
||||
project: strawberry.ID,
|
||||
issue: strawberry.ID,
|
||||
attachment: strawberry.ID,
|
||||
) -> FileAssetType:
|
||||
issue_attachment = await sync_to_async(FileAsset.objects.get)(
|
||||
workspace__slug=slug,
|
||||
project_id=project,
|
||||
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
|
||||
issue=issue,
|
||||
id=attachment,
|
||||
)
|
||||
|
||||
if not issue_attachment.is_uploaded:
|
||||
message = "The attachment is not uploaded."
|
||||
error_extensions = {"code": "ATTACHMENT_NOT_UPLOADED", "statusCode": 400}
|
||||
raise GraphQLError(message, extensions=error_extensions)
|
||||
|
||||
return issue_attachment
|
||||
|
||||
@@ -64,7 +64,6 @@ from .mutations.project import (
|
||||
from .mutations.issue import (
|
||||
IssueMutation,
|
||||
IssueUserPropertyMutation,
|
||||
IssueAttachmentMutation,
|
||||
IssueSubscriptionMutation,
|
||||
)
|
||||
from .mutations.notification import NotificationMutation
|
||||
@@ -88,6 +87,7 @@ from .mutations.issues import (
|
||||
IssueModuleMutation,
|
||||
IssueCycleMutation,
|
||||
IssueLinkMutation,
|
||||
IssueAttachmentMutation,
|
||||
)
|
||||
from .mutations.device import DeviceInformationMutation
|
||||
from .mutations.asset import (
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
from .base import FileAssetType, AssetPresignedUrlResponseType, UserAssetFileEnumType
|
||||
from .base import (
|
||||
FileAssetAssetType,
|
||||
FileAssetEntityType,
|
||||
FileAssetType,
|
||||
AssetPresignedUrlResponseType,
|
||||
)
|
||||
from .user import UserAssetEnumType
|
||||
from .workspace import WorkspaceAssetEnumType
|
||||
from .project import ProjectAssetEnumType
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Python imports
|
||||
from typing import Optional
|
||||
from enum import Enum
|
||||
from datetime import datetime
|
||||
|
||||
# Strawberry imports
|
||||
import strawberry
|
||||
@@ -11,35 +12,8 @@ from strawberry.scalars import JSON
|
||||
from plane.db.models import FileAsset
|
||||
|
||||
|
||||
@strawberry_django.type(FileAsset)
|
||||
class FileAssetType:
|
||||
id: strawberry.ID
|
||||
attributes: JSON
|
||||
asset: str
|
||||
entity_type: str
|
||||
size: float
|
||||
is_uploaded: bool
|
||||
storage_metadata: Optional[JSON]
|
||||
user: strawberry.ID
|
||||
workspace: strawberry.ID
|
||||
project: Optional[strawberry.ID]
|
||||
issue: Optional[strawberry.ID]
|
||||
comment: Optional[strawberry.ID]
|
||||
page: Optional[strawberry.ID]
|
||||
draft_issue: Optional[strawberry.ID]
|
||||
is_archived: bool
|
||||
is_deleted: bool
|
||||
deleted_at: Optional[str]
|
||||
created_by: Optional[strawberry.ID]
|
||||
updated_by: Optional[strawberry.ID]
|
||||
created_at: str
|
||||
updated_at: str
|
||||
# model properties
|
||||
asset_url: Optional[str]
|
||||
|
||||
|
||||
@strawberry.enum
|
||||
class UserAssetFileEnumType(Enum):
|
||||
class FileAssetAssetType(Enum):
|
||||
IMAGE_JPEG = "image/jpeg"
|
||||
IMAGE_PNG = "image/png"
|
||||
IMAGE_WEBP = "image/webp"
|
||||
@@ -50,6 +24,66 @@ class UserAssetFileEnumType(Enum):
|
||||
return self.value
|
||||
|
||||
|
||||
@strawberry.enum
|
||||
class FileAssetEntityType(Enum):
|
||||
USER_COVER = "USER_COVER"
|
||||
USER_AVATAR = "USER_AVATAR"
|
||||
|
||||
WORKSPACE_LOGO = "WORKSPACE_LOGO"
|
||||
|
||||
PROJECT_COVER = "PROJECT_COVER"
|
||||
PROJECT_DESCRIPTION = "PROJECT_DESCRIPTION"
|
||||
PROJECT_ATTACHMENT = "PROJECT_ATTACHMENT"
|
||||
|
||||
PAGE_DESCRIPTION = "PAGE_DESCRIPTION"
|
||||
|
||||
ISSUE_DESCRIPTION = "ISSUE_DESCRIPTION"
|
||||
DRAFT_ISSUE_DESCRIPTION = "DRAFT_ISSUE_DESCRIPTION"
|
||||
COMMENT_DESCRIPTION = "COMMENT_DESCRIPTION"
|
||||
ISSUE_ATTACHMENT = "ISSUE_ATTACHMENT"
|
||||
DRAFT_ISSUE_ATTACHMENT = "DRAFT_ISSUE_ATTACHMENT"
|
||||
|
||||
INITIATIVE_DESCRIPTION = "INITIATIVE_DESCRIPTION"
|
||||
INITIATIVE_ATTACHMENT = "INITIATIVE_ATTACHMENT"
|
||||
INITIATIVE_COMMENT_DESCRIPTION = "INITIATIVE_COMMENT_DESCRIPTION"
|
||||
|
||||
TEAM_SPACE_DESCRIPTION = "TEAM_SPACE_DESCRIPTION"
|
||||
TEAM_SPACE_COMMENT_DESCRIPTION = "TEAM_SPACE_COMMENT_DESCRIPTION"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
|
||||
@strawberry_django.type(FileAsset)
|
||||
class FileAssetType:
|
||||
id: strawberry.ID
|
||||
attributes: JSON
|
||||
asset: str
|
||||
size: float
|
||||
entity_type: FileAssetEntityType
|
||||
entity_identifier: Optional[strawberry.ID]
|
||||
storage_metadata: Optional[JSON]
|
||||
user: strawberry.ID
|
||||
workspace: strawberry.ID
|
||||
draft_issue: Optional[strawberry.ID]
|
||||
project: Optional[strawberry.ID]
|
||||
issue: Optional[strawberry.ID]
|
||||
comment: Optional[strawberry.ID]
|
||||
page: Optional[strawberry.ID]
|
||||
is_uploaded: bool
|
||||
is_archived: bool
|
||||
is_deleted: bool
|
||||
deleted_at: Optional[str]
|
||||
external_id: Optional[strawberry.ID]
|
||||
external_source: Optional[str]
|
||||
created_by: Optional[strawberry.ID]
|
||||
updated_by: Optional[strawberry.ID]
|
||||
created_at: Optional[datetime]
|
||||
updated_at: Optional[datetime]
|
||||
# model properties
|
||||
asset_url: Optional[str]
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class AssetPresignedUrlResponseType:
|
||||
upload_data: JSON
|
||||
|
||||
@@ -4,15 +4,19 @@ from enum import Enum
|
||||
# Strawberry imports
|
||||
import strawberry
|
||||
|
||||
# module imports
|
||||
from plane.graphql.types.asset.base import FileAssetEntityType
|
||||
|
||||
|
||||
@strawberry.enum
|
||||
class ProjectAssetEnumType(Enum):
|
||||
PROJECT_COVER = "PROJECT_COVER"
|
||||
ISSUE_ATTACHMENT = "ISSUE_ATTACHMENT"
|
||||
ISSUE_DESCRIPTION = "ISSUE_DESCRIPTION"
|
||||
PAGE_DESCRIPTION = "PAGE_DESCRIPTION"
|
||||
COMMENT_DESCRIPTION = "COMMENT_DESCRIPTION"
|
||||
DRAFT_ISSUE_DESCRIPTION = "DRAFT_ISSUE_DESCRIPTION"
|
||||
PROJECT_COVER = FileAssetEntityType.PROJECT_COVER.value
|
||||
PAGE_DESCRIPTION = FileAssetEntityType.PAGE_DESCRIPTION.value
|
||||
ISSUE_DESCRIPTION = FileAssetEntityType.ISSUE_DESCRIPTION.value
|
||||
DRAFT_ISSUE_DESCRIPTION = FileAssetEntityType.DRAFT_ISSUE_DESCRIPTION.value
|
||||
COMMENT_DESCRIPTION = FileAssetEntityType.COMMENT_DESCRIPTION.value
|
||||
ISSUE_ATTACHMENT = FileAssetEntityType.ISSUE_ATTACHMENT.value
|
||||
DRAFT_ISSUE_ATTACHMENT = FileAssetEntityType.DRAFT_ISSUE_ATTACHMENT.value
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
@@ -4,11 +4,14 @@ from enum import Enum
|
||||
# Strawberry imports
|
||||
import strawberry
|
||||
|
||||
# module imports
|
||||
from plane.graphql.types.asset.base import FileAssetEntityType
|
||||
|
||||
|
||||
@strawberry.enum
|
||||
class UserAssetEnumType(Enum):
|
||||
USER_AVATAR = "USER_AVATAR"
|
||||
USER_COVER = "USER_COVER"
|
||||
USER_AVATAR = FileAssetEntityType.USER_AVATAR.value
|
||||
USER_COVER = FileAssetEntityType.USER_COVER.value
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
@@ -4,12 +4,15 @@ from enum import Enum
|
||||
# Strawberry imports
|
||||
import strawberry
|
||||
|
||||
# module imports
|
||||
from plane.graphql.types.asset.base import FileAssetEntityType
|
||||
|
||||
|
||||
@strawberry.enum
|
||||
class WorkspaceAssetEnumType(Enum):
|
||||
WORKSPACE_LOGO = "WORKSPACE_LOGO"
|
||||
PROJECT_COVER = "PROJECT_COVER"
|
||||
PAGE_DESCRIPTION = "PAGE_DESCRIPTION"
|
||||
WORKSPACE_LOGO = FileAssetEntityType.WORKSPACE_LOGO.value
|
||||
PROJECT_COVER = FileAssetEntityType.PROJECT_COVER.value
|
||||
PAGE_DESCRIPTION = FileAssetEntityType.PAGE_DESCRIPTION.value
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
@@ -3,62 +3,11 @@ from typing import Optional
|
||||
|
||||
# Strawberry imports
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry.scalars import JSON
|
||||
|
||||
# Module Imports
|
||||
from plane.db.models import FileAsset
|
||||
|
||||
|
||||
@strawberry_django.type(FileAsset)
|
||||
class IssueAttachmentType:
|
||||
id: strawberry.ID
|
||||
user: strawberry.ID
|
||||
workspace: strawberry.ID
|
||||
draft_issue: strawberry.ID
|
||||
project: strawberry.ID
|
||||
issue: strawberry.ID
|
||||
comment: strawberry.ID
|
||||
page: strawberry.ID
|
||||
|
||||
attributes: Optional[JSON]
|
||||
asset: str
|
||||
entity_type: str
|
||||
is_deleted: bool
|
||||
is_archived: bool
|
||||
|
||||
size: float
|
||||
is_uploaded: bool
|
||||
storage_metadata: Optional[JSON]
|
||||
@strawberry.type
|
||||
class IssueAttachmentPresignedUrlResponseType:
|
||||
upload_data: JSON
|
||||
attachment_id: str
|
||||
asset_url: Optional[str]
|
||||
|
||||
external_id: strawberry.ID
|
||||
external_source: str
|
||||
|
||||
@strawberry.field
|
||||
def user(self):
|
||||
return self.user_id
|
||||
|
||||
@strawberry.field
|
||||
def workspace(self):
|
||||
return self.workspace_id
|
||||
|
||||
@strawberry.field
|
||||
def draft_issue(self):
|
||||
return self.draft_issue_id
|
||||
|
||||
@strawberry.field
|
||||
def project(self):
|
||||
return self.project_id
|
||||
|
||||
@strawberry.field
|
||||
def issue(self):
|
||||
return self.external_id
|
||||
|
||||
@strawberry.field
|
||||
def comment(self):
|
||||
return self.comment_id
|
||||
|
||||
@strawberry.field
|
||||
def page(self):
|
||||
return self.page_id
|
||||
|
||||
Reference in New Issue
Block a user