From 65846840ca6f2356ef789392d913a2e86af17108 Mon Sep 17 00:00:00 2001 From: NarayanBavisetti Date: Tue, 1 Oct 2024 19:25:09 +0530 Subject: [PATCH 1/4] chore: changed permission in inbox issue --- apiserver/plane/api/views/inbox.py | 2 +- apiserver/plane/app/views/inbox/base.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apiserver/plane/api/views/inbox.py b/apiserver/plane/api/views/inbox.py index 24eac569d68..f7e18dd76ff 100644 --- a/apiserver/plane/api/views/inbox.py +++ b/apiserver/plane/api/views/inbox.py @@ -285,7 +285,7 @@ def patch(self, request, slug, project_id, issue_id): ) # Only project admins and members can edit inbox issue attributes - if project_member.role > 5: + if project_member.role > 15: serializer = InboxIssueSerializer( inbox_issue, data=request.data, partial=True ) diff --git a/apiserver/plane/app/views/inbox/base.py b/apiserver/plane/app/views/inbox/base.py index 3bd5332dc27..4a32d993034 100644 --- a/apiserver/plane/app/views/inbox/base.py +++ b/apiserver/plane/app/views/inbox/base.py @@ -323,7 +323,7 @@ def create(self, request, slug, project_id): serializer.errors, status=status.HTTP_400_BAD_REQUEST ) - @allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST]) + @allow_permission(allowed_roles=[ROLE.ADMIN], creator=True, model=Issue) def partial_update(self, request, slug, project_id, pk): inbox_id = Inbox.objects.filter( workspace__slug=slug, project_id=project_id @@ -418,7 +418,7 @@ def partial_update(self, request, slug, project_id, pk): ) # Only project admins and members can edit inbox issue attributes - if project_member.role > 5: + if project_member.role > 15: serializer = InboxIssueSerializer( inbox_issue, data=request.data, partial=True ) From f14fd33e28a08bc82a657c881e2e81632e7f09d2 Mon Sep 17 00:00:00 2001 From: gakshita Date: Mon, 7 Oct 2024 17:24:56 +0530 Subject: [PATCH 2/4] chore: fixed permissions for intake --- .../inbox/content/inbox-issue-header.tsx | 51 ++++++++++++++++-- .../content/inbox-issue-mobile-header.tsx | 52 +++++++++++++++++-- web/core/components/inbox/content/root.tsx | 8 +-- web/core/store/inbox/project-inbox.store.ts | 2 +- 4 files changed, 99 insertions(+), 14 deletions(-) diff --git a/web/core/components/inbox/content/inbox-issue-header.tsx b/web/core/components/inbox/content/inbox-issue-header.tsx index efd0e8ee1e3..448133318c5 100644 --- a/web/core/components/inbox/content/inbox-issue-header.tsx +++ b/web/core/components/inbox/content/inbox-issue-header.tsx @@ -89,6 +89,12 @@ export const InboxIssueActionsHeader: FC = observer((p const canDelete = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.PROJECT, workspaceSlug, projectId) || issue?.created_by === currentUser?.id; + const isProjectAdmin = allowPermissions( + [EUserPermissions.ADMIN], + EUserPermissionsLevel.PROJECT, + workspaceSlug, + projectId + ); const isAcceptedOrDeclined = inboxIssue?.status ? [-1, 1, 2].includes(inboxIssue.status) : undefined; // days left for snooze const numberOfDaysLeft = findHowManyDaysLeft(inboxIssue?.snoozed_till); @@ -293,7 +299,15 @@ export const InboxIssueActionsHeader: FC = observer((p size="sm" prependIcon={} className="text-green-500 border-0.5 border-green-500 bg-green-500/20 focus:bg-green-500/20 focus:text-green-500 hover:bg-green-500/40 bg-opacity-20" - onClick={() => setAcceptIssueModal(true)} + onClick={() => + isProjectAdmin + ? setAcceptIssueModal(true) + : setToast({ + type: TOAST_TYPE.ERROR, + title: "Permission denied", + message: "Only project admins can accept issues", + }) + } > Accept @@ -307,7 +321,15 @@ export const InboxIssueActionsHeader: FC = observer((p size="sm" prependIcon={} className="text-red-500 border-0.5 border-red-500 bg-red-500/20 focus:bg-red-500/20 focus:text-red-500 hover:bg-red-500/40 bg-opacity-20" - onClick={() => setDeclineIssueModal(true)} + onClick={() => + isProjectAdmin + ? setDeclineIssueModal(true) + : setToast({ + type: TOAST_TYPE.ERROR, + title: "Permission denied", + message: "Only project admins can deny issues", + }) + } > Decline @@ -341,7 +363,17 @@ export const InboxIssueActionsHeader: FC = observer((p {isAllowed && ( {canMarkAsAccepted && ( - + + isProjectAdmin + ? handleIssueSnoozeAction() + : setToast({ + type: TOAST_TYPE.ERROR, + title: "Permission denied", + message: "Only project admins can snooze/Un-snooze issues", + }) + } + >
{inboxIssue?.snoozed_till && numberOfDaysLeft && numberOfDaysLeft > 0 @@ -351,7 +383,17 @@ export const InboxIssueActionsHeader: FC = observer((p )} {canMarkAsDuplicate && ( - setSelectDuplicateIssue(true)}> + + isProjectAdmin + ? setSelectDuplicateIssue(true) + : setToast({ + type: TOAST_TYPE.ERROR, + title: "Permission denied", + message: "Only project admins can mark issues as duplicate", + }) + } + >
Mark as duplicate @@ -401,6 +443,7 @@ export const InboxIssueActionsHeader: FC = observer((p setIsMobileSidebar={setIsMobileSidebar} isNotificationEmbed={isNotificationEmbed} embedRemoveCurrentNotification={embedRemoveCurrentNotification} + isProjectAdmin={isProjectAdmin} />
diff --git a/web/core/components/inbox/content/inbox-issue-mobile-header.tsx b/web/core/components/inbox/content/inbox-issue-mobile-header.tsx index e87573e9be0..1188062df5d 100644 --- a/web/core/components/inbox/content/inbox-issue-mobile-header.tsx +++ b/web/core/components/inbox/content/inbox-issue-mobile-header.tsx @@ -15,7 +15,7 @@ import { PanelLeft, MoveRight, } from "lucide-react"; -import { Header, CustomMenu, EHeaderVariant } from "@plane/ui"; +import { Header, CustomMenu, EHeaderVariant, TOAST_TYPE, setToast } from "@plane/ui"; // components import { InboxIssueStatus } from "@/components/inbox"; import { IssueUpdateStatus } from "@/components/issues"; @@ -47,6 +47,7 @@ type Props = { setIsMobileSidebar: (value: boolean) => void; isNotificationEmbed: boolean; embedRemoveCurrentNotification?: () => void; + isProjectAdmin: boolean; }; export const InboxIssueActionsMobileHeader: React.FC = observer((props) => { @@ -70,6 +71,7 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) = setIsMobileSidebar, isNotificationEmbed, embedRemoveCurrentNotification, + isProjectAdmin, } = props; const router = useAppRouter(); const issue = inboxIssue?.issue; @@ -139,7 +141,17 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) =
)} {canMarkAsAccepted && !isAcceptedOrDeclined && ( - + + isProjectAdmin + ? handleIssueSnoozeAction() + : setToast({ + type: TOAST_TYPE.ERROR, + title: "Permission denied", + message: "Only project admins can snooze/Un-snooze issues", + }) + } + >
{inboxIssue?.snoozed_till && numberOfDaysLeft && numberOfDaysLeft > 0 ? "Un-snooze" : "Snooze"} @@ -147,7 +159,17 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) = )} {canMarkAsDuplicate && !isAcceptedOrDeclined && ( - setSelectDuplicateIssue(true)}> + + isProjectAdmin + ? setSelectDuplicateIssue(true) + : setToast({ + type: TOAST_TYPE.ERROR, + title: "Permission denied", + message: "Only project admins can mark issues as duplicate", + }) + } + >
Mark as duplicate @@ -155,7 +177,17 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) = )} {canMarkAsAccepted && ( - setAcceptIssueModal(true)}> + + isProjectAdmin + ? setAcceptIssueModal(true) + : setToast({ + type: TOAST_TYPE.ERROR, + title: "Permission denied", + message: "Only project admins can accept issues", + }) + } + >
Accept @@ -163,7 +195,17 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) = )} {canMarkAsDeclined && ( - setDeclineIssueModal(true)}> + + isProjectAdmin + ? setDeclineIssueModal(true) + : setToast({ + type: TOAST_TYPE.ERROR, + title: "Permission denied", + message: "Only project admins can deny issues", + }) + } + >
Decline diff --git a/web/core/components/inbox/content/root.tsx b/web/core/components/inbox/content/root.tsx index 852be8a80b8..504b1d593a7 100644 --- a/web/core/components/inbox/content/root.tsx +++ b/web/core/components/inbox/content/root.tsx @@ -62,10 +62,10 @@ export const InboxContentRoot: FC = observer((props) => { } ); - const isEditable = allowPermissions( - [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST], - EUserPermissionsLevel.PROJECT - ); + const isEditable = + allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.PROJECT) || + inboxIssue.created_by === currentUser?.id; + const isGuest = projectPermissionsByWorkspaceSlugAndProjectId(workspaceSlug, projectId) === EUserPermissions.GUEST; const isOwner = inboxIssue?.issue.created_by === currentUser?.id; const readOnly = !isOwner && isGuest; diff --git a/web/core/store/inbox/project-inbox.store.ts b/web/core/store/inbox/project-inbox.store.ts index bf0a485762a..2897825397b 100644 --- a/web/core/store/inbox/project-inbox.store.ts +++ b/web/core/store/inbox/project-inbox.store.ts @@ -423,7 +423,7 @@ export class ProjectInboxStore implements IProjectInboxStore { if (inboxIssue && issueId) { runInAction(() => { - set(this.inboxIssues, [issueId], new InboxIssueStore(workspaceSlug, projectId, inboxIssue, this.store)); + this.createOrUpdateInboxIssue([inboxIssue], workspaceSlug, projectId); set(this, "loader", undefined); }); await Promise.all([ From d4b9544c91ac72a541f9e72bc59e0c6eb64a5b1d Mon Sep 17 00:00:00 2001 From: gakshita Date: Tue, 8 Oct 2024 20:10:19 +0530 Subject: [PATCH 3/4] fix: refactoring --- .../inbox/content/inbox-issue-header.tsx | 60 ++++++++++--------- .../content/inbox-issue-mobile-header.tsx | 50 +++++++--------- 2 files changed, 54 insertions(+), 56 deletions(-) diff --git a/web/core/components/inbox/content/inbox-issue-header.tsx b/web/core/components/inbox/content/inbox-issue-header.tsx index 448133318c5..19a39e5e92c 100644 --- a/web/core/components/inbox/content/inbox-issue-header.tsx +++ b/web/core/components/inbox/content/inbox-issue-header.tsx @@ -205,6 +205,17 @@ export const InboxIssueActionsHeader: FC = observer((p [handleInboxIssueNavigation] ); + const handleActionWithPermission = (isAdmin: boolean, action: () => void, errorMessage: string) => { + if (isAdmin) action(); + else { + setToast({ + type: TOAST_TYPE.ERROR, + title: "Permission denied", + message: errorMessage, + }); + } + }; + useEffect(() => { if (!isNotificationEmbed) document.addEventListener("keydown", onKeyDown); return () => { @@ -300,13 +311,11 @@ export const InboxIssueActionsHeader: FC = observer((p prependIcon={} className="text-green-500 border-0.5 border-green-500 bg-green-500/20 focus:bg-green-500/20 focus:text-green-500 hover:bg-green-500/40 bg-opacity-20" onClick={() => - isProjectAdmin - ? setAcceptIssueModal(true) - : setToast({ - type: TOAST_TYPE.ERROR, - title: "Permission denied", - message: "Only project admins can accept issues", - }) + handleActionWithPermission( + isProjectAdmin, + () => setAcceptIssueModal(true), + "Only project admins can accept issues" + ) } > Accept @@ -322,13 +331,11 @@ export const InboxIssueActionsHeader: FC = observer((p prependIcon={} className="text-red-500 border-0.5 border-red-500 bg-red-500/20 focus:bg-red-500/20 focus:text-red-500 hover:bg-red-500/40 bg-opacity-20" onClick={() => - isProjectAdmin - ? setDeclineIssueModal(true) - : setToast({ - type: TOAST_TYPE.ERROR, - title: "Permission denied", - message: "Only project admins can deny issues", - }) + handleActionWithPermission( + isProjectAdmin, + () => setDeclineIssueModal(true), + "Only project admins can deny issues" + ) } > Decline @@ -365,13 +372,11 @@ export const InboxIssueActionsHeader: FC = observer((p {canMarkAsAccepted && ( - isProjectAdmin - ? handleIssueSnoozeAction() - : setToast({ - type: TOAST_TYPE.ERROR, - title: "Permission denied", - message: "Only project admins can snooze/Un-snooze issues", - }) + handleActionWithPermission( + isProjectAdmin, + handleIssueSnoozeAction, + "Only project admins can snooze/Un-snooze issues" + ) } >
@@ -385,13 +390,11 @@ export const InboxIssueActionsHeader: FC = observer((p {canMarkAsDuplicate && ( - isProjectAdmin - ? setSelectDuplicateIssue(true) - : setToast({ - type: TOAST_TYPE.ERROR, - title: "Permission denied", - message: "Only project admins can mark issues as duplicate", - }) + handleActionWithPermission( + isProjectAdmin, + () => setSelectDuplicateIssue(true), + "Only project admins can mark issues as duplicate" + ) } >
@@ -444,6 +447,7 @@ export const InboxIssueActionsHeader: FC = observer((p isNotificationEmbed={isNotificationEmbed} embedRemoveCurrentNotification={embedRemoveCurrentNotification} isProjectAdmin={isProjectAdmin} + handleActionWithPermission={handleActionWithPermission} />
diff --git a/web/core/components/inbox/content/inbox-issue-mobile-header.tsx b/web/core/components/inbox/content/inbox-issue-mobile-header.tsx index 1188062df5d..99204f8523a 100644 --- a/web/core/components/inbox/content/inbox-issue-mobile-header.tsx +++ b/web/core/components/inbox/content/inbox-issue-mobile-header.tsx @@ -48,6 +48,7 @@ type Props = { isNotificationEmbed: boolean; embedRemoveCurrentNotification?: () => void; isProjectAdmin: boolean; + handleActionWithPermission: (isAdmin: boolean, action: () => void, errorMessage: string) => void; }; export const InboxIssueActionsMobileHeader: React.FC = observer((props) => { @@ -72,6 +73,7 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) = isNotificationEmbed, embedRemoveCurrentNotification, isProjectAdmin, + handleActionWithPermission, } = props; const router = useAppRouter(); const issue = inboxIssue?.issue; @@ -143,13 +145,11 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) = {canMarkAsAccepted && !isAcceptedOrDeclined && ( - isProjectAdmin - ? handleIssueSnoozeAction() - : setToast({ - type: TOAST_TYPE.ERROR, - title: "Permission denied", - message: "Only project admins can snooze/Un-snooze issues", - }) + handleActionWithPermission( + isProjectAdmin, + handleIssueSnoozeAction, + "Only project admins can snooze/Un-snooze issues" + ) } >
@@ -161,13 +161,11 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) = {canMarkAsDuplicate && !isAcceptedOrDeclined && ( - isProjectAdmin - ? setSelectDuplicateIssue(true) - : setToast({ - type: TOAST_TYPE.ERROR, - title: "Permission denied", - message: "Only project admins can mark issues as duplicate", - }) + handleActionWithPermission( + isProjectAdmin, + () => setSelectDuplicateIssue(true), + "Only project admins can mark issues as duplicate" + ) } >
@@ -179,13 +177,11 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) = {canMarkAsAccepted && ( - isProjectAdmin - ? setAcceptIssueModal(true) - : setToast({ - type: TOAST_TYPE.ERROR, - title: "Permission denied", - message: "Only project admins can accept issues", - }) + handleActionWithPermission( + isProjectAdmin, + () => setAcceptIssueModal(true), + "Only project admins can accept issues" + ) } >
@@ -197,13 +193,11 @@ export const InboxIssueActionsMobileHeader: React.FC = observer((props) = {canMarkAsDeclined && ( - isProjectAdmin - ? setDeclineIssueModal(true) - : setToast({ - type: TOAST_TYPE.ERROR, - title: "Permission denied", - message: "Only project admins can deny issues", - }) + handleActionWithPermission( + isProjectAdmin, + () => setDeclineIssueModal(true), + "Only project admins can deny issues" + ) } >
From 7feafbab32734c9c9d3228adbd0a589291934af5 Mon Sep 17 00:00:00 2001 From: gakshita Date: Tue, 8 Oct 2024 20:14:04 +0530 Subject: [PATCH 4/4] fix: lint --- web/core/components/inbox/content/inbox-issue-mobile-header.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/core/components/inbox/content/inbox-issue-mobile-header.tsx b/web/core/components/inbox/content/inbox-issue-mobile-header.tsx index 99204f8523a..7a66d0976f8 100644 --- a/web/core/components/inbox/content/inbox-issue-mobile-header.tsx +++ b/web/core/components/inbox/content/inbox-issue-mobile-header.tsx @@ -15,7 +15,7 @@ import { PanelLeft, MoveRight, } from "lucide-react"; -import { Header, CustomMenu, EHeaderVariant, TOAST_TYPE, setToast } from "@plane/ui"; +import { Header, CustomMenu, EHeaderVariant } from "@plane/ui"; // components import { InboxIssueStatus } from "@/components/inbox"; import { IssueUpdateStatus } from "@/components/issues";