diff options
| author | 0-Zz-ang <s1998319@gmail.com> | 2025-07-10 15:56:13 +0900 |
|---|---|---|
| committer | 0-Zz-ang <s1998319@gmail.com> | 2025-07-10 15:56:13 +0900 |
| commit | 356929b399ef31a4de82906267df438cf29ea59d (patch) | |
| tree | c353a55c076e987042f99f3dbf1eab54706f6829 /lib/integration/table/integration-table-columns.tsx | |
| parent | 25d569828b704a102f681a627c76c4129afa8be3 (diff) | |
인터페이스 관련 파일 수정
Diffstat (limited to 'lib/integration/table/integration-table-columns.tsx')
| -rw-r--r-- | lib/integration/table/integration-table-columns.tsx | 214 |
1 files changed, 214 insertions, 0 deletions
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 |
