Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion apiserver/plane/app/urls/intake.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from django.urls import path


from plane.app.views import IntakeViewSet, IntakeIssueViewSet
from plane.app.views import (
IntakeViewSet,
IntakeIssueViewSet,
IntakeWorkItemDescriptionVersionEndpoint,
)


urlpatterns = [
Expand Down Expand Up @@ -53,4 +57,14 @@
),
name="inbox-issue",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/intake-work-items/<uuid:work_item_id>/description-versions/",
IntakeWorkItemDescriptionVersionEndpoint.as_view(),
name="intake-work-item-versions",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/intake-work-items/<uuid:work_item_id>/description-versions/<uuid:pk>/",
IntakeWorkItemDescriptionVersionEndpoint.as_view(),
name="intake-work-item-versions",
),
]
18 changes: 9 additions & 9 deletions apiserver/plane/app/urls/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
IssueAttachmentV2Endpoint,
IssueBulkUpdateDateEndpoint,
IssueVersionEndpoint,
IssueDescriptionVersionEndpoint,
WorkItemDescriptionVersionEndpoint,
IssueMetaEndpoint,
IssueDetailIdentifierEndpoint,
)
Expand Down Expand Up @@ -263,22 +263,22 @@
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:issue_id>/versions/",
IssueVersionEndpoint.as_view(),
name="page-versions",
name="issue-versions",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:issue_id>/versions/<uuid:pk>/",
IssueVersionEndpoint.as_view(),
name="page-versions",
name="issue-versions",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:issue_id>/description-versions/",
IssueDescriptionVersionEndpoint.as_view(),
name="page-versions",
"workspaces/<str:slug>/projects/<uuid:project_id>/work-items/<uuid:work_item_id>/description-versions/",
WorkItemDescriptionVersionEndpoint.as_view(),
name="work-item-versions",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:issue_id>/description-versions/<uuid:pk>/",
IssueDescriptionVersionEndpoint.as_view(),
name="page-versions",
"workspaces/<str:slug>/projects/<uuid:project_id>/work-items/<uuid:work_item_id>/description-versions/<uuid:pk>/",
WorkItemDescriptionVersionEndpoint.as_view(),
name="work-item-versions",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:issue_id>/meta/",
Expand Down
8 changes: 6 additions & 2 deletions apiserver/plane/app/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@

from .issue.subscriber import IssueSubscriberViewSet

from .issue.version import IssueVersionEndpoint, IssueDescriptionVersionEndpoint
from .issue.version import IssueVersionEndpoint, WorkItemDescriptionVersionEndpoint

from .module.base import (
ModuleViewSet,
Expand Down Expand Up @@ -184,7 +184,11 @@
EstimatePointEndpoint,
)

from .intake.base import IntakeViewSet, IntakeIssueViewSet
from .intake.base import (
IntakeViewSet,
IntakeIssueViewSet,
IntakeWorkItemDescriptionVersionEndpoint,
)

from .analytic.base import (
AnalyticsEndpoint,
Expand Down
117 changes: 107 additions & 10 deletions apiserver/plane/app/views/intake/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,22 @@
Project,
ProjectMember,
CycleIssue,
IssueDescriptionVersion,
)
from plane.app.serializers import (
IssueCreateSerializer,
IssueSerializer,
IssueDetailSerializer,
IntakeSerializer,
IntakeIssueSerializer,
IntakeIssueDetailSerializer,
IssueDescriptionVersionDetailSerializer,
)
from plane.utils.issue_filters import issue_filters
from plane.bgtasks.issue_activities_task import issue_activity
from plane.bgtasks.issue_description_version_task import issue_description_version_task
from plane.app.views.base import BaseAPIView
from plane.utils.timezone_converter import user_timezone_converter
from plane.utils.global_paginator import paginate
from plane.utils.host import base_host


Expand Down Expand Up @@ -88,7 +94,7 @@ class IntakeIssueViewSet(BaseViewSet):
serializer_class = IntakeIssueSerializer
model = IntakeIssue

filterset_fields = ["statulls"]
filterset_fields = ["status"]

