From 2b490956c9752c1b756780a3461bc1c37b6fe0a7 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 15 Sep 2025 18:58:07 +0900
Subject: (김준회) AVL 관리 및 상세 - 기능 구현 1차 + docker compose 내 오류
 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/avl/table/avl-table.tsx | 100 +++++++++++++++++++++++++++++++-------------
 1 file changed, 70 insertions(+), 30 deletions(-)

(limited to 'lib/avl/table/avl-table.tsx')

diff --git a/lib/avl/table/avl-table.tsx b/lib/avl/table/avl-table.tsx
index a6910ef5..eb9b2079 100644
--- a/lib/avl/table/avl-table.tsx
+++ b/lib/avl/table/avl-table.tsx
@@ -2,7 +2,6 @@
 
 import * as React from "react"
 import type {
-  DataTableAdvancedFilterField,
   DataTableFilterField,
 } from "@/types/table"
 
@@ -10,12 +9,12 @@ import { useDataTable } from "@/hooks/use-data-table"
 import { DataTable } from "@/components/data-table/data-table"
 import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"
 import { Button } from "@/components/ui/button"
-import { Checkbox } from "@/components/ui/checkbox"
 import { toast } from "sonner"
 
 import { getColumns } from "./avl-table-columns"
 import { createAvlListAction, updateAvlListAction, deleteAvlListAction, handleAvlActionAction } from "../service"
 import type { AvlListItem } from "../types"
+import { AvlHistoryModal, type AvlHistoryRecord } from "@/lib/avl/components/avl-history-modal"
 
 // 테이블 메타 타입 확장
 declare module "@tanstack/react-table" {
@@ -52,6 +51,50 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
   const [emptyRows, setEmptyRows] = React.useState<Record<string, AvlListItem>>({})
   const [isCreating, setIsCreating] = React.useState(false)
 
+  // 히스토리 모달 관리
+  const [historyModalOpen, setHistoryModalOpen] = React.useState(false)
+  const [selectedAvlItem, setSelectedAvlItem] = React.useState<AvlListItem | null>(null)
+
+  // 히스토리 데이터 로드 함수
+  const loadHistoryData = React.useCallback(async (avlItem: AvlListItem): Promise<AvlHistoryRecord[]> => {
+    try {
+      // 현재 리비전의 스냅샷 데이터 (실제 저장된 데이터 사용)
+      const currentSnapshot = avlItem.vendorInfoSnapshot || []
+      
+      const historyData: AvlHistoryRecord[] = [
+        {
+          id: avlItem.id,
+          rev: avlItem.rev || 1,
+          createdAt: avlItem.createdAt || new Date().toISOString(),
+          createdBy: avlItem.createdBy || "system",
+          vendorInfoSnapshot: currentSnapshot,
+          changeDescription: "최신 리비전 (확정완료)"
+        }
+      ]
+      
+      // TODO: 실제 구현에서는 DB에서 이전 리비전들의 스냅샷 데이터를 조회해야 함
+      // 현재는 더미 데이터로 이전 리비전들을 시뮬레이션
+      if ((avlItem.rev || 1) > 1) {
+        for (let rev = (avlItem.rev || 1) - 1; rev >= 1; rev--) {
+          historyData.push({
+            id: avlItem.id + rev * 1000, // 임시 ID
+            rev,
+            createdAt: new Date(Date.now() - rev * 24 * 60 * 60 * 1000).toISOString(),
+            createdBy: "system",
+            vendorInfoSnapshot: [], // 이전 리비전의 스냅샷 데이터 (실제로는 DB에서 조회)
+            changeDescription: `리비전 ${rev} 변경사항`
+          })
+        }
+      }
+      
+      return historyData
+    } catch (error) {
+      console.error('히스토리 로드 실패:', error)
+      toast.error("히스토리를 불러오는데 실패했습니다.")
+      return []
+    }
+  }, [])
+
   // 필터 필드 정의
   const filterFields: DataTableFilterField<AvlListItem>[] = [
     {
@@ -83,33 +126,6 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
     },
   ]
 
-  // 고급 필터 필드 정의
-  const advancedFilterFields: DataTableAdvancedFilterField<AvlListItem>[] = [
-    {
-      id: "projectCode",
-      label: "프로젝트 코드",
-      type: "text",
-      placeholder: "프로젝트 코드 입력...",
-    },
-    {
-      id: "shipType",
-      label: "선종",
-      type: "text",
-      placeholder: "선종 입력...",
-    },
-    {
-      id: "avlKind",
-      label: "AVL 종류",
-      type: "text",
-      placeholder: "AVL 종류 입력...",
-    },
-    {
-      id: "createdBy",
-      label: "등재자",
-      type: "text",
-      placeholder: "등재자 입력...",
-    },
-  ]
 
   // 인라인 편집 핸들러 (일괄 저장용)
   const handleCellUpdate = React.useCallback(async (id: string, field: keyof AvlListItem, newValue: any) => {
@@ -186,6 +202,7 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
             avlKind: "",
             htDivision: "",
             rev: 1,
+            vendorInfoSnapshot: null,
             createdAt: new Date().toISOString().split('T')[0],
             updatedAt: new Date().toISOString().split('T')[0],
             createdBy: "system",
@@ -296,6 +313,14 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
           }
           break
 
+        case 'view-history':
+          // 리비전 히스토리 조회
+          if (data?.id && !String(data.id).startsWith('temp-')) {
+            setSelectedAvlItem(data as AvlListItem)
+            setHistoryModalOpen(true)
+          }
+          break
+
         default:
           toast.error(`알 수 없는 액션: ${action}`)
       }
@@ -303,7 +328,7 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
       console.error('액션 처리 실패:', error)
       toast.error("액션 처리 중 오류가 발생했습니다.")
     }
-  }, [pendingChanges, onRefresh])
+  }, [pendingChanges, onRefresh, onRegistrationModeChange])
 
   // 빈 행 저장 핸들러
   const handleSaveEmptyRow = React.useCallback(async (tempId: string) => {
@@ -425,6 +450,10 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
     initialState: {
       sorting: [{ id: "createdAt", desc: true }],
       columnPinning: { right: ["actions"] },
+      pagination: {
+        pageIndex: 0,
+        pageSize: 10,
+      },
     },
     getRowId: (row) => String(row.id),
     meta: tableMeta,
@@ -502,6 +531,17 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
       {/* 데이터 테이블 */}
       <DataTable table={table} />
 
+      {/* 히스토리 모달 */}
+      <AvlHistoryModal
+        isOpen={historyModalOpen}
+        onClose={() => {
+          setHistoryModalOpen(false)
+          setSelectedAvlItem(null)
+        }}
+        avlItem={selectedAvlItem}
+        onLoadHistory={loadHistoryData}
+      />
+
       {/* 디버그 정보 (개발 환경에서만 표시) */}
       {process.env.NODE_ENV === 'development' && (hasPendingChanges || hasEmptyRows) && (
         <div className="text-xs text-muted-foreground p-2 bg-muted rounded">
-- 
cgit v1.2.3

