From b1726a1c9f0bf27b0234c92facb984deccad04cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?= <62714297+PedroChaparro@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:55:23 -0500 Subject: [PATCH] release: v0.50.2 (#286) * fix: Show confirmation dialog when deleting laboratory blocks (#285) * chore(ui): Hide open source section in the home page * fix: Show confirmation dialog when deleting laboratory blocks --- CHANGELOG.md | 18 +- e2e/laboratories/edit-laboratory.spec.ts | 10 ++ package.json | 2 +- .../markdown-block/MarkdownBlockDropDown.tsx | 158 ++++++++---------- .../test-block/TestBlockDropDown.tsx | 144 +++++++--------- .../dialogs/DeleteBlockDialog.tsx | 107 ++++++++++++ src/screens/home/Home.tsx | 5 +- src/types/entities/laboratory-entities.ts | 2 +- 8 files changed, 262 insertions(+), 184 deletions(-) create mode 100644 src/screens/edit-laboratory/dialogs/DeleteBlockDialog.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a2f358..ec92b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [0.50.2](https://github.com/upb-code-labs/react-client/compare/v0.50.1...v0.50.2) (2024-02-08) + + +### Bug Fixes + +* Show confirmation dialog when deleting laboratory blocks ([#285](https://github.com/upb-code-labs/react-client/issues/285)) ([82bd210](https://github.com/upb-code-labs/react-client/commit/82bd210f5eeaec4c96a6bb476f1d0f95e8504e76)) + + + ## [0.50.1](https://github.com/upb-code-labs/react-client/compare/v0.50.0...v0.50.1) (2024-02-06) @@ -34,12 +43,3 @@ -## [0.48.2](https://github.com/upb-code-labs/react-client/compare/v0.48.1...v0.48.2) (2024-01-27) - - -### Bug Fixes - -* Add timezone to laboratories dates ([#271](https://github.com/upb-code-labs/react-client/issues/271)) ([d8c3206](https://github.com/upb-code-labs/react-client/commit/d8c32061d8980228e8fc6ab6914e3de4a583a2b1)) - - - diff --git a/e2e/laboratories/edit-laboratory.spec.ts b/e2e/laboratories/edit-laboratory.spec.ts index 554efea..dca4bec 100644 --- a/e2e/laboratories/edit-laboratory.spec.ts +++ b/e2e/laboratories/edit-laboratory.spec.ts @@ -419,6 +419,11 @@ test.describe.serial("Edit laboratory workflow", () => { await expect(deleteMarkdownBlockButton).toBeVisible(); await deleteMarkdownBlockButton.click(); + // Click on the "proceed" button + let proceedButton = page.getByRole("button", { name: "Proceed" }); + await expect(proceedButton).toBeVisible(); + await proceedButton.click(); + // Assert an alert is shown await expect( page.getByText("The markdown block has been deleted successfully") @@ -441,6 +446,11 @@ test.describe.serial("Edit laboratory workflow", () => { await expect(deleteTestBlockButton).toBeVisible(); await deleteTestBlockButton.click(); + // Click on the "proceed" button + proceedButton = page.getByRole("button", { name: "Proceed" }); + await expect(proceedButton).toBeVisible(); + await proceedButton.click(); + // Assert an alert is shown await expect( page.getByText("The test block has been deleted successfully") diff --git a/package.json b/package.json index e718b98..59b7431 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-client", "private": true, - "version": "0.50.1", + "version": "0.50.2", "type": "module", "scripts": { "dev": "vite", diff --git a/src/screens/edit-laboratory/components/markdown-block/MarkdownBlockDropDown.tsx b/src/screens/edit-laboratory/components/markdown-block/MarkdownBlockDropDown.tsx index c843c53..0312414 100644 --- a/src/screens/edit-laboratory/components/markdown-block/MarkdownBlockDropDown.tsx +++ b/src/screens/edit-laboratory/components/markdown-block/MarkdownBlockDropDown.tsx @@ -1,6 +1,5 @@ import { EditLaboratoryContext } from "@/context/laboratories/EditLaboratoryContext"; import { EditLaboratoryActionType } from "@/hooks/laboratories/editLaboratoryTypes"; -import { deleteMarkdownBlockService } from "@/services/blocks/delete-markdown-block.service"; import { swapBlocksIndexService } from "@/services/blocks/swap-blocks-index.service"; import { updateMarkdownBlockContentService } from "@/services/blocks/update-markdown-block-content.service"; import { @@ -9,7 +8,7 @@ import { } from "@/types/entities/laboratory-entities"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { ArrowDown, ArrowUp, MoreVertical, Save, Trash2 } from "lucide-react"; -import { useContext } from "react"; +import { useContext, useState } from "react"; import { toast } from "sonner"; import { @@ -20,6 +19,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger } from "../../../../components/ui/dropdown-menu"; +import { DeleteBlockDialog } from "../../dialogs/DeleteBlockDialog"; interface MarkdownBlockDropDown { blockUUID: string; @@ -40,6 +40,9 @@ export const MarkdownBlockDropDown = ({ (b) => b.uuid === blockUUID ) as MarkdownBlock; + // Delete block dialog state + const [isDeleteBlockDialogOpen, setIsDeleteBlockDialogOpen] = useState(false); + // Update markdown block mutation const queryClient = useQueryClient(); const { mutate: updateMarkdownBlockMutation } = useMutation({ @@ -71,39 +74,8 @@ export const MarkdownBlockDropDown = ({ } }); - // Delete markdown block mutation - const { mutate: deleteMarkdownBlockMutation } = useMutation({ - mutationFn: deleteMarkdownBlockService, - onError: (error) => { - toast.error(error.message); - }, - onSuccess: () => { - // Update global state - laboratoryStateDispatcher({ - type: EditLaboratoryActionType.DELETE_BLOCK, - payload: { - uuid: blockUUID - } - }); - - // Show a success message - toast.success("The markdown block has been deleted successfully"); - - // Update the laboratory query - queryClient.setQueryData( - ["laboratory", laboratory!.uuid], - (oldData: Laboratory) => { - return { - ...oldData, - blocks: oldData.blocks.filter((b) => b.uuid !== blockUUID) - }; - } - ); - } - }); - // Move markdown block up mutation - const { mutate: moteTestBlockUpMutation } = useMutation({ + const { mutate: moveTestBlockUpMutation } = useMutation({ mutationFn: swapBlocksIndexService, onError: (error) => { toast.error(error.message); @@ -142,7 +114,7 @@ export const MarkdownBlockDropDown = ({ }); // Move markdown block down mutation - const { mutate: moteTestBlockDownMutation } = useMutation({ + const { mutate: moveTestBlockDownMutation } = useMutation({ mutationFn: swapBlocksIndexService, onError: (error) => { toast.error(error.message); @@ -181,60 +153,66 @@ export const MarkdownBlockDropDown = ({ }); return ( - - - - - - Block options - - - moteTestBlockUpMutation({ - first_block_uuid: laboratory!.blocks[blockIndex - 1].uuid, - second_block_uuid: blockUUID - }) - } - > - - Move up - - - moteTestBlockDownMutation({ - first_block_uuid: blockUUID, - second_block_uuid: laboratory!.blocks[blockIndex + 1].uuid - }) - } - > - - Move down - - - updateMarkdownBlockMutation({ - markdownBlockUUID: blockUUID, - content: block.content - }) - } - > - - Save changes - - deleteMarkdownBlockMutation(blockUUID)} - > - - Delete block - - - + <> + + + + + + Block options + + + moveTestBlockUpMutation({ + first_block_uuid: laboratory!.blocks[blockIndex - 1].uuid, + second_block_uuid: blockUUID + }) + } + > + + Move up + + + moveTestBlockDownMutation({ + first_block_uuid: blockUUID, + second_block_uuid: laboratory!.blocks[blockIndex + 1].uuid + }) + } + > + + Move down + + + updateMarkdownBlockMutation({ + markdownBlockUUID: blockUUID, + content: block.content + }) + } + > + + Save changes + + setIsDeleteBlockDialogOpen(true)}> + + Delete block + + + + + ); }; diff --git a/src/screens/edit-laboratory/components/test-block/TestBlockDropDown.tsx b/src/screens/edit-laboratory/components/test-block/TestBlockDropDown.tsx index 609da03..28d2ecb 100644 --- a/src/screens/edit-laboratory/components/test-block/TestBlockDropDown.tsx +++ b/src/screens/edit-laboratory/components/test-block/TestBlockDropDown.tsx @@ -8,14 +8,15 @@ import { } from "@/components/ui/dropdown-menu"; import { EditLaboratoryContext } from "@/context/laboratories/EditLaboratoryContext"; import { EditLaboratoryActionType } from "@/hooks/laboratories/editLaboratoryTypes"; -import { deleteTestBlockService } from "@/services/blocks/delete-test-block.service"; import { swapBlocksIndexService } from "@/services/blocks/swap-blocks-index.service"; import { Laboratory } from "@/types/entities/laboratory-entities"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { ArrowDown, ArrowUp, MoreVertical, Save, Trash2 } from "lucide-react"; -import { RefObject, useContext } from "react"; +import { RefObject, useContext, useState } from "react"; import { toast } from "sonner"; +import { DeleteBlockDialog } from "../../dialogs/DeleteBlockDialog"; + interface TestBlockDropdown { blockUUID: string; blockIndex: number; @@ -27,6 +28,7 @@ export const TestBlockDropDown = ({ blockIndex, formRef }: TestBlockDropdown) => { + // Global laboratory state const { laboratoryStateDispatcher, laboratoryState } = useContext( EditLaboratoryContext ); @@ -41,40 +43,12 @@ export const TestBlockDropDown = ({ ); }; - // Delete test block mutation - const queryClient = useQueryClient(); - const { mutate: deleteTestBlockMutation } = useMutation({ - mutationFn: deleteTestBlockService, - onError: (error) => { - toast.error(error.message); - }, - onSuccess: () => { - // Update the global laboratory state - laboratoryStateDispatcher({ - type: EditLaboratoryActionType.DELETE_BLOCK, - payload: { - uuid: blockUUID - } - }); - - // Show success message - toast.success("The test block has been deleted successfully"); - - // Update the laboratory query - queryClient.setQueryData( - ["laboratory", laboratory!.uuid], - (oldData: Laboratory) => { - return { - ...oldData, - blocks: oldData.blocks.filter((b) => b.uuid !== blockUUID) - }; - } - ); - } - }); + // Delete block dialog state + const [isDeleteBlockDialogOpen, setIsDeleteBlockDialogOpen] = useState(false); // Move test block up mutation - const { mutate: moteTestBlockUpMutation } = useMutation({ + const queryClient = useQueryClient(); + const { mutate: moveTestBlockUpMutation } = useMutation({ mutationFn: swapBlocksIndexService, onError: (error) => { toast.error(error.message); @@ -113,7 +87,7 @@ export const TestBlockDropDown = ({ }); // Move test block down mutation - const { mutate: moteTestBlockDownMutation } = useMutation({ + const { mutate: moveTestBlockDownMutation } = useMutation({ mutationFn: swapBlocksIndexService, onError: (error) => { toast.error(error.message); @@ -152,51 +126,59 @@ export const TestBlockDropDown = ({ }); return ( - - - - - - Block options - - - moteTestBlockUpMutation({ - first_block_uuid: laboratory!.blocks[blockIndex - 1].uuid, - second_block_uuid: blockUUID - }) - } - > - - Move up - - - moteTestBlockDownMutation({ - first_block_uuid: blockUUID, - second_block_uuid: laboratory!.blocks[blockIndex + 1].uuid - }) - } - > - - Move down - - - - Save changes - - deleteTestBlockMutation(blockUUID)}> - - Delete block - - - + <> + + + + + + Block options + + + moveTestBlockUpMutation({ + first_block_uuid: laboratory!.blocks[blockIndex - 1].uuid, + second_block_uuid: blockUUID + }) + } + > + + Move up + + + moveTestBlockDownMutation({ + first_block_uuid: blockUUID, + second_block_uuid: laboratory!.blocks[blockIndex + 1].uuid + }) + } + > + + Move down + + + + Save changes + + setIsDeleteBlockDialogOpen(true)}> + + Delete block + + + + + ); }; diff --git a/src/screens/edit-laboratory/dialogs/DeleteBlockDialog.tsx b/src/screens/edit-laboratory/dialogs/DeleteBlockDialog.tsx new file mode 100644 index 0000000..d700305 --- /dev/null +++ b/src/screens/edit-laboratory/dialogs/DeleteBlockDialog.tsx @@ -0,0 +1,107 @@ +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle +} from "@/components/ui/alert-dialog"; +import { EditLaboratoryContext } from "@/context/laboratories/EditLaboratoryContext"; +import { EditLaboratoryActionType } from "@/hooks/laboratories/editLaboratoryTypes"; +import { deleteMarkdownBlockService } from "@/services/blocks/delete-markdown-block.service"; +import { deleteTestBlockService } from "@/services/blocks/delete-test-block.service"; +import { BlockType, Laboratory } from "@/types/entities/laboratory-entities"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useContext } from "react"; +import { toast } from "sonner"; + +interface DeleteBlockDialogProps { + isDialogOpen: boolean; + setIsDialogOpen: (value: boolean) => void; + blockUUID: string; + blockType: BlockType; +} + +const dialogTexts = { + markdown: { + title: "Are you sure you want to delete this markdown block?", + description: + "This action cannot be undone. Your students will no longer see the content of this block." + }, + test: { + title: "Are you sure you want to delete this test block?", + description: + "This action cannot be undone. Your students will no longer be able to submit their code to this block and their submissions will be deleted too." + } +}; + +export const DeleteBlockDialog = ({ + isDialogOpen, + setIsDialogOpen, + blockUUID, + blockType +}: DeleteBlockDialogProps) => { + console.log({ blockUUID }); + + // Global laboratory state + const { laboratoryStateDispatcher, laboratoryState } = useContext( + EditLaboratoryContext + ); + const { laboratory } = laboratoryState; + + // Delete block mutation + const queryClient = useQueryClient(); + const { mutate: deleteTestBlockMutation } = useMutation({ + mutationFn: + blockType === "test" + ? deleteTestBlockService + : deleteMarkdownBlockService, + onError: (error) => { + toast.error(error.message); + }, + onSuccess: () => { + // Update the global laboratory state + laboratoryStateDispatcher({ + type: EditLaboratoryActionType.DELETE_BLOCK, + payload: { + uuid: blockUUID + } + }); + + // Show success message + toast.success(`The ${blockType} block has been deleted successfully`); + + // Update the laboratory query + queryClient.setQueryData( + ["laboratory", laboratory!.uuid], + (oldData: Laboratory) => { + return { + ...oldData, + blocks: oldData.blocks.filter((b) => b.uuid !== blockUUID) + }; + } + ); + } + }); + + return ( + + + + {dialogTexts[blockType].title} + + {dialogTexts[blockType].description} + + + + Cancel + deleteTestBlockMutation(blockUUID)}> + Proceed + + + + + ); +}; diff --git a/src/screens/home/Home.tsx b/src/screens/home/Home.tsx index 31cde32..b3a2611 100644 --- a/src/screens/home/Home.tsx +++ b/src/screens/home/Home.tsx @@ -1,13 +1,14 @@ import { HomeFeatures } from "./components/HomeFeatures"; import { HomeHeader } from "./components/HomeHeader"; -import { OpenSourceSection } from "./components/OpenSourceSection"; + +/* import { OpenSourceSection } from "./components/OpenSourceSection"; */ export const Home = () => { return (
- + {/* */}
); }; diff --git a/src/types/entities/laboratory-entities.ts b/src/types/entities/laboratory-entities.ts index 3334b28..b91efac 100644 --- a/src/types/entities/laboratory-entities.ts +++ b/src/types/entities/laboratory-entities.ts @@ -1,4 +1,4 @@ -type BlockType = "markdown" | "test"; +export type BlockType = "markdown" | "test"; export type MarkdownBlock = { uuid: string;