mirror of
https://github.com/makeplane/plane.git
synced 2026-07-13 05:49:40 +02:00
Merge pull request #2121 from makeplane/sync/ce-ee
Sync: Community Changes
This commit is contained in:
@@ -21,6 +21,7 @@ from .workspace import (
|
||||
WorkspaceUserPropertiesSerializer,
|
||||
WorkspaceUserLinkSerializer,
|
||||
WorkspaceRecentVisitSerializer,
|
||||
WorkspaceHomePreferenceSerializer,
|
||||
WorkspaceUserMeSerializer,
|
||||
)
|
||||
from .project import (
|
||||
|
||||
@@ -16,10 +16,11 @@ from plane.db.models import (
|
||||
WorkspaceUserProperties,
|
||||
WorkspaceUserLink,
|
||||
UserRecentVisit,
|
||||
Issue,
|
||||
Page,
|
||||
Issue,
|
||||
Page,
|
||||
Project,
|
||||
ProjectMember
|
||||
ProjectMember,
|
||||
WorkspaceHomePreference,
|
||||
)
|
||||
from plane.utils.constants import RESTRICTED_WORKSPACE_SLUGS
|
||||
|
||||
@@ -27,6 +28,7 @@ from plane.utils.constants import RESTRICTED_WORKSPACE_SLUGS
|
||||
from django.core.validators import URLValidator
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
|
||||
class WorkSpaceSerializer(DynamicBaseSerializer):
|
||||
owner = UserLiteSerializer(read_only=True)
|
||||
total_members = serializers.IntegerField(read_only=True)
|
||||
@@ -141,6 +143,7 @@ class WorkspaceUserPropertiesSerializer(BaseSerializer):
|
||||
fields = "__all__"
|
||||
read_only_fields = ["workspace", "user"]
|
||||
|
||||
|
||||
class WorkspaceUserLinkSerializer(BaseSerializer):
|
||||
class Meta:
|
||||
model = WorkspaceUserLink
|
||||
@@ -151,7 +154,7 @@ class WorkspaceUserLinkSerializer(BaseSerializer):
|
||||
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):
|
||||
@@ -163,18 +166,29 @@ class WorkspaceUserLinkSerializer(BaseSerializer):
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class IssueRecentVisitSerializer(serializers.ModelSerializer):
|
||||
project_identifier = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Issue
|
||||
fields = ["name", "state", "priority", "assignees", "type", "sequence_id", "project_id", "project_identifier"]
|
||||
fields = [
|
||||
"name",
|
||||
"state",
|
||||
"priority",
|
||||
"assignees",
|
||||
"type",
|
||||
"sequence_id",
|
||||
"project_id",
|
||||
"project_identifier",
|
||||
]
|
||||
|
||||
def get_project_identifier(self, obj):
|
||||
project = obj.project
|
||||
|
||||
return project.identifier if project else None
|
||||
|
||||
|
||||
class ProjectMemberSerializer(BaseSerializer):
|
||||
member = UserLiteSerializer(read_only=True)
|
||||
|
||||
@@ -182,55 +196,66 @@ class ProjectMemberSerializer(BaseSerializer):
|
||||
model = ProjectMember
|
||||
fields = ["member"]
|
||||
|
||||
|
||||
class ProjectRecentVisitSerializer(serializers.ModelSerializer):
|
||||
project_members = serializers.SerializerMethodField()
|
||||
|
||||
project_members = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Project
|
||||
fields = ["id", "name", "logo_props", "project_members", "identifier"]
|
||||
|
||||
def get_project_members(self, obj):
|
||||
members = ProjectMember.objects.filter(project_id=obj.id).select_related('member')
|
||||
members = ProjectMember.objects.filter(project_id=obj.id).select_related(
|
||||
"member"
|
||||
)
|
||||
|
||||
serializer = ProjectMemberSerializer(members, many=True)
|
||||
return serializer.data
|
||||
|
||||
|
||||
|
||||
class PageRecentVisitSerializer(serializers.ModelSerializer):
|
||||
project_id = serializers.SerializerMethodField()
|
||||
project_identifier = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Page
|
||||
fields = ["id", "name", "logo_props", "project_id", "owned_by", "project_identifier"]
|
||||
fields = [
|
||||
"id",
|
||||
"name",
|
||||
"logo_props",
|
||||
"project_id",
|
||||
"owned_by",
|
||||
"project_identifier",
|
||||
]
|
||||
|
||||
def get_project_id(self, obj):
|
||||
return obj.project_id if hasattr(obj, 'project_id') else obj.projects.values_list('id', flat=True).first()
|
||||
|
||||
return (
|
||||
obj.project_id
|
||||
if hasattr(obj, "project_id")
|
||||
else obj.projects.values_list("id", flat=True).first()
|
||||
)
|
||||
|
||||
def get_project_identifier(self, obj):
|
||||
project = obj.projects.first()
|
||||
|
||||
return project.identifier if project else None
|
||||
|
||||
|
||||
def get_entity_model_and_serializer(entity_type):
|
||||
entity_map = {
|
||||
"issue": (Issue, IssueRecentVisitSerializer),
|
||||
"page": (Page, PageRecentVisitSerializer),
|
||||
"project": (Project, ProjectRecentVisitSerializer)
|
||||
"project": (Project, ProjectRecentVisitSerializer),
|
||||
}
|
||||
return entity_map.get(entity_type, (None, None))
|
||||
|
||||
|
||||
class WorkspaceRecentVisitSerializer(BaseSerializer):
|
||||
entity_data = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = UserRecentVisit
|
||||
fields = [
|
||||
"id",
|
||||
"entity_name",
|
||||
"entity_identifier",
|
||||
"entity_data",
|
||||
"visited_at"
|
||||
]
|
||||
fields = ["id", "entity_name", "entity_identifier", "entity_data", "visited_at"]
|
||||
read_only_fields = ["workspace", "owner", "created_by", "updated_by"]
|
||||
|
||||
def get_entity_data(self, obj):
|
||||
@@ -247,3 +272,10 @@ class WorkspaceRecentVisitSerializer(BaseSerializer):
|
||||
except entity_model.DoesNotExist:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
class WorkspaceHomePreferenceSerializer(BaseSerializer):
|
||||
class Meta:
|
||||
model = WorkspaceHomePreference
|
||||
fields = ["key", "is_enabled", "sort_order"]
|
||||
read_only_fields = ["worspace", "created_by", "update_by"]
|
||||
|
||||
@@ -28,7 +28,8 @@ from plane.app.views import (
|
||||
WorkspaceFavoriteGroupEndpoint,
|
||||
WorkspaceDraftIssueViewSet,
|
||||
QuickLinkViewSet,
|
||||
UserRecentVisitViewSet
|
||||
UserRecentVisitViewSet,
|
||||
WorkspacePreferenceViewSet,
|
||||
)
|
||||
|
||||
|
||||
@@ -215,25 +216,33 @@ 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"
|
||||
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"
|
||||
"workspaces/<str:slug>/quick-links/<uuid:pk>/",
|
||||
QuickLinkViewSet.as_view(
|
||||
{"get": "retrieve", "patch": "partial_update", "delete": "destroy"}
|
||||
),
|
||||
name="workspace-quick-links",
|
||||
),
|
||||
# Widgets
|
||||
path(
|
||||
"workspaces/<str:slug>/home-preferences/",
|
||||
WorkspacePreferenceViewSet.as_view(),
|
||||
name="workspace-home-preference",
|
||||
),
|
||||
path(
|
||||
"workspaces/<str:slug>/home-preferences/<str:key>/",
|
||||
WorkspacePreferenceViewSet.as_view(),
|
||||
name="workspace-home-preference",
|
||||
),
|
||||
path(
|
||||
"workspaces/<str:slug>/recent-visits/",
|
||||
UserRecentVisitViewSet.as_view({"get": "list"}),
|
||||
name="workspace-recent-visits"
|
||||
)
|
||||
name="workspace-recent-visits",
|
||||
),
|
||||
]
|
||||
|
||||
@@ -41,6 +41,7 @@ from .workspace.base import (
|
||||
|
||||
from .workspace.draft import WorkspaceDraftIssueViewSet
|
||||
|
||||
from .workspace.preference import WorkspacePreferenceViewSet
|
||||
from .workspace.favorite import (
|
||||
WorkspaceFavoriteEndpoint,
|
||||
WorkspaceFavoriteGroupEndpoint,
|
||||
|
||||
72
apiserver/plane/app/views/workspace/preference.py
Normal file
72
apiserver/plane/app/views/workspace/preference.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# Module imports
|
||||
from ..base import BaseAPIView
|
||||
from plane.db.models.workspace import WorkspaceHomePreference
|
||||
from plane.app.permissions import allow_permission, ROLE
|
||||
from plane.db.models import Workspace
|
||||
from plane.app.serializers.workspace import WorkspaceHomePreferenceSerializer
|
||||
|
||||
# Third party imports
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
class WorkspacePreferenceViewSet(BaseAPIView):
|
||||
model = WorkspaceHomePreference
|
||||
|
||||
def get_serializer_class(self):
|
||||
return WorkspaceHomePreferenceSerializer
|
||||
|
||||
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
|
||||
def get(self, request, slug):
|
||||
workspace = Workspace.objects.get(slug=slug)
|
||||
|
||||
get_preference = WorkspaceHomePreference.objects.filter(
|
||||
user=request.user, workspace_id=workspace.id
|
||||
)
|
||||
|
||||
create_preference_keys = []
|
||||
|
||||
keys = [key for key, _ in WorkspaceHomePreference.HomeWidgetKeys.choices]
|
||||
|
||||
for preference in keys:
|
||||
if preference not in get_preference.values_list("key", flat=True):
|
||||
create_preference_keys.append(preference)
|
||||
|
||||
preference = WorkspaceHomePreference.objects.bulk_create(
|
||||
[
|
||||
WorkspaceHomePreference(
|
||||
key=key, user=request.user, workspace=workspace
|
||||
)
|
||||
for key in create_preference_keys
|
||||
],
|
||||
batch_size=10,
|
||||
ignore_conflicts=True,
|
||||
)
|
||||
preference = WorkspaceHomePreference.objects.filter(
|
||||
user=request.user, workspace_id=workspace.id
|
||||
)
|
||||
|
||||
return Response(
|
||||
preference.values("key", "is_enabled", "config", "sort_order"),
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
|
||||
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
|
||||
def patch(self, request, slug, key):
|
||||
preference = WorkspaceHomePreference.objects.filter(
|
||||
key=key, workspace__slug=slug
|
||||
).first()
|
||||
|
||||
if preference:
|
||||
serializer = WorkspaceHomePreferenceSerializer(
|
||||
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_400_BAD_REQUEST
|
||||
)
|
||||
@@ -69,6 +69,7 @@ from .workspace import (
|
||||
WorkspaceTheme,
|
||||
WorkspaceUserProperties,
|
||||
WorkspaceUserLink,
|
||||
WorkspaceHomePreference
|
||||
)
|
||||
|
||||
from .favorite import UserFavorite
|
||||
|
||||
Reference in New Issue
Block a user