summaryrefslogtreecommitdiff
path: root/lib/tech-vendors/items-table/item-table-columns.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tech-vendors/items-table/item-table-columns.tsx')
-rw-r--r--lib/tech-vendors/items-table/item-table-columns.tsx192
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