(3) Drop v2: Delete Operation Modal (#5313)

This commit is contained in:
Tuval Simha 2024-08-18 19:08:44 +03:00 committed by GitHub
parent 24aad9c278
commit b93687441e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 116 additions and 43 deletions

View file

@ -1,11 +1,16 @@
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 {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { useToast } from '@/components/ui/use-toast';
import { graphql } from '@/gql';
import { useNotifications } from '@/lib/hooks';
import { TrashIcon } from '@radix-ui/react-icons';
const DeleteOperationMutation = graphql(`
mutation DeleteOperation($selector: TargetSelectorInput!, $id: ID!) {
@ -42,51 +47,81 @@ const DeleteOperationMutation = graphql(`
export type DeleteOperationMutationType = typeof DeleteOperationMutation;
export function DeleteOperationModal(props: {
close: () => void;
isOpen: boolean;
toggleModalOpen: () => void;
operationId: string;
organizationId: string;
projectId: string;
targetId: string;
}): ReactElement {
const { close, operationId } = props;
const { toast } = useToast();
const { isOpen, toggleModalOpen, operationId } = props;
const [, mutate] = useMutation(DeleteOperationMutation);
const notify = useNotifications();
const handleDelete = async () => {
const { error } = await mutate({
id: operationId,
selector: {
target: props.targetId,
organization: props.organizationId,
project: props.projectId,
},
});
toggleModalOpen();
if (error) {
toast({
title: 'Error',
description: error.message,
variant: 'destructive',
});
} else {
toast({
title: 'Operation Deleted',
description: 'The operation has been successfully deleted.',
variant: 'default',
});
}
};
return (
<Modal open onOpenChange={close} className="flex flex-col items-center gap-5">
<TrashIcon className="h-16 w-auto text-red-500 opacity-70" />
<Heading>Delete Operation</Heading>
<p className="text-sm text-gray-500">
Are you sure you wish to delete this operation? This action is irreversible!
</p>
<div className="flex w-full gap-2">
<Button type="button" size="lg" className="w-full justify-center" onClick={close}>
Cancel
</Button>
<Button
size="lg"
className="w-full justify-center"
variant="destructive"
onClick={async () => {
const { error } = await mutate({
id: operationId,
selector: {
target: props.targetId,
organization: props.organizationId,
project: props.projectId,
},
});
if (error) {
notify(error.message, 'error');
}
close();
}}
data-cy="confirm"
>
Delete
</Button>
</div>
</Modal>
<DeleteOperationModalContent
isOpen={isOpen}
toggleModalOpen={toggleModalOpen}
handleDelete={handleDelete}
/>
);
}
export function DeleteOperationModalContent(props: {
isOpen: boolean;
toggleModalOpen: () => void;
handleDelete: () => void;
}): ReactElement {
return (
<Dialog open={props.isOpen} onOpenChange={props.toggleModalOpen}>
<DialogContent className="w-4/5 max-w-[520px] md:w-3/5">
<DialogHeader>
<DialogTitle>Delete Operation</DialogTitle>
<DialogDescription>Do you really want to delete this operation?</DialogDescription>
<DialogDescription>
<span className="font-bold">This action is irreversible!</span>
</DialogDescription>
</DialogHeader>
<DialogFooter className="gap-2">
<Button
variant="outline"
onClick={ev => {
ev.preventDefault();
props.toggleModalOpen();
}}
>
Cancel
</Button>
<Button variant="destructive" onClick={props.handleDelete}>
Delete
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}

View file

@ -168,6 +168,7 @@ const CreateOperationMutation = graphql(`
const CollectionItem = (props: {
node: { id: string; name: string };
toggleDeleteOperationModalOpen: () => void;
canDelete: boolean;
canEdit: boolean;
onDelete: (operationId: string) => void;
@ -237,6 +238,7 @@ const CollectionItem = (props: {
<DropdownMenuItem
onClick={() => {
props.onDelete(props.node.id);
props.toggleDeleteOperationModalOpen();
}}
className="text-red-500"
>
@ -323,6 +325,7 @@ function useOperationCollectionsPlugin(props: {
});
const [collectionId, setCollectionId] = useState('');
const [isDeleteCollectionModalOpen, toggleDeleteCollectionModalOpen] = useToggle();
const [isDeleteOperationModalOpen, toggleDeleteOperationModalOpen] = useToggle();
const [operationToDeleteId, setOperationToDeleteId] = useState<null | string>(null);
const [operationToEditId, setOperationToEditId] = useState<null | string>(null);
const { clearOperation, savedOperation, setSavedOperation } = useSyncOperationState({
@ -565,6 +568,7 @@ function useOperationCollectionsPlugin(props: {
node={node}
canDelete={props.canDelete}
canEdit={props.canEdit}
toggleDeleteOperationModalOpen={toggleDeleteOperationModalOpen}
onDelete={setOperationToDeleteId}
onEdit={setOperationToEditId}
isChanged={!isSame && node.id === queryParamsOperationId}
@ -630,7 +634,8 @@ function useOperationCollectionsPlugin(props: {
organizationId={props.organizationId}
projectId={props.projectId}
targetId={props.targetId}
close={() => setOperationToDeleteId(null)}
isOpen={isDeleteOperationModalOpen}
toggleModalOpen={toggleDeleteOperationModalOpen}
operationId={operationToDeleteId}
/>
)}

View file

@ -0,0 +1,33 @@
import { DeleteOperationModalContent } from '@/components/target/laboratory/delete-operation-modal';
import { Meta, StoryFn, StoryObj } from '@storybook/react';
const meta: Meta<typeof DeleteOperationModalContent> = {
title: 'Modals/Delete Operation Modal',
component: DeleteOperationModalContent,
argTypes: {
isOpen: {
control: 'boolean',
},
toggleModalOpen: {
action: 'toggleModalOpen',
},
handleDelete: {
action: 'onSubmit',
},
},
};
export default meta;
type Story = StoryObj<typeof DeleteOperationModalContent>;
const Template: StoryFn<typeof DeleteOperationModalContent> = args => {
return <DeleteOperationModalContent {...args} />;
};
export const Delete: Story = Template.bind({});
Delete.args = {
isOpen: true,
toggleModalOpen: () => console.log('Close'),
handleDelete: () => console.log('Delete'),
};