summaryrefslogtreecommitdiff
path: root/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx
diff options
context:
space:
mode:
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.tsx396
1 files changed, 200 insertions, 196 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
index ac7ee184..c5380140 100644
--- a/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx
+++ b/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx
@@ -1,197 +1,201 @@
-"use client"
-
-import * as React from "react"
-import { type Table } from "@tanstack/react-table"
-import { Download, FileSpreadsheet, 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"
-import { AddVendorDialog } from "./add-vendor-dialog"
-import { InviteTechVendorDialog } from "./invite-tech-vendor-dialog"
-
-interface TechVendorsTableToolbarActionsProps {
- table: Table<TechVendor>
- onRefresh?: () => void
-}
-
-export function TechVendorsTableToolbarActions({ table, onRefresh }: TechVendorsTableToolbarActionsProps) {
- const [isExporting, setIsExporting] = React.useState(false);
-
- // 선택된 모든 벤더 가져오기
- const selectedVendors = React.useMemo(() => {
- return table
- .getFilteredSelectedRowModel()
- .rows
- .map(row => row.original);
- }, [table.getFilteredSelectedRowModel().rows]);
-
- // 초대 가능한 벤더들 (PENDING_INVITE 상태 + 이메일 있음)
- const invitableVendors = React.useMemo(() => {
- return selectedVendors.filter(vendor =>
- vendor.status === "PENDING_INVITE" && vendor.email
- );
- }, [selectedVendors]);
-
- // 테이블의 모든 벤더 가져오기 (필터링된 결과)
- 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);
- }
- };
-
- // 벤더 추가 성공 시 테이블 새로고침을 위한 핸들러
- const handleVendorAddSuccess = () => {
- // 테이블 데이터 리프레시
- if (onRefresh) {
- onRefresh();
- } else {
- window.location.reload(); // 간단한 새로고침 방법
- }
- };
-
- return (
- <div className="flex items-center gap-2">
- {/* 초대 버튼 - 선택된 PENDING_REVIEW 벤더들이 있을 때만 표시 */}
- {invitableVendors.length > 0 && (
- <InviteTechVendorDialog
- vendors={invitableVendors}
- onSuccess={handleVendorAddSuccess}
- />
- )}
-
- {/* 벤더 추가 다이얼로그 추가 */}
- <AddVendorDialog onSuccess={handleVendorAddSuccess} />
-
- {/* 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>
- )
+"use client"
+
+import * as React from "react"
+import { type Table } from "@tanstack/react-table"
+import { Download, FileSpreadsheet, 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 { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
+
+// import { exportVendorsWithRelatedData } from "./vendor-all-export"
+import { TechVendor } from "@/db/schema/techVendors"
+import { ImportTechVendorButton } from "./import-button"
+import { exportTechVendorTemplate } from "./excel-template-download"
+import { AddVendorDialog } from "./add-vendor-dialog"
+import { InviteTechVendorDialog } from "./invite-tech-vendor-dialog"
+
+interface TechVendorsTableToolbarActionsProps {
+ table: Table<TechVendor>
+ onRefresh?: () => void
+}
+
+export function TechVendorsTableToolbarActions({
+ table,
+ onRefresh
+}: TechVendorsTableToolbarActionsProps) {
+ const [isExporting, setIsExporting] = React.useState(false);
+
+ // 선택된 모든 벤더 가져오기
+ const selectedVendors = React.useMemo(() => {
+ return table
+ .getFilteredSelectedRowModel()
+ .rows
+ .map(row => row.original);
+ }, [table.getFilteredSelectedRowModel().rows]);
+
+ // 초대 가능한 벤더들 (PENDING_INVITE 상태 + 이메일 있음)
+ const invitableVendors = React.useMemo(() => {
+ return selectedVendors.filter(vendor =>
+ vendor.status === "PENDING_INVITE" && vendor.email
+ );
+ }, [selectedVendors]);
+
+ // // 테이블의 모든 벤더 가져오기 (필터링된 결과)
+ // 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);
+ // }
+ // };
+
+ // 벤더 추가 성공 시 테이블 새로고침을 위한 핸들러
+ const handleVendorAddSuccess = () => {
+ // 테이블 데이터 리프레시
+ if (onRefresh) {
+ onRefresh();
+ } else {
+ window.location.reload(); // 간단한 새로고침 방법
+ }
+ };
+
+ return (
+ <div className="flex items-center gap-2">
+ {/* 초대 버튼 - 선택된 PENDING_REVIEW 벤더들이 있을 때만 표시 */}
+ {invitableVendors.length > 0 && (
+ <InviteTechVendorDialog
+ vendors={invitableVendors}
+ onSuccess={handleVendorAddSuccess}
+ />
+ )}
+
+ {/* 벤더 추가 다이얼로그 추가 */}
+ <AddVendorDialog onSuccess={handleVendorAddSuccess} />
+
+ {/* 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