diff options
Diffstat (limited to 'lib/welding/table/ocr-table-toolbar-actions.tsx')
| -rw-r--r-- | lib/welding/table/ocr-table-toolbar-actions.tsx | 128 |
1 files changed, 100 insertions, 28 deletions
diff --git a/lib/welding/table/ocr-table-toolbar-actions.tsx b/lib/welding/table/ocr-table-toolbar-actions.tsx index 6c6d0637..120ff54f 100644 --- a/lib/welding/table/ocr-table-toolbar-actions.tsx +++ b/lib/welding/table/ocr-table-toolbar-actions.tsx @@ -2,9 +2,8 @@ import * as React from "react" import { type Table } from "@tanstack/react-table" -import { Download, RefreshCcw, Upload, FileText, Loader2 } from "lucide-react" +import { Download, RefreshCcw, Upload, FileText, Loader2, ChevronDown } from "lucide-react" -import { exportTableToExcel } from "@/lib/export" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" @@ -20,6 +19,16 @@ import { Progress } from "@/components/ui/progress" import { Badge } from "@/components/ui/badge" import { toast } from "sonner" import { OcrRow } from "@/db/schema" +import { exportTableToExcel } from "@/lib/export_all" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { getOcrAllRows } from "../service" +import { exportOcrDataToExcel } from "./exporft-ocr-data" interface OcrTableToolbarActionsProps { table: Table<OcrRow> @@ -38,6 +47,7 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { const [isUploadDialogOpen, setIsUploadDialogOpen] = React.useState(false) const [selectedFile, setSelectedFile] = React.useState<File | null>(null) const fileInputRef = React.useRef<HTMLInputElement>(null) + const [isExporting, setIsExporting] = React.useState(false) // 다이얼로그 닫기 핸들러 - 업로드 중에는 닫기 방지 const handleDialogOpenChange = (open: boolean) => { @@ -50,11 +60,11 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { }) return // 다이얼로그를 닫지 않음 } - + // 업로드가 진행 중이 아니거나 완료되었으면 초기화 후 닫기 resetUpload() } - + setIsUploadDialogOpen(open) } @@ -75,12 +85,12 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { const allowedTypes = [ 'application/pdf', 'image/jpeg', - 'image/jpg', + 'image/jpg', 'image/png', 'image/tiff', 'image/bmp' ] - + if (!allowedTypes.includes(file.type)) { return "Only PDF and image files (JPG, PNG, TIFF, BMP) are supported" } @@ -151,8 +161,8 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { toast.success( `OCR completed! Extracted ${result.metadata.totalRows} rows from ${result.metadata.totalTables} tables`, { - description: result.warnings?.length - ? `Warnings: ${result.warnings.join(', ')}` + description: result.warnings?.length + ? `Warnings: ${result.warnings.join(', ')}` : undefined } ) @@ -161,7 +171,7 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { setTimeout(() => { setIsUploadDialogOpen(false) resetUpload() - + // 테이블 새로고침 window.location.reload() }, 2000) @@ -205,6 +215,50 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { } } + // 현재 페이지 데이터만 내보내기 + const exportCurrentPage = () => { + exportTableToExcel(table, { + filename: "OCR Result (Current Page)", + excludeColumns: ["select", "actions"], + }) + } + + // 전체 데이터 내보내기 + const exportAllData = async () => { + if (isExporting) return + + setIsExporting(true) + + try { + toast.loading("전체 데이터를 가져오는 중...", { + description: "잠시만 기다려주세요." + }) + + // 모든 데이터 가져오기 + const allData = await getOcrAllRows() + + toast.dismiss() + + if (allData.length === 0) { + toast.warning("내보낼 데이터가 없습니다.") + return + } + + console.log(allData) + + // 새로운 단순한 export 함수 사용 + await exportOcrDataToExcel(allData, `OCR Result (All Data - ${allData.length} rows)`) + + toast.success(`전체 데이터 ${allData.length}개 행이 성공적으로 내보내졌습니다.`) + + } catch (error) { + console.error('Error exporting all data:', error) + toast.error('전체 데이터 내보내기 중 오류가 발생했습니다.') + } finally { + setIsExporting(false) + } + } + return ( <div className="flex items-center gap-2"> {/* OCR 업로드 다이얼로그 */} @@ -215,7 +269,7 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { <span className="hidden sm:inline">Upload OCR</span> </Button> </DialogTrigger> - <DialogContent + <DialogContent className="sm:max-w-md" // 업로드 중에는 ESC 키로도 닫기 방지 onEscapeKeyDown={(e) => { @@ -241,13 +295,13 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { )} </DialogTitle> <DialogDescription> - {isUploading && uploadProgress?.stage !== "complete" + {isUploading && uploadProgress?.stage !== "complete" ? "Processing in progress. Please do not close this dialog." : "Upload a PDF or image file to extract table data using OCR technology." } </DialogDescription> </DialogHeader> - + <div className="space-y-4"> {/* 파일 선택 */} <div className="space-y-2"> @@ -292,7 +346,7 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { <p className="text-xs text-muted-foreground"> {uploadProgress.message} </p> - + {/* 진행 중일 때 안내 메시지 */} {isUploading && uploadProgress.stage !== "complete" && ( <div className="flex items-center gap-2 p-2 bg-blue-50 dark:bg-blue-950/20 rounded-md"> @@ -332,22 +386,40 @@ export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) { </div> </DialogContent> </Dialog> - + {/* Export 버튼 */} - <Button - variant="outline" - size="sm" - onClick={() => - exportTableToExcel(table, { - filename: "OCR Result", - excludeColumns: ["select", "actions"], - }) - } - className="gap-2" - > - <Download className="size-4" aria-hidden="true" /> - <span className="hidden sm:inline">Export</span> - </Button> + {/* Export 드롭다운 메뉴 */} + <DropdownMenu> + <DropdownMenuTrigger asChild> + <Button + variant="outline" + size="sm" + className="gap-2" + disabled={isExporting} + > + {isExporting ? ( + <Loader2 className="size-4 animate-spin" aria-hidden="true" /> + ) : ( + <Download className="size-4" aria-hidden="true" /> + )} + <span className="hidden sm:inline"> + {isExporting ? "Exporting..." : "Export"} + </span> + <ChevronDown className="size-3" aria-hidden="true" /> + </Button> + </DropdownMenuTrigger> + <DropdownMenuContent align="end" className="w-[200px]"> + <DropdownMenuItem onClick={exportAllData} disabled={isExporting}> + <Download className="mr-2 size-4" /> + 전체 데이터 내보내기 + </DropdownMenuItem> + <DropdownMenuSeparator /> + <DropdownMenuItem onClick={exportCurrentPage} disabled={isExporting}> + <Download className="mr-2 size-4" /> + 현재 페이지 내보내기 + </DropdownMenuItem> + </DropdownMenuContent> + </DropdownMenu> </div> ) }
\ No newline at end of file |
