forked from github/plane
Compare commits
5 Commits
preview
...
chore/seri
Author | SHA1 | Date | |
---|---|---|---|
|
168823e5ba | ||
|
ea3b9456f9 | ||
|
2058334559 | ||
|
e1b77d400a | ||
|
77977d7d32 |
@ -1,13 +1,11 @@
|
|||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .user import UserSerializer, UserLiteSerializer, ChangePasswordSerializer, ResetPasswordSerializer, UserAdminLiteSerializer
|
from .user import UserSerializer, ChangePasswordSerializer, ResetPasswordSerializer
|
||||||
from .workspace import (
|
from .workspace import (
|
||||||
WorkSpaceSerializer,
|
WorkSpaceSerializer,
|
||||||
WorkSpaceMemberSerializer,
|
WorkSpaceMemberSerializer,
|
||||||
TeamSerializer,
|
TeamSerializer,
|
||||||
WorkSpaceMemberInviteSerializer,
|
WorkSpaceMemberInviteSerializer,
|
||||||
WorkspaceLiteSerializer,
|
|
||||||
WorkspaceThemeSerializer,
|
WorkspaceThemeSerializer,
|
||||||
WorkspaceMemberAdminSerializer,
|
|
||||||
)
|
)
|
||||||
from .project import (
|
from .project import (
|
||||||
ProjectSerializer,
|
ProjectSerializer,
|
||||||
@ -16,12 +14,11 @@ from .project import (
|
|||||||
ProjectMemberInviteSerializer,
|
ProjectMemberInviteSerializer,
|
||||||
ProjectIdentifierSerializer,
|
ProjectIdentifierSerializer,
|
||||||
ProjectFavoriteSerializer,
|
ProjectFavoriteSerializer,
|
||||||
ProjectLiteSerializer,
|
|
||||||
ProjectMemberLiteSerializer,
|
ProjectMemberLiteSerializer,
|
||||||
ProjectDeployBoardSerializer,
|
ProjectDeployBoardSerializer,
|
||||||
ProjectMemberAdminSerializer,
|
ProjectMemberAdminSerializer,
|
||||||
)
|
)
|
||||||
from .state import StateSerializer, StateLiteSerializer
|
from .state import StateSerializer
|
||||||
from .view import IssueViewSerializer, IssueViewFavoriteSerializer
|
from .view import IssueViewSerializer, IssueViewFavoriteSerializer
|
||||||
from .cycle import CycleSerializer, CycleIssueSerializer, CycleFavoriteSerializer, CycleWriteSerializer
|
from .cycle import CycleSerializer, CycleIssueSerializer, CycleFavoriteSerializer, CycleWriteSerializer
|
||||||
from .asset import FileAssetSerializer
|
from .asset import FileAssetSerializer
|
||||||
@ -32,7 +29,7 @@ from .issue import (
|
|||||||
IssuePropertySerializer,
|
IssuePropertySerializer,
|
||||||
BlockerIssueSerializer,
|
BlockerIssueSerializer,
|
||||||
BlockedIssueSerializer,
|
BlockedIssueSerializer,
|
||||||
IssueAssigneeSerializer,
|
# IssueAssigneeSerializer,
|
||||||
LabelSerializer,
|
LabelSerializer,
|
||||||
IssueSerializer,
|
IssueSerializer,
|
||||||
IssueFlatSerializer,
|
IssueFlatSerializer,
|
||||||
@ -73,7 +70,6 @@ from .page import PageSerializer, PageBlockSerializer, PageFavoriteSerializer
|
|||||||
from .estimate import (
|
from .estimate import (
|
||||||
EstimateSerializer,
|
EstimateSerializer,
|
||||||
EstimatePointSerializer,
|
EstimatePointSerializer,
|
||||||
EstimateReadSerializer,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from .inbox import InboxSerializer, InboxIssueSerializer, IssueStateInboxSerializer
|
from .inbox import InboxSerializer, InboxIssueSerializer, IssueStateInboxSerializer
|
||||||
|
@ -1,5 +1,33 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
def filterFields(self, fields):
|
||||||
|
for field_name in fields:
|
||||||
|
if isinstance(field_name, dict):
|
||||||
|
for key, value in field_name.items():
|
||||||
|
if isinstance(value, list):
|
||||||
|
filterFields(self.fields[key], value)
|
||||||
|
allowed = []
|
||||||
|
for item in fields:
|
||||||
|
if isinstance(item, str):
|
||||||
|
allowed.append(item)
|
||||||
|
elif isinstance(item, dict):
|
||||||
|
allowed.append(list(item.keys())[0])
|
||||||
|
existing = set(self.fields)
|
||||||
|
allowed = set(allowed)
|
||||||
|
for field_name in existing - allowed:
|
||||||
|
self.fields.pop(field_name)
|
||||||
|
return self.fields
|
||||||
|
|
||||||
class BaseSerializer(serializers.ModelSerializer):
|
class BaseSerializer(serializers.ModelSerializer):
|
||||||
id = serializers.PrimaryKeyRelatedField(read_only=True)
|
id = serializers.PrimaryKeyRelatedField(read_only=True)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
# Don't pass the 'fields' arg up to the superclass
|
||||||
|
fields = kwargs.pop("fields", None)
|
||||||
|
|
||||||
|
# Instantiate the superclass normally
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
if fields is not None:
|
||||||
|
# Drop any fields that are not specified in the `fields` argument.
|
||||||
|
self.fields = filterFields(self, fields)
|
||||||
|
@ -6,10 +6,10 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .user import UserLiteSerializer
|
from .user import UserSerializer
|
||||||
from .issue import IssueStateSerializer
|
from .issue import IssueStateSerializer
|
||||||
from .workspace import WorkspaceLiteSerializer
|
from .workspace import WorkSpaceSerializer
|
||||||
from .project import ProjectLiteSerializer
|
from .project import ProjectSerializer
|
||||||
from plane.db.models import Cycle, CycleIssue, CycleFavorite
|
from plane.db.models import Cycle, CycleIssue, CycleFavorite
|
||||||
|
|
||||||
class CycleWriteSerializer(BaseSerializer):
|
class CycleWriteSerializer(BaseSerializer):
|
||||||
@ -20,7 +20,7 @@ class CycleWriteSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class CycleSerializer(BaseSerializer):
|
class CycleSerializer(BaseSerializer):
|
||||||
owned_by = UserLiteSerializer(read_only=True)
|
owned_by = UserSerializer(read_only=True)
|
||||||
is_favorite = serializers.BooleanField(read_only=True)
|
is_favorite = serializers.BooleanField(read_only=True)
|
||||||
total_issues = serializers.IntegerField(read_only=True)
|
total_issues = serializers.IntegerField(read_only=True)
|
||||||
cancelled_issues = serializers.IntegerField(read_only=True)
|
cancelled_issues = serializers.IntegerField(read_only=True)
|
||||||
@ -33,9 +33,9 @@ class CycleSerializer(BaseSerializer):
|
|||||||
total_estimates = serializers.IntegerField(read_only=True)
|
total_estimates = serializers.IntegerField(read_only=True)
|
||||||
completed_estimates = serializers.IntegerField(read_only=True)
|
completed_estimates = serializers.IntegerField(read_only=True)
|
||||||
started_estimates = serializers.IntegerField(read_only=True)
|
started_estimates = serializers.IntegerField(read_only=True)
|
||||||
workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace")
|
workspace_detail = WorkSpaceSerializer(source="workspace",read_only=True)
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(read_only=True, source="project")
|
||||||
|
|
||||||
def get_assignees(self, obj):
|
def get_assignees(self, obj):
|
||||||
members = [
|
members = [
|
||||||
{
|
{
|
||||||
@ -54,7 +54,7 @@ class CycleSerializer(BaseSerializer):
|
|||||||
unique_list = [dict(item) for item in unique_objects]
|
unique_list = [dict(item) for item in unique_objects]
|
||||||
|
|
||||||
return unique_list
|
return unique_list
|
||||||
|
|
||||||
def get_labels(self, obj):
|
def get_labels(self, obj):
|
||||||
labels = [
|
labels = [
|
||||||
{
|
{
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
|
|
||||||
from plane.db.models import Estimate, EstimatePoint
|
from plane.db.models import Estimate, EstimatePoint
|
||||||
from plane.api.serializers import WorkspaceLiteSerializer, ProjectLiteSerializer
|
from plane.api.serializers import WorkSpaceSerializer, ProjectSerializer
|
||||||
|
|
||||||
|
|
||||||
class EstimateSerializer(BaseSerializer):
|
class EstimateSerializer(BaseSerializer):
|
||||||
workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace")
|
workspace_detail = WorkSpaceSerializer(source="workspace", read_only=True)
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(read_only=True, source="project")
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Estimate
|
model = Estimate
|
||||||
@ -27,18 +27,3 @@ class EstimatePointSerializer(BaseSerializer):
|
|||||||
"workspace",
|
"workspace",
|
||||||
"project",
|
"project",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class EstimateReadSerializer(BaseSerializer):
|
|
||||||
points = EstimatePointSerializer(read_only=True, many=True)
|
|
||||||
workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace")
|
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Estimate
|
|
||||||
fields = "__all__"
|
|
||||||
read_only_fields = [
|
|
||||||
"points",
|
|
||||||
"name",
|
|
||||||
"description",
|
|
||||||
]
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from plane.db.models import ExporterHistory
|
from plane.db.models import ExporterHistory
|
||||||
from .user import UserLiteSerializer
|
from .user import UserSerializer
|
||||||
|
|
||||||
|
|
||||||
class ExporterHistorySerializer(BaseSerializer):
|
class ExporterHistorySerializer(BaseSerializer):
|
||||||
initiated_by_detail = UserLiteSerializer(source="initiated_by", read_only=True)
|
initiated_by_detail = UserSerializer(source="initiated_by",read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ExporterHistory
|
model = ExporterHistory
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .user import UserLiteSerializer
|
from .user import UserSerializer
|
||||||
from .project import ProjectLiteSerializer
|
from .project import ProjectSerializer
|
||||||
from .workspace import WorkspaceLiteSerializer
|
from .workspace import WorkSpaceSerializer
|
||||||
from plane.db.models import Importer
|
from plane.db.models import Importer
|
||||||
|
|
||||||
|
|
||||||
class ImporterSerializer(BaseSerializer):
|
class ImporterSerializer(BaseSerializer):
|
||||||
initiated_by_detail = UserLiteSerializer(source="initiated_by", read_only=True)
|
initiated_by_detail = UserSerializer(source="initiated_by", read_only=True)
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectSerializer(source="project", read_only=True)
|
||||||
workspace_detail = WorkspaceLiteSerializer(source="workspace", read_only=True)
|
workspace_detail = WorkSpaceSerializer(source="workspace", read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Importer
|
model = Importer
|
||||||
|
@ -4,15 +4,14 @@ from rest_framework import serializers
|
|||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .issue import IssueFlatSerializer, LabelLiteSerializer
|
from .issue import IssueFlatSerializer, LabelLiteSerializer
|
||||||
from .project import ProjectLiteSerializer
|
from .project import ProjectSerializer
|
||||||
from .state import StateLiteSerializer
|
from .state import StateLiteSerializer
|
||||||
from .project import ProjectLiteSerializer
|
from .user import UserSerializer
|
||||||
from .user import UserLiteSerializer
|
|
||||||
from plane.db.models import Inbox, InboxIssue, Issue
|
from plane.db.models import Inbox, InboxIssue, Issue
|
||||||
|
|
||||||
|
|
||||||
class InboxSerializer(BaseSerializer):
|
class InboxSerializer(BaseSerializer):
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectSerializer(source="project", fields=("id","name","cover_image","icon_prop","emoji","description"), read_only=True)
|
||||||
pending_issue_count = serializers.IntegerField(read_only=True)
|
pending_issue_count = serializers.IntegerField(read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -26,7 +25,7 @@ class InboxSerializer(BaseSerializer):
|
|||||||
|
|
||||||
class InboxIssueSerializer(BaseSerializer):
|
class InboxIssueSerializer(BaseSerializer):
|
||||||
issue_detail = IssueFlatSerializer(source="issue", read_only=True)
|
issue_detail = IssueFlatSerializer(source="issue", read_only=True)
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectSerializer(source="project", fields=("id","name","cover_image","icon_prop","emoji","description"), read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InboxIssue
|
model = InboxIssue
|
||||||
@ -46,9 +45,9 @@ class InboxIssueLiteSerializer(BaseSerializer):
|
|||||||
|
|
||||||
class IssueStateInboxSerializer(BaseSerializer):
|
class IssueStateInboxSerializer(BaseSerializer):
|
||||||
state_detail = StateLiteSerializer(read_only=True, source="state")
|
state_detail = StateLiteSerializer(read_only=True, source="state")
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(source="project", fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
label_details = LabelLiteSerializer(read_only=True, source="labels", many=True)
|
label_details = LabelLiteSerializer(read_only=True, source="labels", many=True)
|
||||||
assignee_details = UserLiteSerializer(read_only=True, source="assignees", many=True)
|
assignee_details = UserSerializer(source="assignees", read_only=True, many=True)
|
||||||
sub_issues_count = serializers.IntegerField(read_only=True)
|
sub_issues_count = serializers.IntegerField(read_only=True)
|
||||||
bridge_id = serializers.UUIDField(read_only=True)
|
bridge_id = serializers.UUIDField(read_only=True)
|
||||||
issue_inbox = InboxIssueLiteSerializer(read_only=True, many=True)
|
issue_inbox = InboxIssueLiteSerializer(read_only=True, many=True)
|
||||||
|
@ -6,11 +6,10 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .user import UserLiteSerializer
|
from .user import UserSerializer
|
||||||
from .state import StateSerializer, StateLiteSerializer
|
from .state import StateSerializer, StateLiteSerializer
|
||||||
from .user import UserLiteSerializer
|
from .project import ProjectSerializer
|
||||||
from .project import ProjectSerializer, ProjectLiteSerializer
|
from .workspace import WorkSpaceSerializer
|
||||||
from .workspace import WorkspaceLiteSerializer
|
|
||||||
from plane.db.models import (
|
from plane.db.models import (
|
||||||
User,
|
User,
|
||||||
Issue,
|
Issue,
|
||||||
@ -54,7 +53,11 @@ class IssueFlatSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class IssueProjectLiteSerializer(BaseSerializer):
|
class IssueProjectLiteSerializer(BaseSerializer):
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectSerializer(
|
||||||
|
source="project",
|
||||||
|
fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Issue
|
model = Issue
|
||||||
@ -71,9 +74,12 @@ class IssueProjectLiteSerializer(BaseSerializer):
|
|||||||
## Find a better approach to save manytomany?
|
## Find a better approach to save manytomany?
|
||||||
class IssueCreateSerializer(BaseSerializer):
|
class IssueCreateSerializer(BaseSerializer):
|
||||||
state_detail = StateSerializer(read_only=True, source="state")
|
state_detail = StateSerializer(read_only=True, source="state")
|
||||||
created_by_detail = UserLiteSerializer(read_only=True, source="created_by")
|
created_by_detail = UserSerializer(
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
source="created_by",
|
||||||
workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace")
|
read_only=True,
|
||||||
|
)
|
||||||
|
project_detail = ProjectSerializer(source="project", read_only=True)
|
||||||
|
workspace_detail = WorkSpaceSerializer(source="workspace", read_only=True)
|
||||||
|
|
||||||
assignees_list = serializers.ListField(
|
assignees_list = serializers.ListField(
|
||||||
child=serializers.PrimaryKeyRelatedField(queryset=User.objects.all()),
|
child=serializers.PrimaryKeyRelatedField(queryset=User.objects.all()),
|
||||||
@ -113,7 +119,11 @@ class IssueCreateSerializer(BaseSerializer):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
if data.get("start_date", None) is not None and data.get("target_date", None) is not None and data.get("start_date", None) > data.get("target_date", None):
|
if (
|
||||||
|
data.get("start_date", None) is not None
|
||||||
|
and data.get("target_date", None) is not None
|
||||||
|
and data.get("start_date", None) > data.get("target_date", None)
|
||||||
|
):
|
||||||
raise serializers.ValidationError("Start date cannot exceed target date")
|
raise serializers.ValidationError("Start date cannot exceed target date")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@ -296,35 +306,19 @@ class IssueCreateSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class IssueActivitySerializer(BaseSerializer):
|
class IssueActivitySerializer(BaseSerializer):
|
||||||
actor_detail = UserLiteSerializer(read_only=True, source="actor")
|
actor_detail = UserSerializer(source="actor", read_only=True)
|
||||||
issue_detail = IssueFlatSerializer(read_only=True, source="issue")
|
issue_detail = IssueFlatSerializer(read_only=True, source="issue")
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(
|
||||||
|
source="project",
|
||||||
|
fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IssueActivity
|
model = IssueActivity
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
|
|
||||||
|
|
||||||
class IssueCommentSerializer(BaseSerializer):
|
|
||||||
actor_detail = UserLiteSerializer(read_only=True, source="actor")
|
|
||||||
issue_detail = IssueFlatSerializer(read_only=True, source="issue")
|
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
|
||||||
workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace")
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = IssueComment
|
|
||||||
fields = "__all__"
|
|
||||||
read_only_fields = [
|
|
||||||
"workspace",
|
|
||||||
"project",
|
|
||||||
"issue",
|
|
||||||
"created_by",
|
|
||||||
"updated_by",
|
|
||||||
"created_at",
|
|
||||||
"updated_at",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class IssuePropertySerializer(BaseSerializer):
|
class IssuePropertySerializer(BaseSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IssueProperty
|
model = IssueProperty
|
||||||
@ -337,8 +331,14 @@ class IssuePropertySerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class LabelSerializer(BaseSerializer):
|
class LabelSerializer(BaseSerializer):
|
||||||
workspace_detail = WorkspaceLiteSerializer(source="workspace", read_only=True)
|
workspace_detail = WorkSpaceSerializer(
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
source="workspace", fields=("id", "name", "slug"), read_only=True
|
||||||
|
)
|
||||||
|
project_detail = ProjectSerializer(
|
||||||
|
source="project",
|
||||||
|
fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Label
|
model = Label
|
||||||
@ -399,12 +399,16 @@ class BlockerIssueSerializer(BaseSerializer):
|
|||||||
read_only_fields = fields
|
read_only_fields = fields
|
||||||
|
|
||||||
|
|
||||||
class IssueAssigneeSerializer(BaseSerializer):
|
# class IssueAssigneeSerializer(BaseSerializer):
|
||||||
assignee_details = UserLiteSerializer(read_only=True, source="assignee")
|
# assignee_details = UserSerializer(
|
||||||
|
# source="assignee",
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
# read_only=True,
|
||||||
|
# )
|
||||||
|
|
||||||
class Meta:
|
# class Meta:
|
||||||
model = IssueAssignee
|
# model = IssueAssignee
|
||||||
fields = "__all__"
|
# fields = "__all__"
|
||||||
|
|
||||||
|
|
||||||
class CycleBaseSerializer(BaseSerializer):
|
class CycleBaseSerializer(BaseSerializer):
|
||||||
@ -468,7 +472,11 @@ class IssueModuleDetailSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class IssueLinkSerializer(BaseSerializer):
|
class IssueLinkSerializer(BaseSerializer):
|
||||||
created_by_detail = UserLiteSerializer(read_only=True, source="created_by")
|
created_by_detail = UserSerializer(
|
||||||
|
source="created_by",
|
||||||
|
fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IssueLink
|
model = IssueLink
|
||||||
@ -522,7 +530,11 @@ class IssueReactionSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class IssueReactionLiteSerializer(BaseSerializer):
|
class IssueReactionLiteSerializer(BaseSerializer):
|
||||||
actor_detail = UserLiteSerializer(read_only=True, source="actor")
|
actor_detail = UserSerializer(
|
||||||
|
source="actor",
|
||||||
|
fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IssueReaction
|
model = IssueReaction
|
||||||
@ -535,7 +547,11 @@ class IssueReactionLiteSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class CommentReactionLiteSerializer(BaseSerializer):
|
class CommentReactionLiteSerializer(BaseSerializer):
|
||||||
actor_detail = UserLiteSerializer(read_only=True, source="actor")
|
actor_detail = UserSerializer(
|
||||||
|
source="actor",
|
||||||
|
fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CommentReaction
|
model = CommentReaction
|
||||||
@ -554,9 +570,7 @@ class CommentReactionSerializer(BaseSerializer):
|
|||||||
read_only_fields = ["workspace", "project", "comment", "actor"]
|
read_only_fields = ["workspace", "project", "comment", "actor"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IssueVoteSerializer(BaseSerializer):
|
class IssueVoteSerializer(BaseSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IssueVote
|
model = IssueVote
|
||||||
fields = ["issue", "vote", "workspace_id", "project_id", "actor"]
|
fields = ["issue", "vote", "workspace_id", "project_id", "actor"]
|
||||||
@ -564,12 +578,20 @@ class IssueVoteSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class IssueCommentSerializer(BaseSerializer):
|
class IssueCommentSerializer(BaseSerializer):
|
||||||
actor_detail = UserLiteSerializer(read_only=True, source="actor")
|
actor_detail = UserSerializer(source="actor", read_only=True)
|
||||||
issue_detail = IssueFlatSerializer(read_only=True, source="issue")
|
issue_detail = IssueFlatSerializer(read_only=True, source="issue")
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(
|
||||||
workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace")
|
source="project",
|
||||||
comment_reactions = CommentReactionLiteSerializer(read_only=True, many=True)
|
fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
workspace_details = WorkSpaceSerializer(
|
||||||
|
source="workspace",
|
||||||
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
comment_reactions = CommentReactionLiteSerializer(read_only=True, many=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IssueComment
|
model = IssueComment
|
||||||
@ -588,7 +610,11 @@ class IssueCommentSerializer(BaseSerializer):
|
|||||||
|
|
||||||
class IssueStateFlatSerializer(BaseSerializer):
|
class IssueStateFlatSerializer(BaseSerializer):
|
||||||
state_detail = StateLiteSerializer(read_only=True, source="state")
|
state_detail = StateLiteSerializer(read_only=True, source="state")
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(
|
||||||
|
source="project",
|
||||||
|
fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Issue
|
model = Issue
|
||||||
@ -605,8 +631,17 @@ class IssueStateFlatSerializer(BaseSerializer):
|
|||||||
class IssueStateSerializer(BaseSerializer):
|
class IssueStateSerializer(BaseSerializer):
|
||||||
label_details = LabelLiteSerializer(read_only=True, source="labels", many=True)
|
label_details = LabelLiteSerializer(read_only=True, source="labels", many=True)
|
||||||
state_detail = StateLiteSerializer(read_only=True, source="state")
|
state_detail = StateLiteSerializer(read_only=True, source="state")
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(
|
||||||
assignee_details = UserLiteSerializer(read_only=True, source="assignees", many=True)
|
source="project",
|
||||||
|
fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
assignee_details = UserSerializer(
|
||||||
|
source="assignees",
|
||||||
|
fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
many=True,
|
||||||
|
)
|
||||||
sub_issues_count = serializers.IntegerField(read_only=True)
|
sub_issues_count = serializers.IntegerField(read_only=True)
|
||||||
bridge_id = serializers.UUIDField(read_only=True)
|
bridge_id = serializers.UUIDField(read_only=True)
|
||||||
attachment_count = serializers.IntegerField(read_only=True)
|
attachment_count = serializers.IntegerField(read_only=True)
|
||||||
@ -618,11 +653,20 @@ class IssueStateSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class IssueSerializer(BaseSerializer):
|
class IssueSerializer(BaseSerializer):
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(
|
||||||
|
source="project",
|
||||||
|
fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
state_detail = StateSerializer(read_only=True, source="state")
|
state_detail = StateSerializer(read_only=True, source="state")
|
||||||
parent_detail = IssueStateFlatSerializer(read_only=True, source="parent")
|
parent_detail = IssueStateFlatSerializer(read_only=True, source="parent")
|
||||||
label_details = LabelSerializer(read_only=True, source="labels", many=True)
|
label_details = LabelSerializer(read_only=True, source="labels", many=True)
|
||||||
assignee_details = UserLiteSerializer(read_only=True, source="assignees", many=True)
|
assignee_details = UserSerializer(
|
||||||
|
source="assignees",
|
||||||
|
fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
many=True,
|
||||||
|
)
|
||||||
# List of issues blocked by this issue
|
# List of issues blocked by this issue
|
||||||
blocked_issues = BlockedIssueSerializer(read_only=True, many=True)
|
blocked_issues = BlockedIssueSerializer(read_only=True, many=True)
|
||||||
# List of issues that block this issue
|
# List of issues that block this issue
|
||||||
@ -648,11 +692,24 @@ class IssueSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class IssueLiteSerializer(BaseSerializer):
|
class IssueLiteSerializer(BaseSerializer):
|
||||||
workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace")
|
workspace_detail = WorkSpaceSerializer(
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
source="workspace",
|
||||||
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
project_detail = ProjectSerializer(
|
||||||
|
source="project",
|
||||||
|
fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
state_detail = StateLiteSerializer(read_only=True, source="state")
|
state_detail = StateLiteSerializer(read_only=True, source="state")
|
||||||
label_details = LabelLiteSerializer(read_only=True, source="labels", many=True)
|
label_details = LabelLiteSerializer(read_only=True, source="labels", many=True)
|
||||||
assignee_details = UserLiteSerializer(read_only=True, source="assignees", many=True)
|
assignee_details = UserSerializer(
|
||||||
|
source="assignees",
|
||||||
|
fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
many=True,
|
||||||
|
)
|
||||||
sub_issues_count = serializers.IntegerField(read_only=True)
|
sub_issues_count = serializers.IntegerField(read_only=True)
|
||||||
cycle_id = serializers.UUIDField(read_only=True)
|
cycle_id = serializers.UUIDField(read_only=True)
|
||||||
module_id = serializers.UUIDField(read_only=True)
|
module_id = serializers.UUIDField(read_only=True)
|
||||||
|
@ -3,9 +3,9 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .user import UserLiteSerializer
|
from .user import UserSerializer
|
||||||
from .project import ProjectSerializer, ProjectLiteSerializer
|
from .project import ProjectSerializer
|
||||||
from .workspace import WorkspaceLiteSerializer
|
from .workspace import WorkSpaceSerializer
|
||||||
from .issue import IssueStateSerializer
|
from .issue import IssueStateSerializer
|
||||||
|
|
||||||
from plane.db.models import (
|
from plane.db.models import (
|
||||||
@ -25,8 +25,12 @@ class ModuleWriteSerializer(BaseSerializer):
|
|||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectSerializer(source="project", fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
workspace_detail = WorkspaceLiteSerializer(source="workspace", read_only=True)
|
workspace_detail = WorkSpaceSerializer(
|
||||||
|
source="workspace",
|
||||||
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Module
|
model = Module
|
||||||
@ -106,7 +110,7 @@ class ModuleFlatSerializer(BaseSerializer):
|
|||||||
|
|
||||||
class ModuleIssueSerializer(BaseSerializer):
|
class ModuleIssueSerializer(BaseSerializer):
|
||||||
module_detail = ModuleFlatSerializer(read_only=True, source="module")
|
module_detail = ModuleFlatSerializer(read_only=True, source="module")
|
||||||
issue_detail = ProjectLiteSerializer(read_only=True, source="issue")
|
issue_detail = ProjectSerializer(source="issue", fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
sub_issues_count = serializers.IntegerField(read_only=True)
|
sub_issues_count = serializers.IntegerField(read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -124,7 +128,11 @@ class ModuleIssueSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class ModuleLinkSerializer(BaseSerializer):
|
class ModuleLinkSerializer(BaseSerializer):
|
||||||
created_by_detail = UserLiteSerializer(read_only=True, source="created_by")
|
created_by_detail = UserSerializer(
|
||||||
|
source="created_by",
|
||||||
|
fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ModuleLink
|
model = ModuleLink
|
||||||
@ -151,9 +159,18 @@ class ModuleLinkSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class ModuleSerializer(BaseSerializer):
|
class ModuleSerializer(BaseSerializer):
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(source="project", fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
lead_detail = UserLiteSerializer(read_only=True, source="lead")
|
lead_detail = UserSerializer(
|
||||||
members_detail = UserLiteSerializer(read_only=True, many=True, source="members")
|
source="lead",
|
||||||
|
fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
members_detail = UserSerializer(
|
||||||
|
source="members",
|
||||||
|
fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
many=True,
|
||||||
|
)
|
||||||
link_module = ModuleLinkSerializer(read_only=True, many=True)
|
link_module = ModuleLinkSerializer(read_only=True, many=True)
|
||||||
is_favorite = serializers.BooleanField(read_only=True)
|
is_favorite = serializers.BooleanField(read_only=True)
|
||||||
total_issues = serializers.IntegerField(read_only=True)
|
total_issues = serializers.IntegerField(read_only=True)
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .user import UserLiteSerializer
|
from .user import UserSerializer
|
||||||
from plane.db.models import Notification
|
from plane.db.models import Notification
|
||||||
|
|
||||||
|
|
||||||
class NotificationSerializer(BaseSerializer):
|
class NotificationSerializer(BaseSerializer):
|
||||||
triggered_by_details = UserLiteSerializer(read_only=True, source="triggered_by")
|
triggered_by_details = UserSerializer(
|
||||||
|
source="triggered_by",
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Notification
|
model = Notification
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
|
|
||||||
|
@ -4,15 +4,19 @@ from rest_framework import serializers
|
|||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .issue import IssueFlatSerializer, LabelLiteSerializer
|
from .issue import IssueFlatSerializer, LabelLiteSerializer
|
||||||
from .workspace import WorkspaceLiteSerializer
|
from .workspace import WorkSpaceSerializer
|
||||||
from .project import ProjectLiteSerializer
|
from .project import ProjectSerializer
|
||||||
from plane.db.models import Page, PageBlock, PageFavorite, PageLabel, Label
|
from plane.db.models import Page, PageBlock, PageFavorite, PageLabel, Label
|
||||||
|
|
||||||
|
|
||||||
class PageBlockSerializer(BaseSerializer):
|
class PageBlockSerializer(BaseSerializer):
|
||||||
issue_detail = IssueFlatSerializer(source="issue", read_only=True)
|
issue_detail = IssueFlatSerializer(source="issue", read_only=True)
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectSerializer(source="project", fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
workspace_detail = WorkspaceLiteSerializer(source="workspace", read_only=True)
|
workspace_detail = WorkSpaceSerializer(
|
||||||
|
source="workspace",
|
||||||
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = PageBlock
|
model = PageBlock
|
||||||
@ -39,8 +43,12 @@ class PageSerializer(BaseSerializer):
|
|||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
blocks = PageBlockLiteSerializer(read_only=True, many=True)
|
blocks = PageBlockLiteSerializer(read_only=True, many=True)
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectSerializer(source="project", fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
workspace_detail = WorkspaceLiteSerializer(source="workspace", read_only=True)
|
workspace_detail = WorkSpaceSerializer(
|
||||||
|
source="workspace",
|
||||||
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Page
|
model = Page
|
||||||
|
@ -6,8 +6,8 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from plane.api.serializers.workspace import WorkSpaceSerializer, WorkspaceLiteSerializer
|
from plane.api.serializers.workspace import WorkSpaceSerializer
|
||||||
from plane.api.serializers.user import UserLiteSerializer, UserAdminLiteSerializer
|
from plane.api.serializers.user import UserSerializer
|
||||||
from plane.db.models import (
|
from plane.db.models import (
|
||||||
Project,
|
Project,
|
||||||
ProjectMember,
|
ProjectMember,
|
||||||
@ -19,7 +19,28 @@ from plane.db.models import (
|
|||||||
|
|
||||||
|
|
||||||
class ProjectSerializer(BaseSerializer):
|
class ProjectSerializer(BaseSerializer):
|
||||||
workspace_detail = WorkspaceLiteSerializer(source="workspace", read_only=True)
|
# workspace = WorkSpaceSerializer(read_only=True)
|
||||||
|
default_assignee = UserSerializer(
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
project_lead = UserSerializer(
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
is_favorite = serializers.BooleanField(read_only=True)
|
||||||
|
total_members = serializers.IntegerField(read_only=True)
|
||||||
|
total_cycles = serializers.IntegerField(read_only=True)
|
||||||
|
total_modules = serializers.IntegerField(read_only=True)
|
||||||
|
is_member = serializers.BooleanField(read_only=True)
|
||||||
|
sort_order = serializers.FloatField(read_only=True)
|
||||||
|
member_role = serializers.IntegerField(read_only=True)
|
||||||
|
is_deployed = serializers.BooleanField(read_only=True)
|
||||||
|
workspace_detail = WorkSpaceSerializer(
|
||||||
|
source="workspace",
|
||||||
|
# fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Project
|
model = Project
|
||||||
@ -78,25 +99,16 @@ class ProjectSerializer(BaseSerializer):
|
|||||||
raise serializers.ValidationError(detail="Project Identifier is already taken")
|
raise serializers.ValidationError(detail="Project Identifier is already taken")
|
||||||
|
|
||||||
|
|
||||||
class ProjectLiteSerializer(BaseSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = Project
|
|
||||||
fields = [
|
|
||||||
"id",
|
|
||||||
"identifier",
|
|
||||||
"name",
|
|
||||||
"cover_image",
|
|
||||||
"icon_prop",
|
|
||||||
"emoji",
|
|
||||||
"description",
|
|
||||||
]
|
|
||||||
read_only_fields = fields
|
|
||||||
|
|
||||||
|
|
||||||
class ProjectDetailSerializer(BaseSerializer):
|
class ProjectDetailSerializer(BaseSerializer):
|
||||||
workspace = WorkSpaceSerializer(read_only=True)
|
workspace = WorkSpaceSerializer(read_only=True)
|
||||||
default_assignee = UserLiteSerializer(read_only=True)
|
default_assignee = UserSerializer(
|
||||||
project_lead = UserLiteSerializer(read_only=True)
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
project_lead = UserSerializer(
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
is_favorite = serializers.BooleanField(read_only=True)
|
is_favorite = serializers.BooleanField(read_only=True)
|
||||||
total_members = serializers.IntegerField(read_only=True)
|
total_members = serializers.IntegerField(read_only=True)
|
||||||
total_cycles = serializers.IntegerField(read_only=True)
|
total_cycles = serializers.IntegerField(read_only=True)
|
||||||
@ -113,8 +125,11 @@ class ProjectDetailSerializer(BaseSerializer):
|
|||||||
|
|
||||||
class ProjectMemberSerializer(BaseSerializer):
|
class ProjectMemberSerializer(BaseSerializer):
|
||||||
workspace = WorkSpaceSerializer(read_only=True)
|
workspace = WorkSpaceSerializer(read_only=True)
|
||||||
project = ProjectLiteSerializer(read_only=True)
|
project = ProjectSerializer(fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
member = UserLiteSerializer(read_only=True)
|
member = UserSerializer(
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProjectMember
|
model = ProjectMember
|
||||||
@ -122,9 +137,24 @@ class ProjectMemberSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class ProjectMemberAdminSerializer(BaseSerializer):
|
class ProjectMemberAdminSerializer(BaseSerializer):
|
||||||
workspace = WorkspaceLiteSerializer(read_only=True)
|
workspace = WorkSpaceSerializer(
|
||||||
project = ProjectLiteSerializer(read_only=True)
|
source="workspace",
|
||||||
member = UserAdminLiteSerializer(read_only=True)
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
project = ProjectSerializer(fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
|
member = UserSerializer(
|
||||||
|
# fields=(
|
||||||
|
# "id",
|
||||||
|
# "first_name",
|
||||||
|
# "last_name",
|
||||||
|
# "avatar",
|
||||||
|
# "is_bot",
|
||||||
|
# "display_name",
|
||||||
|
# "email",
|
||||||
|
# ),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProjectMember
|
model = ProjectMember
|
||||||
@ -132,8 +162,11 @@ class ProjectMemberAdminSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class ProjectMemberInviteSerializer(BaseSerializer):
|
class ProjectMemberInviteSerializer(BaseSerializer):
|
||||||
project = ProjectLiteSerializer(read_only=True)
|
project = ProjectSerializer(fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
workspace = WorkspaceLiteSerializer(read_only=True)
|
workspace = WorkSpaceSerializer(
|
||||||
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProjectMemberInvite
|
model = ProjectMemberInvite
|
||||||
@ -147,7 +180,7 @@ class ProjectIdentifierSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class ProjectFavoriteSerializer(BaseSerializer):
|
class ProjectFavoriteSerializer(BaseSerializer):
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectSerializer(source="project", fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProjectFavorite
|
model = ProjectFavorite
|
||||||
@ -159,7 +192,10 @@ class ProjectFavoriteSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class ProjectMemberLiteSerializer(BaseSerializer):
|
class ProjectMemberLiteSerializer(BaseSerializer):
|
||||||
member = UserLiteSerializer(read_only=True)
|
member = UserSerializer(
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
is_subscribed = serializers.BooleanField(read_only=True)
|
is_subscribed = serializers.BooleanField(read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -169,8 +205,12 @@ class ProjectMemberLiteSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class ProjectDeployBoardSerializer(BaseSerializer):
|
class ProjectDeployBoardSerializer(BaseSerializer):
|
||||||
project_details = ProjectLiteSerializer(read_only=True, source="project")
|
project_details = ProjectSerializer(source="project", fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace")
|
workspace_detail = WorkSpaceSerializer(
|
||||||
|
source="workspace",
|
||||||
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProjectDeployBoard
|
model = ProjectDeployBoard
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .workspace import WorkspaceLiteSerializer
|
from .workspace import WorkSpaceSerializer
|
||||||
from .project import ProjectLiteSerializer
|
from .project import ProjectSerializer
|
||||||
|
|
||||||
from plane.db.models import State
|
from plane.db.models import State
|
||||||
|
|
||||||
|
|
||||||
class StateSerializer(BaseSerializer):
|
class StateSerializer(BaseSerializer):
|
||||||
workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace")
|
workspace_detail = WorkSpaceSerializer(source="workspace", read_only=True)
|
||||||
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
project_detail = ProjectSerializer(source="project", read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = State
|
model = State
|
||||||
|
@ -33,42 +33,6 @@ class UserSerializer(BaseSerializer):
|
|||||||
return bool(obj.first_name) or bool(obj.last_name)
|
return bool(obj.first_name) or bool(obj.last_name)
|
||||||
|
|
||||||
|
|
||||||
class UserLiteSerializer(BaseSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = User
|
|
||||||
fields = [
|
|
||||||
"id",
|
|
||||||
"first_name",
|
|
||||||
"last_name",
|
|
||||||
"avatar",
|
|
||||||
"is_bot",
|
|
||||||
"display_name",
|
|
||||||
]
|
|
||||||
read_only_fields = [
|
|
||||||
"id",
|
|
||||||
"is_bot",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class UserAdminLiteSerializer(BaseSerializer):
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = User
|
|
||||||
fields = [
|
|
||||||
"id",
|
|
||||||
"first_name",
|
|
||||||
"last_name",
|
|
||||||
"avatar",
|
|
||||||
"is_bot",
|
|
||||||
"display_name",
|
|
||||||
"email",
|
|
||||||
]
|
|
||||||
read_only_fields = [
|
|
||||||
"id",
|
|
||||||
"is_bot",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class ChangePasswordSerializer(serializers.Serializer):
|
class ChangePasswordSerializer(serializers.Serializer):
|
||||||
model = User
|
model = User
|
||||||
|
|
||||||
|
@ -3,16 +3,20 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .workspace import WorkspaceLiteSerializer
|
from .workspace import WorkSpaceSerializer
|
||||||
from .project import ProjectLiteSerializer
|
from .project import ProjectSerializer
|
||||||
from plane.db.models import IssueView, IssueViewFavorite
|
from plane.db.models import IssueView, IssueViewFavorite
|
||||||
from plane.utils.issue_filters import issue_filters
|
from plane.utils.issue_filters import issue_filters
|
||||||
|
|
||||||
|
|
||||||
class IssueViewSerializer(BaseSerializer):
|
class IssueViewSerializer(BaseSerializer):
|
||||||
is_favorite = serializers.BooleanField(read_only=True)
|
is_favorite = serializers.BooleanField(read_only=True)
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectSerializer(source="project", fields=("id", "name", "cover_image", "icon_prop", "emoji", "description"), read_only=True)
|
||||||
workspace_detail = WorkspaceLiteSerializer(source="workspace", read_only=True)
|
workspace_detail = WorkSpaceSerializer(
|
||||||
|
source="workspace",
|
||||||
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IssueView
|
model = IssueView
|
||||||
|
@ -3,7 +3,7 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .user import UserLiteSerializer, UserAdminLiteSerializer
|
from .user import UserSerializer
|
||||||
|
|
||||||
from plane.db.models import (
|
from plane.db.models import (
|
||||||
User,
|
User,
|
||||||
@ -17,7 +17,10 @@ from plane.db.models import (
|
|||||||
|
|
||||||
|
|
||||||
class WorkSpaceSerializer(BaseSerializer):
|
class WorkSpaceSerializer(BaseSerializer):
|
||||||
owner = UserLiteSerializer(read_only=True)
|
owner = UserSerializer(
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
total_members = serializers.IntegerField(read_only=True)
|
total_members = serializers.IntegerField(read_only=True)
|
||||||
total_issues = serializers.IntegerField(read_only=True)
|
total_issues = serializers.IntegerField(read_only=True)
|
||||||
|
|
||||||
@ -33,30 +36,16 @@ class WorkSpaceSerializer(BaseSerializer):
|
|||||||
"owner",
|
"owner",
|
||||||
]
|
]
|
||||||
|
|
||||||
class WorkspaceLiteSerializer(BaseSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = Workspace
|
|
||||||
fields = [
|
|
||||||
"name",
|
|
||||||
"slug",
|
|
||||||
"id",
|
|
||||||
]
|
|
||||||
read_only_fields = fields
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WorkSpaceMemberSerializer(BaseSerializer):
|
class WorkSpaceMemberSerializer(BaseSerializer):
|
||||||
member = UserLiteSerializer(read_only=True)
|
member = UserSerializer(
|
||||||
workspace = WorkspaceLiteSerializer(read_only=True)
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name" ,"email"),
|
||||||
|
read_only=True,
|
||||||
class Meta:
|
)
|
||||||
model = WorkspaceMember
|
workspace = WorkSpaceSerializer(
|
||||||
fields = "__all__"
|
fields=("id", "name", "slug"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
class WorkspaceMemberAdminSerializer(BaseSerializer):
|
|
||||||
member = UserAdminLiteSerializer(read_only=True)
|
|
||||||
workspace = WorkspaceLiteSerializer(read_only=True)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WorkspaceMember
|
model = WorkspaceMember
|
||||||
@ -66,7 +55,11 @@ class WorkspaceMemberAdminSerializer(BaseSerializer):
|
|||||||
class WorkSpaceMemberInviteSerializer(BaseSerializer):
|
class WorkSpaceMemberInviteSerializer(BaseSerializer):
|
||||||
workspace = WorkSpaceSerializer(read_only=True)
|
workspace = WorkSpaceSerializer(read_only=True)
|
||||||
total_members = serializers.IntegerField(read_only=True)
|
total_members = serializers.IntegerField(read_only=True)
|
||||||
created_by_detail = UserLiteSerializer(read_only=True, source="created_by")
|
created_by_detail = UserSerializer(
|
||||||
|
source="created_by",
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WorkspaceMemberInvite
|
model = WorkspaceMemberInvite
|
||||||
@ -74,7 +67,12 @@ class WorkSpaceMemberInviteSerializer(BaseSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class TeamSerializer(BaseSerializer):
|
class TeamSerializer(BaseSerializer):
|
||||||
members_detail = UserLiteSerializer(read_only=True, source="members", many=True)
|
members_detail = UserSerializer(
|
||||||
|
source="members",
|
||||||
|
# fields=("id", "first_name", "last_name", "avatar", "is_bot", "display_name"),
|
||||||
|
read_only=True,
|
||||||
|
many=True,
|
||||||
|
)
|
||||||
members = serializers.ListField(
|
members = serializers.ListField(
|
||||||
child=serializers.PrimaryKeyRelatedField(queryset=User.objects.all()),
|
child=serializers.PrimaryKeyRelatedField(queryset=User.objects.all()),
|
||||||
write_only=True,
|
write_only=True,
|
||||||
|
@ -56,6 +56,10 @@ class CycleViewSet(BaseViewSet):
|
|||||||
permission_classes = [
|
permission_classes = [
|
||||||
ProjectEntityPermission,
|
ProjectEntityPermission,
|
||||||
]
|
]
|
||||||
|
# def get_serializer_class(self):
|
||||||
|
# return (
|
||||||
|
# CycleSerializer(nested_fields={"owned_by":("id", "first_name", "last_name", "avatar", "is_bot", "display_name")})
|
||||||
|
# )
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
serializer.save(
|
serializer.save(
|
||||||
@ -148,13 +152,15 @@ class CycleViewSet(BaseViewSet):
|
|||||||
.prefetch_related(
|
.prefetch_related(
|
||||||
Prefetch(
|
Prefetch(
|
||||||
"issue_cycle__issue__assignees",
|
"issue_cycle__issue__assignees",
|
||||||
queryset=User.objects.only("avatar", "first_name", "id").distinct(),
|
queryset=User.objects.only(
|
||||||
|
"avatar", "first_name", "id").distinct(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.prefetch_related(
|
.prefetch_related(
|
||||||
Prefetch(
|
Prefetch(
|
||||||
"issue_cycle__issue__labels",
|
"issue_cycle__issue__labels",
|
||||||
queryset=Label.objects.only("name", "color", "id").distinct(),
|
queryset=Label.objects.only(
|
||||||
|
"name", "color", "id").distinct(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.order_by("-is_favorite", "name")
|
.order_by("-is_favorite", "name")
|
||||||
@ -172,7 +178,8 @@ class CycleViewSet(BaseViewSet):
|
|||||||
# All Cycles
|
# All Cycles
|
||||||
if cycle_view == "all":
|
if cycle_view == "all":
|
||||||
return Response(
|
return Response(
|
||||||
CycleSerializer(queryset, many=True).data, status=status.HTTP_200_OK
|
CycleSerializer(queryset, fields=["id", "created_by", "created_at", "updated_at", "updated_by", "project", "workspace", "name", "description", "start_date", "end_date", "owned_by", "view_props", "sort_order", "is_favorite", "total_issues", "cancelled_issues", "completed_issues", "started_issues", "unstarted_issues"
|
||||||
|
, "backlog_issues", "assignees", "labels", "total_estimates", "completed_estimates", "started_estimates",{"workspace_detail": ["id", "name","slug"]},{ "project_detail": ["id", "name", "cover_image", "icon_prop", "emoji", "description"]}, {"owned_by": ["id", "first_name", "last_name", "avatar", "is_bot", "display_name"]}], many=True).data, status=status.HTTP_200_OK
|
||||||
)
|
)
|
||||||
|
|
||||||
# Current Cycle
|
# Current Cycle
|
||||||
@ -182,7 +189,8 @@ class CycleViewSet(BaseViewSet):
|
|||||||
end_date__gte=timezone.now(),
|
end_date__gte=timezone.now(),
|
||||||
)
|
)
|
||||||
|
|
||||||
data = CycleSerializer(queryset, many=True).data
|
data = CycleSerializer(queryset, fields=["id", "created_by", "created_at", "updated_at", "updated_by", "project", "workspace", "name", "description", "start_date", "end_date", "owned_by", "view_props", "sort_order", "is_favorite", "total_issues", "cancelled_issues", "completed_issues", "started_issues", "unstarted_issues"
|
||||||
|
, "backlog_issues", "assignees", "labels", "total_estimates", "completed_estimates", "started_estimates",{"workspace_detail": ["id", "name","slug"]},{ "project_detail": ["id", "name", "cover_image", "icon_prop", "emoji", "description"]}, {"owned_by": ["id", "first_name", "last_name", "avatar", "is_bot", "display_name"]}], many=True).data
|
||||||
|
|
||||||
if len(data):
|
if len(data):
|
||||||
assignee_distribution = (
|
assignee_distribution = (
|
||||||
@ -256,14 +264,16 @@ class CycleViewSet(BaseViewSet):
|
|||||||
if cycle_view == "upcoming":
|
if cycle_view == "upcoming":
|
||||||
queryset = queryset.filter(start_date__gt=timezone.now())
|
queryset = queryset.filter(start_date__gt=timezone.now())
|
||||||
return Response(
|
return Response(
|
||||||
CycleSerializer(queryset, many=True).data, status=status.HTTP_200_OK
|
CycleSerializer(queryset, fields=["id", "created_by", "created_at", "updated_at", "updated_by", "project", "workspace", "name", "description", "start_date", "end_date", "owned_by", "view_props", "sort_order", "is_favorite", "total_issues", "cancelled_issues", "completed_issues", "started_issues", "unstarted_issues"
|
||||||
|
, "backlog_issues", "assignees", "labels", "total_estimates", "completed_estimates", "started_estimates",{"workspace_detail": ["id", "name","slug"]},{ "project_detail": ["id", "name", "cover_image", "icon_prop", "emoji", "description"]}, {"owned_by": ["id", "first_name", "last_name", "avatar", "is_bot", "display_name"]}], many=True).data, status=status.HTTP_200_OK
|
||||||
)
|
)
|
||||||
|
|
||||||
# Completed Cycles
|
# Completed Cycles
|
||||||
if cycle_view == "completed":
|
if cycle_view == "completed":
|
||||||
queryset = queryset.filter(end_date__lt=timezone.now())
|
queryset = queryset.filter(end_date__lt=timezone.now())
|
||||||
return Response(
|
return Response(
|
||||||
CycleSerializer(queryset, many=True).data, status=status.HTTP_200_OK
|
CycleSerializer(queryset, fields=["id", "created_by", "created_at", "updated_at", "updated_by", "project", "workspace", "name", "description", "start_date", "end_date", "owned_by", "view_props", "sort_order", "is_favorite", "total_issues", "cancelled_issues", "completed_issues", "started_issues", "unstarted_issues"
|
||||||
|
, "backlog_issues", "assignees", "labels", "total_estimates", "completed_estimates", "started_estimates",{"workspace_detail": ["id", "name","slug"]},{ "project_detail": ["id", "name", "cover_image", "icon_prop", "emoji", "description"]}, {"owned_by": ["id", "first_name", "last_name", "avatar", "is_bot", "display_name"]}], many=True).data, status=status.HTTP_200_OK
|
||||||
)
|
)
|
||||||
|
|
||||||
# Draft Cycles
|
# Draft Cycles
|
||||||
@ -274,16 +284,19 @@ class CycleViewSet(BaseViewSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
CycleSerializer(queryset, many=True).data, status=status.HTTP_200_OK
|
CycleSerializer(queryset, fields=["id", "created_by", "created_at", "updated_at", "updated_by", "project", "workspace", "name", "description", "start_date", "end_date", "owned_by", "view_props", "sort_order", "is_favorite", "total_issues", "cancelled_issues", "completed_issues", "started_issues", "unstarted_issues"
|
||||||
|
, "backlog_issues", "assignees", "labels", "total_estimates", "completed_estimates", "started_estimates",{"workspace_detail": ["id", "name","slug"]},{ "project_detail": ["id", "name", "cover_image", "icon_prop", "emoji", "description"]}, {"owned_by": ["id", "first_name", "last_name", "avatar", "is_bot", "display_name"]}], many=True).data, status=status.HTTP_200_OK
|
||||||
)
|
)
|
||||||
|
|
||||||
# Incomplete Cycles
|
# Incomplete Cycles
|
||||||
if cycle_view == "incomplete":
|
if cycle_view == "incomplete":
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
Q(end_date__gte=timezone.now().date()) | Q(end_date__isnull=True),
|
Q(end_date__gte=timezone.now().date()) | Q(
|
||||||
|
end_date__isnull=True),
|
||||||
)
|
)
|
||||||
return Response(
|
return Response(
|
||||||
CycleSerializer(queryset, many=True).data, status=status.HTTP_200_OK
|
CycleSerializer(queryset, fields=["id", "created_by", "created_at", "updated_at", "updated_by", "project", "workspace", "name", "description", "start_date", "end_date", "owned_by", "view_props", "sort_order", "is_favorite", "total_issues", "cancelled_issues", "completed_issues", "started_issues", "unstarted_issues"
|
||||||
|
, "backlog_issues", "assignees", "labels", "total_estimates", "completed_estimates", "started_estimates",{"workspace_detail": ["id", "name","slug"]},{ "project_detail": ["id", "name", "cover_image", "icon_prop", "emoji", "description"]}, {"owned_by": ["id", "first_name", "last_name", "avatar", "is_bot", "display_name"]}], many=True).data, status=status.HTTP_200_OK
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
@ -306,7 +319,8 @@ class CycleViewSet(BaseViewSet):
|
|||||||
request.data.get("start_date", None) is not None
|
request.data.get("start_date", None) is not None
|
||||||
and request.data.get("end_date", None) is not None
|
and request.data.get("end_date", None) is not None
|
||||||
):
|
):
|
||||||
serializer = CycleSerializer(data=request.data)
|
serializer = CycleSerializer(data=request.data, fields=["id", "created_by", "created_at", "updated_at", "updated_by", "project", "workspace", "name", "description", "start_date", "end_date", "owned_by", "view_props", "sort_order", "is_favorite", "total_issues", "cancelled_issues", "completed_issues", "started_issues", "unstarted_issues"
|
||||||
|
, "backlog_issues", "assignees", "labels", "total_estimates", "completed_estimates", "started_estimates",{"workspace_detail": ["id", "name","slug"]},{ "project_detail": ["id", "name", "cover_image", "icon_prop", "emoji", "description"]}, {"owned_by": ["id", "first_name", "last_name", "avatar", "is_bot", "display_name"]}])
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save(
|
serializer.save(
|
||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
@ -342,7 +356,8 @@ class CycleViewSet(BaseViewSet):
|
|||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
serializer = CycleWriteSerializer(cycle, data=request.data, partial=True)
|
serializer = CycleWriteSerializer(
|
||||||
|
cycle, data=request.data, partial=True)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
@ -418,7 +433,8 @@ class CycleViewSet(BaseViewSet):
|
|||||||
.order_by("label_name")
|
.order_by("label_name")
|
||||||
)
|
)
|
||||||
|
|
||||||
data = CycleSerializer(queryset).data
|
data = CycleSerializer(queryset, fields=["id", "created_by", "created_at", "updated_at", "updated_by", "project", "workspace", "name", "description", "start_date", "end_date", "owned_by", "view_props", "sort_order", "is_favorite", "total_issues", "cancelled_issues", "completed_issues", "started_issues", "unstarted_issues"
|
||||||
|
, "backlog_issues", "assignees", "labels", "total_estimates", "completed_estimates", "started_estimates",{"workspace_detail": ["id", "name","slug"]},{ "project_detail": ["id", "name", "cover_image", "icon_prop", "emoji", "description"]}, {"owned_by": ["id", "first_name", "last_name", "avatar", "is_bot", "display_name"]}]).data
|
||||||
data["distribution"] = {
|
data["distribution"] = {
|
||||||
"assignees": assignee_distribution,
|
"assignees": assignee_distribution,
|
||||||
"labels": label_distribution,
|
"labels": label_distribution,
|
||||||
@ -486,7 +502,8 @@ class CycleIssueViewSet(BaseViewSet):
|
|||||||
super()
|
super()
|
||||||
.get_queryset()
|
.get_queryset()
|
||||||
.annotate(
|
.annotate(
|
||||||
sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("issue_id"))
|
sub_issues_count=Issue.issue_objects.filter(
|
||||||
|
parent=OuterRef("issue_id"))
|
||||||
.order_by()
|
.order_by()
|
||||||
.annotate(count=Func(F("id"), function="Count"))
|
.annotate(count=Func(F("id"), function="Count"))
|
||||||
.values("count")
|
.values("count")
|
||||||
@ -512,7 +529,8 @@ class CycleIssueViewSet(BaseViewSet):
|
|||||||
issues = (
|
issues = (
|
||||||
Issue.issue_objects.filter(issue_cycle__cycle_id=cycle_id)
|
Issue.issue_objects.filter(issue_cycle__cycle_id=cycle_id)
|
||||||
.annotate(
|
.annotate(
|
||||||
sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id"))
|
sub_issues_count=Issue.issue_objects.filter(
|
||||||
|
parent=OuterRef("id"))
|
||||||
.order_by()
|
.order_by()
|
||||||
.annotate(count=Func(F("id"), function="Count"))
|
.annotate(count=Func(F("id"), function="Count"))
|
||||||
.values("count")
|
.values("count")
|
||||||
|
@ -13,7 +13,6 @@ from plane.db.models import Project, Estimate, EstimatePoint
|
|||||||
from plane.api.serializers import (
|
from plane.api.serializers import (
|
||||||
EstimateSerializer,
|
EstimateSerializer,
|
||||||
EstimatePointSerializer,
|
EstimatePointSerializer,
|
||||||
EstimateReadSerializer,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -51,10 +50,38 @@ class BulkEstimatePointEndpoint(BaseViewSet):
|
|||||||
|
|
||||||
def list(self, request, slug, project_id):
|
def list(self, request, slug, project_id):
|
||||||
try:
|
try:
|
||||||
estimates = Estimate.objects.filter(
|
estimates = (
|
||||||
workspace__slug=slug, project_id=project_id
|
Estimate.objects.filter(workspace__slug=slug, project_id=project_id)
|
||||||
).prefetch_related("points").select_related("workspace", "project")
|
.prefetch_related("points")
|
||||||
serializer = EstimateReadSerializer(estimates, many=True)
|
.select_related("workspace", "project")
|
||||||
|
)
|
||||||
|
serializer = EstimateSerializer(
|
||||||
|
estimates,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"created_by",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name",
|
||||||
|
"points",
|
||||||
|
"description",
|
||||||
|
],
|
||||||
|
many=True,
|
||||||
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
@ -79,7 +106,31 @@ class BulkEstimatePointEndpoint(BaseViewSet):
|
|||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
estimate_serializer = EstimateSerializer(data=request.data.get("estimate"))
|
estimate_serializer = EstimateSerializer(
|
||||||
|
data=request.data.get("estimate"),
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"created_by",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
],
|
||||||
|
)
|
||||||
if not estimate_serializer.is_valid():
|
if not estimate_serializer.is_valid():
|
||||||
return Response(
|
return Response(
|
||||||
estimate_serializer.errors, status=status.HTTP_400_BAD_REQUEST
|
estimate_serializer.errors, status=status.HTTP_400_BAD_REQUEST
|
||||||
@ -137,7 +188,32 @@ class BulkEstimatePointEndpoint(BaseViewSet):
|
|||||||
estimate = Estimate.objects.get(
|
estimate = Estimate.objects.get(
|
||||||
pk=estimate_id, workspace__slug=slug, project_id=project_id
|
pk=estimate_id, workspace__slug=slug, project_id=project_id
|
||||||
)
|
)
|
||||||
serializer = EstimateReadSerializer(estimate)
|
serializer = EstimateSerializer(
|
||||||
|
estimate,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"created_by",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name",
|
||||||
|
"points",
|
||||||
|
"description",
|
||||||
|
],
|
||||||
|
)
|
||||||
return Response(
|
return Response(
|
||||||
serializer.data,
|
serializer.data,
|
||||||
status=status.HTTP_200_OK,
|
status=status.HTTP_200_OK,
|
||||||
@ -170,7 +246,31 @@ class BulkEstimatePointEndpoint(BaseViewSet):
|
|||||||
estimate = Estimate.objects.get(pk=estimate_id)
|
estimate = Estimate.objects.get(pk=estimate_id)
|
||||||
|
|
||||||
estimate_serializer = EstimateSerializer(
|
estimate_serializer = EstimateSerializer(
|
||||||
estimate, data=request.data.get("estimate"), partial=True
|
estimate,
|
||||||
|
data=request.data.get("estimate"),
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"created_by",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
],
|
||||||
|
partial=True,
|
||||||
)
|
)
|
||||||
if not estimate_serializer.is_valid():
|
if not estimate_serializer.is_valid():
|
||||||
return Response(
|
return Response(
|
||||||
@ -211,7 +311,9 @@ class BulkEstimatePointEndpoint(BaseViewSet):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
EstimatePoint.objects.bulk_update(
|
EstimatePoint.objects.bulk_update(
|
||||||
updated_estimate_points, ["value"], batch_size=10,
|
updated_estimate_points,
|
||||||
|
["value"],
|
||||||
|
batch_size=10,
|
||||||
)
|
)
|
||||||
except IntegrityError as e:
|
except IntegrityError as e:
|
||||||
return Response(
|
return Response(
|
||||||
@ -219,7 +321,9 @@ class BulkEstimatePointEndpoint(BaseViewSet):
|
|||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
estimate_point_serializer = EstimatePointSerializer(estimate_points, many=True)
|
estimate_point_serializer = EstimatePointSerializer(
|
||||||
|
estimate_points, many=True
|
||||||
|
)
|
||||||
return Response(
|
return Response(
|
||||||
{
|
{
|
||||||
"estimate": estimate_serializer.data,
|
"estimate": estimate_serializer.data,
|
||||||
|
@ -23,11 +23,11 @@ class ExportIssuesEndpoint(BaseAPIView):
|
|||||||
try:
|
try:
|
||||||
# Get the workspace
|
# Get the workspace
|
||||||
workspace = Workspace.objects.get(slug=slug)
|
workspace = Workspace.objects.get(slug=slug)
|
||||||
|
|
||||||
provider = request.data.get("provider", False)
|
provider = request.data.get("provider", False)
|
||||||
multiple = request.data.get("multiple", False)
|
multiple = request.data.get("multiple", False)
|
||||||
project_ids = request.data.get("project", [])
|
project_ids = request.data.get("project", [])
|
||||||
|
|
||||||
if provider in ["csv", "xlsx", "json"]:
|
if provider in ["csv", "xlsx", "json"]:
|
||||||
if not project_ids:
|
if not project_ids:
|
||||||
project_ids = Project.objects.filter(
|
project_ids = Project.objects.filter(
|
||||||
@ -77,14 +77,38 @@ class ExportIssuesEndpoint(BaseAPIView):
|
|||||||
try:
|
try:
|
||||||
exporter_history = ExporterHistory.objects.filter(
|
exporter_history = ExporterHistory.objects.filter(
|
||||||
workspace__slug=slug
|
workspace__slug=slug
|
||||||
).select_related("workspace","initiated_by")
|
).select_related("workspace", "initiated_by")
|
||||||
|
|
||||||
if request.GET.get("per_page", False) and request.GET.get("cursor", False):
|
if request.GET.get("per_page", False) and request.GET.get("cursor", False):
|
||||||
return self.paginate(
|
return self.paginate(
|
||||||
request=request,
|
request=request,
|
||||||
queryset=exporter_history,
|
queryset=exporter_history,
|
||||||
on_results=lambda exporter_history: ExporterHistorySerializer(
|
on_results=lambda exporter_history: ExporterHistorySerializer(
|
||||||
exporter_history, many=True
|
exporter_history,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"initiated_by",
|
||||||
|
"status",
|
||||||
|
"url",
|
||||||
|
"token",
|
||||||
|
"project",
|
||||||
|
"provider",
|
||||||
|
{
|
||||||
|
"initiated_by_detail": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
many=True,
|
||||||
).data,
|
).data,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -14,7 +14,7 @@ from django.conf import settings
|
|||||||
from .base import BaseAPIView
|
from .base import BaseAPIView
|
||||||
from plane.api.permissions import ProjectEntityPermission
|
from plane.api.permissions import ProjectEntityPermission
|
||||||
from plane.db.models import Workspace, Project
|
from plane.db.models import Workspace, Project
|
||||||
from plane.api.serializers import ProjectLiteSerializer, WorkspaceLiteSerializer
|
from plane.api.serializers import ProjectSerializer, WorkSpaceSerializer
|
||||||
|
|
||||||
|
|
||||||
class GPTIntegrationEndpoint(BaseAPIView):
|
class GPTIntegrationEndpoint(BaseAPIView):
|
||||||
@ -57,8 +57,26 @@ class GPTIntegrationEndpoint(BaseAPIView):
|
|||||||
{
|
{
|
||||||
"response": text,
|
"response": text,
|
||||||
"response_html": text_html,
|
"response_html": text_html,
|
||||||
"project_detail": ProjectLiteSerializer(project).data,
|
"project_detail": ProjectSerializer(
|
||||||
"workspace_detail": WorkspaceLiteSerializer(workspace).data,
|
project,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
"created_by",
|
||||||
|
"updated_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
],
|
||||||
|
read_only=True,
|
||||||
|
).data,
|
||||||
|
"workspace_detail": WorkSpaceSerializer(
|
||||||
|
workspace,
|
||||||
|
fields=["id", "name", "slug"],
|
||||||
|
).data,
|
||||||
},
|
},
|
||||||
status=status.HTTP_200_OK,
|
status=status.HTTP_200_OK,
|
||||||
)
|
)
|
||||||
|
@ -42,7 +42,6 @@ from plane.utils.html_processor import strip_tags
|
|||||||
|
|
||||||
|
|
||||||
class ServiceIssueImportSummaryEndpoint(BaseAPIView):
|
class ServiceIssueImportSummaryEndpoint(BaseAPIView):
|
||||||
|
|
||||||
def get(self, request, slug, service):
|
def get(self, request, slug, service):
|
||||||
try:
|
try:
|
||||||
if service == "github":
|
if service == "github":
|
||||||
@ -177,7 +176,47 @@ class ImportServiceEndpoint(BaseAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
service_importer.delay(service, importer.id)
|
service_importer.delay(service, importer.id)
|
||||||
serializer = ImporterSerializer(importer)
|
serializer = ImporterSerializer(
|
||||||
|
importer,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
"service",
|
||||||
|
"status",
|
||||||
|
"initiated_by",
|
||||||
|
"metadata",
|
||||||
|
"config",
|
||||||
|
"data",
|
||||||
|
"token",
|
||||||
|
"imported_data",
|
||||||
|
{
|
||||||
|
"initiated_by_detail": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
],
|
||||||
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
|
|
||||||
if service == "jira":
|
if service == "jira":
|
||||||
@ -213,7 +252,47 @@ class ImportServiceEndpoint(BaseAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
service_importer.delay(service, importer.id)
|
service_importer.delay(service, importer.id)
|
||||||
serializer = ImporterSerializer(importer)
|
serializer = ImporterSerializer(
|
||||||
|
importer,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
"service",
|
||||||
|
"status",
|
||||||
|
"initiated_by",
|
||||||
|
"metadata",
|
||||||
|
"config",
|
||||||
|
"data",
|
||||||
|
"token",
|
||||||
|
"imported_data",
|
||||||
|
{
|
||||||
|
"initiated_by_detail": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
],
|
||||||
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
@ -243,7 +322,48 @@ class ImportServiceEndpoint(BaseAPIView):
|
|||||||
.order_by("-created_at")
|
.order_by("-created_at")
|
||||||
.select_related("initiated_by", "project", "workspace")
|
.select_related("initiated_by", "project", "workspace")
|
||||||
)
|
)
|
||||||
serializer = ImporterSerializer(imports, many=True)
|
serializer = ImporterSerializer(
|
||||||
|
imports,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
"service",
|
||||||
|
"status",
|
||||||
|
"initiated_by",
|
||||||
|
"metadata",
|
||||||
|
"config",
|
||||||
|
"data",
|
||||||
|
"token",
|
||||||
|
"imported_data",
|
||||||
|
{
|
||||||
|
"initiated_by_detail": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
],
|
||||||
|
many=True,
|
||||||
|
)
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
@ -284,7 +404,49 @@ class ImportServiceEndpoint(BaseAPIView):
|
|||||||
importer = Importer.objects.get(
|
importer = Importer.objects.get(
|
||||||
pk=pk, service=service, workspace__slug=slug
|
pk=pk, service=service, workspace__slug=slug
|
||||||
)
|
)
|
||||||
serializer = ImporterSerializer(importer, data=request.data, partial=True)
|
serializer = ImporterSerializer(
|
||||||
|
importer,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
"service",
|
||||||
|
"status",
|
||||||
|
"initiated_by",
|
||||||
|
"metadata",
|
||||||
|
"config",
|
||||||
|
"data",
|
||||||
|
"token",
|
||||||
|
"imported_data",
|
||||||
|
{
|
||||||
|
"initiated_by_detail": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
],
|
||||||
|
data=request.data,
|
||||||
|
partial=True,
|
||||||
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
|
@ -152,7 +152,22 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
issues_data = IssueStateInboxSerializer(issues, many=True).data
|
issues_data = IssueStateInboxSerializer(
|
||||||
|
issues,
|
||||||
|
fields=[
|
||||||
|
{
|
||||||
|
"assignee_details": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
many=True,
|
||||||
|
).data
|
||||||
return Response(
|
return Response(
|
||||||
issues_data,
|
issues_data,
|
||||||
status=status.HTTP_200_OK,
|
status=status.HTTP_200_OK,
|
||||||
@ -222,7 +237,19 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
source=request.data.get("source", "in-app"),
|
source=request.data.get("source", "in-app"),
|
||||||
)
|
)
|
||||||
|
|
||||||
serializer = IssueStateInboxSerializer(issue)
|
serializer = IssueStateInboxSerializer(
|
||||||
|
issue,
|
||||||
|
nested_fields={
|
||||||
|
"assignee_details": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
@ -237,10 +264,17 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
||||||
)
|
)
|
||||||
# Get the project member
|
# Get the project member
|
||||||
project_member = ProjectMember.objects.get(workspace__slug=slug, project_id=project_id, member=request.user)
|
project_member = ProjectMember.objects.get(
|
||||||
|
workspace__slug=slug, project_id=project_id, member=request.user
|
||||||
|
)
|
||||||
# Only project members admins and created_by users can access this endpoint
|
# Only project members admins and created_by users can access this endpoint
|
||||||
if project_member.role <= 10 and str(inbox_issue.created_by_id) != str(request.user.id):
|
if project_member.role <= 10 and str(inbox_issue.created_by_id) != str(
|
||||||
return Response({"error": "You cannot edit inbox issues"}, status=status.HTTP_400_BAD_REQUEST)
|
request.user.id
|
||||||
|
):
|
||||||
|
return Response(
|
||||||
|
{"error": "You cannot edit inbox issues"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
# Get issue data
|
# Get issue data
|
||||||
issue_data = request.data.pop("issue", False)
|
issue_data = request.data.pop("issue", False)
|
||||||
@ -251,15 +285,99 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
)
|
)
|
||||||
# Only allow guests and viewers to edit name and description
|
# Only allow guests and viewers to edit name and description
|
||||||
if project_member.role <= 10:
|
if project_member.role <= 10:
|
||||||
# viewers and guests since only viewers and guests
|
# viewers and guests since only viewers and guests
|
||||||
issue_data = {
|
issue_data = {
|
||||||
"name": issue_data.get("name", issue.name),
|
"name": issue_data.get("name", issue.name),
|
||||||
"description_html": issue_data.get("description_html", issue.description_html),
|
"description_html": issue_data.get(
|
||||||
"description": issue_data.get("description", issue.description)
|
"description_html", issue.description_html
|
||||||
|
),
|
||||||
|
"description": issue_data.get("description", issue.description),
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_serializer = IssueCreateSerializer(
|
issue_serializer = IssueCreateSerializer(
|
||||||
issue, data=issue_data, partial=True
|
issue,
|
||||||
|
data=issue_data,
|
||||||
|
fields=[
|
||||||
|
{
|
||||||
|
"created_by_detail": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state_detail": [
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"color",
|
||||||
|
"slug",
|
||||||
|
"sequence",
|
||||||
|
"group",
|
||||||
|
"default",
|
||||||
|
"project",
|
||||||
|
"workspace",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"created_by",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
"assignees_list",
|
||||||
|
"blockers_list",
|
||||||
|
"labels_list",
|
||||||
|
"blocks_list",
|
||||||
|
"PRIORITY_CHOICES",
|
||||||
|
"parent",
|
||||||
|
"state",
|
||||||
|
"estimate_point",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"description_html",
|
||||||
|
"description_stripped",
|
||||||
|
"priority",
|
||||||
|
"start_date",
|
||||||
|
"target_date",
|
||||||
|
"assignees",
|
||||||
|
"sequence_id",
|
||||||
|
"labels",
|
||||||
|
"sort_order",
|
||||||
|
"completed_at",
|
||||||
|
"archived_at",
|
||||||
|
],
|
||||||
|
partial=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
if issue_serializer.is_valid():
|
if issue_serializer.is_valid():
|
||||||
@ -287,7 +405,30 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
# Only project admins and members can edit inbox issue attributes
|
# Only project admins and members can edit inbox issue attributes
|
||||||
if project_member.role > 10:
|
if project_member.role > 10:
|
||||||
serializer = InboxIssueSerializer(
|
serializer = InboxIssueSerializer(
|
||||||
inbox_issue, data=request.data, partial=True
|
inbox_issue,
|
||||||
|
fields=[
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"inbox",
|
||||||
|
"issue",
|
||||||
|
"status",
|
||||||
|
"snoozed_till",
|
||||||
|
"duplicate_to",
|
||||||
|
"source",
|
||||||
|
],
|
||||||
|
data=request.data,
|
||||||
|
partial=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
@ -300,7 +441,9 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
)
|
)
|
||||||
state = State.objects.filter(
|
state = State.objects.filter(
|
||||||
group="cancelled", workspace__slug=slug, project_id=project_id
|
group="cancelled",
|
||||||
|
workspace__slug=slug,
|
||||||
|
project_id=project_id,
|
||||||
).first()
|
).first()
|
||||||
if state is not None:
|
if state is not None:
|
||||||
issue.state = state
|
issue.state = state
|
||||||
@ -318,7 +461,9 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
if issue.state.name == "Triage":
|
if issue.state.name == "Triage":
|
||||||
# Move to default state
|
# Move to default state
|
||||||
state = State.objects.filter(
|
state = State.objects.filter(
|
||||||
workspace__slug=slug, project_id=project_id, default=True
|
workspace__slug=slug,
|
||||||
|
project_id=project_id,
|
||||||
|
default=True,
|
||||||
).first()
|
).first()
|
||||||
if state is not None:
|
if state is not None:
|
||||||
issue.state = state
|
issue.state = state
|
||||||
@ -327,7 +472,9 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
else:
|
else:
|
||||||
return Response(InboxIssueSerializer(inbox_issue).data, status=status.HTTP_200_OK)
|
return Response(
|
||||||
|
InboxIssueSerializer(inbox_issue).data, status=status.HTTP_200_OK
|
||||||
|
)
|
||||||
except InboxIssue.DoesNotExist:
|
except InboxIssue.DoesNotExist:
|
||||||
return Response(
|
return Response(
|
||||||
{"error": "Inbox Issue does not exist"},
|
{"error": "Inbox Issue does not exist"},
|
||||||
@ -348,7 +495,19 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
issue = Issue.objects.get(
|
issue = Issue.objects.get(
|
||||||
pk=inbox_issue.issue_id, workspace__slug=slug, project_id=project_id
|
pk=inbox_issue.issue_id, workspace__slug=slug, project_id=project_id
|
||||||
)
|
)
|
||||||
serializer = IssueStateInboxSerializer(issue)
|
serializer = IssueStateInboxSerializer(
|
||||||
|
issue,
|
||||||
|
nested_fields={
|
||||||
|
"assignee_details": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
@ -363,15 +522,25 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
||||||
)
|
)
|
||||||
# Get the project member
|
# Get the project member
|
||||||
project_member = ProjectMember.objects.get(workspace__slug=slug, project_id=project_id, member=request.user)
|
project_member = ProjectMember.objects.get(
|
||||||
|
workspace__slug=slug, project_id=project_id, member=request.user
|
||||||
|
)
|
||||||
|
|
||||||
if project_member.role <= 10 and str(inbox_issue.created_by_id) != str(request.user.id):
|
if project_member.role <= 10 and str(inbox_issue.created_by_id) != str(
|
||||||
return Response({"error": "You cannot delete inbox issue"}, status=status.HTTP_400_BAD_REQUEST)
|
request.user.id
|
||||||
|
):
|
||||||
|
return Response(
|
||||||
|
{"error": "You cannot delete inbox issue"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
inbox_issue.delete()
|
inbox_issue.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
except InboxIssue.DoesNotExist:
|
except InboxIssue.DoesNotExist:
|
||||||
return Response({"error": "Inbox Issue does not exists"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "Inbox Issue does not exists"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return Response(
|
return Response(
|
||||||
@ -389,7 +558,10 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
project_deploy_board = ProjectDeployBoard.objects.get(workspace__slug=self.kwargs.get("slug"), project_id=self.kwargs.get("project_id"))
|
project_deploy_board = ProjectDeployBoard.objects.get(
|
||||||
|
workspace__slug=self.kwargs.get("slug"),
|
||||||
|
project_id=self.kwargs.get("project_id"),
|
||||||
|
)
|
||||||
if project_deploy_board is not None:
|
if project_deploy_board is not None:
|
||||||
return self.filter_queryset(
|
return self.filter_queryset(
|
||||||
super()
|
super()
|
||||||
@ -407,9 +579,14 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
|
|
||||||
def list(self, request, slug, project_id, inbox_id):
|
def list(self, request, slug, project_id, inbox_id):
|
||||||
try:
|
try:
|
||||||
project_deploy_board = ProjectDeployBoard.objects.get(workspace__slug=slug, project_id=project_id)
|
project_deploy_board = ProjectDeployBoard.objects.get(
|
||||||
|
workspace__slug=slug, project_id=project_id
|
||||||
|
)
|
||||||
if project_deploy_board.inbox is None:
|
if project_deploy_board.inbox is None:
|
||||||
return Response({"error": "Inbox is not enabled for this Project Board"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "Inbox is not enabled for this Project Board"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
filters = issue_filters(request.query_params, "GET")
|
filters = issue_filters(request.query_params, "GET")
|
||||||
issues = (
|
issues = (
|
||||||
@ -452,13 +629,29 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
issues_data = IssueStateInboxSerializer(issues, many=True).data
|
issues_data = IssueStateInboxSerializer(
|
||||||
|
issues,
|
||||||
|
nested_fields={
|
||||||
|
"assignee_details": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
many=True,
|
||||||
|
).data
|
||||||
return Response(
|
return Response(
|
||||||
issues_data,
|
issues_data,
|
||||||
status=status.HTTP_200_OK,
|
status=status.HTTP_200_OK,
|
||||||
)
|
)
|
||||||
except ProjectDeployBoard.DoesNotExist:
|
except ProjectDeployBoard.DoesNotExist:
|
||||||
return Response({"error": "Project Deploy Board does not exist"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "Project Deploy Board does not exist"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return Response(
|
return Response(
|
||||||
@ -468,9 +661,14 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
|
|
||||||
def create(self, request, slug, project_id, inbox_id):
|
def create(self, request, slug, project_id, inbox_id):
|
||||||
try:
|
try:
|
||||||
project_deploy_board = ProjectDeployBoard.objects.get(workspace__slug=slug, project_id=project_id)
|
project_deploy_board = ProjectDeployBoard.objects.get(
|
||||||
|
workspace__slug=slug, project_id=project_id
|
||||||
|
)
|
||||||
if project_deploy_board.inbox is None:
|
if project_deploy_board.inbox is None:
|
||||||
return Response({"error": "Inbox is not enabled for this Project Board"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "Inbox is not enabled for this Project Board"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
if not request.data.get("issue", {}).get("name", False):
|
if not request.data.get("issue", {}).get("name", False):
|
||||||
return Response(
|
return Response(
|
||||||
@ -527,7 +725,19 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
source=request.data.get("source", "in-app"),
|
source=request.data.get("source", "in-app"),
|
||||||
)
|
)
|
||||||
|
|
||||||
serializer = IssueStateInboxSerializer(issue)
|
serializer = IssueStateInboxSerializer(
|
||||||
|
issue,
|
||||||
|
nested_fields={
|
||||||
|
"assignee_details": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
@ -538,33 +748,124 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
|
|
||||||
def partial_update(self, request, slug, project_id, inbox_id, pk):
|
def partial_update(self, request, slug, project_id, inbox_id, pk):
|
||||||
try:
|
try:
|
||||||
project_deploy_board = ProjectDeployBoard.objects.get(workspace__slug=slug, project_id=project_id)
|
project_deploy_board = ProjectDeployBoard.objects.get(
|
||||||
|
workspace__slug=slug, project_id=project_id
|
||||||
|
)
|
||||||
if project_deploy_board.inbox is None:
|
if project_deploy_board.inbox is None:
|
||||||
return Response({"error": "Inbox is not enabled for this Project Board"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "Inbox is not enabled for this Project Board"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
inbox_issue = InboxIssue.objects.get(
|
inbox_issue = InboxIssue.objects.get(
|
||||||
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
||||||
)
|
)
|
||||||
# Get the project member
|
# Get the project member
|
||||||
if str(inbox_issue.created_by_id) != str(request.user.id):
|
if str(inbox_issue.created_by_id) != str(request.user.id):
|
||||||
return Response({"error": "You cannot edit inbox issues"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "You cannot edit inbox issues"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
# Get issue data
|
# Get issue data
|
||||||
issue_data = request.data.pop("issue", False)
|
issue_data = request.data.pop("issue", False)
|
||||||
|
|
||||||
|
|
||||||
issue = Issue.objects.get(
|
issue = Issue.objects.get(
|
||||||
pk=inbox_issue.issue_id, workspace__slug=slug, project_id=project_id
|
pk=inbox_issue.issue_id, workspace__slug=slug, project_id=project_id
|
||||||
)
|
)
|
||||||
# viewers and guests since only viewers and guests
|
# viewers and guests since only viewers and guests
|
||||||
issue_data = {
|
issue_data = {
|
||||||
"name": issue_data.get("name", issue.name),
|
"name": issue_data.get("name", issue.name),
|
||||||
"description_html": issue_data.get("description_html", issue.description_html),
|
"description_html": issue_data.get(
|
||||||
"description": issue_data.get("description", issue.description)
|
"description_html", issue.description_html
|
||||||
|
),
|
||||||
|
"description": issue_data.get("description", issue.description),
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_serializer = IssueCreateSerializer(
|
issue_serializer = IssueCreateSerializer(
|
||||||
issue, data=issue_data, partial=True
|
issue,
|
||||||
|
data=issue_data,
|
||||||
|
fields=[
|
||||||
|
{
|
||||||
|
"created_by_detail": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state_detail": [
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"color",
|
||||||
|
"slug",
|
||||||
|
"sequence",
|
||||||
|
"group",
|
||||||
|
"default",
|
||||||
|
"project",
|
||||||
|
"workspace",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"created_by",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
"assignees_list",
|
||||||
|
"blockers_list",
|
||||||
|
"labels_list",
|
||||||
|
"blocks_list",
|
||||||
|
"PRIORITY_CHOICES",
|
||||||
|
"parent",
|
||||||
|
"state",
|
||||||
|
"estimate_point",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"description_html",
|
||||||
|
"description_stripped",
|
||||||
|
"priority",
|
||||||
|
"start_date",
|
||||||
|
"target_date",
|
||||||
|
"assignees",
|
||||||
|
"sequence_id",
|
||||||
|
"labels",
|
||||||
|
"sort_order",
|
||||||
|
"completed_at",
|
||||||
|
"archived_at",
|
||||||
|
],
|
||||||
|
partial=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
if issue_serializer.is_valid():
|
if issue_serializer.is_valid():
|
||||||
@ -600,17 +901,34 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
|
|
||||||
def retrieve(self, request, slug, project_id, inbox_id, pk):
|
def retrieve(self, request, slug, project_id, inbox_id, pk):
|
||||||
try:
|
try:
|
||||||
project_deploy_board = ProjectDeployBoard.objects.get(workspace__slug=slug, project_id=project_id)
|
project_deploy_board = ProjectDeployBoard.objects.get(
|
||||||
|
workspace__slug=slug, project_id=project_id
|
||||||
|
)
|
||||||
if project_deploy_board.inbox is None:
|
if project_deploy_board.inbox is None:
|
||||||
return Response({"error": "Inbox is not enabled for this Project Board"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "Inbox is not enabled for this Project Board"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
inbox_issue = InboxIssue.objects.get(
|
inbox_issue = InboxIssue.objects.get(
|
||||||
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
||||||
)
|
)
|
||||||
issue = Issue.objects.get(
|
issue = Issue.objects.get(
|
||||||
pk=inbox_issue.issue_id, workspace__slug=slug, project_id=project_id
|
pk=inbox_issue.issue_id, workspace__slug=slug, project_id=project_id
|
||||||
)
|
)
|
||||||
serializer = IssueStateInboxSerializer(issue)
|
serializer = IssueStateInboxSerializer(
|
||||||
|
issue,
|
||||||
|
nested_fields={
|
||||||
|
"assignee_details": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
@ -621,25 +939,35 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
|
|
||||||
def destroy(self, request, slug, project_id, inbox_id, pk):
|
def destroy(self, request, slug, project_id, inbox_id, pk):
|
||||||
try:
|
try:
|
||||||
project_deploy_board = ProjectDeployBoard.objects.get(workspace__slug=slug, project_id=project_id)
|
project_deploy_board = ProjectDeployBoard.objects.get(
|
||||||
|
workspace__slug=slug, project_id=project_id
|
||||||
|
)
|
||||||
if project_deploy_board.inbox is None:
|
if project_deploy_board.inbox is None:
|
||||||
return Response({"error": "Inbox is not enabled for this Project Board"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "Inbox is not enabled for this Project Board"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
inbox_issue = InboxIssue.objects.get(
|
inbox_issue = InboxIssue.objects.get(
|
||||||
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id
|
||||||
)
|
)
|
||||||
|
|
||||||
if str(inbox_issue.created_by_id) != str(request.user.id):
|
if str(inbox_issue.created_by_id) != str(request.user.id):
|
||||||
return Response({"error": "You cannot delete inbox issue"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "You cannot delete inbox issue"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
inbox_issue.delete()
|
inbox_issue.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
except InboxIssue.DoesNotExist:
|
except InboxIssue.DoesNotExist:
|
||||||
return Response({"error": "Inbox Issue does not exists"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{"error": "Inbox Issue does not exists"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return Response(
|
return Response(
|
||||||
{"error": "Something went wrong please try again later"},
|
{"error": "Something went wrong please try again later"},
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -281,6 +281,86 @@ class IssueViewSet(BaseViewSet):
|
|||||||
|
|
||||||
serializer = IssueCreateSerializer(
|
serializer = IssueCreateSerializer(
|
||||||
data=request.data,
|
data=request.data,
|
||||||
|
fields=[
|
||||||
|
{
|
||||||
|
"created_by_detail": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state_detail": [
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"color",
|
||||||
|
"slug",
|
||||||
|
"sequence",
|
||||||
|
"group",
|
||||||
|
"default",
|
||||||
|
"project",
|
||||||
|
"workspace",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"created_by",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
"assignees_list",
|
||||||
|
"blockers_list",
|
||||||
|
"labels_list",
|
||||||
|
"blocks_list",
|
||||||
|
"PRIORITY_CHOICES",
|
||||||
|
"parent",
|
||||||
|
"state",
|
||||||
|
"estimate_point",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"description_html",
|
||||||
|
"description_stripped",
|
||||||
|
"priority",
|
||||||
|
"start_date",
|
||||||
|
"target_date",
|
||||||
|
"assignees",
|
||||||
|
"sequence_id",
|
||||||
|
"labels",
|
||||||
|
"sort_order",
|
||||||
|
"completed_at",
|
||||||
|
"archived_at",
|
||||||
|
],
|
||||||
context={
|
context={
|
||||||
"project_id": project_id,
|
"project_id": project_id,
|
||||||
"workspace_id": project.workspace_id,
|
"workspace_id": project.workspace_id,
|
||||||
@ -493,8 +573,34 @@ class IssueActivityEndpoint(BaseAPIView):
|
|||||||
.order_by("created_at")
|
.order_by("created_at")
|
||||||
.select_related("actor", "issue", "project", "workspace")
|
.select_related("actor", "issue", "project", "workspace")
|
||||||
)
|
)
|
||||||
issue_activities = IssueActivitySerializer(issue_activities, many=True).data
|
issue_activities = IssueActivitySerializer(
|
||||||
issue_comments = IssueCommentSerializer(issue_comments, many=True).data
|
issue_activities,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
many=True,
|
||||||
|
).data
|
||||||
|
issue_comments = IssueCommentSerializer(
|
||||||
|
issue_comments,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
many=True,
|
||||||
|
).data
|
||||||
|
|
||||||
result_list = sorted(
|
result_list = sorted(
|
||||||
chain(issue_activities, issue_comments),
|
chain(issue_activities, issue_comments),
|
||||||
@ -522,6 +628,9 @@ class IssueCommentViewSet(BaseViewSet):
|
|||||||
"workspace__id",
|
"workspace__id",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# def get_serializer_class(self):
|
||||||
|
# return IssueCommentSerializer(nested_fields={"actor_detail":("id", "first_name", "last_name", "avatar", "is_bot", "display_name")})
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
serializer.save(
|
serializer.save(
|
||||||
project_id=self.kwargs.get("project_id"),
|
project_id=self.kwargs.get("project_id"),
|
||||||
@ -550,7 +659,19 @@ class IssueCommentViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("issue_id", None)),
|
issue_id=str(self.kwargs.get("issue_id", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=json.dumps(
|
current_instance=json.dumps(
|
||||||
IssueCommentSerializer(current_instance).data,
|
IssueCommentSerializer(
|
||||||
|
current_instance,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -571,7 +692,19 @@ class IssueCommentViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("issue_id", None)),
|
issue_id=str(self.kwargs.get("issue_id", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=json.dumps(
|
current_instance=json.dumps(
|
||||||
IssueCommentSerializer(current_instance).data,
|
IssueCommentSerializer(
|
||||||
|
current_instance,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -769,7 +902,9 @@ class SubIssuesEndpoint(BaseAPIView):
|
|||||||
.order_by("state_group")
|
.order_by("state_group")
|
||||||
)
|
)
|
||||||
|
|
||||||
result = {item["state_group"]: item["state_count"] for item in state_distribution}
|
result = {
|
||||||
|
item["state_group"]: item["state_count"] for item in state_distribution
|
||||||
|
}
|
||||||
|
|
||||||
serializer = IssueLiteSerializer(
|
serializer = IssueLiteSerializer(
|
||||||
sub_issues,
|
sub_issues,
|
||||||
@ -1507,7 +1642,19 @@ class IssueCommentPublicViewSet(BaseViewSet):
|
|||||||
else "EXTERNAL"
|
else "EXTERNAL"
|
||||||
)
|
)
|
||||||
|
|
||||||
serializer = IssueCommentSerializer(data=request.data)
|
serializer = IssueCommentSerializer(
|
||||||
|
data=request.data,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save(
|
serializer.save(
|
||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
@ -1547,7 +1694,19 @@ class IssueCommentPublicViewSet(BaseViewSet):
|
|||||||
workspace__slug=slug, pk=pk, actor=request.user
|
workspace__slug=slug, pk=pk, actor=request.user
|
||||||
)
|
)
|
||||||
serializer = IssueCommentSerializer(
|
serializer = IssueCommentSerializer(
|
||||||
comment, data=request.data, partial=True
|
comment,
|
||||||
|
data=request.data,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
partial=True,
|
||||||
)
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
@ -1558,7 +1717,19 @@ class IssueCommentPublicViewSet(BaseViewSet):
|
|||||||
issue_id=str(issue_id),
|
issue_id=str(issue_id),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
current_instance=json.dumps(
|
current_instance=json.dumps(
|
||||||
IssueCommentSerializer(comment).data,
|
IssueCommentSerializer(
|
||||||
|
comment,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -1567,7 +1738,8 @@ class IssueCommentPublicViewSet(BaseViewSet):
|
|||||||
except (IssueComment.DoesNotExist, ProjectDeployBoard.DoesNotExist):
|
except (IssueComment.DoesNotExist, ProjectDeployBoard.DoesNotExist):
|
||||||
return Response(
|
return Response(
|
||||||
{"error": "IssueComent Does not exists"},
|
{"error": "IssueComent Does not exists"},
|
||||||
status=status.HTTP_400_BAD_REQUEST,)
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
def destroy(self, request, slug, project_id, issue_id, pk):
|
def destroy(self, request, slug, project_id, issue_id, pk):
|
||||||
try:
|
try:
|
||||||
@ -1590,7 +1762,19 @@ class IssueCommentPublicViewSet(BaseViewSet):
|
|||||||
issue_id=str(issue_id),
|
issue_id=str(issue_id),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
current_instance=json.dumps(
|
current_instance=json.dumps(
|
||||||
IssueCommentSerializer(comment).data,
|
IssueCommentSerializer(
|
||||||
|
comment,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -1835,9 +2019,11 @@ class ExportIssuesEndpoint(BaseAPIView):
|
|||||||
|
|
||||||
def post(self, request, slug):
|
def post(self, request, slug):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
issue_export_task.delay(
|
issue_export_task.delay(
|
||||||
email=request.user.email, data=request.data, slug=slug ,exporter_name=request.user.first_name
|
email=request.user.email,
|
||||||
|
data=request.data,
|
||||||
|
slug=slug,
|
||||||
|
exporter_name=request.user.first_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
@ -1851,4 +2037,4 @@ class ExportIssuesEndpoint(BaseAPIView):
|
|||||||
return Response(
|
return Response(
|
||||||
{"error": "Something went wrong please try again later"},
|
{"error": "Something went wrong please try again later"},
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
@ -91,10 +91,10 @@ class ProjectViewSet(BaseViewSet):
|
|||||||
ProjectBasePermission,
|
ProjectBasePermission,
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_serializer_class(self, *args, **kwargs):
|
# def get_serializer_class(self, *args, **kwargs):
|
||||||
if self.action == "update" or self.action == "partial_update":
|
# if self.action == "update" or self.action == "partial_update":
|
||||||
return ProjectSerializer
|
# return ProjectSerializer(fields=['id', {'workspace_detail': ["id", "name", "slug"]}, 'created_at', 'updated_at', 'name', 'description', 'description_text', 'description_html', 'network', 'identifier', 'emoji', 'icon_prop', 'module_view', 'cycle_view', 'issue_views_view', 'page_view', 'inbox_view', 'cover_image', 'archive_in', 'close_in', 'created_by', 'updated_by', 'workspace', 'default_assignee', 'project_lead', 'estimate', 'default_state', 'sort_order'],)
|
||||||
return ProjectDetailSerializer
|
# return ProjectDetailSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
subquery = ProjectFavorite.objects.filter(
|
subquery = ProjectFavorite.objects.filter(
|
||||||
@ -216,7 +216,38 @@ class ProjectViewSet(BaseViewSet):
|
|||||||
workspace = Workspace.objects.get(slug=slug)
|
workspace = Workspace.objects.get(slug=slug)
|
||||||
|
|
||||||
serializer = ProjectSerializer(
|
serializer = ProjectSerializer(
|
||||||
data={**request.data}, context={"workspace_id": workspace.id}
|
data={**request.data},
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"description_text",
|
||||||
|
"description_html",
|
||||||
|
"network",
|
||||||
|
"identifier",
|
||||||
|
"emoji",
|
||||||
|
"icon_prop",
|
||||||
|
"module_view",
|
||||||
|
"cycle_view",
|
||||||
|
"issue_views_view",
|
||||||
|
"page_view",
|
||||||
|
"inbox_view",
|
||||||
|
"cover_image",
|
||||||
|
"archive_in",
|
||||||
|
"close_in",
|
||||||
|
"created_by",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"default_assignee",
|
||||||
|
"project_lead",
|
||||||
|
"estimate",
|
||||||
|
"default_state",
|
||||||
|
"sort_order",
|
||||||
|
],
|
||||||
|
context={"workspace_id": workspace.id},
|
||||||
)
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
@ -330,6 +361,36 @@ class ProjectViewSet(BaseViewSet):
|
|||||||
serializer = ProjectSerializer(
|
serializer = ProjectSerializer(
|
||||||
project,
|
project,
|
||||||
data={**request.data},
|
data={**request.data},
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"description_text",
|
||||||
|
"description_html",
|
||||||
|
"network",
|
||||||
|
"identifier",
|
||||||
|
"emoji",
|
||||||
|
"icon_prop",
|
||||||
|
"module_view",
|
||||||
|
"cycle_view",
|
||||||
|
"issue_views_view",
|
||||||
|
"page_view",
|
||||||
|
"inbox_view",
|
||||||
|
"cover_image",
|
||||||
|
"archive_in",
|
||||||
|
"close_in",
|
||||||
|
"created_by",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"default_assignee",
|
||||||
|
"project_lead",
|
||||||
|
"estimate",
|
||||||
|
"default_state",
|
||||||
|
"sort_order",
|
||||||
|
],
|
||||||
context={"workspace_id": workspace.id},
|
context={"workspace_id": workspace.id},
|
||||||
partial=True,
|
partial=True,
|
||||||
)
|
)
|
||||||
@ -1263,7 +1324,7 @@ class ProjectDeployBoardIssuesPublicEndpoint(BaseAPIView):
|
|||||||
workspace__slug=slug, project_id=project_id
|
workspace__slug=slug, project_id=project_id
|
||||||
).values("id", "name", "color", "parent")
|
).values("id", "name", "color", "parent")
|
||||||
|
|
||||||
## Grouping the results
|
# Grouping the results
|
||||||
group_by = request.GET.get("group_by", False)
|
group_by = request.GET.get("group_by", False)
|
||||||
if group_by:
|
if group_by:
|
||||||
issues = group_results(issues, group_by)
|
issues = group_results(issues, group_by)
|
||||||
|
@ -42,7 +42,36 @@ class StateViewSet(BaseViewSet):
|
|||||||
|
|
||||||
def create(self, request, slug, project_id):
|
def create(self, request, slug, project_id):
|
||||||
try:
|
try:
|
||||||
serializer = StateSerializer(data=request.data)
|
serializer = StateSerializer(
|
||||||
|
data=request.data,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"color",
|
||||||
|
"slug",
|
||||||
|
"sequence",
|
||||||
|
"group",
|
||||||
|
"default",
|
||||||
|
"project",
|
||||||
|
"workspace",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save(project_id=project_id)
|
serializer.save(project_id=project_id)
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
@ -62,7 +91,37 @@ class StateViewSet(BaseViewSet):
|
|||||||
def list(self, request, slug, project_id):
|
def list(self, request, slug, project_id):
|
||||||
try:
|
try:
|
||||||
state_dict = dict()
|
state_dict = dict()
|
||||||
states = StateSerializer(self.get_queryset(), many=True).data
|
states = StateSerializer(
|
||||||
|
self.get_queryset(),
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"color",
|
||||||
|
"slug",
|
||||||
|
"sequence",
|
||||||
|
"group",
|
||||||
|
"default",
|
||||||
|
"project",
|
||||||
|
"workspace",
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
many=True,
|
||||||
|
).data
|
||||||
|
|
||||||
for key, value in groupby(
|
for key, value in groupby(
|
||||||
sorted(states, key=lambda state: state["group"]),
|
sorted(states, key=lambda state: state["group"]),
|
||||||
@ -82,7 +141,9 @@ class StateViewSet(BaseViewSet):
|
|||||||
try:
|
try:
|
||||||
state = State.objects.get(
|
state = State.objects.get(
|
||||||
~Q(name="Triage"),
|
~Q(name="Triage"),
|
||||||
pk=pk, project_id=project_id, workspace__slug=slug,
|
pk=pk,
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
)
|
)
|
||||||
|
|
||||||
if state.default:
|
if state.default:
|
||||||
|
@ -147,7 +147,18 @@ class UserActivityEndpoint(BaseAPIView, BasePaginator):
|
|||||||
request=request,
|
request=request,
|
||||||
queryset=queryset,
|
queryset=queryset,
|
||||||
on_results=lambda issue_activities: IssueActivitySerializer(
|
on_results=lambda issue_activities: IssueActivitySerializer(
|
||||||
issue_activities, many=True
|
issue_activities,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
many=True,
|
||||||
).data,
|
).data,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -42,12 +42,11 @@ from plane.api.serializers import (
|
|||||||
WorkSpaceMemberSerializer,
|
WorkSpaceMemberSerializer,
|
||||||
TeamSerializer,
|
TeamSerializer,
|
||||||
WorkSpaceMemberInviteSerializer,
|
WorkSpaceMemberInviteSerializer,
|
||||||
UserLiteSerializer,
|
UserSerializer,
|
||||||
ProjectMemberSerializer,
|
ProjectMemberSerializer,
|
||||||
WorkspaceThemeSerializer,
|
WorkspaceThemeSerializer,
|
||||||
IssueActivitySerializer,
|
IssueActivitySerializer,
|
||||||
IssueLiteSerializer,
|
IssueLiteSerializer,
|
||||||
WorkspaceMemberAdminSerializer,
|
|
||||||
)
|
)
|
||||||
from plane.api.views.base import BaseAPIView
|
from plane.api.views.base import BaseAPIView
|
||||||
from . import BaseViewSet
|
from . import BaseViewSet
|
||||||
@ -164,8 +163,8 @@ class WorkSpaceViewSet(BaseViewSet):
|
|||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
## Handling unique integrity error for now
|
# Handling unique integrity error for now
|
||||||
## TODO: Extend this to handle other common errors which are not automatically handled by APIException
|
# TODO: Extend this to handle other common errors which are not automatically handled by APIException
|
||||||
except IntegrityError as e:
|
except IntegrityError as e:
|
||||||
if "already exists" in str(e):
|
if "already exists" in str(e):
|
||||||
return Response(
|
return Response(
|
||||||
@ -300,7 +299,31 @@ class InviteWorkspaceEndpoint(BaseAPIView):
|
|||||||
{
|
{
|
||||||
"error": "Some users are already member of workspace",
|
"error": "Some users are already member of workspace",
|
||||||
"workspace_users": WorkSpaceMemberSerializer(
|
"workspace_users": WorkSpaceMemberSerializer(
|
||||||
workspace_members, many=True
|
workspace_members,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"name",
|
||||||
|
"logo",
|
||||||
|
"owner",
|
||||||
|
"slug",
|
||||||
|
"organization_size",
|
||||||
|
{"workspace": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"member": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
many=True,
|
||||||
).data,
|
).data,
|
||||||
},
|
},
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
@ -542,7 +565,7 @@ class UserWorkspaceInvitationsEndpoint(BaseViewSet):
|
|||||||
|
|
||||||
|
|
||||||
class WorkSpaceMemberViewSet(BaseViewSet):
|
class WorkSpaceMemberViewSet(BaseViewSet):
|
||||||
serializer_class = WorkspaceMemberAdminSerializer
|
serializer_class = WorkSpaceMemberSerializer
|
||||||
model = WorkspaceMember
|
model = WorkspaceMember
|
||||||
|
|
||||||
permission_classes = [
|
permission_classes = [
|
||||||
@ -591,7 +614,32 @@ class WorkSpaceMemberViewSet(BaseViewSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
serializer = WorkSpaceMemberSerializer(
|
serializer = WorkSpaceMemberSerializer(
|
||||||
workspace_member, data=request.data, partial=True
|
workspace_member,
|
||||||
|
data=request.data,
|
||||||
|
partial=True,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"name",
|
||||||
|
"logo",
|
||||||
|
"owner",
|
||||||
|
"slug",
|
||||||
|
"organization_size",
|
||||||
|
{"workspace": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"member": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
@ -725,7 +773,18 @@ class TeamMemberViewSet(BaseViewSet):
|
|||||||
users = list(set(request.data.get("members", [])).difference(members))
|
users = list(set(request.data.get("members", [])).difference(members))
|
||||||
users = User.objects.filter(pk__in=users)
|
users = User.objects.filter(pk__in=users)
|
||||||
|
|
||||||
serializer = UserLiteSerializer(users, many=True)
|
serializer = UserSerializer(
|
||||||
|
users,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
],
|
||||||
|
many=True,
|
||||||
|
)
|
||||||
return Response(
|
return Response(
|
||||||
{
|
{
|
||||||
"error": f"{len(users)} of the member(s) are not a part of the workspace",
|
"error": f"{len(users)} of the member(s) are not a part of the workspace",
|
||||||
@ -791,14 +850,95 @@ class UserLastProjectWithWorkspaceEndpoint(BaseAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
workspace = Workspace.objects.get(pk=last_workspace_id)
|
workspace = Workspace.objects.get(pk=last_workspace_id)
|
||||||
workspace_serializer = WorkSpaceSerializer(workspace)
|
workspace_serializer = WorkSpaceSerializer(
|
||||||
|
workspace,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
{
|
||||||
|
"owner": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"name",
|
||||||
|
"logo",
|
||||||
|
"slug",
|
||||||
|
"organization_size",
|
||||||
|
"created_by",
|
||||||
|
"updated_by",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
project_member = ProjectMember.objects.filter(
|
project_member = ProjectMember.objects.filter(
|
||||||
workspace_id=last_workspace_id, member=request.user
|
workspace_id=last_workspace_id, member=request.user
|
||||||
).select_related("workspace", "project", "member", "workspace__owner")
|
).select_related("workspace", "project", "member", "workspace__owner")
|
||||||
|
|
||||||
project_member_serializer = ProjectMemberSerializer(
|
project_member_serializer = ProjectMemberSerializer(
|
||||||
project_member, many=True
|
project_member,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
{
|
||||||
|
"workspace": [
|
||||||
|
"id",
|
||||||
|
{
|
||||||
|
"owner": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"name",
|
||||||
|
"logo",
|
||||||
|
"slug",
|
||||||
|
"organization_size",
|
||||||
|
"created_by",
|
||||||
|
"updated_by",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project": [
|
||||||
|
"id",
|
||||||
|
"identifier",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"member": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"comment",
|
||||||
|
"role",
|
||||||
|
"view_props",
|
||||||
|
"default_props",
|
||||||
|
"preferences",
|
||||||
|
"sort_order",
|
||||||
|
"created_by",
|
||||||
|
"updated_by",
|
||||||
|
],
|
||||||
|
many=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
@ -825,7 +965,32 @@ class WorkspaceMemberUserEndpoint(BaseAPIView):
|
|||||||
workspace_member = WorkspaceMember.objects.get(
|
workspace_member = WorkspaceMember.objects.get(
|
||||||
member=request.user, workspace__slug=slug
|
member=request.user, workspace__slug=slug
|
||||||
)
|
)
|
||||||
serializer = WorkSpaceMemberSerializer(workspace_member)
|
serializer = WorkSpaceMemberSerializer(
|
||||||
|
workspace_member,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"name",
|
||||||
|
"logo",
|
||||||
|
"owner",
|
||||||
|
"slug",
|
||||||
|
"organization_size",
|
||||||
|
{"workspace": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"member": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
except (Workspace.DoesNotExist, WorkspaceMember.DoesNotExist):
|
except (Workspace.DoesNotExist, WorkspaceMember.DoesNotExist):
|
||||||
return Response({"error": "Forbidden"}, status=status.HTTP_403_FORBIDDEN)
|
return Response({"error": "Forbidden"}, status=status.HTTP_403_FORBIDDEN)
|
||||||
@ -1209,7 +1374,18 @@ class WorkspaceUserActivityEndpoint(BaseAPIView):
|
|||||||
request=request,
|
request=request,
|
||||||
queryset=queryset,
|
queryset=queryset,
|
||||||
on_results=lambda issue_activities: IssueActivitySerializer(
|
on_results=lambda issue_activities: IssueActivitySerializer(
|
||||||
issue_activities, many=True
|
issue_activities,
|
||||||
|
nested_fields={
|
||||||
|
"actor_detail": (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
many=True,
|
||||||
).data,
|
).data,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -1417,7 +1593,7 @@ class WorkspaceUserProfileIssuesEndpoint(BaseAPIView):
|
|||||||
|
|
||||||
issues = IssueLiteSerializer(issue_queryset, many=True).data
|
issues = IssueLiteSerializer(issue_queryset, many=True).data
|
||||||
|
|
||||||
## Grouping the results
|
# Grouping the results
|
||||||
group_by = request.GET.get("group_by", False)
|
group_by = request.GET.get("group_by", False)
|
||||||
if group_by:
|
if group_by:
|
||||||
return Response(
|
return Response(
|
||||||
@ -1464,8 +1640,34 @@ class WorkspaceMembersEndpoint(BaseAPIView):
|
|||||||
workspace__slug=slug,
|
workspace__slug=slug,
|
||||||
member__is_bot=False,
|
member__is_bot=False,
|
||||||
).select_related("workspace", "member")
|
).select_related("workspace", "member")
|
||||||
serialzier = WorkSpaceMemberSerializer(workspace_members, many=True)
|
serializer = WorkSpaceMemberSerializer(
|
||||||
return Response(serialzier.data, status=status.HTTP_200_OK)
|
workspace_members,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"name",
|
||||||
|
"logo",
|
||||||
|
"owner",
|
||||||
|
"slug",
|
||||||
|
"organization_size",
|
||||||
|
{"workspace": ["id", "name", "slug"]},
|
||||||
|
{
|
||||||
|
"member": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
many=True,
|
||||||
|
)
|
||||||
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return Response(
|
return Response(
|
||||||
|
@ -161,7 +161,47 @@ def service_importer(service, importer_id):
|
|||||||
if settings.PROXY_BASE_URL:
|
if settings.PROXY_BASE_URL:
|
||||||
headers = {"Content-Type": "application/json"}
|
headers = {"Content-Type": "application/json"}
|
||||||
import_data_json = json.dumps(
|
import_data_json = json.dumps(
|
||||||
ImporterSerializer(importer).data,
|
ImporterSerializer(
|
||||||
|
importer,
|
||||||
|
fields=[
|
||||||
|
"id",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"updated_by",
|
||||||
|
"workspace",
|
||||||
|
"project",
|
||||||
|
"service",
|
||||||
|
"status",
|
||||||
|
"initiated_by",
|
||||||
|
"metadata",
|
||||||
|
"config",
|
||||||
|
"data",
|
||||||
|
"token",
|
||||||
|
"imported_data",
|
||||||
|
{
|
||||||
|
"initiated_by_detail": [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"avatar",
|
||||||
|
"is_bot",
|
||||||
|
"display_name",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project_detail": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"cover_image",
|
||||||
|
"icon_prop",
|
||||||
|
"emoji",
|
||||||
|
"description",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{"workspace_detail": ["id", "name", "slug"]},
|
||||||
|
],
|
||||||
|
).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
)
|
)
|
||||||
res = requests.post(
|
res = requests.post(
|
||||||
|
@ -1103,7 +1103,7 @@ def issue_activity(
|
|||||||
for issue_activity in issue_activities_created:
|
for issue_activity in issue_activities_created:
|
||||||
headers = {"Content-Type": "application/json"}
|
headers = {"Content-Type": "application/json"}
|
||||||
issue_activity_json = json.dumps(
|
issue_activity_json = json.dumps(
|
||||||
IssueActivitySerializer(issue_activity).data,
|
IssueActivitySerializer(issue_activity,fields=[{"actor_detail":["id", "first_name", "last_name", "avatar", "is_bot", "display_name"]}]).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
)
|
)
|
||||||
_ = requests.post(
|
_ = requests.post(
|
||||||
|
Loading…
Reference in New Issue
Block a user