def get_queryset(self):
return (
Expand Down Expand Up @@ -219,7 +225,7 @@ def list(self, request, slug, project_id):
workspace__slug=slug,
project_id=project_id,
member=request.user,
role=5,
role=ROLE.GUEST.value,
is_active=True,
).exists()
and not project.guest_view_all_features
Expand Down Expand Up @@ -287,6 +293,13 @@ def create(self, request, slug, project_id):
origin=base_host(request=request, is_app=True),
intake=str(intake_issue.id),
)
# updated issue description version
issue_description_version_task.delay(
updated_issue=json.dumps(request.data, cls=DjangoJSONEncoder),
issue_id=str(serializer.data["id"]),
user_id=request.user.id,
is_creating=True,
)
intake_issue = (
IntakeIssue.objects.select_related("issue")
.prefetch_related("issue__labels", "issue__assignees")
Expand Down Expand Up @@ -386,13 +399,16 @@ def partial_update(self, request, slug, project_id, pk):
),
"description": issue_data.get("description", issue.description),
}
current_instance = json.dumps(
IssueDetailSerializer(issue).data, cls=DjangoJSONEncoder
)

issue_serializer = IssueCreateSerializer(
issue, data=issue_data, partial=True, context={"project_id": project_id}
)

if issue_serializer.is_valid():
current_instance = issue

# Log all the updates
requested_data = json.dumps(issue_data, cls=DjangoJSONEncoder)
if issue is not None:
Expand All @@ -402,15 +418,18 @@ def partial_update(self, request, slug, project_id, pk):
actor_id=str(request.user.id),
issue_id=str(issue.id),
project_id=str(project_id),
current_instance=json.dumps(
IssueSerializer(current_instance).data,
cls=DjangoJSONEncoder,
),
current_instance=current_instance,
epoch=int(timezone.now().timestamp()),
notification=True,
origin=base_host(request=request, is_app=True),
intake=str(intake_issue.id),
)
# updated issue description version
issue_description_version_task.delay(
updated_issue=current_instance,
issue_id=str(pk),
user_id=request.user.id,
)
issue_serializer.save()
else:
return Response(
Expand Down Expand Up @@ -550,15 +569,15 @@ def retrieve(self, request, slug, project_id, pk):
workspace__slug=slug,
project_id=project_id,
member=request.user,
role=5,
role=ROLE.GUEST.value,
is_active=True,
).exists()
and not project.guest_view_all_features
and not intake_issue.created_by == request.user
):
return Response(
{"error": "You are not allowed to view this issue"},
status=status.HTTP_400_BAD_REQUEST,
status=status.HTTP_403_FORBIDDEN,
)
issue = IntakeIssueDetailSerializer(intake_issue).data
return Response(issue, status=status.HTTP_200_OK)
Expand All @@ -585,3 +604,81 @@ def destroy(self, request, slug, project_id, pk):

intake_issue.delete()
return Response(status=status.HTTP_204_NO_CONTENT)


class IntakeWorkItemDescriptionVersionEndpoint(BaseAPIView):

def process_paginated_result(self, fields, results, timezone):
paginated_data = results.values(*fields)

datetime_fields = ["created_at", "updated_at"]
paginated_data = user_timezone_converter(
paginated_data, datetime_fields, timezone
)

return paginated_data

