diff options
Diffstat (limited to 'lib/vendor-document-list/table')
5 files changed, 83 insertions, 23 deletions
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 f9d4d695..368b1e1c 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 @@ -91,6 +91,7 @@ export function EnhancedDocTableToolbarActions({ contractId={selectedPackageId} documents={allDocuments} onSyncComplete={handleSyncComplete} + projectType={projectType} /> {/* 일괄 업로드 다이얼로그 */} diff --git a/lib/vendor-document-list/table/enhanced-documents-table.tsx b/lib/vendor-document-list/table/enhanced-documents-table.tsx index 3b623193..d0f2991a 100644 --- a/lib/vendor-document-list/table/enhanced-documents-table.tsx +++ b/lib/vendor-document-list/table/enhanced-documents-table.tsx @@ -42,7 +42,7 @@ export function EnhancedDocumentsTable({ }: FinalIntegratedDocumentsTableProps) { // 데이터 로딩 const [{ data, pageCount, total }] = React.use(promises) - + // 상태 관리 const [rowAction, setRowAction] = React.useState<DataTableRowAction<EnhancedDocument> | null>(null) const [expandedRows, setExpandedRows] = React.useState<Set<string>>(new Set()) diff --git a/lib/vendor-document-list/table/revision-upload-dialog.tsx b/lib/vendor-document-list/table/revision-upload-dialog.tsx index ac58b974..546fa7a3 100644 --- a/lib/vendor-document-list/table/revision-upload-dialog.tsx +++ b/lib/vendor-document-list/table/revision-upload-dialog.tsx @@ -7,6 +7,7 @@ import { z } from "zod" import { toast } from "sonner" import { useRouter } from "next/navigation" import { useSession } from "next-auth/react" +import { mutate } from "swr" // ✅ SWR mutate import 추가 import { Dialog, @@ -77,6 +78,11 @@ interface RevisionUploadDialogProps { presetStage?: string presetRevision?: string mode?: 'new' | 'append' + onUploadComplete?: () => void // ✅ 업로드 완료 콜백 추가 +} + +function getTargetSystem(projectType: "ship" | "plant") { + return projectType === "ship" ? "DOLCE" : "SWP" } export function RevisionUploadDialog({ @@ -87,12 +93,19 @@ export function RevisionUploadDialog({ presetStage, presetRevision, mode = 'new', + onUploadComplete, // ✅ 추가된 prop }: RevisionUploadDialogProps) { + + const targetSystem = React.useMemo( + () => getTargetSystem(projectType), + [projectType] + ) + const [selectedFiles, setSelectedFiles] = React.useState<File[]>([]) const [isUploading, setIsUploading] = React.useState(false) const [uploadProgress, setUploadProgress] = React.useState(0) const router = useRouter() - + // ✅ next-auth session 가져오기 const { data: session } = useSession() @@ -109,7 +122,7 @@ export function RevisionUploadDialog({ defaultValues: { stage: presetStage || document?.currentStageName || "", revision: presetRevision || "", - uploaderName: session?.user?.name || "", // ✅ session.user.name 사용 + uploaderName: session?.user?.name || "", comment: "", attachments: [], }, @@ -146,6 +159,34 @@ export function RevisionUploadDialog({ form.setValue('attachments', updatedFiles, { shouldValidate: true }) } + // ✅ 캐시 갱신 함수 + const refreshCaches = async () => { + try { + // 1. 서버 컴포넌트 캐시 갱신 (Enhanced Documents 등) + router.refresh() + + // 2. SWR 캐시 갱신 (Sync Status) + if (document?.contractId) { + await mutate(`/api/sync/status/${document.contractId}/${targetSystem}`) + console.log('✅ Sync status cache refreshed') + } + + // 3. 다른 관련 SWR 캐시들도 갱신 (필요시) + await mutate(key => + typeof key === 'string' && + key.includes('sync') && + key.includes(String(document?.contractId)) + ) + + // 4. 상위 컴포넌트 콜백 호출 + onUploadComplete?.() + + console.log('✅ All caches refreshed after upload') + } catch (error) { + console.error('❌ Cache refresh failed:', error) + } + } + // 업로드 처리 async function onSubmit(data: RevisionUploadSchema) { if (!document) return @@ -158,8 +199,9 @@ export function RevisionUploadDialog({ formData.append("documentId", String(document.documentId)) formData.append("stage", data.stage) formData.append("revision", data.revision) - formData.append("mode", mode) // 'new' 또는 'append' - + formData.append("mode", mode) + formData.append("targetSystem", targetSystem) + if (data.uploaderName) { formData.append("uploaderName", data.uploaderName) } @@ -175,7 +217,7 @@ export function RevisionUploadDialog({ // 진행률 업데이트 시뮬레이션 const updateProgress = (progress: number) => { - setUploadProgress(Math.min(progress, 95)) // 95%까지만 진행률 표시 + setUploadProgress(Math.min(progress, 95)) } // 파일 크기에 따른 진행률 시뮬레이션 @@ -183,7 +225,7 @@ export function RevisionUploadDialog({ let uploadedSize = 0 const progressInterval = setInterval(() => { - uploadedSize += totalSize * 0.1 // 10%씩 증가 시뮬레이션 + uploadedSize += totalSize * 0.1 const progress = Math.min((uploadedSize / totalSize) * 100, 90) updateProgress(progress) }, 300) @@ -211,10 +253,10 @@ export function RevisionUploadDialog({ console.log('✅ 업로드 성공:', result) - // 잠시 대기 후 다이얼로그 닫기 - setTimeout(() => { + // ✅ 캐시 갱신 및 다이얼로그 닫기 + setTimeout(async () => { + await refreshCaches() handleDialogClose() - router.refresh() }, 1000) } catch (error) { @@ -222,7 +264,7 @@ export function RevisionUploadDialog({ toast.error(error instanceof Error ? error.message : "업로드 중 오류가 발생했습니다") } finally { setIsUploading(false) - setTimeout(() => setUploadProgress(0), 2000) // 2초 후 진행률 리셋 + setTimeout(() => setUploadProgress(0), 2000) } } @@ -230,7 +272,7 @@ export function RevisionUploadDialog({ form.reset({ stage: presetStage || document?.currentStageName || "", revision: presetRevision || "", - uploaderName: session?.user?.name || "", // ✅ 다이얼로그 닫을 때도 session 값으로 리셋 + uploaderName: session?.user?.name || "", comment: "", attachments: [], }) @@ -257,13 +299,15 @@ export function RevisionUploadDialog({ <Badge variant={projectType === "ship" ? "default" : "secondary"}> {projectType === "ship" ? "조선 프로젝트" : "플랜트 프로젝트"} </Badge> - {/* ✅ 현재 사용자 정보 표시 */} + {/* ✅ 타겟 시스템 표시 추가 */} + <Badge variant="outline" className="text-xs"> + → {targetSystem} + </Badge> {session?.user?.name && ( <Badge variant="outline" className="text-xs"> 업로더: {session.user.name} </Badge> )} - {/* ✅ 모드에 따른 정보 표시 */} {mode === 'append' && presetRevision && ( <Badge variant="outline" className="text-xs"> 리비전 {presetRevision}에 파일 추가 @@ -320,7 +364,6 @@ export function RevisionUploadDialog({ /> </FormControl> <FormMessage /> - {/* ✅ 모드에 따른 도움말 표시 */} {mode === 'new' && presetRevision && ( <p className="text-xs text-gray-500"> 자동으로 계산된 다음 리비전입니다. @@ -346,7 +389,7 @@ export function RevisionUploadDialog({ <Input {...field} placeholder="업로더 이름을 입력하세요" - className="bg-gray-50" // ✅ session 값이므로 읽기 전용 느낌으로 스타일링 + className="bg-gray-50" /> </FormControl> <FormMessage /> @@ -420,7 +463,7 @@ export function RevisionUploadDialog({ <FileListIcon /> <FileListInfo> <FileListName>{file.name}</FileListName> - <FileListSize>{prettyBytes(file.size)}</FileListSize> + <FileListSize>{file.size}</FileListSize> </FileListInfo> <FileListAction onClick={() => removeFile(index)} diff --git a/lib/vendor-document-list/table/send-to-shi-button.tsx b/lib/vendor-document-list/table/send-to-shi-button.tsx index e0360144..1a27a794 100644 --- a/lib/vendor-document-list/table/send-to-shi-button.tsx +++ b/lib/vendor-document-list/table/send-to-shi-button.tsx @@ -28,22 +28,26 @@ interface SendToSHIButtonProps { contractId: number documents?: EnhancedDocument[] onSyncComplete?: () => void + projectType: "ship" | "plant" } export function SendToSHIButton({ contractId, documents = [], - onSyncComplete + onSyncComplete, + projectType }: SendToSHIButtonProps) { const [isDialogOpen, setIsDialogOpen] = React.useState(false) const [syncProgress, setSyncProgress] = React.useState(0) + + const targetSystem = projectType === 'ship'?"DOLCE":"SWP" const { syncStatus, isLoading: statusLoading, error: statusError, refetch: refetchStatus - } = useSyncStatus(contractId, 'SHI') + } = useSyncStatus(contractId, targetSystem) const { triggerSync, @@ -71,7 +75,7 @@ export function SendToSHIButton({ const result = await triggerSync({ contractId, - targetSystem: 'SHI' + targetSystem }) clearInterval(progressInterval) @@ -152,10 +156,11 @@ export function SendToSHIButton({ <> <Popover> <PopoverTrigger asChild> + <div className="flex items-center gap-3"> <Button variant="default" size="sm" - className="gap-2 relative bg-blue-600 hover:bg-blue-700" + className="flex items-center bg-blue-600 hover:bg-blue-700" disabled={isSyncing || statusLoading} > {isSyncing ? ( @@ -167,12 +172,13 @@ export function SendToSHIButton({ {syncStatus?.pendingChanges > 0 && ( <Badge variant="destructive" - className="absolute -top-2 -right-2 h-5 w-5 p-0 text-xs flex items-center justify-center" + className="h-5 w-5 p-0 text-xs flex items-center justify-center" > {syncStatus.pendingChanges} </Badge> )} </Button> + </div> </PopoverTrigger> <PopoverContent className="w-80"> diff --git a/lib/vendor-document-list/table/stage-revision-expanded-content.tsx b/lib/vendor-document-list/table/stage-revision-expanded-content.tsx index c2395aa8..d9d53cc9 100644 --- a/lib/vendor-document-list/table/stage-revision-expanded-content.tsx +++ b/lib/vendor-document-list/table/stage-revision-expanded-content.tsx @@ -66,6 +66,7 @@ const getStatusText = (status: string) => { case 'PLANNED': return '계획됨' case 'IN_PROGRESS': return '진행중' case 'SUBMITTED': return '제출됨' + case 'UPLOADED': return '등록됨' case 'UNDER_REVIEW': return '검토중' case 'APPROVED': return '승인됨' case 'REJECTED': return '반려됨' @@ -330,6 +331,8 @@ export const StageRevisionExpandedContent = ({ // 뷰에서 가져온 allStages 데이터를 바로 사용 const stagesWithRevisions = documentData.allStages || [] + console.log(stagesWithRevisions) + if (stagesWithRevisions.length === 0) { return ( <div className="p-6 text-center text-gray-500"> @@ -485,6 +488,7 @@ export const StageRevisionExpandedContent = ({ <TableHead className="w-16 py-1 px-2 text-xs">리비전</TableHead> <TableHead className="w-20 py-1 px-2 text-xs">상태</TableHead> <TableHead className="w-24 py-1 px-2 text-xs">업로더</TableHead> + <TableHead className="w-32 py-1 px-2 text-xs">등록일</TableHead> <TableHead className="w-32 py-1 px-2 text-xs">제출일</TableHead> <TableHead className="w-32 py-1 px-2 text-xs">승인/반려일</TableHead> <TableHead className="min-w-[120px] py-1 px-2 text-xs">첨부파일</TableHead> @@ -525,11 +529,17 @@ export const StageRevisionExpandedContent = ({ <span className="text-xs truncate max-w-[60px]">{revision.uploaderName || '-'}</span> </div> </TableCell> + {/* 제출일 */} + <TableCell className="py-1 px-2"> + <span className="text-xs text-gray-600"> + {revision.uploadedAt ? formatDate(revision.uploadedAt) : '-'} + </span> + </TableCell> {/* 제출일 */} <TableCell className="py-1 px-2"> <span className="text-xs text-gray-600"> - {revision.submittedDate ? formatDate(revision.submittedDate) : '-'} + {revision.externalSentDate ? formatDate(revision.externalSentDate) : '-'} </span> </TableCell> |
