From f3bafb02d154e8309ae9dc6899513b3b65ae320c Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Thu, 20 Jun 2024 16:02:47 +0530 Subject: [PATCH 1/6] fix: change sync repo scope --- .github/workflows/repo-sync.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/repo-sync.yml b/.github/workflows/repo-sync.yml index 665a7dbe2e..9ac4771ef6 100644 --- a/.github/workflows/repo-sync.yml +++ b/.github/workflows/repo-sync.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - develop + - preview env: SOURCE_BRANCH_NAME: ${{ github.ref_name }} From 198452430f996d22eba0499d0b1c6fa65e1d82ca Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Thu, 20 Jun 2024 16:04:46 +0530 Subject: [PATCH 2/6] [WEB-1674] chore: views access control (#4885) * chore: access control changes in views * chore: view serializer change --- apiserver/plane/app/serializers/view.py | 8 +--- apiserver/plane/app/views/view/base.py | 57 +++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/apiserver/plane/app/serializers/view.py b/apiserver/plane/app/serializers/view.py index 32fba7d0c9..6b08ae80b8 100644 --- a/apiserver/plane/app/serializers/view.py +++ b/apiserver/plane/app/serializers/view.py @@ -3,18 +3,12 @@ from rest_framework import serializers # Module imports from .base import DynamicBaseSerializer -from .workspace import WorkspaceLiteSerializer -from .project import ProjectLiteSerializer from plane.db.models import IssueView from plane.utils.issue_filters import issue_filters class IssueViewSerializer(DynamicBaseSerializer): is_favorite = serializers.BooleanField(read_only=True) - project_detail = ProjectLiteSerializer(source="project", read_only=True) - workspace_detail = WorkspaceLiteSerializer( - source="workspace", read_only=True - ) class Meta: model = IssueView @@ -24,6 +18,8 @@ class IssueViewSerializer(DynamicBaseSerializer): "project", "query", "owned_by", + "access", + "is_locked", ] def create(self, validated_data): diff --git a/apiserver/plane/app/views/view/base.py b/apiserver/plane/app/views/view/base.py index 8e9f5b284a..fc44866fc2 100644 --- a/apiserver/plane/app/views/view/base.py +++ b/apiserver/plane/app/views/view/base.py @@ -69,11 +69,40 @@ class WorkspaceViewViewSet(BaseViewSet): .get_queryset() .filter(workspace__slug=self.kwargs.get("slug")) .filter(project__isnull=True) + .filter(Q(owned_by=self.request.user) | Q(access=1)) .select_related("workspace") .order_by(self.request.GET.get("order_by", "-created_at")) .distinct() ) + def partial_update(self, request, slug, pk): + workspace_view = IssueView.objects.get( + pk=pk, + workspace__slug=slug, + ) + + if workspace_view.is_locked: + return Response( + {"error": "view is locked"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + # Only update the view if owner is updating + if workspace_view.owned_by_id != request.user.id: + return Response( + {"error": "Only the owner of the view can update the view"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + serializer = IssueViewSerializer( + workspace_view, 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) + class WorkspaceViewIssuesViewSet(BaseViewSet): permission_classes = [ @@ -294,6 +323,7 @@ class IssueViewViewSet(BaseViewSet): project__project_projectmember__is_active=True, project__archived_at__isnull=True, ) + .filter(Q(owned_by=self.request.user) | Q(access=1)) .select_related("project") .select_related("workspace") .annotate(is_favorite=Exists(subquery)) @@ -313,6 +343,33 @@ class IssueViewViewSet(BaseViewSet): ).data return Response(views, status=status.HTTP_200_OK) + def partial_update(self, request, slug, project_id, pk): + issue_view = IssueView.objects.get( + pk=pk, workspace__slug=slug, project_id=project_id + ) + + if issue_view.is_locked: + return Response( + {"error": "view is locked"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + # Only update the view if owner is updating + if issue_view.owned_by_id != request.user.id: + return Response( + {"error": "Only the owner of the view can update the view"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + serializer = IssueViewSerializer( + issue_view, 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) + class IssueViewFavoriteViewSet(BaseViewSet): model = UserFavorite From 4e5b44593018706e4e089df68bbc86d9c1dce231 Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Thu, 20 Jun 2024 16:05:24 +0530 Subject: [PATCH 3/6] chore: workspace cycles (#4886) --- apiserver/plane/app/views/workspace/cycle.py | 24 -------------------- 1 file changed, 24 deletions(-) diff --git a/apiserver/plane/app/views/workspace/cycle.py b/apiserver/plane/app/views/workspace/cycle.py index fa2954d673..f642416e3b 100644 --- a/apiserver/plane/app/views/workspace/cycle.py +++ b/apiserver/plane/app/views/workspace/cycle.py @@ -2,7 +2,6 @@ from django.db.models import ( Q, Count, - Sum, ) # Third party modules @@ -87,29 +86,6 @@ class WorkspaceCyclesEndpoint(BaseAPIView): ), ) ) - .annotate( - total_estimates=Sum("issue_cycle__issue__estimate_point") - ) - .annotate( - completed_estimates=Sum( - "issue_cycle__issue__estimate_point", - filter=Q( - issue_cycle__issue__state__group="completed", - issue_cycle__issue__archived_at__isnull=True, - issue_cycle__issue__is_draft=False, - ), - ) - ) - .annotate( - started_estimates=Sum( - "issue_cycle__issue__estimate_point", - filter=Q( - issue_cycle__issue__state__group="started", - issue_cycle__issue__archived_at__isnull=True, - issue_cycle__issue__is_draft=False, - ), - ) - ) .order_by(self.kwargs.get("order_by", "-created_at")) .distinct() ) From 24adddd29ff84e75738beeea3d52003dafa969c4 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Thu, 20 Jun 2024 16:08:14 +0530 Subject: [PATCH 4/6] [WEB-1647] chore: breadcrumb items loader (#4887) * chore: breadcrumb item loader added * chore: breadcrumb item loader implementation --- packages/ui/src/breadcrumbs/breadcrumbs.tsx | 16 +++++++++++++--- .../(detail)/[projectId]/archives/header.tsx | 4 ++-- .../archives/issues/(detail)/header.tsx | 4 ++-- .../[projectId]/cycles/(detail)/header.tsx | 16 +++++++++++----- .../[projectId]/cycles/(list)/header.tsx | 4 ++-- .../(detail)/[projectId]/draft-issues/header.tsx | 11 ++++++++--- .../(detail)/[projectId]/inbox/header.tsx | 4 ++-- .../[projectId]/issues/(detail)/header.tsx | 4 ++-- .../[projectId]/issues/(list)/header.tsx | 14 ++++++++++---- .../[projectId]/modules/(detail)/header.tsx | 16 +++++++++++----- .../[projectId]/modules/(list)/header.tsx | 4 ++-- .../[projectId]/pages/(detail)/header.tsx | 4 ++-- .../(detail)/[projectId]/pages/(list)/header.tsx | 4 ++-- .../(detail)/[projectId]/settings/header.tsx | 4 ++-- .../views/(detail)/[viewId]/header.tsx | 11 ++++++++--- .../(detail)/[projectId]/views/(list)/header.tsx | 4 ++-- .../(projects)/settings/header.tsx | 4 ++-- 17 files changed, 83 insertions(+), 45 deletions(-) diff --git a/packages/ui/src/breadcrumbs/breadcrumbs.tsx b/packages/ui/src/breadcrumbs/breadcrumbs.tsx index 253e8308e0..0318256911 100644 --- a/packages/ui/src/breadcrumbs/breadcrumbs.tsx +++ b/packages/ui/src/breadcrumbs/breadcrumbs.tsx @@ -4,9 +4,10 @@ import { ChevronRight } from "lucide-react"; type BreadcrumbsProps = { children: React.ReactNode; onBack?: () => void; + isLoading?: boolean; }; -const Breadcrumbs = ({ children, onBack }: BreadcrumbsProps) => { +const Breadcrumbs = ({ children, onBack, isLoading = false }: BreadcrumbsProps) => { const [isSmallScreen, setIsSmallScreen] = React.useState(false); React.useEffect(() => { @@ -21,6 +22,13 @@ const Breadcrumbs = ({ children, onBack }: BreadcrumbsProps) => { const childrenArray = React.Children.toArray(children); + const BreadcrumbItemLoader = ( +
+ + +
+ ); + return (
{!isSmallScreen && ( @@ -33,7 +41,7 @@ const Breadcrumbs = ({ children, onBack }: BreadcrumbsProps) => {
)}
0 ? "hidden sm:flex" : "flex"}`}> - {child} + {isLoading ? BreadcrumbItemLoader : child}
))} @@ -50,7 +58,9 @@ const Breadcrumbs = ({ children, onBack }: BreadcrumbsProps) => { )}