diff options
Diffstat (limited to 'lib/vendor-document-list/table')
4 files changed, 182 insertions, 97 deletions
diff --git a/lib/vendor-document-list/table/add-doc-dialog.tsx b/lib/vendor-document-list/table/add-doc-dialog.tsx index b108721c..9bedc810 100644 --- a/lib/vendor-document-list/table/add-doc-dialog.tsx +++ b/lib/vendor-document-list/table/add-doc-dialog.tsx @@ -37,9 +37,10 @@ type CreateDocumentSchema = z.infer<typeof createDocumentSchema>; interface AddDocumentListDialogProps { projectType: "ship" | "plant"; contractId: number; + onSuccess?: () => void; // ✅ onSuccess 콜백 추가 } -export function AddDocumentListDialog({ projectType, contractId }: AddDocumentListDialogProps) { +export function AddDocumentListDialog({ projectType, contractId, onSuccess }: AddDocumentListDialogProps) { const [open, setOpen] = React.useState(false); const [isSubmitting, setIsSubmitting] = React.useState(false); const router = useRouter(); @@ -98,8 +99,12 @@ export function AddDocumentListDialog({ projectType, contractId }: AddDocumentLi } as CreateDocumentInputType); if (result.success) { - // 성공 시 캐시 무효화 - await invalidateDocumentCache(contractId); + // ✅ 캐시 무효화 시도 (에러가 나더라도 계속 진행) + try { + await invalidateDocumentCache(contractId); + } catch (cacheError) { + console.warn('Cache invalidation failed:', cacheError); + } // 토스트 메시지 toast({ @@ -109,10 +114,23 @@ export function AddDocumentListDialog({ projectType, contractId }: AddDocumentLi }); // 모달 닫기 및 폼 리셋 - form.reset(); + form.reset({ + docNumber: "", + title: "", + stages: defaultStages + }); setOpen(false); - router.refresh(); + // ✅ 성공 콜백 호출 (부모 컴포넌트에서 추가 처리 가능) + if (onSuccess) { + onSuccess(); + } + + // ✅ 라우터 새로고침 (약간의 지연을 두고 실행) + setTimeout(() => { + router.refresh(); + }, 100); + } else { // 실패 시 에러 토스트 toast({ diff --git a/lib/vendor-document-list/table/enhanced-doc-table-columns.tsx b/lib/vendor-document-list/table/enhanced-doc-table-columns.tsx index 534a80a0..c8487d82 100644 --- a/lib/vendor-document-list/table/enhanced-doc-table-columns.tsx +++ b/lib/vendor-document-list/table/enhanced-doc-table-columns.tsx @@ -30,7 +30,9 @@ import { FileText, Eye, Edit, - Trash2 + Trash2, + Building, + Code } from "lucide-react" import { cn } from "@/lib/utils" @@ -140,7 +142,11 @@ export function getUpdatedEnhancedColumns({ setRowAction, projectType }: GetColumnsProps): ColumnDef<EnhancedDocumentsView>[] { - return [ + const isPlantProject = projectType === "plant" + + + // 기본 컬럼들 + const baseColumns: ColumnDef<EnhancedDocumentsView>[] = [ // 체크박스 선택 { id: "select", @@ -177,13 +183,8 @@ export function getUpdatedEnhancedColumns({ cell: ({ row }) => { const doc = row.original return ( - <div className="flex flex-col gap-1 items-start"> {/* ✅ items-start 추가 */} + <div className="flex flex-col gap-1 items-start"> <span className="font-mono text-sm font-medium">{doc.docNumber}</span> - {/* {doc.currentStagePriority && ( - <Badge variant={getPriorityColor(doc.currentStagePriority)} className="self-start inline-flex w-auto shrink-0 whitespace-nowrap text-xs" > - {getPriorityText(doc.currentStagePriority)} - </Badge> - )} */} </div> ) }, @@ -193,7 +194,93 @@ export function getUpdatedEnhancedColumns({ excelHeader: "문서번호" }, }, + ] + // ✅ Ship 프로젝트용 추가 컬럼들 + const plantColumns: ColumnDef<EnhancedDocumentsView>[] = isPlantProject ? [ + // 벤더 문서번호 + { + accessorKey: "vendorDocNumber", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="벤더 문서번호" /> + ), + cell: ({ row }) => { + const doc = row.original + return ( + <div className="flex flex-col gap-1 items-start"> + {doc.vendorDocNumber ? ( + <span className="font-mono text-sm text-blue-600">{doc.vendorDocNumber}</span> + ) : ( + <span className="text-gray-400 text-sm">-</span> + )} + </div> + ) + }, + size: 120, + enableResizing: true, + meta: { + excelHeader: "벤더 문서번호" + }, + }, + + // 프로젝트 코드 + { + accessorKey: "projectCode", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="프로젝트" /> + ), + cell: ({ row }) => { + const doc = row.original + return ( + <div className="flex items-center gap-2"> + {/* <Code className="w-4 h-4 text-gray-500" /> */} + <span className="font-mono text-sm font-medium text-gray-700"> + {doc.projectCode || '-'} + </span> + </div> + ) + }, + size: 100, + enableResizing: true, + meta: { + excelHeader: "프로젝트 코드" + }, + }, + + // 벤더 정보 + { + accessorKey: "vendorName", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="벤더" /> + ), + cell: ({ row }) => { + const doc = row.original + return ( + <div className="flex flex-col gap-1 items-start"> + <div className="flex items-center gap-2"> + {/* <Building className="w-4 h-4 text-gray-500" /> */} + <span className="text-sm font-medium text-gray-900"> + {doc.vendorName || '-'} + </span> + </div> + {doc.vendorCode && ( + <span className="text-xs font-mono text-gray-500 bg-gray-100 px-2 py-0.5 rounded"> + {doc.vendorCode} + </span> + )} + </div> + ) + }, + size: 150, + enableResizing: true, + meta: { + excelHeader: "벤더명" + }, + }, + ] : [] + + // 나머지 공통 컬럼들 + const commonColumns: ColumnDef<EnhancedDocumentsView>[] = [ // 문서명 + 담당자 { accessorKey: "title", @@ -223,7 +310,7 @@ export function getUpdatedEnhancedColumns({ </div> ) }, - size: 250, + size: isPlantProject ? 200 : 250, // Ship 프로젝트일 때는 너비 조정 enableResizing: true, meta: { excelHeader: "문서명" @@ -341,7 +428,6 @@ export function getUpdatedEnhancedColumns({ return ( <div className="flex flex-col gap-1 items-start"> <span className="font-mono text-sm font-medium">{doc.latestRevision}</span> - {/* <div className="text-xs text-gray-500">{doc.latestRevisionUploaderName}</div> */} {doc.latestRevisionStatus && ( <Badge variant={getStatusColor(doc.latestRevisionStatus)} className="self-start inline-flex w-auto shrink-0 whitespace-nowrap text-xs" > {getStatusText(doc.latestRevisionStatus)} @@ -381,7 +467,6 @@ export function getUpdatedEnhancedColumns({ }, // 액션 메뉴 - // 액션 메뉴 { id: "actions", enableHiding: false, @@ -532,6 +617,13 @@ export function getUpdatedEnhancedColumns({ size: 40, } ] + + // ✅ 모든 컬럼을 순서대로 결합 + return [ + ...baseColumns, // 체크박스, 문서번호 + ...plantColumns, // Ship 전용 컬럼들 (조건부) + ...commonColumns // 나머지 공통 컬럼들 + ] } // 확장된 행 컨텐츠 컴포넌트 (업데이트된 버전) diff --git a/lib/vendor-document-list/table/enhanced-doc-table-toolbar-actions.tsx b/lib/vendor-document-list/table/enhanced-doc-table-toolbar-actions.tsx index 368b1e1c..fa1b957b 100644 --- a/lib/vendor-document-list/table/enhanced-doc-table-toolbar-actions.tsx +++ b/lib/vendor-document-list/table/enhanced-doc-table-toolbar-actions.tsx @@ -40,6 +40,16 @@ export function EnhancedDocTableToolbarActions({ // 필요시 추가 액션 수행 } + const handleDocumentAdded = () => { + // 테이블 새로고침 + table.resetRowSelection() + + // 추가적인 새로고침 시도 + setTimeout(() => { + window.location.reload() // 강제 새로고침 + }, 500) + } + return ( <div className="flex items-center gap-2"> {/* 기존 액션들 */} @@ -52,14 +62,13 @@ export function EnhancedDocTableToolbarActions({ /> ) : null} - {/* 메인 액션 버튼들 */} - {projectType === "plant" && ( - <Button onClick={onNewDocument} className="flex items-center gap-2"> - <Plus className="w-4 h-4" /> - 새 문서 - </Button> - )} - + {/* ✅ AddDocumentListDialog에 필요한 props 전달 */} + <AddDocumentListDialog + projectType={projectType} + contractId={selectedPackageId} + onSuccess={handleDocumentAdded} // ✅ 성공 콜백 추가 + /> + {/* 일괄 업로드 버튼 */} <Button variant="outline" diff --git a/lib/vendor-document-list/table/enhanced-documents-table.tsx b/lib/vendor-document-list/table/enhanced-documents-table.tsx index d0f2991a..14c52455 100644 --- a/lib/vendor-document-list/table/enhanced-documents-table.tsx +++ b/lib/vendor-document-list/table/enhanced-documents-table.tsx @@ -10,7 +10,7 @@ import type { import { useDataTable } from "@/hooks/use-data-table" import { StageRevisionExpandedContent } from "./stage-revision-expanded-content" import { RevisionUploadDialog } from "./revision-upload-dialog" -import { SimplifiedDocumentEditDialog } from "./simplified-document-edit-dialog" +// ✅ UpdateDocumentSheet import 추가 import { EnhancedDocTableToolbarActions } from "./enhanced-doc-table-toolbar-actions" import { getEnhancedDocuments } from "../enhanced-document-service" import type { EnhancedDocument } from "@/types/enhanced-documents" @@ -27,22 +27,28 @@ import { import { getUpdatedEnhancedColumns } from "./enhanced-doc-table-columns" import { ExpandableDataTable } from "@/components/data-table/expandable-data-table" import { toast } from "sonner" -// import { ViewDocumentDialog } from "@/components/documents/view-document-dialog" +import { UpdateDocumentSheet } from "./update-doc-sheet" interface FinalIntegratedDocumentsTableProps { promises: Promise<[Awaited<ReturnType<typeof getEnhancedDocuments>>]> selectedPackageId: number projectType: "ship" | "plant" + // ✅ contractId 추가 (AddDocumentListDialog에서 필요) + contractId: number } export function EnhancedDocumentsTable({ promises, selectedPackageId, projectType, + contractId, // ✅ contractId 추가 }: FinalIntegratedDocumentsTableProps) { // 데이터 로딩 const [{ data, pageCount, total }] = React.use(promises) + console.log(data) + + // 상태 관리 const [rowAction, setRowAction] = React.useState<DataTableRowAction<EnhancedDocument> | null>(null) const [expandedRows, setExpandedRows] = React.useState<Set<string>>(new Set()) @@ -51,14 +57,12 @@ export function EnhancedDocumentsTable({ // ✅ 스테이지 확장 상태 관리 (문서별로 관리) const [expandedStages, setExpandedStages] = React.useState<Record<string, Record<number, boolean>>>({}) - // 다이얼로그 상태들 + // ✅ 다이얼로그 상태들 - editDialogOpen -> editSheetOpen으로 변경 const [uploadDialogOpen, setUploadDialogOpen] = React.useState(false) - const [editDialogOpen, setEditDialogOpen] = React.useState(false) - // const [viewDialogOpen, setViewDialogOpen] = React.useState(false) + const [editSheetOpen, setEditSheetOpen] = React.useState(false) // Sheet로 변경 const [selectedDocument, setSelectedDocument] = React.useState<EnhancedDocument | null>(null) const [selectedStage, setSelectedStage] = React.useState<string>("") const [selectedRevision, setSelectedRevision] = React.useState<string>("") - // const [selectedRevisions, setSelectedRevisions] = React.useState<any[]>([]) const [uploadMode, setUploadMode] = React.useState<'new' | 'append'>('new') // 다음 리비전 계산 함수 @@ -94,7 +98,7 @@ export function EnhancedDocumentsTable({ // 액션 타입에 따른 다이얼로그 열기 switch (action.type) { case "update": - setEditDialogOpen(true) + setEditSheetOpen(true) // ✅ Sheet 열기로 변경 break case "upload": setSelectedStage(action.row.original.currentStageName || "") @@ -114,9 +118,7 @@ export function EnhancedDocumentsTable({ } } }, - projectType - }), [expandedRows, projectType] ) @@ -219,19 +221,10 @@ export function EnhancedDocumentsTable({ return sortedRevisions[sortedRevisions.length - 1]?.revision || null }, []) - // const handleEditDocument = (document: EnhancedDocument) => { - // setSelectedDocument(document) - // setEditDialogOpen(true) - // } - - // const handleViewRevisions = (revisions: any[]) => { - // setSelectedRevisions(revisions) - // setViewDialogOpen(true) - // } - + // ✅ 새 문서 추가 핸들러 - EnhancedDocTableToolbarActions에서 AddDocumentListDialog를 직접 렌더링하므로 별도 상태 관리 불필요 const handleNewDocument = () => { - setSelectedDocument(null) - setEditDialogOpen(true) + // AddDocumentListDialog는 자체적으로 Dialog trigger를 가지므로 별도 처리 불필요 + // EnhancedDocTableToolbarActions에서 처리됨 } // ✅ 스테이지 토글 핸들러 추가 @@ -266,19 +259,32 @@ export function EnhancedDocumentsTable({ } } - // 다이얼로그 닫기 + // ✅ 다이얼로그 닫기 함수 수정 const closeAllDialogs = () => { setUploadDialogOpen(false) - setEditDialogOpen(false) - // setViewDialogOpen(false) + setEditSheetOpen(false) // editDialogOpen -> editSheetOpen setSelectedDocument(null) setSelectedStage("") setSelectedRevision("") - // setSelectedRevisions([]) setUploadMode('new') // ✅ 모드 초기화 setRowAction(null) } + // ✅ EnhancedDocument를 UpdateDocumentSheet의 document 형식으로 변환하는 함수 + const convertToUpdateFormat = React.useCallback((doc: EnhancedDocument | null) => { + if (!doc) return null + + return { + id: doc.documentId, + contractId: contractId, // contractId 사용 + docNumber: doc.docNumber, + title: doc.title, + status: doc.status || "pending", // 기본값 설정 + description: doc.description || null, + remarks: doc.remarks || null, + } + }, [contractId]) + // 필터 필드 정의 const filterFields: DataTableFilterField<EnhancedDocument>[] = [ { @@ -473,7 +479,6 @@ export function EnhancedDocumentsTable({ <StageRevisionExpandedContent document={document} onUploadRevision={handleUploadRevision} - // onViewRevision={handleViewRevisions} projectType={projectType} expandedStages={expandedStages[String(document.documentId)] || {}} onStageToggle={(stageId) => handleStageToggle(String(document.documentId), stageId)} @@ -492,44 +497,18 @@ export function EnhancedDocumentsTable({ table={table} projectType={projectType} selectedPackageId={selectedPackageId} + contractId={contractId} // ✅ contractId 추가 onNewDocument={handleNewDocument} onBulkAction={handleBulkAction} /> </DataTableAdvancedToolbar> </ExpandableDataTable> </div> - - {/* 선택된 항목 정보 */} - {/* {table.getFilteredSelectedRowModel().rows.length > 0 && ( - <div className="flex items-center justify-between p-4 bg-blue-50 border border-blue-200 rounded-lg"> - <span className="text-sm text-blue-700"> - {table.getFilteredSelectedRowModel().rows.length}개 항목이 선택되었습니다 - </span> - <div className="flex gap-2"> - <Button - size="sm" - variant="outline" - onClick={() => table.toggleAllRowsSelected(false)} - > - 선택 해제 - </Button> - <Button - size="sm" - onClick={() => { - const selectedRows = table.getFilteredSelectedRowModel().rows - handleBulkAction('bulk_approve', selectedRows) - }} - > - 선택 항목 승인 - </Button> - </div> - </div> - )} */} </div> - {/* 분리된 다이얼로그들 */} + {/* ✅ 분리된 다이얼로그들 - UpdateDocumentSheet와 AddDocumentListDialog로 교체 */} - {/* ✅ 리비전 업로드 다이얼로그 - mode props 추가 */} + {/* 리비전 업로드 다이얼로그 - mode props 추가 */} <RevisionUploadDialog open={uploadDialogOpen} onOpenChange={(open) => { @@ -543,28 +522,15 @@ export function EnhancedDocumentsTable({ mode={uploadMode} /> - {/* 문서 편집 다이얼로그 */} - <SimplifiedDocumentEditDialog - open={editDialogOpen} - onOpenChange={(open) => { - if (!open) closeAllDialogs() - else setEditDialogOpen(open) - }} - document={selectedDocument} - projectType={projectType} - /> - - {/* PDF 뷰어 다이얼로그 (기존 ViewDocumentDialog 재사용) */} - - {/* <ViewDocumentDialog - open={viewDialogOpen} + {/* ✅ 문서 편집 Sheet로 교체 */} + <UpdateDocumentSheet + open={editSheetOpen} onOpenChange={(open) => { if (!open) closeAllDialogs() - else setViewDialogOpen(open) + else setEditSheetOpen(open) }} - revisions={selectedRevisions} + document={convertToUpdateFormat(selectedDocument)} /> - */} </div> ) }
\ No newline at end of file |
