diff options
Diffstat (limited to 'lib/avl/table/avl-table.tsx')
| -rw-r--r-- | lib/avl/table/avl-table.tsx | 100 |
1 files changed, 70 insertions, 30 deletions
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"> |
