Skip to content

Commit

Permalink
Merge pull request #3007 from the-deep/features/leave-project
Browse files Browse the repository at this point in the history
Leave Project
  • Loading branch information
AdityaKhatri authored Dec 5, 2024
2 parents 9667288 + fc3d7c8 commit 2a96517
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 5 deletions.
85 changes: 82 additions & 3 deletions app/views/ExploreDeepContent/ProjectContent/ActionCell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -31,6 +37,17 @@ export interface Props {
variant?: ButtonProps<string>['variant'];
}

const LEAVE_PROJECT = gql`
mutation LeaveProject($projectId: ID!) {
project(id: $projectId) {
leaveProject {
errors
ok
}
}
}
`;

const CANCEL_JOIN_PROJECT = gql`
mutation CancelJoinProject(
$projectId: ID!,
Expand Down Expand Up @@ -92,19 +109,68 @@ function ActionCell(props: Props) {
},
);

const [
leaveProject,
] = useMutation<LeaveProjectMutation, LeaveProjectMutationVariables>(
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(
<NonFieldError
className={styles.alertError}
error={formError}
/>,
{ 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 (
<div className={_cs(styles.actionCell, className)}>
{!membershipPending ? (
{!isMember && !membershipPending && (
<Button
name={undefined}
onClick={showJoinModal}
Expand All @@ -114,7 +180,8 @@ function ActionCell(props: Props) {
>
Join
</Button>
) : (
)}
{membershipPending && (
<ConfirmButton
name={undefined}
onConfirm={handleCancelJoinProjectClick}
Expand All @@ -126,6 +193,18 @@ function ActionCell(props: Props) {
Cancel Join
</ConfirmButton>
)}
{isMember && (
<ConfirmButton
name={undefined}
onConfirm={handleLeaveProject}
message="Are you sure you want to leave this project?"
variant="secondary"
spacing="compact"
>
Leave Project
</ConfirmButton>

)}
{projectJoinModalShown && (
<ProjectJoinModal
projectId={projectId}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.alert-error {
color: var(--dui-color-white);
}
.action-cell {
display: flex;
justify-content: flex-end;
Expand Down
94 changes: 92 additions & 2 deletions app/views/Home/ProjectItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import {
IoBookmarkOutline,
IoLockOpenOutline,
IoEllipsisVertical,
} from 'react-icons/io5';
import {
RiPushpinFill,
Expand Down Expand Up @@ -36,12 +37,19 @@ import {
Kraken,
QuickActionButton,
useAlert,
QuickActionDropdownMenu,
DropdownMenuItem,
useConfirmation,
} from '@the-deep/deep-ui';
import { useMutation, gql } from '@apollo/client';
import { removeNull } from '@togglecorp/toggle-form';

import _ts from '#ts';
import SmartButtonLikeLink from '#base/components/SmartButtonLikeLink';
import SmartQuickActionLink from '#base/components/SmartQuickActionLink';
import { ObjectError, transformToFormError } from '#base/utils/errorTransform';
import ProgressLine from '#components/ProgressLine';
import NonFieldError from '#components/NonFieldError';
import FrameworkImageButton from '#components/framework/FrameworkImageButton';
import routes from '#base/configs/routes';

Expand All @@ -54,10 +62,10 @@ import {
PinProjectMutationVariables,
UnpinProjectMutation,
UnpinProjectMutationVariables,
LeaveProjectMutation,
LeaveProjectMutationVariables,
} from '#generated/types';

import _ts from '#ts';

import styles from './styles.css';

const PIN_PROJECT = gql`
Expand All @@ -84,6 +92,17 @@ mutation UnpinProject ($projectId: ID!) {
}
`;

const LEAVE_PROJECT = gql`
mutation LeaveProject($projectId: ID!) {
project(id: $projectId) {
leaveProject {
errors
ok
}
}
}
`;

const tickFormatter = (value: number | string) => {
const date = new Date(value);
return date.toDateString();
Expand Down Expand Up @@ -213,6 +232,47 @@ function ProjectItem(props: RecentProjectItemProps) {
},
);

const [
leaveProject,
] = useMutation<LeaveProjectMutation, LeaveProjectMutationVariables>(
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(
<NonFieldError
className={styles.alertError}
error={formError}
/>,
{ 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,
Expand Down Expand Up @@ -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<string>({
showConfirmationInitially: false,
onConfirm: handleLeaveProject,
message: 'Are you sure you want to leave this project?',
});

if (isNotDefined(projectId)) {
return null;
}
Expand Down Expand Up @@ -349,6 +428,16 @@ function ProjectItem(props: RecentProjectItemProps) {
>
Open Project
</SmartButtonLikeLink>
<QuickActionDropdownMenu
label={<IoEllipsisVertical />}
>
<DropdownMenuItem
name={projectId}
onClick={onleaveProjectClick}
>
Leave Project
</DropdownMenuItem>
</QuickActionDropdownMenu>
</>
)}
contentClassName={styles.content}
Expand Down Expand Up @@ -521,6 +610,7 @@ function ProjectItem(props: RecentProjectItemProps) {
</ResponsiveContainer>
</ContainerCard>
</div>
{modal}
</ContainerCard>
);
}
Expand Down
4 changes: 4 additions & 0 deletions app/views/Home/ProjectItem/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,7 @@
font-weight: var(--font-weight-bold);
}
}

.alert-error {
color: var(--dui-color-white);
}

0 comments on commit 2a96517

Please sign in to comment.