diff --git a/backend/index.js b/backend/index.js index e73d42a..2e05077 100644 --- a/backend/index.js +++ b/backend/index.js @@ -55,11 +55,13 @@ const casesShowRoute = require("./routes/cases/show")(sequelize); const casesNewRoute = require("./routes/cases/new")(sequelize); const casesEditRoute = require("./routes/cases/edit")(sequelize); const casesDeleteRoute = require("./routes/cases/delete")(sequelize); +const casesBulkDeleteRoute = require("./routes/cases/bulkDelete")(sequelize); app.use("/cases", casesIndexRoute); app.use("/cases", casesShowRoute); app.use("/cases", casesNewRoute); app.use("/cases", casesEditRoute); app.use("/cases", casesDeleteRoute); +app.use("/cases", casesBulkDeleteRoute); // "/steps" const stepsNewRoute = require("./routes/steps/new")(sequelize); diff --git a/backend/routes/cases/bulkDelete.js b/backend/routes/cases/bulkDelete.js new file mode 100644 index 0000000..7dc2614 --- /dev/null +++ b/backend/routes/cases/bulkDelete.js @@ -0,0 +1,25 @@ +const express = require("express"); +const router = express.Router(); +const defineCase = require("../../models/cases"); +const { DataTypes } = require("sequelize"); + +module.exports = function (sequelize) { + const Case = defineCase(sequelize, DataTypes); + + router.post("/bulkdelete", async (req, res) => { + const { caseIds } = req.body; + if (!caseIds || !Array.isArray(caseIds)) { + return res.status(400).send("Invalid caseIds array"); + } + + try { + await Case.destroy({ where: { id: caseIds } }); + res.status(204).send(); + } catch (error) { + console.error(error); + res.status(500).send("Internal Server Error"); + } + }); + + return router; +}; diff --git a/frontend/app/projects/[projectId]/folders/[folderId]/cases/page.tsx b/frontend/app/projects/[projectId]/folders/[folderId]/cases/page.tsx index 9131a63..66c6f95 100644 --- a/frontend/app/projects/[projectId]/folders/[folderId]/cases/page.tsx +++ b/frontend/app/projects/[projectId]/folders/[folderId]/cases/page.tsx @@ -89,6 +89,28 @@ async function fetchDeleteCase(caseId: number) { } } +async function fetchDeleteCases(deleteCases: string[]) { + const fetchOptions = { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ caseIds: deleteCases }), + }; + + const url = `${apiServer}/cases/bulkdelete`; + + try { + const response = await fetch(url, fetchOptions); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + } catch (error) { + console.error("Error deleting cases:", error); + throw error; + } +} + export default function Page({ params, }: { @@ -123,6 +145,12 @@ export default function Page({ setCases(data); }; + const handleDeleteCases = async (deleteCases: string[]) => { + await fetchDeleteCases(deleteCases); + const data = await fetchCases(url); + setCases(data); + } + return ( <> handleCreateCase(params.folderId)} onDeleteCase={handleDeleteCase} + onDeleteCases={handleDeleteCases} /> ); diff --git a/frontend/app/projects/[projectId]/folders/[folderId]/cases/test-case-table.tsx b/frontend/app/projects/[projectId]/folders/[folderId]/cases/test-case-table.tsx index 58afc18..192dfc0 100644 --- a/frontend/app/projects/[projectId]/folders/[folderId]/cases/test-case-table.tsx +++ b/frontend/app/projects/[projectId]/folders/[folderId]/cases/test-case-table.tsx @@ -16,7 +16,7 @@ import { SortDescriptor, Link, } from "@nextui-org/react"; -import { Plus, MoreVertical } from "lucide-react"; +import { Plus, MoreVertical, Trash } from "lucide-react"; const headerColumns = [ { name: "ID", uid: "id", sortable: true }, @@ -48,9 +48,16 @@ type Props = { cases: Case[]; onCreateCase: () => void; onDeleteCase: (caseId: number) => void; + onDeleteCases: (selectedCases: string[]) => void; }; -export default function TestCaseTable({ projectId, cases, onCreateCase, onDeleteCase }: Props) { +export default function TestCaseTable({ + projectId, + cases, + onCreateCase, + onDeleteCase, + onDeleteCases, +}: Props) { const [selectedKeys, setSelectedKeys] = useState(new Set([])); const [sortDescriptor, setSortDescriptor] = useState({ column: "id", @@ -102,7 +109,10 @@ export default function TestCaseTable({ projectId, cases, onCreateCase, onDelete - onDeleteCase(testCase.id)}> + onDeleteCase(testCase.id)} + > Delete test case @@ -132,20 +142,36 @@ export default function TestCaseTable({ projectId, cases, onCreateCase, onDelete [] ); + const onDeleteCasesClick = async() => { + setSelectedKeys(new Set([])); + onDeleteCases([...selectedKeys]) + } + return ( <>
-

- Cases -

- +

Cases

+
+ {selectedKeys.size > 0 && ( + + )} + +