Create delete run confirm dialog
This commit is contained in:
34
frontend/components/DeleteConfirmDialog.tsx
Normal file
34
frontend/components/DeleteConfirmDialog.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { Button, Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from '@nextui-org/react';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isOpen: boolean;
|
||||||
|
onCancel: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
closeText: string;
|
||||||
|
confirmText: string;
|
||||||
|
deleteText: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ProjectDialog({ isOpen, onCancel, onConfirm, closeText, confirmText, deleteText }: Props) {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isOpen={isOpen}
|
||||||
|
onOpenChange={() => {
|
||||||
|
onCancel();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader className="flex flex-col gap-1">{deleteText}</ModalHeader>
|
||||||
|
<ModalBody>{confirmText}</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button variant="light" onPress={onCancel}>
|
||||||
|
{closeText}
|
||||||
|
</Button>
|
||||||
|
<Button color="danger" onPress={() => onConfirm()}>
|
||||||
|
{deleteText}
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -207,7 +207,10 @@
|
|||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"new_run": "New Run",
|
"new_run": "New Run",
|
||||||
"delete_run": "Delete Run",
|
"delete_run": "Delete Run",
|
||||||
"no_runs_found": "No runs found"
|
"no_runs_found": "No runs found",
|
||||||
|
"close": "Close",
|
||||||
|
"are_you_sure": "Are you sure you want to delete the run?",
|
||||||
|
"delete": "Delete"
|
||||||
},
|
},
|
||||||
"Run": {
|
"Run": {
|
||||||
"back_to_runs": "Back to test runs",
|
"back_to_runs": "Back to test runs",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"organize_test_cases": "テストケースを整理とグラフィカルなテスト管理",
|
"organize_test_cases": "テストケースを整理とグラフィカルなテスト管理",
|
||||||
"case_edit": "テストケース",
|
"case_edit": "テストケース",
|
||||||
"case_home": "ダッシュボード",
|
"case_home": "ダッシュボード",
|
||||||
"case_run": "テスト実行"
|
"case_run": "テストラン"
|
||||||
},
|
},
|
||||||
"Header": {
|
"Header": {
|
||||||
"title": "オープンソーステストケース管理ツール",
|
"title": "オープンソーステストケース管理ツール",
|
||||||
@@ -89,12 +89,12 @@
|
|||||||
"Project": {
|
"Project": {
|
||||||
"home": "ホーム",
|
"home": "ホーム",
|
||||||
"test_cases": "テストケース",
|
"test_cases": "テストケース",
|
||||||
"test_runs": "テストの実行"
|
"test_runs": "テストラン"
|
||||||
},
|
},
|
||||||
"Home": {
|
"Home": {
|
||||||
"Folders": "フォルダー",
|
"Folders": "フォルダー",
|
||||||
"test_cases": "テストケース",
|
"test_cases": "テストケース",
|
||||||
"test_runs": "テスト実行",
|
"test_runs": "テストラン",
|
||||||
"progress": "進捗",
|
"progress": "進捗",
|
||||||
"untested": "未実行",
|
"untested": "未実行",
|
||||||
"passed": "成功",
|
"passed": "成功",
|
||||||
@@ -198,18 +198,21 @@
|
|||||||
"max_file_size": "最大ファイルサイズ"
|
"max_file_size": "最大ファイルサイズ"
|
||||||
},
|
},
|
||||||
"Runs": {
|
"Runs": {
|
||||||
"run_list": "テストの実行一覧",
|
"run_list": "テストラン一覧",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"name": "名前",
|
"name": "名前",
|
||||||
"description": "詳細",
|
"description": "詳細",
|
||||||
"last_update": "最終更新",
|
"last_update": "最終更新",
|
||||||
"actions": "アクション",
|
"actions": "アクション",
|
||||||
"new_run": "新規テストの実行",
|
"new_run": "新規テストラン",
|
||||||
"delete_run": "テストの実行を削除",
|
"delete_run": "テストランを削除",
|
||||||
"no_runs_found": "テストの実行がありません"
|
"no_runs_found": "テストランがありません",
|
||||||
|
"close": "閉じる",
|
||||||
|
"are_you_sure": "テストランを削除してもよろしいですか?",
|
||||||
|
"delete": "削除"
|
||||||
},
|
},
|
||||||
"Run": {
|
"Run": {
|
||||||
"back_to_runs": "テストの実行一覧に戻る",
|
"back_to_runs": "テストラン一覧に戻る",
|
||||||
"updating": "更新中...",
|
"updating": "更新中...",
|
||||||
"update": "更新",
|
"update": "更新",
|
||||||
"progress": "進捗",
|
"progress": "進捗",
|
||||||
@@ -238,8 +241,8 @@
|
|||||||
"skipped": "スキップ",
|
"skipped": "スキップ",
|
||||||
"select_test_case": "テストケースを選択",
|
"select_test_case": "テストケースを選択",
|
||||||
"test_case_selection": "テストケース選択",
|
"test_case_selection": "テストケース選択",
|
||||||
"include_in_run": "テストの実行に含める",
|
"include_in_run": "テストランに含める",
|
||||||
"exclude_from_run": "テストの実行から除外する",
|
"exclude_from_run": "テストランから除外する",
|
||||||
"no_cases_found": "テストケースが見つかりません"
|
"no_cases_found": "テストケースが見つかりません"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
'use client';
|
|
||||||
import { Button, Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from '@nextui-org/react';
|
|
||||||
import { ProjectsMessages } from '@/types/project';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
isOpen: boolean;
|
|
||||||
deleteProjectId: number | null;
|
|
||||||
onCancel: () => void;
|
|
||||||
onConfirm: (projectId: number | number) => {};
|
|
||||||
messages: ProjectsMessages;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function ProjectDialog({ isOpen, deleteProjectId, onCancel, onConfirm, messages }: Props) {
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
isOpen={isOpen}
|
|
||||||
onOpenChange={() => {
|
|
||||||
onCancel();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ModalContent>
|
|
||||||
<ModalHeader className="flex flex-col gap-1">{messages.delete}</ModalHeader>
|
|
||||||
<ModalBody>{messages.areYouSure}</ModalBody>
|
|
||||||
<ModalFooter>
|
|
||||||
<Button variant="light" onPress={onCancel}>
|
|
||||||
{messages.close}
|
|
||||||
</Button>
|
|
||||||
<Button color="danger" onPress={() => onConfirm(deleteProjectId)}>
|
|
||||||
{messages.delete}
|
|
||||||
</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ import { ProjectType, ProjectsMessages } from '@/types/project';
|
|||||||
import ProjectsTable from './ProjectsTable';
|
import ProjectsTable from './ProjectsTable';
|
||||||
import ProjectDialog from './ProjectDialog';
|
import ProjectDialog from './ProjectDialog';
|
||||||
import { fetchProjects, createProject, updateProject, deleteProject } from './projectsControl';
|
import { fetchProjects, createProject, updateProject, deleteProject } from './projectsControl';
|
||||||
import ProjectDeleteDialog from './ProjectDeleteDialog';
|
import DeleteConfirmDialog from '@/components/DeleteConfirmDialog';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
messages: ProjectsMessages;
|
messages: ProjectsMessages;
|
||||||
@@ -47,11 +47,11 @@ export default function ProjectsPage({ messages, locale }: Props) {
|
|||||||
setEditingProject(null);
|
setEditingProject(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
// delete dialog
|
// delete confirm dialog
|
||||||
const [isDeleteProjectDialogOpen, setIsDeleteProjectDialogOpen] = useState(false);
|
const [isDeleteConfirmDialogOpen, setIsDeleteConfirmDialogOpen] = useState(false);
|
||||||
const [deleteProjectId, setDeleteProjectId] = useState<number | null>(null);
|
const [deleteProjectId, setDeleteProjectId] = useState<number | null>(null);
|
||||||
const closeDeleteDialog = () => {
|
const closeDeleteConfirmDialog = () => {
|
||||||
setIsDeleteProjectDialogOpen(false);
|
setIsDeleteConfirmDialogOpen(false);
|
||||||
setDeleteProjectId(null);
|
setDeleteProjectId(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,13 +74,15 @@ export default function ProjectsPage({ messages, locale }: Props) {
|
|||||||
|
|
||||||
const onDeleteClick = (projectId: number) => {
|
const onDeleteClick = (projectId: number) => {
|
||||||
setDeleteProjectId(projectId);
|
setDeleteProjectId(projectId);
|
||||||
setIsDeleteProjectDialogOpen(true);
|
setIsDeleteConfirmDialogOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onConfirm = async (projectId: number) => {
|
const onConfirm = async () => {
|
||||||
await deleteProject(context.token.access_token, projectId);
|
if (deleteProjectId) {
|
||||||
setProjects(projects.filter((project) => project.id !== projectId));
|
await deleteProject(context.token.access_token, deleteProjectId);
|
||||||
closeDeleteDialog();
|
setProjects(projects.filter((project) => project.id !== deleteProjectId));
|
||||||
|
closeDeleteConfirmDialog();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -110,12 +112,13 @@ export default function ProjectsPage({ messages, locale }: Props) {
|
|||||||
messages={messages}
|
messages={messages}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ProjectDeleteDialog
|
<DeleteConfirmDialog
|
||||||
isOpen={isDeleteProjectDialogOpen}
|
isOpen={isDeleteConfirmDialogOpen}
|
||||||
deleteProjectId={deleteProjectId}
|
onCancel={closeDeleteConfirmDialog}
|
||||||
onCancel={closeDeleteDialog}
|
|
||||||
onConfirm={onConfirm}
|
onConfirm={onConfirm}
|
||||||
messages={messages}
|
closeText={messages.close}
|
||||||
|
confirmText={messages.areYouSure}
|
||||||
|
deleteText={messages.delete}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Plus } from 'lucide-react';
|
|||||||
import RunsTable from './RunsTable';
|
import RunsTable from './RunsTable';
|
||||||
import { fetchRuns, createRun, deleteRun } from './runsControl';
|
import { fetchRuns, createRun, deleteRun } from './runsControl';
|
||||||
import { RunsMessages } from '@/types/run';
|
import { RunsMessages } from '@/types/run';
|
||||||
|
import DeleteConfirmDialog from '@/components/DeleteConfirmDialog';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
@@ -15,6 +16,14 @@ type Props = {
|
|||||||
export default function RunsPage({ projectId, locale, messages }: Props) {
|
export default function RunsPage({ projectId, locale, messages }: Props) {
|
||||||
const [runs, setRuns] = useState([]);
|
const [runs, setRuns] = useState([]);
|
||||||
|
|
||||||
|
// delete confirm dialog
|
||||||
|
const [isDeleteConfirmDialogOpen, setIsDeleteConfirmDialogOpen] = useState(false);
|
||||||
|
const [deleteRunId, setDeleteRunId] = useState<number | null>(null);
|
||||||
|
const closeDeleteConfirmDialog = () => {
|
||||||
|
setIsDeleteConfirmDialogOpen(false);
|
||||||
|
setDeleteRunId(null);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function fetchDataEffect() {
|
async function fetchDataEffect() {
|
||||||
try {
|
try {
|
||||||
@@ -39,13 +48,26 @@ export default function RunsPage({ projectId, locale, messages }: Props) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDeleteClick = async (runId: number) => {
|
// const onDeleteClick = async (runId: number) => {
|
||||||
try {
|
// try {
|
||||||
await deleteRun(runId);
|
// await deleteRun(runId);
|
||||||
const data = await fetchRuns(projectId);
|
// const data = await fetchRuns(projectId);
|
||||||
setRuns(data);
|
// setRuns(data);
|
||||||
} catch (error: any) {
|
// } catch (error: any) {
|
||||||
console.error('Error deleting run:', error);
|
// console.error('Error deleting run:', error);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
const onDeleteClick = (runId: number) => {
|
||||||
|
setDeleteRunId(runId);
|
||||||
|
setIsDeleteConfirmDialogOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onConfirm = async () => {
|
||||||
|
if (deleteRunId) {
|
||||||
|
await deleteRun(deleteRunId);
|
||||||
|
setRuns(runs.filter((run) => run.id !== deleteRunId));
|
||||||
|
closeDeleteConfirmDialog();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -61,6 +83,15 @@ export default function RunsPage({ projectId, locale, messages }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<RunsTable projectId={projectId} runs={runs} onDeleteRun={onDeleteClick} messages={messages} locale={locale} />
|
<RunsTable projectId={projectId} runs={runs} onDeleteRun={onDeleteClick} messages={messages} locale={locale} />
|
||||||
|
|
||||||
|
<DeleteConfirmDialog
|
||||||
|
isOpen={isDeleteConfirmDialogOpen}
|
||||||
|
onCancel={closeDeleteConfirmDialog}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
closeText={messages.close}
|
||||||
|
confirmText={messages.areYouSure}
|
||||||
|
deleteText={messages.delete}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ export default function Page({ params }: { params: { projectId: string; locale:
|
|||||||
newRun: t('new_run'),
|
newRun: t('new_run'),
|
||||||
deleteRun: t('delete_run'),
|
deleteRun: t('delete_run'),
|
||||||
noRunsFound: t('no_runs_found'),
|
noRunsFound: t('no_runs_found'),
|
||||||
|
close: t('close'),
|
||||||
|
areYouSure: t('are_you_sure'),
|
||||||
|
delete: t('delete'),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ type RunsMessages = {
|
|||||||
newRun: string;
|
newRun: string;
|
||||||
deleteRun: string;
|
deleteRun: string;
|
||||||
noRunsFound: string;
|
noRunsFound: string;
|
||||||
|
close: string;
|
||||||
|
areYouSure: string;
|
||||||
|
delete: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type RunMessages = {
|
type RunMessages = {
|
||||||
|
|||||||
Reference in New Issue
Block a user