const [pullRequests, setPullRequests] = useState<any[]>([]);
const [openModalNumber, setOpenModalNumber] = useState<number | null>(null);
데이터들을 배열로 가져오는 것뿐만 아니라 Modal을 Open하는 것 또한 배열로 가져와야한다.
<div className="flex items-center gap-3">
<Badge variant="default">{pullRequest.state}</Badge>
<span className="font-medium">
<a onClick={() => setOpenModalNumber(pullRequest.number)}>
{pullRequest.title}
</a>
<PullRequestModal
open={openModalNumber === pullRequest.number}
onOpenChange={() => setOpenModalNumber(null)}
number={pullRequest.number}
/>
</span>
</div>
또한 onClick과 onOpenChange로 관리하는 모달의 열림상태도 배열상태의 함수로 설정해서 구분할 수 있어야한다.
export default function PullRequestModal({
open,
onOpenChange,
number,
title,
head,
base,
}:{
open: boolean;
onOpenChange: (open: boolean) => void;
number: number;
title: string;
head: string;
base: string;
})
Modal에서는 파라미터 값을 전달해주어야한다.
const fetchChangeList = async (owner: string, repo: string) => {
console.log("number : ", number);
console.log("owner : ", owner);
console.log("repo : ", repo);
const response = await fetch(`${getApiUrl()}/github/project/${projectId}/pull-request-file-changes/${number}/${owner}/${repo}`, {
credentials: "include",
method: "GET",
});
if(!response.ok) {
throw new Error("Failed to fetch change list");
}
const data = await response.json();
console.log(data);
setChangeList(data);
}
파일 목록을 가져오기 위해서는 먼저 사전에 만들어둔 백엔드로 파일 목록을 가져와야한다.
이 파일 목록으로 먼저 ChangeList를 만들어준다.
const fetchPullRequestChanges = async (filename: string, owner: string, repo: string, prNumber: number) => {
try {
setLoadingFiles(prev => ({ ...prev, [filename]: true }));
const response = await fetch(`${getApiUrl()}/github/repos/${owner}/${repo}/pulls/${prNumber}/files`, {
credentials: "include",
});
if(!response.ok) {
throw new Error("Failed to fetch pull request changes");
}
const data = await response.json();
console.log(data);
// 특정 파일명과 매칭되는 데이터 찾기
const matchedFile = data.find((file: any) => file.filename === filename);
if (matchedFile) {
setFileChanges(prev => ({ ...prev, [filename]: matchedFile }));
}
} catch (error) {
console.error("파일 변경 내역 불러오기 실패:", error);
} finally {
setLoadingFiles(prev => ({ ...prev, [filename]: false }));
}
}
const handleToggleFile = async (filename: string) => {
if (openFiles.includes(filename)) {
setOpenFiles(openFiles.filter(f => f !== filename));
} else {
setOpenFiles([...openFiles, filename]);
// 이미 받아온 적이 없다면 fetch
if (!fileChanges[filename]) {
await fetchPullRequestChanges(filename, owner, repo, number);
}
}
};
파일 변경 내역을 이후 따로 불러온다.