feat: workspace user preference api (#6497)

* feat: workspace user preference api

* feat: remove sort order calculation

* Return 404 error
This commit is contained in:
Sangeetha 2025-01-28 20:50:24 +05:30 committed by GitHub
parent 51b52a7fc3
commit 6a8d3202b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 99 additions and 2 deletions

View file

@ -22,6 +22,7 @@ from plane.db.models import (
ProjectMember, ProjectMember,
WorkspaceHomePreference, WorkspaceHomePreference,
Sticky, Sticky,
WorkspaceUserPreference,
) )
from plane.utils.constants import RESTRICTED_WORKSPACE_SLUGS from plane.utils.constants import RESTRICTED_WORKSPACE_SLUGS
@ -258,3 +259,10 @@ class StickySerializer(BaseSerializer):
fields = "__all__" fields = "__all__"
read_only_fields = ["workspace", "owner"] read_only_fields = ["workspace", "owner"]
extra_kwargs = {"name": {"required": False}} extra_kwargs = {"name": {"required": False}}
class WorkspaceUserPreferenceSerializer(BaseSerializer):
class Meta:
model = WorkspaceUserPreference
fields = ["key", "is_pinned", "sort_order"]
read_only_fields = ["workspace", "created_by", "updated_by"]

View file

@ -31,6 +31,7 @@ from plane.app.views import (
UserRecentVisitViewSet, UserRecentVisitViewSet,
WorkspaceHomePreferenceViewSet, WorkspaceHomePreferenceViewSet,
WorkspaceStickyViewSet, WorkspaceStickyViewSet,
WorkspaceUserPreferenceViewSet,
) )
@ -258,4 +259,15 @@ urlpatterns = [
), ),
name="workspace-sticky", name="workspace-sticky",
), ),
# User Preference
path(
"workspaces/<str:slug>/user-preferences/",
WorkspaceUserPreferenceViewSet.as_view(),
name="workspace-user-preference",
),
path(
"workspaces/<str:slug>/user-preferences/<str:key>/",
WorkspaceUserPreferenceViewSet.as_view(),
name="workspace-user-preference",
),
] ]

View file

@ -48,6 +48,7 @@ from .workspace.favorite import (
WorkspaceFavoriteGroupEndpoint, WorkspaceFavoriteGroupEndpoint,
) )
from .workspace.recent_visit import UserRecentVisitViewSet from .workspace.recent_visit import UserRecentVisitViewSet
from .workspace.user_preference import WorkspaceUserPreferenceViewSet
from .workspace.member import ( from .workspace.member import (
WorkSpaceMemberViewSet, WorkSpaceMemberViewSet,

View file

@ -0,0 +1,74 @@
# Module imports
from ..base import BaseAPIView
from plane.db.models.workspace import WorkspaceUserPreference
from plane.app.serializers.workspace import WorkspaceUserPreferenceSerializer
from plane.app.permissions import allow_permission, ROLE
from plane.db.models import Workspace
# Third party imports
from rest_framework.response import Response
from rest_framework import status
class WorkspaceUserPreferenceViewSet(BaseAPIView):
model = WorkspaceUserPreference
def get_serializer_class(self):
return WorkspaceUserPreferenceSerializer
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def get(self, request, slug):
workspace = Workspace.objects.get(slug=slug)
get_preference = WorkspaceUserPreference.objects.filter(
user=request.user, workspace_id=workspace.id
)
create_preference_keys = []
keys = [key for key, _ in WorkspaceUserPreference.UserPreferenceKeys.choices]
for preference in keys:
if preference not in get_preference.values_list("key", flat=True):
create_preference_keys.append(preference)
preference = WorkspaceUserPreference.objects.bulk_create(
[
WorkspaceUserPreference(
key=key, user=request.user, workspace=workspace
)
for key in create_preference_keys
],
batch_size=10,
ignore_conflicts=True,
)
preference = WorkspaceUserPreference.objects.filter(
user=request.user, workspace_id=workspace.id
)
return Response(
preference.values("key", "is_pinned", "sort_order"),
status=status.HTTP_200_OK,
)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def patch(self, request, slug, key):
preference = WorkspaceUserPreference.objects.filter(
key=key, workspace__slug=slug, user=request.user
).first()
if preference:
serializer = WorkspaceUserPreferenceSerializer(
preference, 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": "Preference not found"}, status=status.HTTP_404_NOT_FOUND
)

View file

@ -69,7 +69,8 @@ from .workspace import (
WorkspaceTheme, WorkspaceTheme,
WorkspaceUserProperties, WorkspaceUserProperties,
WorkspaceUserLink, WorkspaceUserLink,
WorkspaceHomePreference WorkspaceHomePreference,
WorkspaceUserPreference,
) )
from .favorite import UserFavorite from .favorite import UserFavorite

View file

@ -388,7 +388,6 @@ class WorkspaceHomePreference(BaseModel):
return f"{self.workspace.name} {self.user.email} {self.key}" return f"{self.workspace.name} {self.user.email} {self.key}"
class WorkspaceUserPreference(BaseModel): class WorkspaceUserPreference(BaseModel):
"""Preference for the workspace for a user""" """Preference for the workspace for a user"""
@ -396,6 +395,8 @@ class WorkspaceUserPreference(BaseModel):
CYCLES = "cycles", "Cycles" CYCLES = "cycles", "Cycles"
VIEWS = "views", "Views" VIEWS = "views", "Views"
ANALYTICS = "analytics", "Analytics" ANALYTICS = "analytics", "Analytics"
TEAMS = "teams", "Teams"
INITIATIVES = "initiatives", "Initiatives"
PROJECTS = "projects", "Projects" PROJECTS = "projects", "Projects"
workspace = models.ForeignKey( workspace = models.ForeignKey(