summaryrefslogtreecommitdiff
path: root/lib/avl/table/avl-table.tsx
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-09-15 18:58:07 +0900
committerjoonhoekim <26rote@gmail.com>2025-09-15 18:58:07 +0900
commit2b490956c9752c1b756780a3461bc1c37b6fe0a7 (patch)
treeb0b8a03c8de5dfce4b6c7373a9d608306e9147c0 /lib/avl/table/avl-table.tsx
parente7818a457371849e29519497ebf046f385f05ab6 (diff)
(김준회) AVL 관리 및 상세 - 기능 구현 1차
+ docker compose 내 오류 수정
Diffstat (limited to 'lib/avl/table/avl-table.tsx')
-rw-r--r--lib/avl/table/avl-table.tsx100
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">