diff options
| -rw-r--r-- | app/[lng]/partners/(partners)/dolce-upload-v3/dolce-upload-page-v3.tsx | 7 | ||||
| -rw-r--r-- | lib/dolce/dialogs/detail-drawing-dialog.tsx | 6 | ||||
| -rw-r--r-- | lib/dolce/table/file-list-columns.tsx | 14 |
3 files changed, 23 insertions, 4 deletions
diff --git a/app/[lng]/partners/(partners)/dolce-upload-v3/dolce-upload-page-v3.tsx b/app/[lng]/partners/(partners)/dolce-upload-v3/dolce-upload-page-v3.tsx index 513cfe1e..55bedb38 100644 --- a/app/[lng]/partners/(partners)/dolce-upload-v3/dolce-upload-page-v3.tsx +++ b/app/[lng]/partners/(partners)/dolce-upload-v3/dolce-upload-page-v3.tsx @@ -85,6 +85,7 @@ export default function DolceUploadPageV3({ searchParams }: DolceUploadPageV3Pro const [files, setFiles] = useState<FileInfoItem[]>([]); const [isLoadingDetails, setIsLoadingDetails] = useState(false); const [, setIsLoadingFiles] = useState(false); + const [downloadingFileId, setDownloadingFileId] = useState<string | null>(null); // 다이얼로그 상태 const [bulkUploadDialogOpen, setBulkUploadDialogOpen] = useState(false); @@ -311,6 +312,7 @@ export default function DolceUploadPageV3({ searchParams }: DolceUploadPageV3Pro const handleDownload = async (file: FileInfoItem) => { try { + setDownloadingFileId(file.FileId); toast.info(t("detailDialog.downloadPreparing")); const response = await fetch("/api/dolce/download", { method: "POST", @@ -337,6 +339,8 @@ export default function DolceUploadPageV3({ searchParams }: DolceUploadPageV3Pro } catch (error) { console.error("파일 다운로드 실패:", error); toast.error(t("detailDialog.downloadError")); + } finally { + setDownloadingFileId(null); } }; @@ -375,7 +379,8 @@ export default function DolceUploadPageV3({ searchParams }: DolceUploadPageV3Pro const fileColumns = createFileListColumns({ onDownload: handleDownload, onDelete: handleDeleteFile, - lng + lng, + downloadingFileId }); if (isLoading) { diff --git a/lib/dolce/dialogs/detail-drawing-dialog.tsx b/lib/dolce/dialogs/detail-drawing-dialog.tsx index afe4a4c2..99154296 100644 --- a/lib/dolce/dialogs/detail-drawing-dialog.tsx +++ b/lib/dolce/dialogs/detail-drawing-dialog.tsx @@ -59,6 +59,7 @@ export function DetailDrawingDialog({ const [editDialogOpen, setEditDialogOpen] = useState(false); const [editingDetailDrawing, setEditingDetailDrawing] = useState<DetailDwgReceiptItem | null>(null); const [uploadFilesDialogOpen, setUploadFilesDialogOpen] = useState(false); + const [downloadingFileId, setDownloadingFileId] = useState<string | null>(null); // 상세도면 목록 로드 const loadDetailDrawings = useCallback(async () => { @@ -126,6 +127,7 @@ export function DetailDrawingDialog({ const handleDownload = async (file: FileInfoItem) => { try { + setDownloadingFileId(file.FileId); toast.info(t("detailDialog.downloadPreparing")); // 파일 생성자의 userId를 사용하여 다운로드 @@ -159,6 +161,8 @@ export function DetailDrawingDialog({ } catch (error) { console.error("파일 다운로드 실패:", error); toast.error(t("detailDialog.downloadError")); + } finally { + setDownloadingFileId(null); } }; @@ -187,7 +191,7 @@ export function DetailDrawingDialog({ loadFiles(); }; - const fileColumns = createFileListColumns({ onDownload: handleDownload, lng }); + const fileColumns = createFileListColumns({ onDownload: handleDownload, lng, downloadingFileId }); // RegisterId + UploadId 조합으로 고유 ID 생성 const getDetailDrawingId = (detail: DetailDwgReceiptItem) => { diff --git a/lib/dolce/table/file-list-columns.tsx b/lib/dolce/table/file-list-columns.tsx index 38b1f1c9..3018e240 100644 --- a/lib/dolce/table/file-list-columns.tsx +++ b/lib/dolce/table/file-list-columns.tsx @@ -3,19 +3,21 @@ import { ColumnDef } from "@tanstack/react-table"; import { FileInfoItem } from "../actions"; import { Button } from "@/components/ui/button"; -import { Download, Trash2 } from "lucide-react"; +import { Download, Trash2, Loader2 } from "lucide-react"; import { formatDolceDateTime } from "../utils/date-formatter"; interface FileListColumnsProps { onDownload: (file: FileInfoItem) => void; onDelete?: (file: FileInfoItem) => void; lng?: string; + downloadingFileId?: string | null; } export const createFileListColumns = ({ onDownload, onDelete, lng = "ko", + downloadingFileId, }: FileListColumnsProps): ColumnDef<FileInfoItem>[] => [ { accessorKey: "FileSeq", @@ -64,23 +66,31 @@ export const createFileListColumns = ({ minSize: 160, cell: ({ row }) => { const isLocal = row.original.FileServerId === "LOCAL"; + const isDownloading = downloadingFileId === row.original.FileId; + return ( <div className="flex gap-2 items-center justify-center"> <Button variant="outline" size="sm" + disabled={isDownloading} onClick={(e) => { e.stopPropagation(); onDownload(row.original); }} > - <Download className="h-4 w-4 mr-2" /> + {isDownloading ? ( + <Loader2 className="h-4 w-4 mr-2 animate-spin" /> + ) : ( + <Download className="h-4 w-4 mr-2" /> + )} {lng === "ko" ? "다운로드" : "Download"} </Button> {isLocal && onDelete && ( <Button variant="destructive" size="sm" + disabled={isDownloading} onClick={(e) => { e.stopPropagation(); onDelete(row.original); |
