summaryrefslogtreecommitdiff
path: root/lib/swp
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-10-27 10:54:48 +0900
committerjoonhoekim <26rote@gmail.com>2025-10-27 10:54:48 +0900
commit92766c1f2096852e7f224629963a412af8a16586 (patch)
treee79600d6df56fce1a84fe8a76d69339e5d1a85c4 /lib/swp
parent65a68325658401dd8a90ea900c1542c17c63d7ce (diff)
(김준회) SWP 코드추출 리팩터링, 파일수 조회 쿼리 통일, 헬프다이얼로그 문구 개선
Diffstat (limited to 'lib/swp')
-rw-r--r--lib/swp/actions.ts21
-rw-r--r--lib/swp/table/swp-help-dialog.tsx10
-rw-r--r--lib/swp/table/swp-revision-list-dialog.tsx310
-rw-r--r--lib/swp/table/swp-table-toolbar.tsx4
-rw-r--r--lib/swp/table/swp-table.tsx275
5 files changed, 342 insertions, 278 deletions
diff --git a/lib/swp/actions.ts b/lib/swp/actions.ts
index 7411f414..f58793e2 100644
--- a/lib/swp/actions.ts
+++ b/lib/swp/actions.ts
@@ -110,7 +110,7 @@ export async function fetchSwpDocuments(params: SwpTableParams) {
sync_status: swpDocuments.sync_status,
last_synced_at: swpDocuments.last_synced_at,
revision_count: sql<number>`COUNT(DISTINCT ${swpDocumentRevisions.id})::int`,
- file_count: sql<number>`COUNT(${swpDocumentFiles.id})::int`,
+ file_count: sql<number>`COUNT(DISTINCT ${swpDocumentFiles.id})::int`,
})
.from(swpDocuments)
.leftJoin(swpDocumentRevisions, eq(swpDocuments.DOC_NO, swpDocumentRevisions.DOC_NO))
@@ -162,14 +162,21 @@ export async function fetchDocumentRevisions(docNo: string) {
OFDC_NO: swpDocumentRevisions.OFDC_NO,
sync_status: swpDocumentRevisions.sync_status,
last_synced_at: swpDocumentRevisions.last_synced_at,
- file_count: sql<number>`(
- SELECT COUNT(*)::int
- FROM swp.swp_document_files f
- WHERE f.revision_id = ${swpDocumentRevisions.id}
- )`,
+ file_count: sql<number>`COUNT(DISTINCT ${swpDocumentFiles.id})::int`,
})
.from(swpDocumentRevisions)
+ .leftJoin(swpDocumentFiles, eq(swpDocumentRevisions.id, swpDocumentFiles.revision_id))
.where(eq(swpDocumentRevisions.DOC_NO, docNo))
+ .groupBy(
+ swpDocumentRevisions.id,
+ swpDocumentRevisions.DOC_NO,
+ swpDocumentRevisions.REV_NO,
+ swpDocumentRevisions.STAGE,
+ swpDocumentRevisions.ACTV_NO,
+ swpDocumentRevisions.OFDC_NO,
+ swpDocumentRevisions.sync_status,
+ swpDocumentRevisions.last_synced_at
+ )
.orderBy(desc(swpDocumentRevisions.REV_NO));
return revisions;
@@ -268,7 +275,7 @@ export async function fetchSwpStats(projNo?: string) {
.select({
total_documents: sql<number>`COUNT(DISTINCT ${swpDocuments.DOC_NO})::int`,
total_revisions: sql<number>`COUNT(DISTINCT ${swpDocumentRevisions.id})::int`,
- total_files: sql<number>`COUNT(${swpDocumentFiles.id})::int`,
+ total_files: sql<number>`COUNT(DISTINCT ${swpDocumentFiles.id})::int`,
last_sync: sql<Date>`MAX(${swpDocuments.last_synced_at})`,
})
.from(swpDocuments)
diff --git a/lib/swp/table/swp-help-dialog.tsx b/lib/swp/table/swp-help-dialog.tsx
index 18f29644..6880a8c7 100644
--- a/lib/swp/table/swp-help-dialog.tsx
+++ b/lib/swp/table/swp-help-dialog.tsx
@@ -32,7 +32,7 @@ export function SwpUploadHelpDialog() {
<div className="space-y-6">
{/* 파일명 형식 */}
<div className="space-y-2">
- <h3 className="text-sm font-semibold">📋 파일명 형식</h3>
+ <h3 className="text-sm font-semibold">파일명 형식</h3>
<div className="rounded-lg bg-muted p-4 font-mono text-sm">
[OWN_DOC_NO]_[REV_NO]_[STAGE]_[YYYYMMDDhhmmss].[확장자]
</div>
@@ -43,7 +43,7 @@ export function SwpUploadHelpDialog() {
{/* 각 항목 설명 - 1라인 형태 */}
<div className="space-y-3">
- <h3 className="text-sm font-semibold">📝 항목 설명</h3>
+ <h3 className="text-sm font-semibold">항목 설명</h3>
<div className="flex items-center gap-3 rounded-lg border p-3">
<Badge variant="secondary" className="font-mono shrink-0">
@@ -71,7 +71,7 @@ export function SwpUploadHelpDialog() {
</Badge>
<div className="text-sm">
<span className="font-medium">스테이지</span>
- <span className="text-muted-foreground"> - 중공업이 설정한 스테이지입니다 (예: IFA, IFC, AFC, BFC)</span>
+ <span className="text-muted-foreground"> - 스테이지 정보를 입력해주세요. (예: IFA, IFC)</span>
</div>
</div>
@@ -88,7 +88,7 @@ export function SwpUploadHelpDialog() {
{/* 예시 */}
<div className="space-y-2">
- <h3 className="text-sm font-semibold">✅ 올바른 예시</h3>
+ <h3 className="text-sm font-semibold">올바른 예시</h3>
<div className="space-y-2">
<div className="rounded-lg bg-green-50 dark:bg-green-950/30 border border-green-200 dark:border-green-800 p-3">
<code className="text-xs font-mono text-green-700 dark:text-green-300">
@@ -105,7 +105,7 @@ export function SwpUploadHelpDialog() {
{/* 잘못된 예시 */}
<div className="space-y-2">
- <h3 className="text-sm font-semibold">❌ 잘못된 예시</h3>
+ <h3 className="text-sm font-semibold">잘못된 예시</h3>
<div className="space-y-2">
<div className="rounded-lg bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-800 p-3">
<code className="text-xs font-mono text-red-700 dark:text-red-300">
diff --git a/lib/swp/table/swp-revision-list-dialog.tsx b/lib/swp/table/swp-revision-list-dialog.tsx
new file mode 100644
index 00000000..74402bd9
--- /dev/null
+++ b/lib/swp/table/swp-revision-list-dialog.tsx
@@ -0,0 +1,310 @@
+"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<number, FileRow[]>;
+ loadingRevisions: boolean;
+ loadingFiles: Set<number>;
+ onLoadFiles: (revisionId: number) => void;
+ onLoadAllFiles: () => void;
+}
+
+export function SwpRevisionListDialog({
+ open,
+ onOpenChange,
+ document,
+ revisions,
+ fileData,
+ loadingRevisions,
+ loadingFiles,
+ onLoadFiles,
+ onLoadAllFiles,
+}: SwpRevisionListDialogProps) {
+ return (
+ <Dialog open={open} onOpenChange={onOpenChange}>
+ <DialogContent className="max-w-6xl max-h-[90vh]">
+ <DialogHeader>
+ <DialogTitle>문서 상세</DialogTitle>
+ {document && (
+ <DialogDescription>
+ {document.DOC_NO} - {document.DOC_TITLE}
+ </DialogDescription>
+ )}
+ </DialogHeader>
+
+ {document && (
+ <div className="space-y-4 overflow-y-auto">
+ {/* 문서 정보 */}
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-4 p-4 bg-muted/30 rounded-lg">
+ <div>
+ <span className="text-sm font-semibold">프로젝트:</span>
+ <div className="text-sm">{document.PROJ_NO}</div>
+ {document.PROJ_NM && (
+ <div className="text-xs text-muted-foreground">{document.PROJ_NM}</div>
+ )}
+ </div>
+ <div>
+ <span className="text-sm font-semibold">패키지:</span>
+ <div className="text-sm">{document.PKG_NO || "-"}</div>
+ </div>
+ <div>
+ <span className="text-sm font-semibold">업체:</span>
+ <div className="text-sm">{document.CPY_NM || "-"}</div>
+ {document.VNDR_CD && (
+ <div className="text-xs text-muted-foreground">{document.VNDR_CD}</div>
+ )}
+ </div>
+ <div>
+ <span className="text-sm font-semibold">최신 리비전:</span>
+ <div className="text-sm">{document.LTST_REV_NO || "-"}</div>
+ </div>
+ </div>
+
+ {/* 리비전 및 파일 목록 */}
+ {loadingRevisions ? (
+ <div className="flex items-center justify-center p-8">
+ <Loader2 className="h-6 w-6 animate-spin" />
+ <span className="ml-2">리비전 로딩 중...</span>
+ </div>
+ ) : revisions.length ? (
+ <DocumentDetailView
+ revisions={revisions}
+ fileData={fileData}
+ loadingFiles={loadingFiles}
+ onLoadFiles={onLoadFiles}
+ onLoadAllFiles={onLoadAllFiles}
+ />
+ ) : (
+ <div className="p-8 text-center text-muted-foreground">
+ 리비전 없음
+ </div>
+ )}
+ </div>
+ )}
+ </DialogContent>
+ </Dialog>
+ );
+}
+
+// ============================================================================
+// 문서 상세 뷰 (Dialog용)
+// ============================================================================
+
+interface DocumentDetailViewProps {
+ revisions: RevisionRow[];
+ fileData: Record<number, FileRow[]>;
+ loadingFiles: Set<number>;
+ onLoadFiles: (revisionId: number) => void;
+ onLoadAllFiles: () => void;
+}
+
+function DocumentDetailView({
+ revisions,
+ fileData,
+ loadingFiles,
+ onLoadFiles,
+ onLoadAllFiles,
+}: DocumentDetailViewProps) {
+ const [expandedRevisions, setExpandedRevisions] = useState<ExpandedState>({});
+ 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 (
+ <div className="space-y-4">
+ {/* 전체 펼치기/접기 버튼 */}
+ <div className="flex justify-end">
+ <Button
+ variant="outline"
+ size="sm"
+ onClick={handleExpandAll}
+ >
+ {allExpanded ? "모두 접기" : "모두 펼치기"}
+ </Button>
+ </div>
+
+ {/* 리비전 테이블 */}
+ <div className="rounded-md border">
+ <Table>
+ <TableHeader>
+ {revisionTable.getHeaderGroups().map((headerGroup) => (
+ <TableRow key={headerGroup.id} className="bg-muted/50">
+ {headerGroup.headers.map((header) => (
+ <TableHead key={header.id} className="font-semibold">
+ {header.isPlaceholder
+ ? null
+ : flexRender(
+ header.column.columnDef.header,
+ header.getContext()
+ )}
+ </TableHead>
+ ))}
+ </TableRow>
+ ))}
+ </TableHeader>
+ <TableBody>
+ {revisionTable.getRowModel().rows.map((row) => (
+ <React.Fragment key={row.id}>
+ {/* 리비전 행 */}
+ <TableRow className="bg-muted/20">
+ {row.getVisibleCells().map((cell) => (
+ <TableCell key={cell.id}>
+ {cell.column.id === "expander" ? (
+ <div
+ onClick={() => {
+ row.toggleExpanded();
+ if (!row.getIsExpanded()) {
+ handleRevisionExpand(row.original.id);
+ }
+ }}
+ className="cursor-pointer"
+ >
+ {flexRender(
+ cell.column.columnDef.cell,
+ cell.getContext()
+ )}
+ </div>
+ ) : (
+ flexRender(cell.column.columnDef.cell, cell.getContext())
+ )}
+ </TableCell>
+ ))}
+ </TableRow>
+
+ {/* 파일 행들 (확장 시) */}
+ {row.getIsExpanded() && (
+ <TableRow>
+ <TableCell colSpan={swpRevisionColumns.length} className="p-0 bg-blue-50/30">
+ {loadingFiles.has(row.original.id) ? (
+ <div className="flex items-center justify-center p-4">
+ <Loader2 className="h-5 w-5 animate-spin" />
+ <span className="ml-2 text-sm">파일 로딩 중...</span>
+ </div>
+ ) : fileData[row.original.id]?.length ? (
+ <FileSubTable files={fileData[row.original.id]} />
+ ) : (
+ <div className="p-4 text-center text-sm text-muted-foreground">
+ 파일 없음
+ </div>
+ )}
+ </TableCell>
+ </TableRow>
+ )}
+ </React.Fragment>
+ ))}
+ </TableBody>
+ </Table>
+ </div>
+ </div>
+ );
+}
+
+// ============================================================================
+// 파일 서브 테이블
+// ============================================================================
+
+interface FileSubTableProps {
+ files: FileRow[];
+}
+
+function FileSubTable({ files }: FileSubTableProps) {
+ const fileTable = useReactTable({
+ data: files,
+ columns: swpFileColumns,
+ getCoreRowModel: getCoreRowModel(),
+ });
+
+ return (
+ <div className="border-l-4 border-green-200">
+ <Table>
+ <TableHeader>
+ {fileTable.getHeaderGroups().map((headerGroup) => (
+ <TableRow key={headerGroup.id} className="bg-blue-50/50">
+ {headerGroup.headers.map((header) => (
+ <TableHead key={header.id} className="font-semibold text-xs">
+ {header.isPlaceholder
+ ? null
+ : flexRender(
+ header.column.columnDef.header,
+ header.getContext()
+ )}
+ </TableHead>
+ ))}
+ </TableRow>
+ ))}
+ </TableHeader>
+ <TableBody>
+ {fileTable.getRowModel().rows.map((row) => (
+ <TableRow key={row.id} className="bg-green-50/20 hover:bg-green-50/40">
+ {row.getVisibleCells().map((cell) => (
+ <TableCell key={cell.id} className="py-2">
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
+ </TableCell>
+ ))}
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </div>
+ );
+}
+
diff --git a/lib/swp/table/swp-table-toolbar.tsx b/lib/swp/table/swp-table-toolbar.tsx
index fc8337f5..e7a2ef30 100644
--- a/lib/swp/table/swp-table-toolbar.tsx
+++ b/lib/swp/table/swp-table-toolbar.tsx
@@ -227,10 +227,6 @@ export function SwpTableToolbar({
{isSyncing ? "동기화 중..." : "SWP 동기화"}
</Button>
</div>
-
- <div className="text-sm text-muted-foreground">
- SWP 문서 관리 시스템
- </div>
<div className="flex items-center gap-2">
{/* 벤더만 파일 업로드 기능 사용 가능 */}
diff --git a/lib/swp/table/swp-table.tsx b/lib/swp/table/swp-table.tsx
index 8ae90bdd..47c9905a 100644
--- a/lib/swp/table/swp-table.tsx
+++ b/lib/swp/table/swp-table.tsx
@@ -17,16 +17,9 @@ import {
TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
-import {
- Dialog,
- DialogContent,
- DialogHeader,
- DialogTitle,
- DialogDescription,
-} from "@/components/ui/dialog";
-import { Loader2 } from "lucide-react";
-import { swpDocumentColumns, swpRevisionColumns, swpFileColumns, type RevisionRow, type FileRow } from "./swp-table-columns";
+import { swpDocumentColumns, type RevisionRow, type FileRow } from "./swp-table-columns";
import { fetchDocumentRevisions, fetchRevisionFiles, type SwpDocumentWithStats } from "../actions";
+import { SwpRevisionListDialog } from "./swp-revision-list-dialog";
interface SwpTableProps {
initialData: SwpDocumentWithStats[];
@@ -227,259 +220,17 @@ export function SwpTable({
</div>
{/* 문서 상세 Dialog */}
- <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
- <DialogContent className="max-w-6xl max-h-[90vh]">
- <DialogHeader>
- <DialogTitle>문서 상세</DialogTitle>
- {selectedDocument && (
- <DialogDescription>
- {selectedDocument.DOC_NO} - {selectedDocument.DOC_TITLE}
- </DialogDescription>
- )}
- </DialogHeader>
-
- {selectedDocument && (
- <div className="space-y-4 overflow-y-auto">
- {/* 문서 정보 */}
- <div className="grid grid-cols-1 md:grid-cols-4 gap-4 p-4 bg-muted/30 rounded-lg">
- <div>
- <span className="text-sm font-semibold">프로젝트:</span>
- <div className="text-sm">{selectedDocument.PROJ_NO}</div>
- {selectedDocument.PROJ_NM && (
- <div className="text-xs text-muted-foreground">{selectedDocument.PROJ_NM}</div>
- )}
- </div>
- <div>
- <span className="text-sm font-semibold">패키지:</span>
- <div className="text-sm">{selectedDocument.PKG_NO || "-"}</div>
- </div>
- <div>
- <span className="text-sm font-semibold">업체:</span>
- <div className="text-sm">{selectedDocument.CPY_NM || "-"}</div>
- {selectedDocument.VNDR_CD && (
- <div className="text-xs text-muted-foreground">{selectedDocument.VNDR_CD}</div>
- )}
- </div>
- <div>
- <span className="text-sm font-semibold">최신 리비전:</span>
- <div className="text-sm">{selectedDocument.LTST_REV_NO || "-"}</div>
- </div>
- </div>
-
- {/* 리비전 및 파일 목록 */}
- {loadingRevisions.has(selectedDocument.DOC_NO) ? (
- <div className="flex items-center justify-center p-8">
- <Loader2 className="h-6 w-6 animate-spin" />
- <span className="ml-2">리비전 로딩 중...</span>
- </div>
- ) : revisionData[selectedDocument.DOC_NO]?.length ? (
- <DocumentDetailView
- revisions={revisionData[selectedDocument.DOC_NO]}
- fileData={fileData}
- loadingFiles={loadingFiles}
- onLoadFiles={loadFiles}
- onLoadAllFiles={() => loadAllFiles(selectedDocument.DOC_NO)}
- />
- ) : (
- <div className="p-8 text-center text-muted-foreground">
- 리비전 없음
- </div>
- )}
- </div>
- )}
- </DialogContent>
- </Dialog>
- </div>
- );
-}
-
-// ============================================================================
-// 문서 상세 뷰 (Dialog용)
-// ============================================================================
-
-interface DocumentDetailViewProps {
- revisions: RevisionRow[];
- fileData: Record<number, FileRow[]>;
- loadingFiles: Set<number>;
- onLoadFiles: (revisionId: number) => void;
- onLoadAllFiles: () => void;
-}
-
-function DocumentDetailView({
- revisions,
- fileData,
- loadingFiles,
- onLoadFiles,
- onLoadAllFiles,
-}: DocumentDetailViewProps) {
- const [expandedRevisions, setExpandedRevisions] = useState<ExpandedState>({});
- 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 (
- <div className="space-y-4">
- {/* 전체 펼치기/접기 버튼 */}
- <div className="flex justify-end">
- <Button
- variant="outline"
- size="sm"
- onClick={handleExpandAll}
- >
- {allExpanded ? "모두 접기" : "모두 펼치기"}
- </Button>
- </div>
-
- {/* 리비전 테이블 */}
- <div className="rounded-md border">
- <Table>
- <TableHeader>
- {revisionTable.getHeaderGroups().map((headerGroup) => (
- <TableRow key={headerGroup.id} className="bg-muted/50">
- {headerGroup.headers.map((header) => (
- <TableHead key={header.id} className="font-semibold">
- {header.isPlaceholder
- ? null
- : flexRender(
- header.column.columnDef.header,
- header.getContext()
- )}
- </TableHead>
- ))}
- </TableRow>
- ))}
- </TableHeader>
- <TableBody>
- {revisionTable.getRowModel().rows.map((row) => (
- <React.Fragment key={row.id}>
- {/* 리비전 행 */}
- <TableRow className="bg-muted/20">
- {row.getVisibleCells().map((cell) => (
- <TableCell key={cell.id}>
- {cell.column.id === "expander" ? (
- <div
- onClick={() => {
- row.toggleExpanded();
- if (!row.getIsExpanded()) {
- handleRevisionExpand(row.original.id);
- }
- }}
- className="cursor-pointer"
- >
- {flexRender(
- cell.column.columnDef.cell,
- cell.getContext()
- )}
- </div>
- ) : (
- flexRender(cell.column.columnDef.cell, cell.getContext())
- )}
- </TableCell>
- ))}
- </TableRow>
-
- {/* 파일 행들 (확장 시) */}
- {row.getIsExpanded() && (
- <TableRow>
- <TableCell colSpan={swpRevisionColumns.length} className="p-0 bg-blue-50/30">
- {loadingFiles.has(row.original.id) ? (
- <div className="flex items-center justify-center p-4">
- <Loader2 className="h-5 w-5 animate-spin" />
- <span className="ml-2 text-sm">파일 로딩 중...</span>
- </div>
- ) : fileData[row.original.id]?.length ? (
- <FileSubTable files={fileData[row.original.id]} />
- ) : (
- <div className="p-4 text-center text-sm text-muted-foreground">
- 파일 없음
- </div>
- )}
- </TableCell>
- </TableRow>
- )}
- </React.Fragment>
- ))}
- </TableBody>
- </Table>
- </div>
- </div>
- );
-}
-
-// ============================================================================
-// 파일 서브 테이블
-// ============================================================================
-
-interface FileSubTableProps {
- files: FileRow[];
-}
-
-function FileSubTable({ files }: FileSubTableProps) {
- const fileTable = useReactTable({
- data: files,
- columns: swpFileColumns,
- getCoreRowModel: getCoreRowModel(),
- });
-
- return (
- <div className="border-l-4 border-green-200">
- <Table>
- <TableHeader>
- {fileTable.getHeaderGroups().map((headerGroup) => (
- <TableRow key={headerGroup.id} className="bg-blue-50/50">
- {headerGroup.headers.map((header) => (
- <TableHead key={header.id} className="font-semibold text-xs">
- {header.isPlaceholder
- ? null
- : flexRender(
- header.column.columnDef.header,
- header.getContext()
- )}
- </TableHead>
- ))}
- </TableRow>
- ))}
- </TableHeader>
- <TableBody>
- {fileTable.getRowModel().rows.map((row) => (
- <TableRow key={row.id} className="bg-green-50/20 hover:bg-green-50/40">
- {row.getVisibleCells().map((cell) => (
- <TableCell key={cell.id} className="py-2">
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
- </TableCell>
- ))}
- </TableRow>
- ))}
- </TableBody>
- </Table>
+ <SwpRevisionListDialog
+ open={dialogOpen}
+ onOpenChange={setDialogOpen}
+ document={selectedDocument}
+ revisions={selectedDocument ? revisionData[selectedDocument.DOC_NO] || [] : []}
+ fileData={fileData}
+ loadingRevisions={selectedDocument ? loadingRevisions.has(selectedDocument.DOC_NO) : false}
+ loadingFiles={loadingFiles}
+ onLoadFiles={loadFiles}
+ onLoadAllFiles={() => selectedDocument && loadAllFiles(selectedDocument.DOC_NO)}
+ />
</div>
);
}