Create run dialog
This commit is contained in:
@@ -200,15 +200,22 @@
|
||||
},
|
||||
"Runs": {
|
||||
"run_list": "Test Run List",
|
||||
"run": "Run",
|
||||
"new_run": "New Run",
|
||||
"edit_run": "Edit Run",
|
||||
"delete_run": "Delete Run",
|
||||
"id": "ID",
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
"last_update": "Last update",
|
||||
"actions": "Actions",
|
||||
"new_run": "New Run",
|
||||
"delete_run": "Delete Run",
|
||||
"run_name": "Run name",
|
||||
"run_description": "Run description",
|
||||
"no_runs_found": "No runs found",
|
||||
"close": "Close",
|
||||
"create": "Create",
|
||||
"update": "Update",
|
||||
"please_enter": "Please enter run name",
|
||||
"are_you_sure": "Are you sure you want to delete the run?",
|
||||
"delete": "Delete"
|
||||
},
|
||||
|
||||
@@ -199,15 +199,22 @@
|
||||
},
|
||||
"Runs": {
|
||||
"run_list": "テストラン一覧",
|
||||
"run": "テストラン",
|
||||
"new_run": "新規テストラン",
|
||||
"edit_run": "テストランを編集",
|
||||
"delete_run": "テストランを削除",
|
||||
"id": "ID",
|
||||
"name": "名前",
|
||||
"description": "詳細",
|
||||
"last_update": "最終更新",
|
||||
"actions": "アクション",
|
||||
"new_run": "新規テストラン",
|
||||
"delete_run": "テストランを削除",
|
||||
"run_name": "テストラン名",
|
||||
"run_description": "テストラン詳細",
|
||||
"no_runs_found": "テストランがありません",
|
||||
"close": "閉じる",
|
||||
"create": "作成",
|
||||
"update": "更新",
|
||||
"please_enter": "テストラン名を入力してください",
|
||||
"are_you_sure": "テストランを削除してもよろしいですか?",
|
||||
"delete": "削除"
|
||||
},
|
||||
|
||||
@@ -25,13 +25,13 @@ type Props = {
|
||||
export default function ProjectDialog({ isOpen, editingProject, onCancel, onSubmit, messages }: Props) {
|
||||
const [projectName, setProjectName] = useState({
|
||||
text: editingProject ? editingProject.name : '',
|
||||
isValid: false,
|
||||
isInvalid: false,
|
||||
errorMessage: '',
|
||||
});
|
||||
|
||||
const [projectDetail, setProjectDetail] = useState({
|
||||
text: editingProject ? editingProject.detail : '',
|
||||
isValid: false,
|
||||
isInvalid: false,
|
||||
errorMessage: '',
|
||||
});
|
||||
|
||||
@@ -67,12 +67,12 @@ export default function ProjectDialog({ isOpen, editingProject, onCancel, onSubm
|
||||
|
||||
const clear = () => {
|
||||
setProjectName({
|
||||
isValid: false,
|
||||
isInvalid: false,
|
||||
text: '',
|
||||
errorMessage: '',
|
||||
});
|
||||
setProjectDetail({
|
||||
isValid: false,
|
||||
isInvalid: false,
|
||||
text: '',
|
||||
errorMessage: '',
|
||||
});
|
||||
@@ -82,7 +82,7 @@ export default function ProjectDialog({ isOpen, editingProject, onCancel, onSubm
|
||||
if (!projectName.text) {
|
||||
setProjectName({
|
||||
text: '',
|
||||
isValid: false,
|
||||
isInvalid: true,
|
||||
errorMessage: messages.pleaseEnter,
|
||||
});
|
||||
|
||||
@@ -107,7 +107,7 @@ export default function ProjectDialog({ isOpen, editingProject, onCancel, onSubm
|
||||
type="text"
|
||||
label={messages.projectName}
|
||||
value={projectName.text}
|
||||
isInvalid={projectName.isValid}
|
||||
isInvalid={projectName.isInvalid}
|
||||
errorMessage={projectName.errorMessage}
|
||||
onChange={(e) => {
|
||||
setProjectName({
|
||||
@@ -119,7 +119,7 @@ export default function ProjectDialog({ isOpen, editingProject, onCancel, onSubm
|
||||
<Textarea
|
||||
label={messages.projectDetail}
|
||||
value={projectDetail.text}
|
||||
isInvalid={projectDetail.isValid}
|
||||
isInvalid={projectDetail.isInvalid}
|
||||
errorMessage={projectDetail.errorMessage}
|
||||
onChange={(e) => {
|
||||
setProjectDetail({
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
'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 { RunType, RunsMessages } from '@/types/run';
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
editingRun: RunType | null;
|
||||
onCancel: () => void;
|
||||
onSubmit: (name: string, description: string) => void;
|
||||
messages: RunsMessages;
|
||||
};
|
||||
|
||||
export default function RunDialog({ isOpen, editingRun, onCancel, onSubmit, messages }: Props) {
|
||||
const [runName, setRunName] = useState({
|
||||
text: editingRun ? editingRun.name : '',
|
||||
isInvalid: false,
|
||||
errorMessage: '',
|
||||
});
|
||||
|
||||
const [runDescription, setRunDescription] = useState({
|
||||
text: editingRun ? editingRun.description : '',
|
||||
isInvalid: false,
|
||||
errorMessage: '',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (editingRun) {
|
||||
setRunName({
|
||||
...runName,
|
||||
text: editingRun.name,
|
||||
});
|
||||
|
||||
setRunDescription({
|
||||
...runDescription,
|
||||
text: editingRun.description ? editingRun.description : '',
|
||||
});
|
||||
} else {
|
||||
setRunName({
|
||||
...runName,
|
||||
text: '',
|
||||
});
|
||||
|
||||
setRunDescription({
|
||||
...runDescription,
|
||||
text: '',
|
||||
});
|
||||
}
|
||||
}, [editingRun]);
|
||||
|
||||
const clear = () => {
|
||||
setRunName({
|
||||
isInvalid: false,
|
||||
text: '',
|
||||
errorMessage: '',
|
||||
});
|
||||
setRunDescription({
|
||||
isInvalid: false,
|
||||
text: '',
|
||||
errorMessage: '',
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!runName.text) {
|
||||
setRunName({
|
||||
text: '',
|
||||
isInvalid: true,
|
||||
errorMessage: messages.pleaseEnter,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
onSubmit(runName.text, runDescription.text);
|
||||
clear();
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
onOpenChange={() => {
|
||||
onCancel();
|
||||
}}
|
||||
>
|
||||
<ModalContent>
|
||||
<ModalHeader className="flex flex-col gap-1">{messages.run}</ModalHeader>
|
||||
<ModalBody>
|
||||
<Input
|
||||
type="text"
|
||||
label={messages.runName}
|
||||
value={runName.text}
|
||||
isInvalid={runName.isInvalid}
|
||||
errorMessage={runName.errorMessage}
|
||||
onChange={(e) => {
|
||||
setRunName({
|
||||
...runName,
|
||||
text: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Textarea
|
||||
label={messages.runDescription}
|
||||
value={runDescription.text}
|
||||
isInvalid={runDescription.isInvalid}
|
||||
errorMessage={runDescription.errorMessage}
|
||||
onChange={(e) => {
|
||||
setRunDescription({
|
||||
...runDescription,
|
||||
text: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button variant="light" onPress={onCancel}>
|
||||
{messages.close}
|
||||
</Button>
|
||||
<Button color="primary" onPress={validate}>
|
||||
{editingRun && editingRun.createdAt ? messages.update : messages.create}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
@@ -3,8 +3,9 @@ import { useEffect, useState } from 'react';
|
||||
import { Button } from '@nextui-org/react';
|
||||
import { Plus } from 'lucide-react';
|
||||
import RunsTable from './RunsTable';
|
||||
import { fetchRuns, createRun, deleteRun } from './runsControl';
|
||||
import { RunsMessages } from '@/types/run';
|
||||
import { fetchRuns, createRun, updateRun, deleteRun } from './runsControl';
|
||||
import { RunType, RunsMessages } from '@/types/run';
|
||||
import RunDialog from './RunDialog';
|
||||
import DeleteConfirmDialog from '@/components/DeleteConfirmDialog';
|
||||
|
||||
type Props = {
|
||||
@@ -13,9 +14,33 @@ type Props = {
|
||||
messages: RunsMessages;
|
||||
};
|
||||
|
||||
const defaultRun = {
|
||||
id: null,
|
||||
name: 'Untitled Run',
|
||||
configurations: null,
|
||||
description: null,
|
||||
state: null,
|
||||
projectId: null,
|
||||
createdAt: null,
|
||||
updatedAt: null,
|
||||
};
|
||||
|
||||
export default function RunsPage({ projectId, locale, messages }: Props) {
|
||||
const [runs, setRuns] = useState([]);
|
||||
|
||||
// run dialog
|
||||
const [isRunDialogOpen, setIsRunDialogOpen] = useState(false);
|
||||
const [editingRun, setEditingRun] = useState<RunType | null>(null);
|
||||
const openDialogForCreate = () => {
|
||||
setIsRunDialogOpen(true);
|
||||
setEditingRun(defaultRun);
|
||||
};
|
||||
|
||||
const closeDialog = () => {
|
||||
setIsRunDialogOpen(false);
|
||||
setEditingRun(null);
|
||||
};
|
||||
|
||||
// delete confirm dialog
|
||||
const [isDeleteConfirmDialogOpen, setIsDeleteConfirmDialogOpen] = useState(false);
|
||||
const [deleteRunId, setDeleteRunId] = useState<number | null>(null);
|
||||
@@ -37,27 +62,18 @@ export default function RunsPage({ projectId, locale, messages }: Props) {
|
||||
fetchDataEffect();
|
||||
}, []);
|
||||
|
||||
const onCreateClick = async () => {
|
||||
try {
|
||||
const newRun = await createRun(projectId);
|
||||
const updateRuns = [...runs];
|
||||
updateRuns.push(newRun);
|
||||
setRuns(updateRuns);
|
||||
} catch (error: any) {
|
||||
console.error('Error deleting run:', error);
|
||||
const onSubmit = async (name: string, description: string) => {
|
||||
if (editingRun && editingRun.createdAt) {
|
||||
const updatedRun = await updateRun(editingRun);
|
||||
const updatedRuns = runs.map((run) => (run.id === updatedRun.id ? updatedRun : run));
|
||||
setRuns(updatedRuns);
|
||||
} else {
|
||||
const newRun = await createRun(projectId, name, description);
|
||||
setRuns([...runs, newRun]);
|
||||
}
|
||||
closeDialog();
|
||||
};
|
||||
|
||||
// const onDeleteClick = async (runId: number) => {
|
||||
// try {
|
||||
// await deleteRun(runId);
|
||||
// const data = await fetchRuns(projectId);
|
||||
// setRuns(data);
|
||||
// } catch (error: any) {
|
||||
// console.error('Error deleting run:', error);
|
||||
// }
|
||||
// };
|
||||
|
||||
const onDeleteClick = (runId: number) => {
|
||||
setDeleteRunId(runId);
|
||||
setIsDeleteConfirmDialogOpen(true);
|
||||
@@ -76,7 +92,7 @@ export default function RunsPage({ projectId, locale, messages }: Props) {
|
||||
<div className="w-full p-3 flex items-center justify-between">
|
||||
<h3 className="font-bold">{messages.runList}</h3>
|
||||
<div>
|
||||
<Button startContent={<Plus size={16} />} size="sm" color="primary" onClick={onCreateClick}>
|
||||
<Button startContent={<Plus size={16} />} size="sm" color="primary" onClick={openDialogForCreate}>
|
||||
{messages.newRun}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -84,6 +100,14 @@ export default function RunsPage({ projectId, locale, messages }: Props) {
|
||||
|
||||
<RunsTable projectId={projectId} runs={runs} onDeleteRun={onDeleteClick} messages={messages} locale={locale} />
|
||||
|
||||
<RunDialog
|
||||
isOpen={isRunDialogOpen}
|
||||
editingRun={editingRun}
|
||||
onCancel={closeDialog}
|
||||
onSubmit={onSubmit}
|
||||
messages={messages}
|
||||
/>
|
||||
|
||||
<DeleteConfirmDialog
|
||||
isOpen={isDeleteConfirmDialogOpen}
|
||||
onCancel={closeDeleteConfirmDialog}
|
||||
|
||||
@@ -5,15 +5,22 @@ export default function Page({ params }: { params: { projectId: string; locale:
|
||||
const t = useTranslations('Runs');
|
||||
const messages = {
|
||||
runList: t('run_list'),
|
||||
run: t('run'),
|
||||
editRun: t('edit_run'),
|
||||
newRun: t('new_run'),
|
||||
deleteRun: t('delete_run'),
|
||||
id: t('id'),
|
||||
name: t('name'),
|
||||
description: t('description'),
|
||||
lastUpdate: t('last_update'),
|
||||
actions: t('actions'),
|
||||
newRun: t('new_run'),
|
||||
deleteRun: t('delete_run'),
|
||||
runName: t('run_name'),
|
||||
runDescription: t('run_description'),
|
||||
noRunsFound: t('no_runs_found'),
|
||||
close: t('close'),
|
||||
create: t('create'),
|
||||
update: t('update'),
|
||||
pleaseEnter: t('please_enter'),
|
||||
areYouSure: t('are_you_sure'),
|
||||
delete: t('delete'),
|
||||
};
|
||||
|
||||
@@ -46,11 +46,11 @@ async function fetchRuns(projectId: string) {
|
||||
}
|
||||
}
|
||||
|
||||
async function createRun(projectId: string) {
|
||||
async function createRun(projectId: string, name: string, description: string) {
|
||||
const newTestRun = {
|
||||
name: 'untitled run',
|
||||
name,
|
||||
configurations: 0,
|
||||
description: '',
|
||||
description,
|
||||
state: 0,
|
||||
projectId: projectId,
|
||||
};
|
||||
|
||||
@@ -33,15 +33,22 @@ type ProgressSeriesType = {
|
||||
|
||||
type RunsMessages = {
|
||||
runList: string;
|
||||
run: string;
|
||||
newRun: string;
|
||||
editRun: string;
|
||||
deleteRun: string;
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
lastUpdate: string;
|
||||
actions: string;
|
||||
newRun: string;
|
||||
deleteRun: string;
|
||||
noRunsFound: string;
|
||||
runName: string;
|
||||
runDescription: string;
|
||||
close: string;
|
||||
create: string;
|
||||
update: string;
|
||||
pleaseEnter: string;
|
||||
noRunsFound: string;
|
||||
areYouSure: string;
|
||||
delete: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user