refactor: update links to different endpoints (#338)

This commit is contained in:
pablohashescobar 2023-02-28 02:09:22 +05:30 committed by GitHub
parent 7b4d7f12f5
commit 1b369feb6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 126 additions and 115 deletions

View File

@ -36,9 +36,15 @@ from .issue import (
IssueSerializer,
IssueFlatSerializer,
IssueStateSerializer,
IssueLinkSerializer,
)
from .module import ModuleWriteSerializer, ModuleSerializer, ModuleIssueSerializer
from .module import (
ModuleWriteSerializer,
ModuleSerializer,
ModuleIssueSerializer,
ModuleLinkSerializer,
)
from .api_token import APITokenSerializer

View File

@ -28,11 +28,6 @@ from plane.db.models import (
)
class IssueLinkCreateSerializer(serializers.Serializer):
url = serializers.CharField(required=True)
title = serializers.CharField(required=False)
class IssueFlatSerializer(BaseSerializer):
## Contain only flat fields
@ -82,11 +77,6 @@ class IssueCreateSerializer(BaseSerializer):
write_only=True,
required=False,
)
links_list = serializers.ListField(
child=IssueLinkCreateSerializer(),
write_only=True,
required=False,
)
class Meta:
model = Issue
@ -105,7 +95,6 @@ class IssueCreateSerializer(BaseSerializer):
assignees = validated_data.pop("assignees_list", None)
labels = validated_data.pop("labels_list", None)
blocks = validated_data.pop("blocks_list", None)
links = validated_data.pop("links_list", None)
project = self.context["project"]
issue = Issue.objects.create(**validated_data, project=project)
@ -174,24 +163,6 @@ class IssueCreateSerializer(BaseSerializer):
batch_size=10,
)
if links is not None:
IssueLink.objects.bulk_create(
[
IssueLink(
issue=issue,
project=project,
workspace=project.workspace,
created_by=issue.created_by,
updated_by=issue.updated_by,
title=link.get("title", None),
url=link.get("url", None),
)
for link in links
],
batch_size=10,
ignore_conflicts=True,
)
return issue
def update(self, instance, validated_data):
@ -199,7 +170,6 @@ class IssueCreateSerializer(BaseSerializer):
assignees = validated_data.pop("assignees_list", None)
labels = validated_data.pop("labels_list", None)
blocks = validated_data.pop("blocks_list", None)
links = validated_data.pop("links_list", None)
if blockers is not None:
IssueBlocker.objects.filter(block=instance).delete()
@ -269,25 +239,6 @@ class IssueCreateSerializer(BaseSerializer):
batch_size=10,
)
if links is not None:
IssueLink.objects.filter(issue=instance).delete()
IssueLink.objects.bulk_create(
[
IssueLink(
issue=instance,
project=instance.project,
workspace=instance.project.workspace,
created_by=instance.created_by,
updated_by=instance.updated_by,
title=link.get("title", None),
url=link.get("url", None),
)
for link in links
],
batch_size=10,
ignore_conflicts=True,
)
return super().update(instance, validated_data)
@ -456,6 +407,15 @@ class IssueLinkSerializer(BaseSerializer):
class Meta:
model = IssueLink
fields = "__all__"
read_only_fields = [
"workspace",
"project",
"created_by",
"updated_by",
"created_at",
"updated_at",
"issue",
]
# Issue Serializer with state details

View File

