diff --git a/backend/routes/steps/delete.js b/backend/routes/steps/delete.js index f007129..95360be 100644 --- a/backend/routes/steps/delete.js +++ b/backend/routes/steps/delete.js @@ -7,11 +7,12 @@ const { DataTypes, Op } = require('sequelize'); module.exports = function (sequelize) { const Step = defineStep(sequelize, DataTypes); const CaseStep = defineCaseStep(sequelize, DataTypes); + const { verifySignedIn } = require('../../middleware/auth')(sequelize); + const { verifyProjectDeveloperFromCaseId } = require('../../middleware/verifyEditable')(sequelize); - router.delete('/:stepId', async (req, res) => { + router.delete('/:stepId', verifySignedIn, verifyProjectDeveloperFromCaseId, async (req, res) => { const stepId = req.params.stepId; - // TODO The caseId should not be specified from the front end, but should be traced from stepId by association. - const caseId = req.query.parentCaseId; + const caseId = req.query.caseId; const t = await sequelize.transaction(); diff --git a/backend/routes/steps/new.js b/backend/routes/steps/new.js index 825897a..0089553 100644 --- a/backend/routes/steps/new.js +++ b/backend/routes/steps/new.js @@ -7,10 +7,12 @@ const { DataTypes, Op } = require('sequelize'); module.exports = function (sequelize) { const Step = defineStep(sequelize, DataTypes); const CaseStep = defineCaseStep(sequelize, DataTypes); + const { verifySignedIn } = require('../../middleware/auth')(sequelize); + const { verifyProjectDeveloperFromCaseId } = require('../../middleware/verifyEditable')(sequelize); - router.post('/', async (req, res) => { + router.post('/', verifySignedIn, verifyProjectDeveloperFromCaseId, async (req, res) => { const newStepNo = req.query.newStepNo; - const caseId = req.query.parentCaseId; + const caseId = req.query.caseId; const t = await sequelize.transaction(); diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseAttachmentsEditor.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseAttachmentsEditor.tsx index 3ad2008..0255db7 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseAttachmentsEditor.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseAttachmentsEditor.tsx @@ -1,23 +1,30 @@ import { Image, Button, Tooltip, Card, CardBody } from '@nextui-org/react'; import { AttachmentType, CaseMessages } from '@/types/case'; -import { Trash, ArrowDownToLine } from 'lucide-react'; +import { Trash, ArrowDownToLine, ArrowUpFromLine } from 'lucide-react'; import { isImage } from './isImage'; +import { ChangeEvent, DragEvent } from 'react'; type Props = { + isDisabled: boolean; attachments: AttachmentType[]; onAttachmentDownload: (attachmentId: number, downloadFileName: string) => void; onAttachmentDelete: (attachmentId: number) => void; + onFilesDrop: (event: DragEvent) => void; + onFilesInput: (event: ChangeEvent) => void; messages: CaseMessages; }; export default function CaseAttachmentsEditor({ + isDisabled = false, attachments = [], onAttachmentDownload, onAttachmentDelete, + onFilesDrop, + onFilesInput, messages, }: Props) { - let images = []; - let others = []; + let images: AttachmentType[] = []; + let others: AttachmentType[] = []; attachments.forEach((attachment) => { if (isImage(attachment)) { @@ -39,6 +46,7 @@ export default function CaseAttachmentsEditor({ { setTestCase({ @@ -349,33 +350,16 @@ export default function CaseEditor({ projectId, folderId, caseId, messages, loca
{messages.attachments}
fetchDownloadAttachment(attachmentId, downloadFileName) } onAttachmentDelete={onAttachmentDelete} + onFilesDrop={handleDrop} + onFilesInput={handleInput} messages={messages} /> -
event.preventDefault()} - > - -
); diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseStepsEditor.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseStepsEditor.tsx index 4f53030..77cf918 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseStepsEditor.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseStepsEditor.tsx @@ -3,6 +3,7 @@ import { CaseMessages, StepType } from '@/types/case'; import { Plus, Trash } from 'lucide-react'; type Props = { + isDisabled: boolean; steps: StepType[]; onStepUpdate: (stepId: number, step: StepType) => void; onStepPlus: (newStepNo: number) => void; @@ -10,7 +11,7 @@ type Props = { messages: CaseMessages; }; -export default function StepsEditor({ steps, onStepUpdate, onStepPlus, onStepDelete, messages }: Props) { +export default function StepsEditor({ isDisabled, steps, onStepUpdate, onStepPlus, onStepDelete, messages }: Props) { // sort steps by junction table's column const sortedSteps = steps.slice().sort((a, b) => { const stepNoA = a.caseSteps.stepNo; @@ -51,6 +52,7 @@ export default function StepsEditor({ steps, onStepUpdate, onStepPlus, onStepDel