Added leave project support

This commit is contained in:
Daniel Hougaard
2024-06-17 22:09:31 +02:00
parent b226fdac9d
commit 6e0dfc72e4

View File

@@ -1,29 +1,52 @@
import { useMemo } from "react";
import { useRouter } from "next/router";
import { createNotification } from "@app/components/notifications";
import { ProjectPermissionCan } from "@app/components/permissions";
import { Button, DeleteActionModal } from "@app/components/v2";
import { LeaveProjectModal } from "@app/components/v2/LeaveProjectModal";
import {
ProjectPermissionActions,
ProjectPermissionSub,
useOrganization,
useProjectPermission,
useWorkspace
} from "@app/context";
import { useToggle } from "@app/hooks";
import { useDeleteWorkspace } from "@app/hooks/api";
import { useDeleteWorkspace, useGetWorkspaceUsers, useLeaveProject } from "@app/hooks/api";
import { usePopUp } from "@app/hooks/usePopUp";
export const DeleteProjectSection = () => {
const router = useRouter();
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
"deleteWorkspace"
"deleteWorkspace",
"leaveWorkspace"
] as const);
const { currentOrg } = useOrganization();
const { hasProjectRole, membership } = useProjectPermission();
const { currentWorkspace } = useWorkspace();
const [isDeleting, setIsDeleting] = useToggle();
const [isLeaving, setIsLeaving] = useToggle();
const deleteWorkspace = useDeleteWorkspace();
const leaveProject = useLeaveProject();
const { data: members, isLoading: isMembersLoading } = useGetWorkspaceUsers(
currentWorkspace?.id || ""
);
// If isNoAccessMember is true, then the user can't read the workspace members. So we need to handle this case separately.
const isNoAccessMember = hasProjectRole("no-access");
const isOnlyAdminMember = useMemo(() => {
if (!members || !membership || !hasProjectRole("admin")) return false;
const adminMembers = members.filter(
(member) => member.roles.map((r) => r.role).includes("admin") && member.id !== membership.id // exclude the current user
);
return !adminMembers.length;
}, [members, membership]);
const handleDeleteWorkspaceSubmit = async () => {
setIsDeleting.on();
@@ -53,23 +76,97 @@ export const DeleteProjectSection = () => {
}
};
const handleLeaveWorkspaceSubmit = async () => {
console.log({
currentWorkspace,
currentOrg,
members,
isNoAccessMember,
membership
});
try {
setIsLeaving.on();
if (!currentWorkspace?.id || !currentOrg?.id) return;
// If there's no members, and the user has access to read members, something went wrong.
if (!members && !isNoAccessMember) return;
// If the user has access to read members, and there's less than 2 members, they can't leave the project.
if (!isNoAccessMember && members!.length < 2) {
createNotification({
text: "You can't leave the project as you are the only member",
type: "error"
});
return;
}
// If the user has access to read members, and there's less than 1 admin member excluding the current user, they can't leave the project.
if (!isNoAccessMember) {
if (!members) return;
if (isOnlyAdminMember) {
createNotification({
text: "You can't leave a project with no admin members left. Promote another member to admin first.",
type: "error"
});
return;
}
}
await leaveProject.mutateAsync({
workspaceId: currentWorkspace.id,
organizationId: currentOrg.id
});
router.push(`/org/${currentOrg.id}/overview`);
} catch (err) {
console.error(err);
createNotification({
text: "Failed to leave project",
type: "error"
});
} finally {
setIsLeaving.off();
}
};
return (
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<p className="mb-4 text-xl font-semibold text-mineshaft-100">Danger Zone</p>
<ProjectPermissionCan I={ProjectPermissionActions.Delete} a={ProjectPermissionSub.Workspace}>
{(isAllowed) => (
<div className="space-x-4">
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={ProjectPermissionSub.Workspace}
>
{(isAllowed) => (
<Button
isLoading={isDeleting}
isDisabled={!isAllowed || isDeleting}
colorSchema="danger"
variant="outline_bg"
type="submit"
onClick={() => handlePopUpOpen("deleteWorkspace")}
>
{`Delete ${currentWorkspace?.name}`}
</Button>
)}
</ProjectPermissionCan>
{!!isOnlyAdminMember && (
<Button
isLoading={isDeleting}
isDisabled={!isAllowed || isDeleting}
disabled={isMembersLoading || (members && members?.length < 2)}
isLoading={isLeaving}
colorSchema="danger"
variant="outline_bg"
type="submit"
onClick={() => handlePopUpOpen("deleteWorkspace")}
onClick={() => handlePopUpOpen("leaveWorkspace")}
>
{`Delete ${currentWorkspace?.name}`}
{`Leave ${currentWorkspace?.name}`}
</Button>
)}
</ProjectPermissionCan>
</div>
<DeleteActionModal
isOpen={popUp.deleteWorkspace.isOpen}
title="Are you sure want to delete this project?"
@@ -79,6 +176,16 @@ export const DeleteProjectSection = () => {
buttonText="Delete Project"
onDeleteApproved={handleDeleteWorkspaceSubmit}
/>
<LeaveProjectModal
isOpen={popUp.leaveWorkspace.isOpen}
title="Are you sure want to leave this project?"
subTitle={`If you leave ${currentWorkspace?.name} you will lose access to the project and it's contents.`}
onChange={(isOpen) => handlePopUpToggle("leaveWorkspace", isOpen)}
deleteKey="confirm"
buttonText="Leave Project"
onLeaveApproved={handleLeaveWorkspaceSubmit}
/>
</div>
);
};