[WEB-2928] feat: Home Quick links CRUD (#6290)

* Crud for wuick links

* Validate quick link existence

* Add custom method for destroy and retrieve

* Add List method

* Remove print statements

* List all the workspace quick links

* Filter by user
This commit is contained in:
Sangeetha 2024-12-31 15:06:24 +05:30 committed by GitHub
parent ec2af13258
commit 25f7d813b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 108 additions and 0 deletions

View file

@ -19,6 +19,7 @@ from .workspace import (
WorkspaceMemberAdminSerializer,
WorkspaceMemberMeSerializer,
WorkspaceUserPropertiesSerializer,
WorkspaceUserLinkSerializer
)
from .project import (
ProjectSerializer,

View file

@ -11,9 +11,13 @@ from plane.db.models import (
WorkspaceMemberInvite,
WorkspaceTheme,
WorkspaceUserProperties,
WorkspaceUserLink
)
from plane.utils.constants import RESTRICTED_WORKSPACE_SLUGS
# Django imports
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
class WorkSpaceSerializer(DynamicBaseSerializer):
owner = UserLiteSerializer(read_only=True)
@ -106,3 +110,25 @@ class WorkspaceUserPropertiesSerializer(BaseSerializer):
model = WorkspaceUserProperties
fields = "__all__"
read_only_fields = ["workspace", "user"]
class WorkspaceUserLinkSerializer(BaseSerializer):
class Meta:
model = WorkspaceUserLink
fields = "__all__"
read_only_fields = ["workspace", "owner"]
def to_internal_value(self, data):
url = data.get("url", "")
if url and not url.startswith(("http://", "https://")):
data["url"] = "http://" + url
return super().to_internal_value(data)
def validate_url(self, value):
url_validator = URLValidator()
try:
url_validator(value)
except ValidationError:
raise serializers.ValidationError({"error": "Invalid URL format."})
return value

View file

@ -27,6 +27,7 @@ from plane.app.views import (
WorkspaceFavoriteEndpoint,
WorkspaceFavoriteGroupEndpoint,
WorkspaceDraftIssueViewSet,
QuickLinkViewSet
)
@ -213,4 +214,16 @@ urlpatterns = [
WorkspaceDraftIssueViewSet.as_view({"post": "create_draft_to_issue"}),
name="workspace-drafts-issues",
),
# quick link
path(
"workspaces/<str:slug>/quick-links/",
QuickLinkViewSet.as_view({"get": "list", "post": "create"}),
name="workspace-quick-links "
),
path(
"workspaces/<str:slug>/quick-links/<uuid:pk>/",
QuickLinkViewSet.as_view({"get": "retrieve", "patch": "partial_update", "delete": "destroy"}),
name="workspace-quick-links"
)
]

View file

@ -72,6 +72,7 @@ from .workspace.user import (
from .workspace.estimate import WorkspaceEstimatesEndpoint
from .workspace.module import WorkspaceModulesEndpoint
from .workspace.cycle import WorkspaceCyclesEndpoint
from .workspace.quick_link import QuickLinkViewSet
from .state.base import StateViewSet
from .view.base import (

View file

@ -0,0 +1,67 @@
# Third party imports
from rest_framework import status
from rest_framework.response import Response
# Module imports
from plane.db.models import WorkspaceUserLink, Workspace
from plane.app.serializers import WorkspaceUserLinkSerializer
from ..base import BaseViewSet
from plane.app.permissions import allow_permission, ROLE
class QuickLinkViewSet(BaseViewSet):
model = WorkspaceUserLink
def get_serializer_class(self):
return WorkspaceUserLinkSerializer
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def create(self, request, slug):
workspace = Workspace.objects.get(slug=slug, owner=request.user)
serializer = WorkspaceUserLinkSerializer(data=request.data)
if serializer.is_valid():
serializer.save(workspace_id=workspace.id, owner=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def partial_update(self, request, slug, pk):
quick_link = WorkspaceUserLink.objects.filter(pk=pk, workspace__slug=slug, owner=request.user).first()
if quick_link:
serializer = WorkspaceUserLinkSerializer(quick_link, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return Response({"detail": "Quick link not found."}, status=status.HTTP_404_NOT_FOUND)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def retrieve(self, request, slug, pk):
try:
quick_link = WorkspaceUserLink.objects.get(
pk=pk,
workspace__slug=slug,
owner=request.user
)
serializer = WorkspaceUserLinkSerializer(quick_link)
return Response(serializer.data, status=status.HTTP_200_OK)
except WorkspaceUserLink.DoesNotExist:
return Response(
{"error": "Quick link not found."},
status=status.HTTP_404_NOT_FOUND
)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def destroy(self, request, slug, pk):
quick_link = WorkspaceUserLink.objects.get(pk=pk, workspace__slug=slug, owner=request.user)
quick_link.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def list(self, request, slug):
quick_links = WorkspaceUserLink.objects.filter(workspace__slug=slug, owner=request.user)
serializer = WorkspaceUserLinkSerializer(quick_links, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)