From 684cd304bf0ab1c2b0b72668fb4efd9f9892339d Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Tue, 4 Nov 2025 10:15:32 +0900 Subject: (김준회) dolce: B4 일괄업로드 UX 개선 (추가 업로드시 파일리스트 상태 유지, 프로젝트 우선 선택 강제, 프로젝트 변경시 이전 데이터 삭제 경고) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ship/bulk-b4-upload-dialog.tsx | 153 ++++++++++++++------- 1 file changed, 104 insertions(+), 49 deletions(-) diff --git a/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx b/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx index 44f9c801..43788c8a 100644 --- a/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx +++ b/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx @@ -15,6 +15,16 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog" +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "@/components/ui/alert-dialog" import { Button } from "@/components/ui/button" import { Form, @@ -107,6 +117,8 @@ export function BulkB4UploadDialog({ const [parsedFiles, setParsedFiles] = React.useState([]) const [isDragging, setIsDragging] = React.useState(false) const [currentProjectId, setCurrentProjectId] = React.useState("") + const [showProjectChangeWarning, setShowProjectChangeWarning] = React.useState(false) + const [pendingProjectId, setPendingProjectId] = React.useState("") const router = useRouter() // 프로젝트 ID 추출 @@ -126,47 +138,57 @@ export function BulkB4UploadDialog({ }, }) + // 프로젝트 변경 핸들러 + const handleProjectChange = (newProjectId: string) => { + // 기존 파일 목록이 있고, 다른 프로젝트로 변경하는 경우 경고 표시 + if (parsedFiles.length > 0 && currentProjectId && currentProjectId !== newProjectId) { + setPendingProjectId(newProjectId) + setShowProjectChangeWarning(true) + } else { + // 파일 목록이 비어있거나 첫 선택인 경우 바로 변경 + setCurrentProjectId(newProjectId) + form.setValue("projectId", newProjectId) + } + } + + // 프로젝트 변경 확인 처리 + const confirmProjectChange = () => { + // 파일 목록 초기화하고 프로젝트 변경 + setParsedFiles([]) + form.setValue("files", []) + setCurrentProjectId(pendingProjectId) + form.setValue("projectId", pendingProjectId) + setShowProjectChangeWarning(false) + setPendingProjectId("") + } + + // 프로젝트 변경 취소 처리 + const cancelProjectChange = () => { + setShowProjectChangeWarning(false) + setPendingProjectId("") + } + // 파일 선택 시 파싱 const handleFilesChange = (files: File[]) => { - const currentProject = form.watch("projectId") - - // 프로젝트가 변경되었거나 처음 선택하는 경우 - if (!currentProject || currentProject !== currentProjectId) { - setCurrentProjectId(currentProject) - const parsed = files.map(file => { - const { docNumber, revision } = parseFileName(file.name) - return { - file, - docNumber, - revision, - status: docNumber ? 'pending' as const : 'ignored' as const, - message: !docNumber ? 'docNumber를 찾을 수 없음' : undefined - } - }) - setParsedFiles(parsed) - form.setValue("files", files) - } else { - // 같은 프로젝트에서 파일 추가하는 경우 - const parsed = files.map(file => { - const { docNumber, revision } = parseFileName(file.name) - return { - file, - docNumber, - revision, - status: docNumber ? 'pending' as const : 'ignored' as const, - message: !docNumber ? 'docNumber를 찾을 수 없음' : undefined - } - }) + const parsed = files.map(file => { + const { docNumber, revision } = parseFileName(file.name) + return { + file, + docNumber, + revision, + status: docNumber ? 'pending' as const : 'ignored' as const, + message: !docNumber ? 'docNumber를 찾을 수 없음' : undefined + } + }) - // 기존 파일들과 새 파일들을 합침 (중복 파일명은 새 것으로 대체) - const existingFileNames = new Set(parsedFiles.map(pf => pf.file.name)) - const newFiles = parsed.filter(pf => !existingFileNames.has(pf.file.name)) - const combinedParsed = [...parsedFiles, ...newFiles] - const combinedFiles = [...parsedFiles.map(pf => pf.file), ...newFiles.map(pf => pf.file)] + // 기존 파일들과 새 파일들을 합침 (중복 파일명은 제외) + const existingFileNames = new Set(parsedFiles.map(pf => pf.file.name)) + const newFiles = parsed.filter(pf => !existingFileNames.has(pf.file.name)) + const combinedParsed = [...parsedFiles, ...newFiles] + const combinedFiles = [...parsedFiles.map(pf => pf.file), ...newFiles.map(pf => pf.file)] - setParsedFiles(combinedParsed) - form.setValue("files", combinedFiles) - } + setParsedFiles(combinedParsed) + form.setValue("files", combinedFiles) } // 파일 제거 @@ -296,6 +318,8 @@ export function BulkB4UploadDialog({ setParsedFiles([]) setIsDragging(false) setCurrentProjectId("") + setShowProjectChangeWarning(false) + setPendingProjectId("") } }, [open, form]) @@ -303,7 +327,26 @@ export function BulkB4UploadDialog({ const ignoredFileCount = parsedFiles.filter(pf => !pf.docNumber).length return ( - + <> + {/* 프로젝트 변경 경고 다이얼로그 */} + + + + 프로젝트 변경 확인 + + 프로젝트를 변경하면 현재 선택된 {parsedFiles.length}개의 파일이 모두 제거됩니다. + 계속하시겠습니까? + + + + 취소 + 확인 + + + + + {/* 메인 업로드 다이얼로그 */} + B4 Document Bulk Upload @@ -324,7 +367,11 @@ export function BulkB4UploadDialog({ render={({ field }) => ( Select Project * - @@ -347,14 +394,16 @@ export function BulkB4UploadDialog({ Select Files
handleFilesChange(Array.from(e.target.files || []))} className="hidden" id="file-upload" - disabled={isUploading} + disabled={!currentProjectId || isUploading} />
+ ) } \ No newline at end of file -- cgit v1.2.3