diff options
Diffstat (limited to 'lib/tech-vendors/items-table/item-table-columns.tsx')
| -rw-r--r-- | lib/tech-vendors/items-table/item-table-columns.tsx | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/lib/tech-vendors/items-table/item-table-columns.tsx b/lib/tech-vendors/items-table/item-table-columns.tsx new file mode 100644 index 00000000..72986849 --- /dev/null +++ b/lib/tech-vendors/items-table/item-table-columns.tsx @@ -0,0 +1,192 @@ +"use client" + +import * as React from "react" +import { type DataTableRowAction } from "@/types/table" +import { type ColumnDef } from "@tanstack/react-table" +import { MoreHorizontal } from "lucide-react" +import { format } from "date-fns" +import { ko } from "date-fns/locale" + +import { Badge } from "@/components/ui/badge" +import { Button } from "@/components/ui/button" +import { Checkbox } from "@/components/ui/checkbox" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" + +import { TechVendorItemsView } from "@/db/schema/techVendors" +import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" +import { + techVendorItemsColumnsConfig, + shipbuildingColumnsConfig, + offshoreTopColumnsConfig, + offshoreHullColumnsConfig +} from "@/config/techVendorItemsColumnsConfig" + +interface ColumnConfig { + id: string + label: string + excelHeader: string + type: string + minWidth: number + defaultWidth: number + group?: string +} + +interface GetColumnsOptions { + setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<TechVendorItemsView> | null>> + vendorType: string +} + +export function getColumns({ setRowAction, vendorType }: GetColumnsOptions): ColumnDef<TechVendorItemsView>[] { + // 벤더 타입에 따라 적절한 컬럼 설정 선택 + const columnsConfig = (() => { + switch (vendorType) { + case "조선": + return shipbuildingColumnsConfig; + case "해양TOP": + return offshoreTopColumnsConfig; + case "해양HULL": + return offshoreHullColumnsConfig; + default: + return techVendorItemsColumnsConfig; + } + })(); + + // ---------------------------------------------------------------- + // 1) select 컬럼 (체크박스) + // ---------------------------------------------------------------- + const selectColumn: ColumnDef<TechVendorItemsView> = { + id: "select", + header: ({ table }) => ( + <Checkbox + checked={ + table.getIsAllPageRowsSelected() || + (table.getIsSomePageRowsSelected() && "indeterminate") + } + onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + className="translate-y-[2px]" + /> + ), + cell: ({ row }) => ( + <Checkbox + checked={row.getIsSelected()} + onCheckedChange={(value) => row.toggleSelected(!!value)} + aria-label="Select row" + className="translate-y-[2px]" + /> + ), + enableSorting: false, + enableHiding: false, + } + + // ---------------------------------------------------------------- + // 2) actions 컬럼 (Dropdown 메뉴) + // ---------------------------------------------------------------- + // const actionsColumn: ColumnDef<TechVendorItemsView> = { + // id: "actions", + // 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"> + // <DropdownMenuLabel>Actions</DropdownMenuLabel> + // <DropdownMenuItem onClick={() => + // setRowAction({ + // type: "update", + // row, + // }) + // }> + // View Details + // </DropdownMenuItem> + // </DropdownMenuContent> + // </DropdownMenu> + // ) + // }, + // } + + // ---------------------------------------------------------------- + // 3) 일반 컬럼들을 "그룹"별로 묶어 중첩 columns 생성 + // ---------------------------------------------------------------- + const groupMap: Record<string, ColumnDef<TechVendorItemsView>[]> = {} + + columnsConfig.forEach((cfg: ColumnConfig) => { + // 만약 group가 없으면 "_noGroup" 처리 + const groupName = cfg.group || "_noGroup" + + if (!groupMap[groupName]) { + groupMap[groupName] = [] + } + + // child column 정의 + const childCol: ColumnDef<TechVendorItemsView> = { + accessorKey: cfg.id, + enableResizing: true, + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title={cfg.label} /> + ), + minSize: cfg.minWidth, + size: cfg.defaultWidth, + meta: { + excelHeader: cfg.excelHeader, + group: cfg.group, + type: cfg.type, + }, + cell: ({ row, cell }) => { + if (cfg.id === "createdAt" || cfg.id === "updatedAt") { + const dateVal = cell.getValue() as Date + return format(dateVal, "PPP", { locale: ko }) + } + + if (cfg.id === "techVendorType") { + const type = cell.getValue() as string + return type ? ( + <Badge variant="outline" className="capitalize"> + {type} + </Badge> + ) : null + } + + return row.getValue(cfg.id) ?? "" + }, + } + + groupMap[groupName].push(childCol) + }) + + // ---------------------------------------------------------------- + // 3-2) groupMap에서 실제 상위 컬럼(그룹)을 만들기 + // ---------------------------------------------------------------- + const nestedColumns: ColumnDef<TechVendorItemsView>[] = [] + + Object.entries(groupMap).forEach(([groupName, colDefs]) => { + if (groupName === "_noGroup") { + nestedColumns.push(...colDefs) + } else { + nestedColumns.push({ + id: groupName, + header: groupName, + columns: colDefs, + }) + } + }) + + // ---------------------------------------------------------------- + // 4) 최종 컬럼 배열: select, nestedColumns, actions + // ---------------------------------------------------------------- + return [ + selectColumn, + ...nestedColumns, + // actionsColumn, + ] +}
\ No newline at end of file |