@ -10,24 +10,12 @@ from .issue import IssueStateSerializer
from plane.db.models import User, Module, ModuleMember, ModuleIssue, ModuleLink
class LinkCreateSerializer(serializers.Serializer):
url = serializers.CharField(required=True)
title = serializers.CharField(required=False)
class ModuleWriteSerializer(BaseSerializer):
members_list = serializers.ListField(
child=serializers.PrimaryKeyRelatedField(queryset=User.objects.all()),
write_only=True,
required=False,
)
links_list = serializers.ListField(
child=LinkCreateSerializer(),
write_only=True,
required=False,
)
class Meta:
model = Module
@ -42,9 +30,7 @@ class ModuleWriteSerializer(BaseSerializer):
]
def create(self, validated_data):
members = validated_data.pop("members_list", None)
links = validated_data.pop("links_list", None)
project = self.context["project"]
@ -67,30 +53,10 @@ class ModuleWriteSerializer(BaseSerializer):
ignore_conflicts=True,
)
if links is not None:
ModuleLink.objects.bulk_create(
[
ModuleLink(
module=module,
project=project,
workspace=project.workspace,
created_by=module.created_by,
updated_by=module.updated_by,
title=link.get("title", None),
url=link.get("url", None),
)
for link in links
],
batch_size=10,
ignore_conflicts=True,
)
return module
def update(self, instance, validated_data):
members = validated_data.pop("members_list", None)
links = validated_data.pop("links_list", None)
if members is not None:
ModuleMember.objects.filter(module=instance).delete()
@ -110,25 +76,6 @@ class ModuleWriteSerializer(BaseSerializer):
ignore_conflicts=True,
)
if links is not None:
ModuleLink.objects.filter(module=instance).delete()
ModuleLink.objects.bulk_create(
[
ModuleLink(
module=instance,
project=instance.project,
workspace=instance.project.workspace,
created_by=instance.created_by,
updated_by=instance.updated_by,
title=link.get("title", None),
url=link.get("url", None),
)
for link in links
],
batch_size=10,
ignore_conflicts=True,
)
return super().update(instance, validated_data)
@ -147,7 +94,6 @@ class ModuleFlatSerializer(BaseSerializer):
class ModuleIssueSerializer(BaseSerializer):
module_detail = ModuleFlatSerializer(read_only=True, source="module")
issue_detail = IssueStateSerializer(read_only=True, source="issue")
sub_issues_count = serializers.IntegerField(read_only=True)
@ -167,7 +113,6 @@ class ModuleIssueSerializer(BaseSerializer):
class ModuleLinkSerializer(BaseSerializer):
created_by_detail = UserLiteSerializer(read_only=True, source="created_by")
class Meta:
@ -180,11 +125,11 @@ class ModuleLinkSerializer(BaseSerializer):
"updated_by",
"created_at",
"updated_at",
"module",
]
class ModuleSerializer(BaseSerializer):
project_detail = ProjectSerializer(read_only=True, source="project")
lead_detail = UserLiteSerializer(read_only=True, source="lead")
members_detail = UserLiteSerializer(read_only=True, many=True, source="members")

View File

