[WEB-2467] fix: platform bug (#5621)

* fix: reaction endpoint

* fix: project label edit permission

* fix: guest role upgrade

* fix: list layout dnd permission

* fix: module and cycle toast alert

* fix: leave project redirection
This commit is contained in:
Anmol Singh Bhatia
2024-09-17 16:43:51 +05:30
committed by GitHub
parent 7aea820cfa
commit 7d7415b235
11 changed files with 46 additions and 14 deletions

View File

@@ -37,7 +37,7 @@ class IssueReactionViewSet(BaseViewSet):
.distinct()
)
@allow_permission(ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
def create(self, request, slug, project_id, issue_id):
serializer = IssueReactionSerializer(data=request.data)
if serializer.is_valid():
@@ -60,7 +60,7 @@ class IssueReactionViewSet(BaseViewSet):
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@allow_permission(ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
def destroy(self, request, slug, project_id, issue_id, reaction_code):
issue_reaction = IssueReaction.objects.get(
workspace__slug=slug,

View File

@@ -54,7 +54,7 @@ export const CycleDeleteModal: React.FC<ICycleDelete> = observer((props) => {
});
})
.catch((errors) => {
const isPermissionError = errors?.error === "Only admin or owner can delete the cycle";
const isPermissionError = errors?.error === "You don't have the required permissions.";
const currentError = isPermissionError
? PROJECT_ERROR_MESSAGES.permissionError
: PROJECT_ERROR_MESSAGES.cycleDeleteError;

View File

@@ -4,6 +4,7 @@ import { MutableRefObject, useEffect, useRef, useState } from "react";
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { cn } from "@plane/editor";
// plane packages
import {
@@ -90,6 +91,7 @@ export const ListGroup = observer((props: Props) => {
const [isExpanded, setIsExpanded] = useState(true);
const groupRef = useRef<HTMLDivElement | null>(null);
const { projectId } = useParams();
const projectState = useProjectState();
const {
@@ -216,7 +218,8 @@ export const ListGroup = observer((props: Props) => {
);
}, [groupRef?.current, group, orderBy, getGroupIndex, setDragColumnOrientation, setIsDraggingOverColumn]);
const isDragAllowed = !!group_by && DRAG_ALLOWED_GROUPS.includes(group_by);
const isDragAllowed =
!!group_by && DRAG_ALLOWED_GROUPS.includes(group_by) && canEditProperties(projectId?.toString());
const canOverlayBeVisible = orderBy !== "sort_order" || !!group.isDropDisabled;
const isGroupByCreatedBy = group_by === "created_by";

View File

@@ -6,12 +6,28 @@ import { ProjectIssueQuickActions } from "@/components/issues";
// components
// types
// constants
import { useUserPermissions } from "@/hooks/store";
import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/user-permissions";
import { BaseListRoot } from "../base-list-root";
export const ListLayout: FC = observer(() => {
const { workspaceSlug, projectId } = useParams();
const { allowPermissions } = useUserPermissions();
if (!workspaceSlug || !projectId) return null;
return <BaseListRoot QuickActions={ProjectIssueQuickActions} />;
const canEditPropertiesBasedOnProject = (projectId: string) =>
allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
EUserPermissionsLevel.PROJECT,
workspaceSlug.toString(),
projectId
);
return (
<BaseListRoot
QuickActions={ProjectIssueQuickActions}
canEditPropertiesBasedOnProject={canEditPropertiesBasedOnProject}
/>
);
});

View File

@@ -25,10 +25,20 @@ type Props = {
droppedLabelId: string | undefined,
dropAtEndOfList: boolean
) => void;
isEditable?: boolean;
};
export const ProjectSettingLabelGroup: React.FC<Props> = observer((props) => {
const { label, labelChildren, handleLabelDelete, isUpdating, setIsUpdating, isLastChild, onDrop } = props;
const {
label,
labelChildren,
handleLabelDelete,
isUpdating,
setIsUpdating,
isLastChild,
onDrop,
isEditable = false,
} = props;
// states
const [isEditLabelForm, setEditLabelForm] = useState(false);
@@ -123,6 +133,7 @@ export const ProjectSettingLabelGroup: React.FC<Props> = observer((props) => {
isChild
isLastChild={index === labelChildren.length - 1}
onDrop={onDrop}
isEditable={isEditable}
/>
</div>
</div>

View File

@@ -111,6 +111,7 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
setIsUpdating={setIsUpdating}
isLastChild={index === projectLabelsTree.length - 1}
onDrop={onDrop}
isEditable={isEditable}
/>
);
}
@@ -123,6 +124,7 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
isChild={false}
isLastChild={index === projectLabelsTree.length - 1}
onDrop={onDrop}
isEditable={isEditable}
/>
);
})}

View File

@@ -56,7 +56,7 @@ export const DeleteModuleModal: React.FC<Props> = observer((props) => {
});
})
.catch((errors) => {
const isPermissionError = errors?.error === "Only admin or creator can delete the module";
const isPermissionError = errors?.error === "You don't have the required permissions.";
const currentError = isPermissionError
? PROJECT_ERROR_MESSAGES.permissionError
: PROJECT_ERROR_MESSAGES.moduleDeleteError;

View File

@@ -60,10 +60,10 @@ export const LeaveProjectModal: FC<ILeaveProjectModal> = observer((props) => {
if (data) {
if (data.projectName === project?.name) {
if (data.confirmLeave === "Leave Project") {
router.push(`/${workspaceSlug}/projects`);
return leaveProject(workspaceSlug.toString(), project.id)
.then(() => {
handleClose();
router.push(`/${workspaceSlug}/projects`);
captureEvent(PROJECT_MEMBER_LEAVE, {
state: "SUCCESS",
element: "Project settings members page",

View File

@@ -38,6 +38,7 @@ export const ProjectMemberListItem: React.FC<Props> = observer((props) => {
if (!workspaceSlug || !projectId || !memberId) return;
if (memberId === currentUser?.id) {
router.push(`/${workspaceSlug}/projects`);
await leaveProject(workspaceSlug.toString(), projectId.toString())
.then(async () => {
captureEvent(PROJECT_MEMBER_LEAVE, {
@@ -45,7 +46,6 @@ export const ProjectMemberListItem: React.FC<Props> = observer((props) => {
element: "Project settings members page",
});
await fetchProjects(workspaceSlug.toString());
router.push(`/${workspaceSlug}/projects`);
})
.catch((err) =>
setToast({

View File

@@ -97,9 +97,11 @@ export const AccountTypeColumn: React.FC<AccountTypeProps> = observer((props) =>
// derived values
const isCurrentUser = currentUser?.id === rowData.member.id;
const isAdminOrGuest = [EUserPermissions.ADMIN, EUserPermissions.GUEST].includes(rowData.role);
const userWorkspaceRole = getWorkspaceMemberDetails(rowData.member.id)?.role;
const isRoleNonEditable = isCurrentUser || (isAdminOrGuest && userWorkspaceRole !== EUserPermissions.MEMBER);
const isProjectAdminOrGuest = [EUserPermissions.ADMIN, EUserPermissions.GUEST].includes(rowData.role);
const isWorkspaceMember = [EUserPermissions.MEMBER].includes(
Number(getWorkspaceMemberDetails(rowData.member.id)?.role) ?? EUserPermissions.GUEST
);
const isRoleNonEditable = isCurrentUser || (isProjectAdminOrGuest && !isWorkspaceMember);
const checkCurrentOptionWorkspaceRole = (value: string) => {
const currentMemberWorkspaceRole = getWorkspaceMemberDetails(value)?.role as EUserPermissions | undefined;

View File

@@ -114,9 +114,7 @@ export const AccountTypeColumn: React.FC<AccountTypeProps> = observer((props) =>
<CustomSelect
value={value}
onChange={(value: EUserPermissions) => {
console.log({ value, workspaceSlug }, "onChange");
if (!workspaceSlug) return;
updateMember(workspaceSlug.toString(), rowData.member.id, {
role: value as unknown as EUserPermissions, // Cast value to unknown first, then to EUserPermissions
}).catch((err) => {