diff options
Diffstat (limited to 'lib/vendor-document-list')
| -rw-r--r-- | lib/vendor-document-list/ship/import-from-dolce-button.tsx | 188 |
1 files changed, 143 insertions, 45 deletions
diff --git a/lib/vendor-document-list/ship/import-from-dolce-button.tsx b/lib/vendor-document-list/ship/import-from-dolce-button.tsx index fe7f55c7..76d66960 100644 --- a/lib/vendor-document-list/ship/import-from-dolce-button.tsx +++ b/lib/vendor-document-list/ship/import-from-dolce-button.tsx @@ -1,4 +1,4 @@ -// import-from-dolce-button.tsx - 최적화된 버전 +// import-from-dolce-button.tsx - 리비전/첨부파일 포함 버전 "use client" import * as React from "react" @@ -223,20 +223,30 @@ export function ImportFromDOLCEButton({ } }, [debouncedProjectIds, fetchAllImportStatus]) - - - // 🔥 전체 통계 메모이제이션 + // 🔥 전체 통계 메모이제이션 - 리비전과 첨부파일 추가 const totalStats = React.useMemo(() => { const statuses = Array.from(importStatusMap.values()) return statuses.reduce((acc, status) => ({ availableDocuments: acc.availableDocuments + (status.availableDocuments || 0), newDocuments: acc.newDocuments + (status.newDocuments || 0), updatedDocuments: acc.updatedDocuments + (status.updatedDocuments || 0), + availableRevisions: acc.availableRevisions + (status.availableRevisions || 0), + newRevisions: acc.newRevisions + (status.newRevisions || 0), + updatedRevisions: acc.updatedRevisions + (status.updatedRevisions || 0), + availableAttachments: acc.availableAttachments + (status.availableAttachments || 0), + newAttachments: acc.newAttachments + (status.newAttachments || 0), + updatedAttachments: acc.updatedAttachments + (status.updatedAttachments || 0), importEnabled: acc.importEnabled || status.importEnabled }), { availableDocuments: 0, newDocuments: 0, updatedDocuments: 0, + availableRevisions: 0, + newRevisions: 0, + updatedRevisions: 0, + availableAttachments: 0, + newAttachments: 0, + updatedAttachments: 0, importEnabled: false }) }, [importStatusMap]) @@ -347,7 +357,14 @@ export function ImportFromDOLCEButton({ } }, [projectIds, fetchAllImportStatus, onImportComplete, t]) - // 🔥 상태 뱃지 메모이제이션 + // 🔥 전체 변경 사항 계산 + const totalChanges = React.useMemo(() => { + return totalStats.newDocuments + totalStats.updatedDocuments + + totalStats.newRevisions + totalStats.updatedRevisions + + totalStats.newAttachments + totalStats.updatedAttachments + }, [totalStats]) + + // 🔥 상태 뱃지 메모이제이션 - 리비전과 첨부파일 포함 const statusBadge = React.useMemo(() => { if (loadingVendorProjects) { return <Badge variant="secondary">{t('dolceImport.status.loadingProjectInfo')}</Badge> @@ -365,7 +382,7 @@ export function ImportFromDOLCEButton({ return <Badge variant="secondary">{t('dolceImport.status.importDisabled')}</Badge> } - if (totalStats.newDocuments > 0 || totalStats.updatedDocuments > 0) { + if (totalChanges > 0) { return ( <Badge variant="samsung" className="gap-1"> <AlertTriangle className="w-3 h-3" /> @@ -380,10 +397,10 @@ export function ImportFromDOLCEButton({ {t('dolceImport.status.synchronized')} </Badge> ) - }, [loadingVendorProjects, statusLoading, importStatusMap.size, totalStats, projectIds.length, t]) + }, [loadingVendorProjects, statusLoading, importStatusMap.size, totalStats.importEnabled, totalChanges, projectIds.length, t]) - const canImport = totalStats.importEnabled && - (totalStats.newDocuments > 0 || totalStats.updatedDocuments > 0) + // 🔥 가져오기 가능 여부 - 리비전과 첨부파일도 체크 + const canImport = totalStats.importEnabled && totalChanges > 0 // 🔥 새로고침 핸들러 최적화 const handleRefresh = React.useCallback(() => { @@ -391,24 +408,20 @@ export function ImportFromDOLCEButton({ fetchAllImportStatus() }, [fetchAllImportStatus]) - - // 🔥 자동 동기화 실행 (기존 useEffect들 다음에 추가) - React.useEffect(() => { + // 🔥 자동 동기화 실행 (기존 useEffect들 다음에 추가) + React.useEffect(() => { // 조건: 가져오기 가능하고, 동기화할 항목이 있고, 현재 진행중이 아닐 때 - if (canImport && - (totalStats.newDocuments > 0 || totalStats.updatedDocuments > 0) && - !isImporting && - !isDialogOpen) { + if (canImport && totalChanges > 0 && !isImporting && !isDialogOpen) { // 상태 로딩이 완료된 후 잠깐 대기 (사용자가 상태를 확인할 수 있도록) const timer = setTimeout(() => { - console.log(`🔄 자동 동기화 시작: 새 문서 ${totalStats.newDocuments}개, 업데이트 ${totalStats.updatedDocuments}개`) + console.log(`🔄 자동 동기화 시작: ${totalChanges}개 항목`) // 동기화 시작 알림 toast.info( - '새로운 문서가 발견되어 자동 동기화를 시작합니다', + '새로운 변경사항이 발견되어 자동 동기화를 시작합니다', { - description: `새 문서 ${totalStats.newDocuments}개, 업데이트 ${totalStats.updatedDocuments}개`, + description: `총 ${totalChanges}개 항목 (문서/리비전/첨부파일)`, duration: 3000 } ) @@ -424,9 +437,8 @@ export function ImportFromDOLCEButton({ return () => clearTimeout(timer) } - }, [canImport, totalStats.newDocuments, totalStats.updatedDocuments, isImporting, isDialogOpen, handleImport]) + }, [canImport, totalChanges, isImporting, isDialogOpen, handleImport]) - // 로딩 중이거나 projectIds가 없으면 버튼을 표시하지 않음 if (projectIds.length === 0) { return null @@ -449,12 +461,12 @@ export function ImportFromDOLCEButton({ <Download className="w-4 h-4" /> )} <span className="hidden sm:inline">{t('dolceImport.buttons.getList')}</span> - {totalStats.newDocuments + totalStats.updatedDocuments > 0 && ( + {totalChanges > 0 && ( <Badge variant="samsung" className="h-5 w-5 p-0 text-xs flex items-center justify-center" > - {totalStats.newDocuments + totalStats.updatedDocuments} + {totalChanges} </Badge> )} </Button> @@ -493,21 +505,75 @@ export function ImportFromDOLCEButton({ <div className="space-y-3"> <Separator /> - <div className="grid grid-cols-2 gap-4 text-sm"> - <div> - <div className="text-muted-foreground">{t('dolceImport.labels.newDocuments')}</div> - <div className="font-medium">{totalStats.newDocuments || 0}</div> - </div> - <div> - <div className="text-muted-foreground">{t('dolceImport.labels.updates')}</div> - <div className="font-medium">{totalStats.updatedDocuments || 0}</div> + {/* 문서 정보 */} + <div className="space-y-2"> + <div className="font-medium text-sm">{t('dolceImport.labels.documents')}</div> + <div className="grid grid-cols-3 gap-3 text-sm"> + <div> + <div className="text-muted-foreground">{t('dolceImport.labels.total')}</div> + <div className="font-medium">{totalStats.availableDocuments || 0}</div> + </div> + <div> + <div className="text-muted-foreground">{t('dolceImport.labels.new')}</div> + <div className="font-medium text-green-600">{totalStats.newDocuments || 0}</div> + </div> + <div> + <div className="text-muted-foreground">{t('dolceImport.labels.updates')}</div> + <div className="font-medium text-blue-600">{totalStats.updatedDocuments || 0}</div> + </div> </div> </div> - <div className="text-sm"> - <div className="text-muted-foreground">{t('dolceImport.labels.totalDocuments')}</div> - <div className="font-medium">{totalStats.availableDocuments || 0}</div> - </div> + {/* 리비전 정보 */} + {(totalStats.availableRevisions > 0 || totalStats.newRevisions > 0 || totalStats.updatedRevisions > 0) && ( + <div className="space-y-2"> + <div className="font-medium text-sm">{t('dolceImport.labels.revisions')}</div> + <div className="grid grid-cols-3 gap-3 text-sm"> + <div> + <div className="text-muted-foreground">{t('dolceImport.labels.total')}</div> + <div className="font-medium">{totalStats.availableRevisions || 0}</div> + </div> + <div> + <div className="text-muted-foreground">{t('dolceImport.labels.new')}</div> + <div className="font-medium text-green-600">{totalStats.newRevisions || 0}</div> + </div> + <div> + <div className="text-muted-foreground">{t('dolceImport.labels.updates')}</div> + <div className="font-medium text-blue-600">{totalStats.updatedRevisions || 0}</div> + </div> + </div> + </div> + )} + + {/* 첨부파일 정보 */} + {(totalStats.availableAttachments > 0 || totalStats.newAttachments > 0 || totalStats.updatedAttachments > 0) && ( + <div className="space-y-2"> + <div className="font-medium text-sm">{t('dolceImport.labels.attachments')}</div> + <div className="grid grid-cols-3 gap-3 text-sm"> + <div> + <div className="text-muted-foreground">{t('dolceImport.labels.total')}</div> + <div className="font-medium">{totalStats.availableAttachments || 0}</div> + </div> + <div> + <div className="text-muted-foreground">{t('dolceImport.labels.new')}</div> + <div className="font-medium text-green-600">{totalStats.newAttachments || 0}</div> + </div> + <div> + <div className="text-muted-foreground">{t('dolceImport.labels.updates')}</div> + <div className="font-medium text-blue-600">{totalStats.updatedAttachments || 0}</div> + </div> + </div> + </div> + )} + + {/* 요약 */} + {totalChanges > 0 && ( + <div className="bg-muted/50 rounded-lg p-3"> + <div className="text-sm font-medium"> + {t('dolceImport.labels.totalChanges')}: <span className="text-primary">{totalChanges}</span> + </div> + </div> + )} {/* 각 프로젝트별 세부 정보 */} {projectIds.length > 1 && ( @@ -522,11 +588,29 @@ export function ImportFromDOLCEButton({ <div key={projectId} className="text-xs"> <div className="font-medium">{t('dolceImport.labels.projectLabel', { projectId })}</div> {status ? ( - <div className="text-muted-foreground"> - {t('dolceImport.descriptions.projectDetails', { - newDocuments: status.newDocuments, - updatedDocuments: status.updatedDocuments - })} + <div className="text-muted-foreground space-y-1"> + <div> + {t('dolceImport.descriptions.projectDocuments', { + newDocuments: status.newDocuments, + updatedDocuments: status.updatedDocuments + })} + </div> + {(status.newRevisions > 0 || status.updatedRevisions > 0) && ( + <div> + {t('dolceImport.descriptions.projectRevisions', { + newRevisions: status.newRevisions, + updatedRevisions: status.updatedRevisions + })} + </div> + )} + {(status.newAttachments > 0 || status.updatedAttachments > 0) && ( + <div> + {t('dolceImport.descriptions.projectAttachments', { + newAttachments: status.newAttachments, + updatedAttachments: status.updatedAttachments + })} + </div> + )} </div> ) : ( <div className="text-destructive">{t('dolceImport.status.statusCheckFailed')}</div> @@ -595,14 +679,28 @@ export function ImportFromDOLCEButton({ <div className="rounded-lg border p-4 space-y-3"> <div className="flex items-center justify-between text-sm"> <span>{t('dolceImport.labels.itemsToImport')}</span> - <span className="font-medium"> - {totalStats.newDocuments + totalStats.updatedDocuments} - </span> + <span className="font-medium">{totalChanges}</span> + </div> + + <div className="space-y-1 text-xs text-muted-foreground"> + {totalStats.newDocuments + totalStats.updatedDocuments > 0 && ( + <div> + • {t('dolceImport.labels.documents')}: {totalStats.newDocuments} {t('dolceImport.labels.new')}, {totalStats.updatedDocuments} {t('dolceImport.labels.updates')} + </div> + )} + {totalStats.newRevisions + totalStats.updatedRevisions > 0 && ( + <div> + • {t('dolceImport.labels.revisions')}: {totalStats.newRevisions} {t('dolceImport.labels.new')}, {totalStats.updatedRevisions} {t('dolceImport.labels.updates')} + </div> + )} + {totalStats.newAttachments + totalStats.updatedAttachments > 0 && ( + <div> + • {t('dolceImport.labels.attachments')}: {totalStats.newAttachments} {t('dolceImport.labels.new')}, {totalStats.updatedAttachments} {t('dolceImport.labels.updates')} + </div> + )} </div> <div className="text-xs text-muted-foreground"> - {t('dolceImport.descriptions.includesNewAndUpdated')} - <br /> {t('dolceImport.descriptions.b4DocumentsNote')} {projectIds.length > 1 && ( <> |
