From 96563b438ea0b05dd29e4e1a79eee14c10d9f17b Mon Sep 17 00:00:00 2001 From: rahulramesha <71900764+rahulramesha@users.noreply.github.com> Date: Fri, 28 Jun 2024 20:57:31 +0530 Subject: [PATCH] [WEB-1255] fix: edit and delete access control for views (#4964) --- web/core/components/views/quick-actions.tsx | 8 +++++--- web/core/components/views/view-list-item-action.tsx | 4 ++-- web/core/components/workspace/views/quick-action.tsx | 10 ++++++---- web/core/store/member/index.ts | 9 ++++----- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/web/core/components/views/quick-actions.tsx b/web/core/components/views/quick-actions.tsx index dbb4af80f2..b2d8680b71 100644 --- a/web/core/components/views/quick-actions.tsx +++ b/web/core/components/views/quick-actions.tsx @@ -32,9 +32,11 @@ export const ViewQuickActions: React.FC = observer((props) => { // store hooks const { membership: { currentProjectRole }, + data, } = useUser(); // auth - const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER; + const isOwner = view?.owned_by === data?.id; + const isAdmin = !!currentProjectRole && currentProjectRole == EUserProjectRoles.ADMIN; const viewLink = `${workspaceSlug}/projects/${projectId}/views/${view.id}`; const handleCopyText = () => @@ -53,7 +55,7 @@ export const ViewQuickActions: React.FC = observer((props) => { action: () => setCreateUpdateViewModal(true), title: "Edit", icon: Pencil, - shouldRender: isEditingAllowed, + shouldRender: isOwner, }, { key: "open-new-tab", @@ -72,7 +74,7 @@ export const ViewQuickActions: React.FC = observer((props) => { action: () => setDeleteViewModal(true), title: "Delete", icon: Trash2, - shouldRender: isEditingAllowed, + shouldRender: isOwner || isAdmin, }, ]; diff --git a/web/core/components/views/view-list-item-action.tsx b/web/core/components/views/view-list-item-action.tsx index b7d37e3d72..03c27ecb0e 100644 --- a/web/core/components/views/view-list-item-action.tsx +++ b/web/core/components/views/view-list-item-action.tsx @@ -56,7 +56,7 @@ export const ViewListItemAction: FC = observer((props) => { removeViewFromFavorites(workspaceSlug.toString(), projectId.toString(), view.id); }; - const createdByDetails = view.created_by ? getUserDetails(view.created_by) : undefined; + const ownedByDetails = view.owned_by ? getUserDetails(view.owned_by) : undefined; return ( <> @@ -81,7 +81,7 @@ export const ViewListItemAction: FC = observer((props) => { {/* created by */} - {} + {} {isEditingAllowed && ( = observer((props) => { // store hooks const { membership: { currentWorkspaceRole }, + data, } = useUser(); // auth - const isEditingAllowed = !!currentWorkspaceRole && currentWorkspaceRole >= EUserProjectRoles.MEMBER; + const isOwner = view?.owned_by === data?.id; + const isAdmin = !!currentWorkspaceRole && currentWorkspaceRole === EUserWorkspaceRoles.ADMIN; const viewLink = `${workspaceSlug}/workspace-views/${view.id}`; const handleCopyText = () => @@ -56,7 +58,7 @@ export const WorkspaceViewQuickActions: React.FC = observer((props) => { action: () => setUpdateViewModal(true), title: "Edit", icon: Pencil, - shouldRender: isEditingAllowed, + shouldRender: isOwner, }, { key: "open-new-tab", @@ -75,7 +77,7 @@ export const WorkspaceViewQuickActions: React.FC = observer((props) => { action: () => setDeleteViewModal(true), title: "Delete", icon: Trash2, - shouldRender: isEditingAllowed, + shouldRender: isOwner || isAdmin, }, ]; diff --git a/web/core/store/member/index.ts b/web/core/store/member/index.ts index 9ab757b0ad..36f3972f7c 100644 --- a/web/core/store/member/index.ts +++ b/web/core/store/member/index.ts @@ -1,5 +1,6 @@ -import { action, makeObservable, observable } from "mobx"; -// types +import { makeObservable, observable } from "mobx"; +import { computedFn } from "mobx-utils"; +// type import { IUserLite } from "@plane/types"; // store import { CoreRootStore } from "../root.store"; @@ -27,8 +28,6 @@ export class MemberRootStore implements IMemberRootStore { makeObservable(this, { // observables memberMap: observable, - // computed actions - getUserDetails: action, }); // sub-stores this.workspace = new WorkspaceMemberStore(this, _rootStore); @@ -39,5 +38,5 @@ export class MemberRootStore implements IMemberRootStore { * @description get user details rom userId * @param userId */ - getUserDetails = (userId: string): IUserLite | undefined => this.memberMap?.[userId] ?? undefined; + getUserDetails = computedFn((userId: string): IUserLite | undefined => this.memberMap?.[userId] ?? undefined); }