feat: inplement auth for cases

This commit is contained in:
Takeshi Kimata
2024-06-03 22:51:26 +09:00
parent e4db79047a
commit fe8b82cb4b
14 changed files with 106 additions and 98 deletions

View File

@@ -1,8 +1,10 @@
'use client';
import { useEffect, useState } from 'react';
import { useState, useEffect, useContext } from 'react';
import { TokenContext } from '@/utils/TokenProvider';
import TestCaseTable from './TestCaseTable';
import { fetchCases, createCase, deleteCase, deleteCases } from './caseControl';
import { CasesMessages } from '@/types/case';
import { fetchCases, createCase, deleteCases } from './caseControl';
import { CaseType, CasesMessages } from '@/types/case';
import DeleteConfirmDialog from '@/components/DeleteConfirmDialog';
type Props = {
projectId: string;
@@ -12,11 +14,18 @@ type Props = {
};
export default function CasesPane({ projectId, folderId, messages, locale }: Props) {
const [cases, setCases] = useState([]);
const [cases, setCases] = useState<CaseType[]>([]);
const context = useContext(TokenContext);
useEffect(() => {
async function fetchDataEffect() {
if (!context.isSignedIn()) {
return;
}
try {
const data = await fetchCases(folderId);
const data = await fetchCases(context.token.access_token, folderId);
console.log(data);
setCases(data);
} catch (error: any) {
console.error('Error in effect:', error.message);
@@ -24,25 +33,39 @@ export default function CasesPane({ projectId, folderId, messages, locale }: Pro
}
fetchDataEffect();
}, []);
}, [context, folderId]);
const handleCreateCase = async (folderId: string) => {
const newCase = await createCase(folderId);
const newCase = await createCase(context.token.access_token, folderId);
const updateCases = [...cases];
updateCases.push(newCase);
setCases(updateCases);
};
const handleDeleteCase = async (caseId: number) => {
await deleteCase(caseId);
const data = await fetchCases(folderId);
setCases(data);
// Delete confirm dialog
const [isDeleteConfirmDialogOpen, setIsDeleteConfirmDialogOpen] = useState(false);
const [deleteCaseIds, setDeleteCaseIds] = useState<number[]>([]);
const closeDeleteConfirmDialog = () => {
setIsDeleteConfirmDialogOpen(false);
setDeleteCaseIds([]);
};
const handleDeleteCases = async (deleteCaseIds: string[]) => {
await deleteCases(deleteCaseIds);
const data = await fetchCases(folderId);
setCases(data);
const onDeleteCases = (deleteCaseIds: number[]) => {
setDeleteCaseIds(deleteCaseIds);
setIsDeleteConfirmDialogOpen(true);
};
const onDeleteCase = async (deleteCaseId: number) => {
setDeleteCaseIds([deleteCaseId]);
setIsDeleteConfirmDialogOpen(true);
};
const onConfirm = async () => {
if (deleteCaseIds.length > 0) {
await deleteCases(context.token.access_token, deleteCaseIds);
setCases(cases.filter((entry) => !deleteCaseIds.includes(entry.id)));
closeDeleteConfirmDialog();
}
};
return (
@@ -51,11 +74,20 @@ export default function CasesPane({ projectId, folderId, messages, locale }: Pro
projectId={projectId}
cases={cases}
onCreateCase={() => handleCreateCase(folderId)}
onDeleteCase={handleDeleteCase}
onDeleteCases={handleDeleteCases}
onDeleteCase={() => onDeleteCase}
onDeleteCases={() => onDeleteCases}
messages={messages}
locale={locale}
/>
<DeleteConfirmDialog
isOpen={isDeleteConfirmDialogOpen}
onCancel={closeDeleteConfirmDialog}
onConfirm={onConfirm}
closeText={messages.close}
confirmText={messages.areYouSure}
deleteText={messages.delete}
/>
</>
);
}

View File

@@ -16,28 +16,12 @@ import {
} from '@nextui-org/react';
import { Link, NextUiLinkClasses } from '@/src/navigation';
import { Plus, MoreVertical, Trash, Circle } from 'lucide-react';
import { CasesMessages } from '@/types/case';
import { CaseType, CasesMessages } from '@/types/case';
import { priorities } from '@/config/selection';
type Case = {
id: number;
title: string;
state: number;
priority: number;
type: number;
automationStatus: number;
description: string;
template: number;
preConditions: string;
expectedResults: string;
folderId: number;
createdAt: string;
updatedAt: string;
};
type Props = {
projectId: string;
cases: Case[];
cases: CaseType[];
onCreateCase: () => void;
onDeleteCase: (caseId: number) => void;
onDeleteCases: (selectedCases: string[]) => void;

View File

@@ -2,7 +2,7 @@ import Config from '@/config/config';
const apiServer = Config.apiServer;
import { CaseType } from '@/types/case';
async function fetchCase(caseId: number) {
async function fetchCase(jwt: string, caseId: number) {
const url = `${apiServer}/cases/${caseId}`;
try {
@@ -10,6 +10,7 @@ async function fetchCase(caseId: number) {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwt}`,
},
});
@@ -24,7 +25,7 @@ async function fetchCase(caseId: number) {
}
}
async function fetchCases(folderId: string) {
async function fetchCases(jwt: string, folderId: string) {
const url = `${apiServer}/cases?folderId=${folderId}`;
try {
@@ -32,6 +33,7 @@ async function fetchCases(folderId: string) {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwt}`,
},
});
@@ -46,7 +48,7 @@ async function fetchCases(folderId: string) {
}
}
async function createCase(folderId: string) {
async function createCase(jwt: string, folderId: string) {
const newCase = {
title: 'untitled case',
state: 0,
@@ -64,6 +66,7 @@ async function createCase(folderId: string) {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwt}`,
},
body: JSON.stringify(newCase),
};
@@ -83,11 +86,12 @@ async function createCase(folderId: string) {
}
}
async function updateCase(updateCaseData: CaseType) {
async function updateCase(jwt: string, updateCaseData: CaseType) {
const fetchOptions = {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwt}`,
},
body: JSON.stringify(updateCaseData),
};
@@ -107,34 +111,36 @@ async function updateCase(updateCaseData: CaseType) {
}
}
async function deleteCase(caseId: number) {
const fetchOptions = {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
};
// async function deleteCase(jwt: string, caseId: number) {
// const fetchOptions = {
// method: 'DELETE',
// headers: {
// 'Content-Type': 'application/json',
// Authorization: `Bearer ${jwt}`,
// },
// };
const url = `${apiServer}/cases/${caseId}`;
// const url = `${apiServer}/cases/${caseId}`;
try {
const response = await fetch(url, fetchOptions);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
} catch (error: any) {
console.error('Error deleting case:', error);
throw error;
}
}
// try {
// const response = await fetch(url, fetchOptions);
// if (!response.ok) {
// throw new Error(`HTTP error! Status: ${response.status}`);
// }
// } catch (error: any) {
// console.error('Error deleting case:', error);
// throw error;
// }
// }
async function deleteCases(deleteCases: string[]) {
async function deleteCases(jwt: string, deleteCaseIds: number[]) {
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwt}`,
},
body: JSON.stringify({ caseIds: deleteCases }),
body: JSON.stringify({ caseIds: deleteCaseIds }),
};
const url = `${apiServer}/cases/bulkdelete`;
@@ -150,4 +156,4 @@ async function deleteCases(deleteCases: string[]) {
}
}
export { fetchCase, fetchCases, updateCase, createCase, deleteCase, deleteCases };
export { fetchCase, fetchCases, updateCase, createCase, deleteCases };

View File

@@ -11,6 +11,8 @@ export default function Page({ params }: { params: { projectId: string; folderId
actions: t('actions'),
deleteCase: t('delete_case'),
delete: t('delete'),
close: t('close'),
areYouSure: t('are_you_sure'),
newTestCase: t('new_test_case'),
status: t('status'),
critical: t('critical'),