(2) Drop modals from V2: Delete Project Modal (#5231)

Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com>
This commit is contained in:
Tuval Simha 2024-07-25 10:35:22 +03:00 committed by GitHub
parent fe026dc6c2
commit 7badbf804a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 135 additions and 78 deletions

View file

@ -1,75 +0,0 @@
import { ReactElement } from 'react';
import { useMutation } from 'urql';
import { Button } from '@/components/ui/button';
import { Heading } from '@/components/ui/heading';
import { Modal } from '@/components/v2';
import { graphql } from '@/gql';
import { TrashIcon } from '@radix-ui/react-icons';
import { useRouter } from '@tanstack/react-router';
export const DeleteProjectMutation = graphql(`
mutation deleteProject($selector: ProjectSelectorInput!) {
deleteProject(selector: $selector) {
selector {
organization
project
}
deletedProject {
__typename
id
}
}
}
`);
export const DeleteProjectModal = (props: {
isOpen: boolean;
toggleModalOpen: () => void;
organizationId: string;
projectId: string;
}): ReactElement => {
const { isOpen, toggleModalOpen } = props;
const [, mutate] = useMutation(DeleteProjectMutation);
const router = useRouter();
return (
<Modal
open={isOpen}
onOpenChange={toggleModalOpen}
className="flex flex-col items-center gap-5"
>
<TrashIcon className="h-16 w-auto text-red-500 opacity-70" />
<Heading>Delete project</Heading>
<p className="text-sm text-gray-500">
Are you sure you wish to delete this project? This action is irreversible!
</p>
<div className="flex w-full gap-2">
<Button type="button" size="lg" className="w-full justify-center" onClick={toggleModalOpen}>
Cancel
</Button>
<Button
size="lg"
className="w-full justify-center"
variant="destructive"
onClick={async () => {
await mutate({
selector: {
organization: props.organizationId,
project: props.projectId,
},
});
toggleModalOpen();
void router.navigate({
to: `/${props.organizationId}`,
params: {
organizationId: props.organizationId,
},
});
}}
>
Delete
</Button>
</div>
</Modal>
);
};

View file

@ -1,5 +1,4 @@
export { ChangePermissionsModal } from './change-permissions';
export { ConnectSchemaModal } from './connect-schema';
export { DeleteOrganizationModal } from './delete-organization';
export { DeleteProjectModal } from './delete-project';
export { TransferOrganizationOwnershipModal } from './transfer-organization-ownership';

View file

@ -12,9 +12,9 @@ import type { DeleteCollectionMutationType } from '@/components/target/laborator
import type { DeleteOperationMutationType } from '@/components/target/laboratory/delete-operation-modal';
import type { CreateAccessToken_CreateTokenMutation } from '@/components/target/settings/registry-access-token';
import type { DeleteOrganizationDocument } from '@/components/v2/modals/delete-organization';
import { type DeleteProjectMutation } from '@/components/v2/modals/delete-project';
import { graphql } from '@/gql';
import type { CreateOrganizationMutation } from '@/pages/organization-new';
import type { DeleteProjectMutation } from '@/pages/project-settings';
import { CollectionsQuery } from '@/pages/target-laboratory';
import {
TokensDocument,

View file

@ -16,6 +16,14 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { DocsLink } from '@/components/ui/docs-note';
import { HiveLogo } from '@/components/ui/icon';
import { Meta } from '@/components/ui/meta';
@ -23,7 +31,6 @@ import { Subtitle, Title } from '@/components/ui/page';
import { QueryError } from '@/components/ui/query-error';
import { useToast } from '@/components/ui/use-toast';
import { Input } from '@/components/v2/input';
import { DeleteProjectModal } from '@/components/v2/modals';
import { graphql, useFragment } from '@/gql';
import { ProjectType } from '@/gql/graphql';
import { canAccessProject, ProjectAccessScope, useProjectAccess } from '@/lib/access/project';
@ -431,3 +438,96 @@ export function ProjectSettingsPage(props: { organizationId: string; projectId:
</>
);
}
export const DeleteProjectMutation = graphql(`
mutation deleteProject($selector: ProjectSelectorInput!) {
deleteProject(selector: $selector) {
selector {
organization
project
}
deletedProject {
__typename
id
}
}
}
`);
export function DeleteProjectModal(props: {
isOpen: boolean;
toggleModalOpen: () => void;
organizationId: string;
projectId: string;
}) {
const { organizationId, projectId } = props;
const [, mutate] = useMutation(DeleteProjectMutation);
const { toast } = useToast();
const router = useRouter();
const handleDelete = async () => {
const { error } = await mutate({
selector: {
organization: organizationId,
project: projectId,
},
});
if (error) {
toast({
variant: 'destructive',
title: 'Failed to delete project',
description: error.message,
});
} else {
toast({
title: 'Project deleted',
description: 'The project has been successfully deleted.',
});
props.toggleModalOpen();
void router.navigate({
to: '/$organizationId',
params: {
organizationId,
},
});
}
};
return (
<DeleteProjectModalContent
isOpen={props.isOpen}
toggleModalOpen={props.toggleModalOpen}
handleDelete={handleDelete}
/>
);
}
export function DeleteProjectModalContent(props: {
isOpen: boolean;
toggleModalOpen: () => void;
handleDelete: () => void;
}) {
return (
<Dialog open={props.isOpen} onOpenChange={props.toggleModalOpen}>
<DialogContent className="w-4/5 max-w-[520px] md:w-3/5">
<DialogHeader>
<DialogTitle>Delete project</DialogTitle>
</DialogHeader>
<DialogDescription>
Every target and its published schema, reported data, and settings associated with this
project will be permanently deleted.
</DialogDescription>
<DialogDescription className="font-bold">This action is irreversible!</DialogDescription>
<DialogFooter className="gap-2">
<Button variant="outline" onClick={props.toggleModalOpen}>
Cancel
</Button>
<Button variant="destructive" onClick={props.handleDelete}>
Delete
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}

View file

@ -0,0 +1,33 @@
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { DeleteProjectModalContent } from '@/pages/project-settings';
import { Meta, StoryObj } from '@storybook/react';
const meta: Meta<typeof DeleteProjectModalContent> = {
title: 'Modals/Delete Project Modal',
component: DeleteProjectModalContent,
};
export default meta;
type Story = StoryObj<typeof DeleteProjectModalContent>;
export const Default: Story = {
render: () => {
const [openModal, setOpenModal] = useState(false);
const toggleModalOpen = () => setOpenModal(!openModal);
return (
<>
<Button onClick={toggleModalOpen}>Open Modal</Button>
{openModal && (
<DeleteProjectModalContent
handleDelete={() => console.log('Delete')}
isOpen={openModal}
toggleModalOpen={toggleModalOpen}
key="delete-project-modal"
/>
)}
</>
);
},
};