@ -65,6 +65,8 @@ from plane.api.views import (
IssuePropertyViewSet,
LabelViewSet,
SubIssuesEndpoint,
IssueLinkViewSet,
ModuleLinkViewSet,
## End Issues
# States
StateViewSet,
@ -573,6 +575,28 @@ urlpatterns = [
SubIssuesEndpoint.as_view(),
name="sub-issues",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:issue_id>/issue-links/",
IssueLinkViewSet.as_view(
{
"get": "list",
"post": "create",
}
),
name="project-issue-links",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:issue_id>/issue-links/<uuid:pk>/",
IssueLinkViewSet.as_view(
{
"get": "retrieve",
"put": "update",
"patch": "partial_update",
"delete": "destroy",
}
),
name="project-issue-links",
),
## End Issues
## Issue Activity
path(
@ -705,6 +729,28 @@ urlpatterns = [
),
name="project-module-issues",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/modules/<uuid:module_id>/module-links/",
ModuleLinkViewSet.as_view(
{
"get": "list",
"post": "create",
}
),
name="project-issue-module-links",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/modules/<uuid:module_id>/module-links/<uuid:pk>/",
ModuleLinkViewSet.as_view(
{
"get": "retrieve",
"put": "update",
"patch": "partial_update",
"delete": "destroy",
}
),
name="project-issue-module-links",
),
## End Modules
# API Tokens
path("api-tokens/", ApiTokenEndpoint.as_view(), name="api-tokens"),

View File

@ -58,6 +58,7 @@ from .issue import (
BulkDeleteIssuesEndpoint,
UserWorkSpaceIssues,
SubIssuesEndpoint,
IssueLinkViewSet,
)
from .auth_extended import (
@ -76,7 +77,7 @@ from .authentication import (
MagicSignInGenerateEndpoint,
)
from .module import ModuleViewSet, ModuleIssueViewSet
from .module import ModuleViewSet, ModuleIssueViewSet, ModuleLinkViewSet
from .api_token import ApiTokenEndpoint

View File

@ -23,6 +23,7 @@ from plane.api.serializers import (
IssueSerializer,
LabelSerializer,
IssueFlatSerializer,
IssueLinkSerializer,
)
from plane.api.permissions import (
ProjectEntityPermission,
@ -185,7 +186,7 @@ class IssueViewSet(BaseViewSet):
)
issues = IssueSerializer(issue_queryset, many=True).data
## Grouping the results
group_by = request.GET.get("group_by", False)
if group_by:
@ -690,3 +691,29 @@ class SubIssuesEndpoint(BaseAPIView):
{"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST,
)
class IssueLinkViewSet(BaseViewSet):
permission_classes = [
ProjectEntityPermission,
]
model = IssueLink
serializer_class = IssueLinkSerializer
def perform_create(self, serializer):
serializer.save(
project_id=self.kwargs.get("project_id"),
issue_id=self.kwargs.get("issue_id"),
)
def get_queryset(self):
return (
super()
.get_queryset()
.filter(workspace__slug=self.kwargs.get("slug"))
.filter(project_id=self.kwargs.get("project_id"))
.filter(issue_id=self.kwargs.get("issue_id"))
.filter(project__project_projectmember__member=self.request.user)
.distinct()
)

View File

@ -17,6 +17,7 @@ from plane.api.serializers import (
ModuleWriteSerializer,
ModuleSerializer,
ModuleIssueSerializer,
ModuleLinkSerializer,
)
from plane.api.permissions import ProjectEntityPermission
from plane.db.models import (
@ -258,3 +259,29 @@ class ModuleIssueViewSet(BaseViewSet):
{"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST,
)
class ModuleLinkViewSet(BaseViewSet):
permission_classes = [
ProjectEntityPermission,
]
model = ModuleLink
serializer_class = ModuleLinkSerializer
def perform_create(self, serializer):
serializer.save(
project_id=self.kwargs.get("project_id"),
module_id=self.kwargs.get("module_id"),
)
def get_queryset(self):
return (
super()
.get_queryset()
.filter(workspace__slug=self.kwargs.get("slug"))
.filter(project_id=self.kwargs.get("project_id"))
.filter(module_id=self.kwargs.get("module_id"))
.filter(project__project_projectmember__member=self.request.user)
.distinct()
)

View File

@ -174,6 +174,7 @@ class IssueLink(ProjectBaseModel):
issue = models.ForeignKey(
"db.Issue", on_delete=models.CASCADE, related_name="issue_link"
)
metadata = models.JSONField(default=dict)
class Meta:
verbose_name = "Issue Link"

View File

@ -7,7 +7,6 @@ from . import ProjectBaseModel
class Module(ProjectBaseModel):
name = models.CharField(max_length=255, verbose_name="Module Name")
description = models.TextField(verbose_name="Module Description", blank=True)
description_text = models.JSONField(
@ -41,7 +40,6 @@ class Module(ProjectBaseModel):
through_fields=("module", "member"),
)
class Meta:
unique_together = ["name", "project"]
verbose_name = "Module"
@ -54,7 +52,6 @@ class Module(ProjectBaseModel):
class ModuleMember(ProjectBaseModel):
module = models.ForeignKey("db.Module", on_delete=models.CASCADE)
member = models.ForeignKey("db.User", on_delete=models.CASCADE)
@ -70,7 +67,6 @@ class ModuleMember(ProjectBaseModel):
class ModuleIssue(ProjectBaseModel):
module = models.ForeignKey(
"db.Module", on_delete=models.CASCADE, related_name="issue_module"
)
@ -89,10 +85,12 @@ class ModuleIssue(ProjectBaseModel):
class ModuleLink(ProjectBaseModel):
title = models.CharField(max_length=255, null=True)
url = models.URLField()
module = models.ForeignKey(Module, on_delete=models.CASCADE, related_name="link_module")
module = models.ForeignKey(
Module, on_delete=models.CASCADE, related_name="link_module"
)
metadata = models.JSONField(default=dict)
class Meta:
verbose_name = "Module Link"
@ -101,4 +99,4 @@ class ModuleLink(ProjectBaseModel):
ordering = ("-created_at",)
def __str__(self):
return f"{self.module.name} {self.url}"
return f"{self.module.name} {self.url}"