* chore: traige state in intake * chore: triage state changes * feat: implement intake state dropdown component and integrate into issue properties * chore: added the triage state validation * chore: added triage state filter * chore: added workspace filter * fix: migration file * chore: added triage group state check * chore: updated the filters * chore: updated the filters * chore: added variables for intake state * fix: import error * refactor: improve project intake state retrieval logic and update TriageGroupIcon component * chore: changed the intake validation logic * refactor: update intake state types and clean up unused interfaces * chore: changed the state color * chore: changed the update serializer * chore: updated with current instance * chore: update TriageGroupIcon color to match new intake state group color * chore: stringified value * chore: added validation in serializer * chore: added logger instead of print * fix: correct component closing syntax in ActiveProjectItem * chore: updated the migration file * chore: added noop in migation --------- Co-authored-by: b-saikrishnakanth <bsaikrishnakanth97@gmail.com>
138 lines
4.7 KiB
Python
138 lines
4.7 KiB
Python
# Third party frameworks
|
|
from rest_framework import serializers
|
|
|
|
# Module imports
|
|
from .base import BaseSerializer
|
|
from .issue import IssueIntakeSerializer, LabelLiteSerializer, IssueDetailSerializer
|
|
from .project import ProjectLiteSerializer
|
|
from .state import StateLiteSerializer
|
|
from .user import UserLiteSerializer
|
|
from plane.db.models import Intake, IntakeIssue, Issue
|
|
|
|
|
|
class IntakeSerializer(BaseSerializer):
|
|
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
|
pending_issue_count = serializers.IntegerField(read_only=True)
|
|
|
|
class Meta:
|
|
model = Intake
|
|
fields = "__all__"
|
|
read_only_fields = ["project", "workspace"]
|
|
|
|
|
|
class IntakeIssueSerializer(BaseSerializer):
|
|
issue = IssueIntakeSerializer(read_only=True)
|
|
|
|
class Meta:
|
|
model = IntakeIssue
|
|
fields = [
|
|
"id",
|
|
"status",
|
|
"duplicate_to",
|
|
"snoozed_till",
|
|
"source",
|
|
"issue",
|
|
"created_by",
|
|
]
|
|
read_only_fields = ["project", "workspace"]
|
|
|
|
def validate(self, attrs):
|
|
"""
|
|
Validate that if status is being changed to accepted (1),
|
|
the project has a default state to transition to.
|
|
"""
|
|
from plane.db.models import State
|
|
|
|
# Check if status is being updated to accepted
|
|
if attrs.get("status") == 1:
|
|
intake_issue = self.instance
|
|
issue = intake_issue.issue
|
|
|
|
# Check if issue is in TRIAGE state
|
|
if issue.state and issue.state.group == State.TRIAGE:
|
|
# Verify default state exists before allowing the update
|
|
default_state = State.objects.filter(
|
|
workspace=intake_issue.workspace, project=intake_issue.project, default=True
|
|
).first()
|
|
|
|
if not default_state:
|
|
raise serializers.ValidationError(
|
|
{"status": "Cannot accept intake issue: No default state found for the project"}
|
|
)
|
|
|
|
return attrs
|
|
|
|
def update(self, instance, validated_data):
|
|
from plane.db.models import State
|
|
|
|
# Update the intake issue
|
|
instance = super().update(instance, validated_data)
|
|
|
|
# If status is accepted (1), transition the issue state from TRIAGE to default
|
|
if validated_data.get("status") == 1:
|
|
issue = instance.issue
|
|
if issue.state and issue.state.group == State.TRIAGE:
|
|
# Get the default project state
|
|
default_state = State.objects.filter(
|
|
workspace=instance.workspace,
|
|
project=instance.project,
|
|
default=True
|
|
).first()
|
|
if default_state:
|
|
issue.state = default_state
|
|
issue.save()
|
|
|
|
return instance
|
|
|
|
def to_representation(self, instance):
|
|
# Pass the annotated fields to the Issue instance if they exist
|
|
if hasattr(instance, "label_ids"):
|
|
instance.issue.label_ids = instance.label_ids
|
|
return super().to_representation(instance)
|
|
|
|
|
|
class IntakeIssueDetailSerializer(BaseSerializer):
|
|
issue = IssueDetailSerializer(read_only=True)
|
|
duplicate_issue_detail = IssueIntakeSerializer(read_only=True, source="duplicate_to")
|
|
|
|
class Meta:
|
|
model = IntakeIssue
|
|
fields = [
|
|
"id",
|
|
"status",
|
|
"duplicate_to",
|
|
"snoozed_till",
|
|
"duplicate_issue_detail",
|
|
"source",
|
|
"issue",
|
|
]
|
|
read_only_fields = ["project", "workspace"]
|
|
|
|
def to_representation(self, instance):
|
|
# Pass the annotated fields to the Issue instance if they exist
|
|
if hasattr(instance, "assignee_ids"):
|
|
instance.issue.assignee_ids = instance.assignee_ids
|
|
if hasattr(instance, "label_ids"):
|
|
instance.issue.label_ids = instance.label_ids
|
|
|
|
return super().to_representation(instance)
|
|
|
|
|
|
class IntakeIssueLiteSerializer(BaseSerializer):
|
|
class Meta:
|
|
model = IntakeIssue
|
|
fields = ["id", "status", "duplicate_to", "snoozed_till", "source"]
|
|
read_only_fields = fields
|
|
|
|
|
|
class IssueStateIntakeSerializer(BaseSerializer):
|
|
state_detail = StateLiteSerializer(read_only=True, source="state")
|
|
project_detail = ProjectLiteSerializer(read_only=True, source="project")
|
|
label_details = LabelLiteSerializer(read_only=True, source="labels", many=True)
|
|
assignee_details = UserLiteSerializer(read_only=True, source="assignees", many=True)
|
|
sub_issues_count = serializers.IntegerField(read_only=True)
|
|
issue_intake = IntakeIssueLiteSerializer(read_only=True, many=True)
|
|
|
|
class Meta:
|
|
model = Issue
|
|
fields = "__all__"
|