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