"use client"; import React, { useState } from "react"; import { useReactTable, getCoreRowModel, getExpandedRowModel, flexRender, ExpandedState, } from "@tanstack/react-table"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from "@/components/ui/dialog"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { Loader2 } from "lucide-react"; import { swpRevisionColumns, swpFileColumns, type RevisionRow, type FileRow } from "./swp-table-columns"; import type { SwpDocumentWithStats } from "../actions"; interface SwpRevisionListDialogProps { open: boolean; onOpenChange: (open: boolean) => void; document: SwpDocumentWithStats | null; revisions: RevisionRow[]; fileData: Record; loadingRevisions: boolean; loadingFiles: Set; onLoadFiles: (revisionId: number) => void; onLoadAllFiles: () => void; } export function SwpRevisionListDialog({ open, onOpenChange, document, revisions, fileData, loadingRevisions, loadingFiles, onLoadFiles, onLoadAllFiles, }: SwpRevisionListDialogProps) { return ( Document Detail {document && ( {document.DOC_NO} - {document.DOC_TITLE} )} {document && (
{/* 문서 정보 */}
Project:
{document.PROJ_NO}
{document.PROJ_NM && (
{document.PROJ_NM}
)}
Package:
{document.PKG_NO || "-"}
Company:
{document.CPY_NM || "-"}
{document.VNDR_CD && (
{document.VNDR_CD}
)}
Last Revision Number:
{document.LTST_REV_NO || "-"}
{/* 리비전 및 파일 목록 */} {loadingRevisions ? (
Loading revisions...
) : revisions.length ? ( ) : (
No revisions
)}
)}
); } // ============================================================================ // 문서 상세 뷰 (Dialog용) // ============================================================================ interface DocumentDetailViewProps { revisions: RevisionRow[]; fileData: Record; loadingFiles: Set; onLoadFiles: (revisionId: number) => void; onLoadAllFiles: () => void; } function DocumentDetailView({ revisions, fileData, loadingFiles, onLoadFiles, onLoadAllFiles, }: DocumentDetailViewProps) { const [expandedRevisions, setExpandedRevisions] = useState({}); const [allExpanded, setAllExpanded] = useState(false); const revisionTable = useReactTable({ data: revisions, columns: swpRevisionColumns, state: { expanded: expandedRevisions, }, onExpandedChange: setExpandedRevisions, getCoreRowModel: getCoreRowModel(), getExpandedRowModel: getExpandedRowModel(), getRowCanExpand: () => true, }); const handleExpandAll = () => { if (allExpanded) { setExpandedRevisions({}); } else { const expanded: ExpandedState = {}; revisions.forEach((_, index) => { expanded[index] = true; }); setExpandedRevisions(expanded); onLoadAllFiles(); } setAllExpanded(!allExpanded); }; const handleRevisionExpand = (revisionId: number) => { onLoadFiles(revisionId); }; return (
{/* 전체 펼치기/접기 버튼 */}
{/* Revision Table */}
{revisionTable.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext() )} ))} ))} {revisionTable.getRowModel().rows.map((row) => ( {/* Revision Row */} {row.getVisibleCells().map((cell) => ( {cell.column.id === "expander" ? (
{ row.toggleExpanded(); if (!row.getIsExpanded()) { handleRevisionExpand(row.original.id); } }} className="cursor-pointer" > {flexRender( cell.column.columnDef.cell, cell.getContext() )}
) : ( flexRender(cell.column.columnDef.cell, cell.getContext()) )}
))}
{/* File Rows (when expanded) */} {row.getIsExpanded() && ( {loadingFiles.has(row.original.id) ? (
Loading files...
) : fileData[row.original.id]?.length ? ( ) : (
No files
)}
)}
))}
); } // ============================================================================ // File Sub Table // ============================================================================ interface FileSubTableProps { files: FileRow[]; } function FileSubTable({ files }: FileSubTableProps) { const fileTable = useReactTable({ data: files, columns: swpFileColumns, getCoreRowModel: getCoreRowModel(), }); return (
{fileTable.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext() )} ))} ))} {fileTable.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} ))}
); }