@allow_permission(allowed_roles=[ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
def get(self, request, slug, project_id, work_item_id, pk=None):
project = Project.objects.get(pk=project_id)
issue = Issue.objects.get(
workspace__slug=slug, project_id=project_id, pk=work_item_id
)

if (
ProjectMember.objects.filter(
workspace__slug=slug,
project_id=project_id,
member=request.user,
role=ROLE.GUEST.value,
is_active=True,
).exists()
and not project.guest_view_all_features
and not issue.created_by == request.user
):
return Response(
{"error": "You are not allowed to view this issue"},
status=status.HTTP_403_FORBIDDEN,
)

if pk:
issue_description_version = IssueDescriptionVersion.objects.get(
workspace__slug=slug,
project_id=project_id,
issue_id=work_item_id,
pk=pk,
)

serializer = IssueDescriptionVersionDetailSerializer(
issue_description_version
)
return Response(serializer.data, status=status.HTTP_200_OK)

cursor = request.GET.get("cursor", None)

required_fields = [
"id",
"workspace",
"project",
"issue",
"last_saved_at",
"owned_by",
"created_at",
"updated_at",
"created_by",
"updated_by",
]

issue_description_versions_queryset = IssueDescriptionVersion.objects.filter(
workspace__slug=slug, project_id=project_id, issue_id=work_item_id
)

paginated_data = paginate(
base_queryset=issue_description_versions_queryset,
queryset=issue_description_versions_queryset,
cursor=cursor,
on_result=lambda results: self.process_paginated_result(
required_fields, results, request.user.user_timezone
),
)
return Response(paginated_data, status=status.HTTP_200_OK)
6 changes: 3 additions & 3 deletions apiserver/plane/app/views/issue/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ def retrieve(self, request, slug, project_id, pk=None):
):
return Response(
{"error": "You are not allowed to view this issue"},
status=status.HTTP_400_BAD_REQUEST,
status=status.HTTP_403_FORBIDDEN,
)

recent_visited_task.delay(
Expand Down Expand Up @@ -632,7 +632,7 @@ def partial_update(self, request, slug, project_id, pk=None):
)

current_instance = json.dumps(
IssueSerializer(issue).data, cls=DjangoJSONEncoder
IssueDetailSerializer(issue).data, cls=DjangoJSONEncoder
)

requested_data = json.dumps(self.request.data, cls=DjangoJSONEncoder)
Expand Down Expand Up @@ -1278,7 +1278,7 @@ def get(self, request, slug, project_identifier, issue_identifier):
):
return Response(
{"error": "You are not allowed to view this issue"},
status=status.HTTP_400_BAD_REQUEST,
status=status.HTTP_403_FORBIDDEN,
)

recent_visited_task.delay(
Expand Down
42 changes: 36 additions & 6 deletions apiserver/plane/app/views/issue/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
from rest_framework.response import Response

# Module imports
from plane.db.models import IssueVersion, IssueDescriptionVersion
from plane.db.models import (
IssueVersion,
IssueDescriptionVersion,
Project,
ProjectMember,
Issue,
)
from ..base import BaseAPIView
from plane.app.serializers import (
IssueVersionDetailSerializer,
Expand Down Expand Up @@ -66,7 +72,7 @@ def get(self, request, slug, project_id, issue_id, pk=None):
return Response(paginated_data, status=status.HTTP_200_OK)


class IssueDescriptionVersionEndpoint(BaseAPIView):
class WorkItemDescriptionVersionEndpoint(BaseAPIView):
def process_paginated_result(self, fields, results, timezone):
paginated_data = results.values(*fields)

Expand All @@ -78,10 +84,34 @@ def process_paginated_result(self, fields, results, timezone):
return paginated_data

@allow_permission(allowed_roles=[ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
def get(self, request, slug, project_id, issue_id, pk=None):
def get(self, request, slug, project_id, work_item_id, pk=None):
project = Project.objects.get(pk=project_id)
issue = Issue.objects.get(
workspace__slug=slug, project_id=project_id, pk=work_item_id
)

if (
ProjectMember.objects.filter(
workspace__slug=slug,
project_id=project_id,
member=request.user,
role=ROLE.GUEST.value,
is_active=True,
).exists()
and not project.guest_view_all_features
and not issue.created_by == request.user
):
return Response(
{"error": "You are not allowed to view this issue"},
status=status.HTTP_403_FORBIDDEN,
)

if pk:
issue_description_version = IssueDescriptionVersion.objects.get(
workspace__slug=slug, project_id=project_id, issue_id=issue_id, pk=pk
workspace__slug=slug,
project_id=project_id,
issue_id=work_item_id,
pk=pk,
)

serializer = IssueDescriptionVersionDetailSerializer(
Expand All @@ -105,8 +135,8 @@ def get(self, request, slug, project_id, issue_id, pk=None):
]

issue_description_versions_queryset = IssueDescriptionVersion.objects.filter(
workspace__slug=slug, project_id=project_id, issue_id=issue_id
)
workspace__slug=slug, project_id=project_id, issue_id=work_item_id
).order_by("-created_at")
paginated_data = paginate(
base_queryset=issue_description_versions_queryset,
queryset=issue_description_versions_queryset,
Expand Down
2 changes: 1 addition & 1 deletion apiserver/plane/app/views/view/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ def retrieve(self, request, slug, project_id, pk):
):
return Response(
{"error": "You are not allowed to view this issue"},
status=status.HTTP_400_BAD_REQUEST,
status=status.HTTP_403_FORBIDDEN,
)

serializer = IssueViewSerializer(issue_view)
Expand Down
Loading