diff --git a/app/views/ExploreDeepContent/ProjectContent/ActionCell/index.tsx b/app/views/ExploreDeepContent/ProjectContent/ActionCell/index.tsx index 7ff9289a27..e0dc700fd6 100644 --- a/app/views/ExploreDeepContent/ProjectContent/ActionCell/index.tsx +++ b/app/views/ExploreDeepContent/ProjectContent/ActionCell/index.tsx @@ -12,10 +12,16 @@ import { useModalState } from '#hooks/stateManagement'; import { CancelJoinProjectMutation, CancelJoinProjectMutationVariables, + LeaveProjectMutation, + LeaveProjectMutationVariables, } from '#generated/types'; import ProjectJoinModal from '#components/general/ProjectJoinModal'; +import { ObjectError, transformToFormError } from '#base/utils/errorTransform'; +import { removeNull } from '@togglecorp/toggle-form'; + +import NonFieldError from '#components/NonFieldError'; import styles from './styles.css'; export interface Props { @@ -31,6 +37,17 @@ export interface Props { variant?: ButtonProps['variant']; } +const LEAVE_PROJECT = gql` +mutation LeaveProject($projectId: ID!) { + project(id: $projectId) { + leaveProject { + errors + ok + } + } +} +`; + const CANCEL_JOIN_PROJECT = gql` mutation CancelJoinProject( $projectId: ID!, @@ -92,19 +109,68 @@ function ActionCell(props: Props) { }, ); + const [ + leaveProject, + ] = useMutation( + LEAVE_PROJECT, + { + onCompleted: (response) => { + const leaveProjectResponse = response?.project?.leaveProject; + if (!leaveProjectResponse) { + return; + } + const { + ok, + errors, + } = leaveProjectResponse; + + if (ok) { + alert.show( + 'Project successfully left.', + { variant: 'success' }, + ); + onMemberStatusChange(); + } else if (errors) { + const formError = transformToFormError(removeNull(errors) as ObjectError[]); + alert.show( + , + { variant: 'error' }, + ); + } + }, + onError: (gqlError) => { + alert.show( + gqlError.message ?? 'An error occurred while leaving a project.', + { variant: 'error' }, + ); + }, + }, + ); + + const handleLeaveProject = useCallback(() => ( + leaveProject({ + variables: { + projectId, + }, + }) + ), [leaveProject, projectId]); + const handleCancelJoinProjectClick = useCallback(() => { cancelJoinProject({ variables: { projectId }, }); }, [projectId, cancelJoinProject]); - if (isMember || isRejected) { + if (isRejected) { return null; } return (
- {!membershipPending ? ( + {!isMember && !membershipPending && ( - ) : ( + )} + {membershipPending && ( )} + {isMember && ( + + Leave Project + + + )} {projectJoinModalShown && ( { const date = new Date(value); return date.toDateString(); @@ -213,6 +232,47 @@ function ProjectItem(props: RecentProjectItemProps) { }, ); + const [ + leaveProject, + ] = useMutation( + LEAVE_PROJECT, + { + onCompleted: (response) => { + const leaveProjectResponse = response?.project?.leaveProject; + if (!leaveProjectResponse) { + return; + } + const { + ok, + errors, + } = leaveProjectResponse; + + if (ok) { + onProjectPinChange(); + alert.show( + 'Project successfully left.', + { variant: 'success' }, + ); + } else if (errors) { + const formError = transformToFormError(removeNull(errors) as ObjectError[]); + alert.show( + , + { variant: 'error' }, + ); + } + }, + onError: (gqlError) => { + alert.show( + gqlError.message ?? 'An error occurred while leaving a project.', + { variant: 'error' }, + ); + }, + }, + ); + const activeUserRendererParams = useCallback((_: unknown, data: UserEntityDateType) => ({ className: styles.recentlyActiveItem, label: data.name, @@ -278,6 +338,25 @@ function ProjectItem(props: RecentProjectItemProps) { pinProject, ]); + const handleLeaveProject = useCallback((id: string | undefined) => { + if (id) { + leaveProject({ + variables: { + projectId: id, + }, + }); + } + }, [leaveProject]); + + const [ + modal, + onleaveProjectClick, + ] = useConfirmation({ + showConfirmationInitially: false, + onConfirm: handleLeaveProject, + message: 'Are you sure you want to leave this project?', + }); + if (isNotDefined(projectId)) { return null; } @@ -349,6 +428,16 @@ function ProjectItem(props: RecentProjectItemProps) { > Open Project + } + > + + Leave Project + + )} contentClassName={styles.content} @@ -521,6 +610,7 @@ function ProjectItem(props: RecentProjectItemProps) {
+ {modal} ); } diff --git a/app/views/Home/ProjectItem/styles.css b/app/views/Home/ProjectItem/styles.css index 61c9bc9a65..f4603104b8 100644 --- a/app/views/Home/ProjectItem/styles.css +++ b/app/views/Home/ProjectItem/styles.css @@ -110,3 +110,7 @@ font-weight: var(--font-weight-bold); } } + +.alert-error { + color: var(--dui-color-white); +}