diff --git a/backend/index.js b/backend/index.js index efa523d..ec81c6f 100644 --- a/backend/index.js +++ b/backend/index.js @@ -36,8 +36,12 @@ app.use('/projects', projectsDeleteRoute); // "/folders" const foldersIndexRoute = require('./routes/folders/index')(sequelize); const foldersNewRoute = require('./routes/folders/new')(sequelize); +const foldersEditRoute = require('./routes/folders/edit')(sequelize); +const foldersDeleteRoute = require('./routes/folders/delete')(sequelize); app.use('/folders', foldersIndexRoute); app.use('/folders', foldersNewRoute); +app.use('/folders', foldersEditRoute); +app.use('/folders', foldersDeleteRoute); // "/runs" const runsIndexRoute = require('./routes/runs/index')(sequelize); diff --git a/backend/routes/folders/delete.js b/backend/routes/folders/delete.js new file mode 100644 index 0000000..870db49 --- /dev/null +++ b/backend/routes/folders/delete.js @@ -0,0 +1,25 @@ +const express = require("express"); +const router = express.Router(); +const defineFolder = require("../../models/folders"); +const { DataTypes } = require("sequelize"); + +module.exports = function (sequelize) { + const Folder = defineFolder(sequelize, DataTypes); + + router.delete("/:folderId", async (req, res) => { + const folderId = req.params.folderId; + try { + const folder = await Folder.findByPk(folderId); + if (!folder) { + return res.status(404).send("Folder not found"); + } + await folder.destroy(); + res.status(204).send(); + } catch (error) { + console.error(error); + res.status(500).send("Internal Server Error"); + } + }); + + return router; +}; diff --git a/backend/routes/folders/edit.js b/backend/routes/folders/edit.js new file mode 100644 index 0000000..18be78f --- /dev/null +++ b/backend/routes/folders/edit.js @@ -0,0 +1,31 @@ +const express = require("express"); +const router = express.Router(); +const defineFolder = require("../../models/folders"); +const { DataTypes } = require("sequelize"); + +module.exports = function (sequelize) { + const Folder = defineFolder(sequelize, DataTypes); + + router.put("/:folderId", async (req, res) => { + const folderId = req.params.folderId; + const { name, detail, projectId, parentFolderId } = req.body; + try { + const folder = await Folder.findByPk(folderId); + if (!folder) { + return res.status(404).send("Folder not found"); + } + await folder.update({ + name, + detail, + projectId, + parentFolderId, + }); + res.json(folder); + } catch (error) { + console.error(error); + res.status(500).send("Internal Server Error"); + } + }); + + return router; +}; diff --git a/frontend/app/projects/[projectId]/folders/folder-dialog.tsx b/frontend/app/projects/[projectId]/folders/folder-dialog.tsx new file mode 100644 index 0000000..2483775 --- /dev/null +++ b/frontend/app/projects/[projectId]/folders/folder-dialog.tsx @@ -0,0 +1,140 @@ +"use client"; +import React from "react"; +import { useState, useEffect } from "react"; +import { + Button, + Input, + Textarea, + Modal, + ModalContent, + ModalHeader, + ModalBody, + ModalFooter, +} from "@nextui-org/react"; +import { FolderType } from "./layout"; + +type Props = { + isOpen: boolean; + editingFolder: FolderType; + onCancel: () => void; + onSubmit: (name: string, detail: string) => void; +}; + +export function FolderDialog({ + isOpen, + editingFolder, + onCancel, + onSubmit, +}: Props) { + const [folderName, setFolderName] = useState({ + text: editingFolder ? editingFolder.name : "", + isValid: false, + errorMessage: "", + }); + + const [folderDetail, setFolderDetail] = useState({ + text: editingFolder ? editingFolder.detail : "", + isValid: false, + errorMessage: "", + }); + + useEffect(() => { + if (editingFolder) { + setFolderName({ + ...folderName, + text: editingFolder.name, + }); + + setFolderDetail({ + ...folderDetail, + text: editingFolder.detail ? editingFolder.detail : "", + }); + } else { + setFolderName({ + ...folderName, + text: "", + }); + + setFolderDetail({ + ...folderDetail, + text: "", + }); + } + }, [editingFolder]); + + const clear = () => { + setFolderName({ + isValid: false, + text: "", + errorMessage: "", + }); + setFolderDetail({ + isValid: false, + text: "", + errorMessage: "", + }); + }; + + const validate = () => { + if (!folderName.text) { + setFolderName({ + text: "", + isValid: false, + errorMessage: "Please enter folder name", + }); + + return; + } + + onSubmit(folderName.text, folderDetail.text); + clear(); + }; + + return ( + { + onCancel(); + }} + > + + Folder + + { + setFolderName({ + ...folderName, + text: e.target.value, + }); + }} + /> +