diff options
Diffstat (limited to 'lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx')
| -rw-r--r-- | lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx b/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx new file mode 100644 index 00000000..82383a3a --- /dev/null +++ b/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx @@ -0,0 +1,166 @@ +"use client" + +import * as React from "react" +import { type Table } from "@tanstack/react-table" +import { Download, FileSpreadsheet, Upload, Check, BuildingIcon, FileText } from "lucide-react" +import { toast } from "sonner" + +import { exportTableToExcel } from "@/lib/export" +import { Button } from "@/components/ui/button" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" + +import { exportVendorsWithRelatedData } from "./vendor-all-export" +import { TechVendor } from "@/db/schema/techVendors" +import { ImportTechVendorButton } from "./import-button" +import { exportTechVendorTemplate } from "./excel-template-download" + +interface TechVendorsTableToolbarActionsProps { + table: Table<TechVendor> +} + +export function TechVendorsTableToolbarActions({ table }: TechVendorsTableToolbarActionsProps) { + const [isExporting, setIsExporting] = React.useState(false); + + // 선택된 모든 벤더 가져오기 + const selectedVendors = React.useMemo(() => { + return table + .getFilteredSelectedRowModel() + .rows + .map(row => row.original); + }, [table.getFilteredSelectedRowModel().rows]); + + // 테이블의 모든 벤더 가져오기 (필터링된 결과) + const allFilteredVendors = React.useMemo(() => { + return table + .getFilteredRowModel() + .rows + .map(row => row.original); + }, [table.getFilteredRowModel().rows]); + + // 선택된 벤더 통합 내보내기 함수 실행 + const handleSelectedExport = async () => { + if (selectedVendors.length === 0) { + toast.warning("내보낼 협력업체를 선택해주세요."); + return; + } + + try { + setIsExporting(true); + toast.info(`선택된 ${selectedVendors.length}개 업체의 정보를 내보내는 중입니다...`); + await exportVendorsWithRelatedData(selectedVendors, "selected-vendors-detailed"); + toast.success(`${selectedVendors.length}개 업체 정보 내보내기가 완료되었습니다.`); + } catch (error) { + console.error("상세 정보 내보내기 오류:", error); + toast.error("상세 정보 내보내기 중 오류가 발생했습니다."); + } finally { + setIsExporting(false); + } + }; + + // 모든 벤더 통합 내보내기 함수 실행 + const handleAllFilteredExport = async () => { + if (allFilteredVendors.length === 0) { + toast.warning("내보낼 협력업체가 없습니다."); + return; + } + + try { + setIsExporting(true); + toast.info(`총 ${allFilteredVendors.length}개 업체의 정보를 내보내는 중입니다...`); + await exportVendorsWithRelatedData(allFilteredVendors, "all-vendors-detailed"); + toast.success(`${allFilteredVendors.length}개 업체 정보 내보내기가 완료되었습니다.`); + } catch (error) { + console.error("상세 정보 내보내기 오류:", error); + toast.error("상세 정보 내보내기 중 오류가 발생했습니다."); + } finally { + setIsExporting(false); + } + }; + + return ( + <div className="flex items-center gap-2"> + {/* Import 버튼 추가 */} + <ImportTechVendorButton + onSuccess={() => { + // 성공 시 테이블 새로고침 + toast.success("업체 정보 가져오기가 완료되었습니다."); + }} + /> + + {/* Export 드롭다운 메뉴로 변경 */} + <DropdownMenu> + <DropdownMenuTrigger asChild> + <Button + variant="outline" + size="sm" + className="gap-2" + disabled={isExporting} + > + <Download className="size-4" aria-hidden="true" /> + <span className="hidden sm:inline"> + {isExporting ? "내보내는 중..." : "Export"} + </span> + </Button> + </DropdownMenuTrigger> + <DropdownMenuContent align="end"> + {/* 템플릿 다운로드 추가 */} + <DropdownMenuItem + onClick={() => exportTechVendorTemplate()} + disabled={isExporting} + > + <FileText className="mr-2 size-4" /> + <span>Excel 템플릿 다운로드</span> + </DropdownMenuItem> + + <DropdownMenuSeparator /> + + {/* 기본 내보내기 - 현재 테이블에 보이는 데이터만 */} + <DropdownMenuItem + onClick={() => + exportTableToExcel(table, { + filename: "vendors", + excludeColumns: ["select", "actions"], + }) + } + disabled={isExporting} + > + <FileText className="mr-2 size-4" /> + <span>현재 테이블 데이터 내보내기</span> + </DropdownMenuItem> + + <DropdownMenuSeparator /> + + {/* 선택된 벤더만 상세 내보내기 */} + <DropdownMenuItem + onClick={handleSelectedExport} + disabled={selectedVendors.length === 0 || isExporting} + > + <FileSpreadsheet className="mr-2 size-4" /> + <span>선택한 업체 상세 정보 내보내기</span> + {selectedVendors.length > 0 && ( + <span className="ml-1 text-xs text-muted-foreground">({selectedVendors.length}개)</span> + )} + </DropdownMenuItem> + + {/* 모든 필터링된 벤더 상세 내보내기 */} + <DropdownMenuItem + onClick={handleAllFilteredExport} + disabled={allFilteredVendors.length === 0 || isExporting} + > + <Download className="mr-2 size-4" /> + <span>모든 업체 상세 정보 내보내기</span> + {allFilteredVendors.length > 0 && ( + <span className="ml-1 text-xs text-muted-foreground">({allFilteredVendors.length}개)</span> + )} + </DropdownMenuItem> + </DropdownMenuContent> + </DropdownMenu> + </div> + ) +}
\ No newline at end of file |
