summaryrefslogtreecommitdiff
path: root/lib/approval-template/table/approval-template-table-toolbar-actions.tsx
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-08-11 09:34:40 +0000
committerjoonhoekim <26rote@gmail.com>2025-08-11 09:34:40 +0000
commitbcd462d6e60871b86008e072f4b914138fc5c328 (patch)
treec22876fd6c6e7e48254587848b9dff50cdb8b032 /lib/approval-template/table/approval-template-table-toolbar-actions.tsx
parentcbb4c7fe0b94459162ad5e998bc05cd293e0ff96 (diff)
(김준회) 리치텍스트에디터 (결재템플릿을 위한 공통컴포넌트), command-menu 에러 수정, 결재 템플릿 관리, 결재선 관리, ECC RFQ+PR Item 수신시 비즈니스테이블(ProcurementRFQ) 데이터 적재, WSDL 오류 수정
Diffstat (limited to 'lib/approval-template/table/approval-template-table-toolbar-actions.tsx')
-rw-r--r--lib/approval-template/table/approval-template-table-toolbar-actions.tsx114
1 files changed, 114 insertions, 0 deletions
diff --git a/lib/approval-template/table/approval-template-table-toolbar-actions.tsx b/lib/approval-template/table/approval-template-table-toolbar-actions.tsx
new file mode 100644
index 00000000..08aba97a
--- /dev/null
+++ b/lib/approval-template/table/approval-template-table-toolbar-actions.tsx
@@ -0,0 +1,114 @@
+"use client"
+
+import * as React from "react"
+import { type Table } from "@tanstack/react-table"
+import { Download, Plus, Trash } from "lucide-react"
+
+import { Button } from "@/components/ui/button"
+import { type ApprovalTemplate } from "@/lib/approval-template/service"
+import { toast } from "sonner"
+import { DeleteApprovalTemplateDialog } from "./delete-approval-template-dialog"
+
+interface ApprovalTemplateTableToolbarActionsProps {
+ table: Table<ApprovalTemplate>
+ onCreateTemplate: () => void
+}
+
+export function ApprovalTemplateTableToolbarActions({
+ table,
+ onCreateTemplate,
+}: ApprovalTemplateTableToolbarActionsProps) {
+ const [showDeleteDialog, setShowDeleteDialog] = React.useState(false)
+
+ const selectedRows = table.getFilteredSelectedRowModel().rows
+ const selectedTemplates = selectedRows.map((row) => row.original)
+
+ // CSV 내보내기
+ const exportToCsv = React.useCallback(() => {
+ const headers = [
+ "이름",
+ "제목",
+ "카테고리",
+ "생성일",
+ "수정일",
+ ]
+
+ const csvData = [
+ headers,
+ ...table.getFilteredRowModel().rows.map((row) => {
+ const t = row.original
+ return [
+ t.name,
+ t.subject,
+ t.category ?? "-",
+ new Date(t.createdAt).toLocaleDateString("ko-KR"),
+ new Date(t.updatedAt).toLocaleDateString("ko-KR"),
+ ]
+ }),
+ ]
+
+ const csvContent = csvData
+ .map((row) => row.map((field) => `"${field}"`).join(","))
+ .join("\n")
+
+ const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" })
+ const link = document.createElement("a")
+
+ if (link.download !== undefined) {
+ const url = URL.createObjectURL(blob)
+ link.setAttribute("href", url)
+ link.setAttribute(
+ "download",
+ `approval_templates_${new Date().toISOString().split("T")[0]}.csv`,
+ )
+ link.style.visibility = "hidden"
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ }
+
+ toast.success("템플릿 목록이 CSV로 내보내졌습니다.")
+ }, [table])
+
+ return (
+ <div className="flex items-center gap-2">
+ {/* 새 템플릿 버튼 */}
+ <Button variant="default" size="sm" onClick={onCreateTemplate}>
+ <Plus className="mr-2 size-4" aria-hidden="true" />
+ 새 템플릿
+ </Button>
+
+ {/* CSV 내보내기 */}
+ <Button variant="outline" size="sm" onClick={exportToCsv}>
+ <Download className="mr-2 size-4" aria-hidden="true" />
+ 내보내기
+ </Button>
+
+ {/* 일괄 삭제 */}
+ {selectedTemplates.length > 0 && (
+ <>
+ <Button
+ variant="outline"
+ size="sm"
+ onClick={() => setShowDeleteDialog(true)}
+ className="text-destructive hover:text-destructive"
+ >
+ <Trash className="mr-2 size-4" aria-hidden="true" />
+ 삭제 ({selectedTemplates.length})
+ </Button>
+
+ <DeleteApprovalTemplateDialog
+ open={showDeleteDialog}
+ onOpenChange={setShowDeleteDialog}
+ templates={selectedTemplates}
+ showTrigger={false}
+ onSuccess={() => {
+ table.toggleAllRowsSelected(false)
+ setShowDeleteDialog(false)
+ }}
+ />
+ </>
+ )}
+ </div>
+ )
+}