From 356929b399ef31a4de82906267df438cf29ea59d Mon Sep 17 00:00:00 2001
From: 0-Zz-ang <s1998319@gmail.com>
Date: Thu, 10 Jul 2025 15:56:13 +0900
Subject: 인터페이스 관련 파일 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../table/integration-table-columns.tsx            | 214 +++++++++++++++++++++
 1 file changed, 214 insertions(+)
 create mode 100644 lib/integration/table/integration-table-columns.tsx

(limited to 'lib/integration/table/integration-table-columns.tsx')

diff --git a/lib/integration/table/integration-table-columns.tsx b/lib/integration/table/integration-table-columns.tsx
new file mode 100644
index 00000000..330b7797
--- /dev/null
+++ b/lib/integration/table/integration-table-columns.tsx
@@ -0,0 +1,214 @@
+"use client"
+
+import { type DataTableRowAction } from "@/types/table"
+import { type ColumnDef } from "@tanstack/react-table"
+import { MoreHorizontal } from "lucide-react"
+
+import { Badge } from "@/components/ui/badge"
+import { Button } from "@/components/ui/button"
+import {
+  DropdownMenu,
+  DropdownMenuContent,
+  DropdownMenuItem,
+  DropdownMenuSeparator,
+  DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import { integrations } from "@/db/schema/integration"
+
+interface GetColumnsProps {
+  setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<typeof integrations.$inferSelect> | null>>;
+}
+
+/**
+ * tanstack table 컬럼 정의
+ */
+export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<typeof integrations.$inferSelect>[] {
+  // ----------------------------------------------------------------
+  // 1) select 컬럼 (체크박스)
+  // ----------------------------------------------------------------
+  const selectColumn: ColumnDef<typeof integrations.$inferSelect> = {
+    id: "select",
+    header: ({ table }) => (
+      <input
+        type="checkbox"
+        checked={table.getIsAllPageRowsSelected()}
+        onChange={(value) => table.toggleAllPageRowsSelected(!!value.target.checked)}
+        aria-label="Select all"
+        className="translate-y-[2px]"
+      />
+    ),
+    cell: ({ row }) => (
+      <input
+        type="checkbox"
+        checked={row.getIsSelected()}
+        onChange={(value) => row.toggleSelected(!!value.target.checked)}
+        aria-label="Select row"
+        className="translate-y-[2px]"
+      />
+    ),
+    enableSorting: false,
+    enableHiding: false,
+  }
+
+  // ----------------------------------------------------------------
+  // 3) 데이터 컬럼들
+  // ----------------------------------------------------------------
+  const dataColumns: ColumnDef<typeof integrations.$inferSelect>[] = [
+    {
+      accessorKey: "code",
+      header: "코드",
+      filterFn: "includesString",
+      enableSorting: true,
+      enableHiding: false,
+      cell: ({ row }) => {
+        const code = row.getValue("code") as string;
+        return <div className="font-medium">{code}</div>;
+      },
+      minSize: 100
+    },
+    {
+      accessorKey: "name",
+      header: "이름",
+      filterFn: "includesString",
+      enableSorting: true,
+      enableHiding: false,
+      cell: ({ row }) => {
+        const name = row.getValue("name") as string;
+        return <div>{name}</div>;
+      },
+      minSize: 150
+    },
+    {
+      accessorKey: "type",
+      header: "타입",
+      filterFn: "includesString",
+      enableSorting: true,
+      enableHiding: false,
+      cell: ({ row }) => {
+        const type = row.getValue("type") as string;
+        return getTypeBadge(type);
+      },
+      minSize: 100
+    },
+    {
+      accessorKey: "sourceSystem",
+      header: "소스 시스템",
+      filterFn: "includesString",
+      enableSorting: true,
+      enableHiding: false,
+      cell: ({ row }) => {
+        const sourceSystem = row.getValue("sourceSystem") as string;
+        return <div>{sourceSystem}</div>;
+      },
+      minSize: 120
+    },
+    {
+      accessorKey: "targetSystem",
+      header: "타겟 시스템",
+      filterFn: "includesString",
+      enableSorting: true,
+      enableHiding: false,
+      cell: ({ row }) => {
+        const targetSystem = row.getValue("targetSystem") as string;
+        return <div>{targetSystem}</div>;
+      },
+      minSize: 120
+    },
+    {
+      accessorKey: "status",
+      header: "상태",
+      filterFn: "includesString",
+      enableSorting: true,
+      enableHiding: false,
+      cell: ({ row }) => {
+        const status = row.getValue("status") as string;
+        return getStatusBadge(status);
+      },
+      minSize: 80
+    },
+    {
+      accessorKey: "description",
+      header: "설명",
+      filterFn: "includesString",
+      enableSorting: true,
+      enableHiding: false,
+      cell: ({ row }) => {
+        const description = row.getValue("description") as string;
+        return <div className="max-w-xs truncate">{description || "-"}</div>;
+      },
+      minSize: 150
+    },
+    {
+      accessorKey: "createdAt",
+      header: "생성일",
+      filterFn: "includesString",
+      enableSorting: true,
+      enableHiding: false,
+      cell: ({ row }) => {
+        const createdAt = row.getValue("createdAt") as string;
+        return <div>{new Date(createdAt).toLocaleDateString()}</div>;
+      },
+      minSize: 80
+    },
+  ]
+
+  // ----------------------------------------------------------------
+  // 4) 컬럼 조합
+  // ----------------------------------------------------------------
+  const actionsColumn: ColumnDef<typeof integrations.$inferSelect> = {
+    id: "actions",
+    header: "",
+    enableSorting: false,
+    enableHiding: false,
+    cell: function Cell({ row }) {
+      return (
+        <DropdownMenu>
+          <DropdownMenuTrigger asChild>
+            <Button variant="ghost" className="h-8 w-8 p-0">
+              <span className="sr-only">Open menu</span>
+              <MoreHorizontal className="h-4 w-4" />
+            </Button>
+          </DropdownMenuTrigger>
+          <DropdownMenuContent align="end" className="w-40">
+            <DropdownMenuItem onClick={() => setRowAction({ type: "update", row })}>
+              Edit
+            </DropdownMenuItem>
+            <DropdownMenuSeparator />
+            <DropdownMenuItem onClick={() => setRowAction({ type: "delete", row })}>
+              Delete
+              <span className="ml-auto text-xs text-muted-foreground">⌘⌫</span>
+            </DropdownMenuItem>
+          </DropdownMenuContent>
+        </DropdownMenu>
+      );
+    },
+  }
+
+  return [selectColumn, ...dataColumns, actionsColumn]
+}
+
+const getStatusBadge = (status: string) => {
+  switch (status) {
+    case "active":
+      return <Badge variant="default">활성</Badge>;
+    case "inactive":
+      return <Badge variant="secondary">비활성</Badge>;
+    case "deprecated":
+      return <Badge variant="destructive">사용중단</Badge>;
+    default:
+      return <Badge variant="outline">{status}</Badge>;
+  }
+};
+
+const getTypeBadge = (type: string) => {
+  switch (type) {
+    case "rest_api":
+      return <Badge variant="outline">REST API</Badge>;
+    case "soap":
+      return <Badge variant="outline">SOAP</Badge>;
+    case "db_to_db":
+      return <Badge variant="outline">DB to DB</Badge>;
+    default:
+      return <Badge variant="outline">{type}</Badge>;
+  }
+}; 
\ No newline at end of file
-- 
cgit v1.2.3

