summaryrefslogtreecommitdiff
path: root/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-11-04 10:15:32 +0900
committerjoonhoekim <26rote@gmail.com>2025-11-04 10:15:32 +0900
commit684cd304bf0ab1c2b0b72668fb4efd9f9892339d (patch)
tree4a8f787b396957684749ff58ad23774d69b34a10 /lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx
parent718b780e11459494c2f7f71bef76afdaabf20f32 (diff)
(김준회) dolce: B4 일괄업로드 UX 개선 (추가 업로드시 파일리스트 상태 유지, 프로젝트 우선 선택 강제, 프로젝트 변경시 이전 데이터 삭제 경고)
Diffstat (limited to 'lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx')
-rw-r--r--lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx153
1 files 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<ParsedFile[]>([])
const [isDragging, setIsDragging] = React.useState(false)
const [currentProjectId, setCurrentProjectId] = React.useState<string>("")
+ const [showProjectChangeWarning, setShowProjectChangeWarning] = React.useState(false)
+ const [pendingProjectId, setPendingProjectId] = React.useState<string>("")
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 (
- <Dialog open={open} onOpenChange={onOpenChange}>
+ <>
+ {/* 프로젝트 변경 경고 다이얼로그 */}
+ <AlertDialog open={showProjectChangeWarning} onOpenChange={setShowProjectChangeWarning}>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>프로젝트 변경 확인</AlertDialogTitle>
+ <AlertDialogDescription>
+ 프로젝트를 변경하면 현재 선택된 {parsedFiles.length}개의 파일이 모두 제거됩니다.
+ 계속하시겠습니까?
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel onClick={cancelProjectChange}>취소</AlertDialogCancel>
+ <AlertDialogAction onClick={confirmProjectChange}>확인</AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+
+ {/* 메인 업로드 다이얼로그 */}
+ <Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-3xl">
<DialogHeader>
<DialogTitle>B4 Document Bulk Upload</DialogTitle>
@@ -324,7 +367,11 @@ export function BulkB4UploadDialog({
render={({ field }) => (
<FormItem>
<FormLabel>Select Project *</FormLabel>
- <Select onValueChange={field.onChange} value={field.value}>
+ <Select
+ onValueChange={handleProjectChange}
+ value={field.value}
+ disabled={isUploading}
+ >
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Please select a project" />
@@ -347,14 +394,16 @@ export function BulkB4UploadDialog({
<FormLabel>Select Files</FormLabel>
<div
className={`border-2 border-dashed rounded-lg p-6 transition-all duration-200 ${
- isDragging
- ? 'border-primary bg-primary/5 scale-[1.02]'
- : 'border-muted-foreground/30 hover:border-muted-foreground/50'
+ !currentProjectId || isUploading
+ ? 'border-muted-foreground/20 opacity-50 cursor-not-allowed'
+ : isDragging
+ ? 'border-primary bg-primary/5 scale-[1.02]'
+ : 'border-muted-foreground/30 hover:border-muted-foreground/50'
}`}
- onDragEnter={handleDragEnter}
- onDragLeave={handleDragLeave}
- onDragOver={handleDragOver}
- onDrop={handleDrop}
+ onDragEnter={!currentProjectId || isUploading ? undefined : handleDragEnter}
+ onDragLeave={!currentProjectId || isUploading ? undefined : handleDragLeave}
+ onDragOver={!currentProjectId || isUploading ? undefined : handleDragOver}
+ onDrop={!currentProjectId || isUploading ? undefined : handleDrop}
>
<input
type="file"
@@ -363,12 +412,12 @@ export function BulkB4UploadDialog({
onChange={(e) => handleFilesChange(Array.from(e.target.files || []))}
className="hidden"
id="file-upload"
- disabled={isUploading}
+ disabled={!currentProjectId || isUploading}
/>
<label
htmlFor="file-upload"
className={`flex flex-col items-center justify-center ${
- isUploading ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'
+ !currentProjectId || isUploading ? 'cursor-not-allowed' : 'cursor-pointer'
}`}
>
<Upload className={`h-10 w-10 mb-2 transition-colors ${
@@ -377,7 +426,12 @@ export function BulkB4UploadDialog({
<p className={`text-sm transition-colors ${
isDragging ? 'text-primary font-medium' : 'text-muted-foreground'
}`}>
- {isDragging ? '파일을 여기에 놓으세요' : '클릭하거나 파일을 드래그하여 업로드'}
+ {!currentProjectId
+ ? '먼저 프로젝트를 선택해주세요'
+ : isDragging
+ ? '파일을 여기에 놓으세요'
+ : '클릭하거나 파일을 드래그하여 업로드'
+ }
</p>
<p className="text-xs text-muted-foreground mt-1">
PDF, DOC, DOCX, XLS, XLSX, DWG, DXF
@@ -498,5 +552,6 @@ export function BulkB4UploadDialog({
</Form>
</DialogContent>
</Dialog>
+ </>
)
} \ No newline at end of file