diff --git a/backend/middleware/verifyEditable.js b/backend/middleware/verifyEditable.js index bc7d578..ec7c8fc 100644 --- a/backend/middleware/verifyEditable.js +++ b/backend/middleware/verifyEditable.js @@ -81,8 +81,8 @@ function verifyEditableMiddleware(sequelize) { return res.status(400).json({ error: 'projectId is required' }); } - const isDeveloper = await isDeveloper(projectId, req.userId); - if (isDeveloper) { + const isDeveloperRet = await isDeveloper(projectId, req.userId); + if (isDeveloperRet) { next(); return; } @@ -109,8 +109,8 @@ function verifyEditableMiddleware(sequelize) { return res.status(404).send('failed to find projectId'); } - const isDeveloper = await isDeveloper(projectId, req.userId); - if (isDeveloper) { + const isDeveloperRet = await isDeveloper(projectId, req.userId); + if (isDeveloperRet) { next(); return; } @@ -149,8 +149,8 @@ function verifyEditableMiddleware(sequelize) { return res.status(404).send('failed to find projectId'); } - const isDeveloper = await isDeveloper(projectId, req.userId); - if (isDeveloper) { + const isDeveloperRet = await isDeveloper(projectId, req.userId); + if (isDeveloperRet) { next(); return; } @@ -161,6 +161,8 @@ function verifyEditableMiddleware(sequelize) { async function isDeveloper(projectId, userId) { const Project = defineProject(sequelize, DataTypes); const Member = defineMember(sequelize, DataTypes); + Project.hasMany(Member, { foreignKey: 'projectId' }); + Member.belongsTo(Project, { foreignKey: 'projectId' }); const project = await Project.findOne({ where: { id: projectId }, @@ -177,7 +179,7 @@ function verifyEditableMiddleware(sequelize) { } // owner has developer or higher authority - if (project.userId === req.userId) { + if (project.userId === userId) { return true; } diff --git a/frontend/messages/en.json b/frontend/messages/en.json index e11fb90..dd053f1 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -162,7 +162,11 @@ "high": "High", "medium": "Medium", "low": "Low", - "no_cases_found": "No test cases found" + "no_cases_found": "No test cases found", + "case_title": "Test Case Title", + "case_description": "Test Case Description", + "create": "Create", + "please_eEnter": "Please enter test case title" }, "Case": { "back_to_cases": "Back to test cases", diff --git a/frontend/messages/ja.json b/frontend/messages/ja.json index 798c1f4..237fa98 100644 --- a/frontend/messages/ja.json +++ b/frontend/messages/ja.json @@ -161,7 +161,11 @@ "high": "高", "medium": "中", "low": "低", - "no_cases_found": "テストケースがありません" + "no_cases_found": "テストケースがありません", + "case_title": "テストケースタイトル", + "case_description": "テストケース詳細", + "create": "作成", + "please_rnter": "テストケースタイトルを入力してください" }, "Case": { "back_to_cases": "テストケース一覧に戻る", diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/FoldersPane.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/FoldersPane.tsx index 4383063..9fa6937 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/folders/FoldersPane.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/FoldersPane.tsx @@ -25,7 +25,7 @@ export default function FoldersPane({ projectId, messages, locale }: Props) { const [selectedFolder, setSelectedFolder] = useState(null); const { folderId } = useGetCurrentIds(); const [isFolderDialogOpen, setIsFolderDialogOpen] = useState(false); - const [editingFolder, setEditingProject] = useState(null); + const [editingFolder, setEditingFolder] = useState(null); useEffect(() => { async function fetchDataEffect() { @@ -54,12 +54,12 @@ export default function FoldersPane({ projectId, messages, locale }: Props) { const openDialogForCreate = () => { setIsFolderDialogOpen(true); - setEditingProject(null); + setEditingFolder(null); }; const closeDialog = () => { setIsFolderDialogOpen(false); - setEditingProject(null); + setEditingFolder(null); }; const onSubmit = async (name: string, detail: string) => { @@ -82,7 +82,7 @@ export default function FoldersPane({ projectId, messages, locale }: Props) { }; const onEditClick = (folder: FolderType) => { - setEditingProject(folder); + setEditingFolder(folder); setIsFolderDialogOpen(true); }; diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/CaseDialog.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/CaseDialog.tsx new file mode 100644 index 0000000..c896fda --- /dev/null +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/CaseDialog.tsx @@ -0,0 +1,102 @@ +'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 { CasesMessages } from '@/types/case'; + +type Props = { + isOpen: boolean; + onCancel: () => void; + onSubmit: (title: string, description: string) => void; + messages: CasesMessages; +}; + +export default function CaseDialog({ isOpen, onCancel, onSubmit, messages }: Props) { + const [caseTitle, setCaseName] = useState({ + text: 'Untitled Case', + isValid: false, + errorMessage: '', + }); + + const [caseDescription, setCaseDescription] = useState({ + text: '', + isValid: false, + errorMessage: '', + }); + + const clear = () => { + setCaseName({ + isValid: false, + text: 'Untitled Case', + errorMessage: '', + }); + setCaseDescription({ + isValid: false, + text: '', + errorMessage: '', + }); + }; + + const validate = () => { + if (!caseTitle.text) { + setCaseName({ + text: '', + isValid: true, + errorMessage: messages.pleaseEnter, + }); + + return; + } + + onSubmit(caseTitle.text, caseDescription.text); + clear(); + }; + + return ( + { + onCancel(); + }} + > + + {messages.newTestCase} + + { + setCaseName({ + ...caseTitle, + text: e.target.value, + }); + }} + /> +