From 3cde5c2c7d157bb0fe353de5e67e4b35506bb4e2 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Tue, 23 Sep 2025 20:05:46 +0900
Subject: (김준회) Vendorpool 수정요청사항 - 컬럼리사이징 관련 문제 해결 -
 공통컴포넌트에 columnResizeMode: "onChange" 속성 추가
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/avl/table/avl-table-columns.tsx | 568 +++++++++++++++++++-----------------
 1 file changed, 295 insertions(+), 273 deletions(-)

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

diff --git a/lib/avl/table/avl-table-columns.tsx b/lib/avl/table/avl-table-columns.tsx
index d95a29b0..6ec2c3db 100644
--- a/lib/avl/table/avl-table-columns.tsx
+++ b/lib/avl/table/avl-table-columns.tsx
@@ -1,7 +1,7 @@
 import { Checkbox } from "@/components/ui/checkbox"
 import { Button } from "@/components/ui/button"
 import { Badge } from "@/components/ui/badge"
-import { Eye, Edit, Trash2, History } from "lucide-react"
+import { Eye, History } from "lucide-react"
 import { type ColumnDef } from "@tanstack/react-table"
 import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
 import { AvlListItem } from "../types"
@@ -26,303 +26,325 @@ declare module "@tanstack/react-table" {
 // 테이블 컬럼 정의 함수
 export function getColumns({ selectedRows = [], onRowSelect }: GetColumnsProps): ColumnDef<AvlListItem>[] {
   const columns: ColumnDef<AvlListItem>[] = [
-    // 기본 정보 그룹
+    // select 컬럼
     {
-      header: "AVL 정보",
-      columns: [
-      {
-        id: "select",
-        header: () => <div className="text-center">선택</div>,
-        cell: ({ row }) => (
-          <div className="flex justify-center">
-            <Checkbox
-              checked={selectedRows.includes(row.original.id)}
-              onCheckedChange={(checked) => {
-                onRowSelect?.(row.original.id, !!checked)
-              }}
-              aria-label="행 선택"
-              className="translate-y-[2px]"
-            />
+      id: "select",
+      header: () => <div className="text-center">선택</div>,
+      cell: ({ row }) => (
+        <div className="flex justify-center">
+          <Checkbox
+            checked={selectedRows.includes(row.original.id)}
+            onCheckedChange={(checked) => {
+              onRowSelect?.(row.original.id, !!checked)
+            }}
+            aria-label="행 선택"
+            className="translate-y-[2px]"
+          />
+        </div>
+      ),
+      enableSorting: false,
+      enableHiding: false,
+      enableResizing: false,
+      size: 10,
+      minSize: 10,
+      maxSize: 10,
+    },
+    // No 컬럼
+    {
+      accessorKey: "no",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="No" />
+      ),
+      cell: ({ getValue }) => <div className="text-center">{getValue() as number}</div>,
+      enableResizing: true,
+      size: 60,
+    },
+    // AVL 분류 컬럼
+    {
+      accessorKey: "isTemplate",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="AVL 분류" />
+      ),
+      cell: ({ getValue }) => {
+        const value = getValue() as boolean
+        return (
+          <div className="text-center">
+            {value ? "표준 AVL" : "프로젝트 AVL"}
           </div>
-        ),
-        enableSorting: false,
-        enableHiding: false,
-        size: 40,
-      },
-      {
-        accessorKey: "no",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="No" />
-        ),
-        cell: ({ getValue }) => <div className="text-center">{getValue() as number}</div>,
-        size: 60,
-      },
-      {
-        accessorKey: "isTemplate",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="AVL 분류" />
-        ),
-        cell: ({ getValue }) => {
-          const value = getValue() as boolean
-          return (
-            <div className="text-center">
-              {value ? "표준 AVL" : "프로젝트 AVL"}
-            </div>
-          )
-        },
-        size: 120,
+        )
       },
-      {
-        accessorKey: "constructionSector",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="공사부문" />
-        ),
-        cell: ({ getValue }) => {
-          const value = getValue() as string
-          return (
-            <div className="text-center">
-              {value}
-            </div>
-          )
-        },
-        size: 100,
-      },
-      {
-        accessorKey: "projectCode",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="프로젝트 코드" />
-        ),
-        cell: ({ getValue }) => {
-          const value = getValue() as string
-          return (
-            <div className="text-center">
-              {value}
-            </div>
-          )
-        },
-        size: 140,
-      },
-      {
-        accessorKey: "shipType",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="선종" />
-        ),
-        cell: ({ getValue }) => {
-          const value = getValue() as string
-          return (
-            <div className="text-center">
-              {value}
-            </div>
-          )
-        },
-        size: 100,
-      },
-      {
-        accessorKey: "avlKind",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="AVL 종류" />
-        ),
-        cell: ({ getValue }) => {
-          const value = getValue() as string
-          return (
-            <div className="text-center">
-              {value}
-            </div>
-          )
-        },
-        size: 120,
-      },
-      {
-        accessorKey: "htDivision",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="H/T 구분" />
-        ),
-        cell: ({ getValue }) => {
-          const value = getValue() as string
-          return (
-            <div className="text-center">
-              {value}
-            </div>
-          )
-        },
-        size: 80,
-      },
-      {
-        accessorKey: "rev",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="Rev" />
-        ),
-        cell: ({ getValue, row, table }) => {
-          const value = getValue() as number
-          return (
-            <div className="flex items-center gap-1">
-              <Badge variant="outline" className="font-mono">
-                {value || 1}
-              </Badge>
-              <Button
-                variant="ghost"
-                size="sm"
-                className="h-6 w-6 p-0"
-                onClick={() => table.options.meta?.onAction?.('view-history', row.original)}
-                title="리비전 히스토리 보기"
-              >
-                <History className="h-3 w-3" />
-              </Button>
-            </div>
-          )
-        },
-        size: 100,
-      },
-    ],
-  },
-
-  // 집계 그룹
-  {
-    header: "등록정보",
-    columns: [
-      {
-        accessorKey: "PKG",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="PKG" />
-        ),
+      enableResizing: true,
+      size: 120,
+    },
+    // 공사부문 컬럼
+    {
+      accessorKey: "constructionSector",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="공사부문" />
+      ),
+      cell: ({ getValue }) => {
+        const value = getValue() as string
+        return (
+          <div className="text-center">
+            {value}
+          </div>
+        )
       },
-      {
-        accessorKey: "materialGroup",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="자재그룹" />
-        ),
+      enableResizing: true,
+      size: 100,
+    },
+    // 프로젝트 코드 컬럼
+    {
+      accessorKey: "projectCode",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="프로젝트 코드" />
+      ),
+      cell: ({ getValue }) => {
+        const value = getValue() as string
+        return (
+          <div className="text-center">
+            {value}
+          </div>
+        )
       },
-      {
-        accessorKey: "vendor",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="협력업체" />
-        ),
+      enableResizing: true,
+      size: 140,
+    },
+    // 선종 컬럼
+    {
+      accessorKey: "shipType",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="선종" />
+      ),
+      cell: ({ getValue }) => {
+        const value = getValue() as string
+        return (
+          <div className="text-center">
+            {value}
+          </div>
+        )
       },
-      {
-        accessorKey: "Tier",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="Tier" />
-        ),
+      enableResizing: true,
+      size: 100,
+    },
+    // AVL 종류 컬럼
+    {
+      accessorKey: "avlKind",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="AVL 종류" />
+      ),
+      cell: ({ getValue }) => {
+        const value = getValue() as string
+        return (
+          <div className="text-center">
+            {value}
+          </div>
+        )
       },
-      {
-        accessorKey: "ownerSuggestion",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="선주 제안" />
-        ),
+      enableResizing: true,
+      size: 120,
+    },
+    // H/T 구분 컬럼
+    {
+      accessorKey: "htDivision",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="H/T 구분" />
+      ),
+      cell: ({ getValue }) => {
+        const value = getValue() as string
+        return (
+          <div className="text-center">
+            {value}
+          </div>
+        )
       },
-      {
-        accessorKey: "shiSuggestion",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="SHI 제안" />
-        ),
+      enableResizing: true,
+      size: 80,
+    },
+    // Rev 컬럼
+    {
+      accessorKey: "rev",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="Rev" />
+      ),
+      cell: ({ getValue, row, table }) => {
+        const value = getValue() as number
+        return (
+          <div className="flex items-center gap-1">
+            <Badge variant="outline" className="font-mono">
+              {value || 1}
+            </Badge>
+            <Button
+              variant="ghost"
+              size="sm"
+              className="h-6 w-6 p-0"
+              onClick={() => table.options.meta?.onAction?.('view-history', row.original)}
+              title="리비전 히스토리 보기"
+            >
+              <History className="h-3 w-3" />
+            </Button>
+          </div>
+        )
       },
-    ],
-  },
-
-  // 등록 정보 그룹
-  {
-    header: "작성정보",
-    columns: [
-      {
-        accessorKey: "createdAt",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="등록일" />
-        ),
-        cell: ({ getValue }) => {
-          const date = getValue() as string
-          return <div className="text-center text-sm">{date}</div>
-        },
-        size: 100,
+      enableResizing: true,
+      size: 100,
+    },
+    // PKG 컬럼
+    {
+      accessorKey: "PKG",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="PKG" />
+      ),
+      enableResizing: true,
+      size: 80,
+    },
+    // 자재그룹 컬럼
+    {
+      accessorKey: "materialGroup",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="자재그룹" />
+      ),
+      enableResizing: true,
+      size: 120,
+    },
+    // 협력업체 컬럼
+    {
+      accessorKey: "vendor",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="협력업체" />
+      ),
+      enableResizing: true,
+      size: 150,
+    },
+    // Tier 컬럼
+    {
+      accessorKey: "Tier",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="Tier" />
+      ),
+      enableResizing: true,
+      size: 60,
+    },
+    // 선주 제안 컬럼
+    {
+      accessorKey: "ownerSuggestion",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="선주 제안" />
+      ),
+      enableResizing: true,
+      size: 100,
+    },
+    // SHI 제안 컬럼
+    {
+      accessorKey: "shiSuggestion",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="SHI 제안" />
+      ),
+      enableResizing: true,
+      size: 100,
+    },
+    // 등록일 컬럼
+    {
+      accessorKey: "createdAt",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="등록일" />
+      ),
+      cell: ({ getValue }) => {
+        const date = getValue() as string
+        return <div className="text-center text-sm">{date}</div>
       },
-      {
-        accessorKey: "createdBy",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="등록자" />
-        ),
-        cell: ({ getValue }) => {
-          const date = getValue() as string
-          return <div className="text-center text-sm">{date}</div>
-        },
-        size: 100,
+      enableResizing: true,
+      size: 100,
+    },
+    // 등록자 컬럼
+    {
+      accessorKey: "createdBy",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="등록자" />
+      ),
+      cell: ({ getValue }) => {
+        const value = getValue() as string
+        return <div className="text-center text-sm">{value}</div>
       },
-      {
-        accessorKey: "updatedAt",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="최종변경일" />
-        ),
-        cell: ({ getValue }) => {
-          const date = getValue() as string
-          return <div className="text-center text-sm">{date}</div>
-        },
-        size: 100,
+      enableResizing: true,
+      size: 100,
+    },
+    // 최종변경일 컬럼
+    {
+      accessorKey: "updatedAt",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="최종변경일" />
+      ),
+      cell: ({ getValue }) => {
+        const date = getValue() as string
+        return <div className="text-center text-sm">{date}</div>
       },
-      {
-        accessorKey: "updatedBy",
-        header: ({ column }) => (
-          <DataTableColumnHeaderSimple column={column} title="최종변경자" />
-        ),
-        cell: ({ getValue }) => {
-          const date = getValue() as string
-          return <div className="text-center text-sm">{date}</div>
-        },
-        size: 100,
+      enableResizing: true,
+      size: 100,
+    },
+    // 최종변경자 컬럼
+    {
+      accessorKey: "updatedBy",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="최종변경자" />
+      ),
+      cell: ({ getValue }) => {
+        const value = getValue() as string
+        return <div className="text-center text-sm">{value}</div>
       },
-    ],
-  },
-
-  // 액션 그룹
-  {
-    id: "actions",
-    header: "액션",
-    columns: [
-      {
-        id: "actions",
-        header: () => <div className="text-center">액션</div>,
-        cell: ({ row, table }) => {
-          const isEmptyRow = table.options.meta?.isEmptyRow?.(row.id) || false
-
-          if (isEmptyRow) {
-            return (
-              <div className="flex items-center justify-center gap-1">
-                <Button
-                  variant="ghost"
-                  size="sm"
-                  onClick={() => table.options.meta?.onSaveEmptyRow?.(row.id)}
-                  className="h-8 w-8 p-0"
-                >
-                  저장
-                </Button>
-                <Button
-                  variant="ghost"
-                  size="sm"
-                  onClick={() => table.options.meta?.onCancelEmptyRow?.(row.id)}
-                  className="h-8 w-8 p-0 text-destructive hover:text-destructive"
-                >
-                  취소
-                </Button>
-              </div>
-            )
-          }
+      enableResizing: true,
+      size: 100,
+    },
+    // 액션 컬럼
+    {
+      id: "actions",
+      header: () => <div className="text-center">액션</div>,
+      cell: ({ row, table }) => {
+        const isEmptyRow = table.options.meta?.isEmptyRow?.(row.id) || false
 
+        if (isEmptyRow) {
           return (
             <div className="flex items-center justify-center gap-1">
               <Button
                 variant="ghost"
                 size="sm"
-                onClick={() => table.options.meta?.onAction?.("view-detail", { id: row.original.id })}
+                onClick={() => table.options.meta?.onSaveEmptyRow?.(row.id)}
                 className="h-8 w-8 p-0"
-                title="상세보기"
               >
-                <Eye className="h-4 w-4" />
+                저장
+              </Button>
+              <Button
+                variant="ghost"
+                size="sm"
+                onClick={() => table.options.meta?.onCancelEmptyRow?.(row.id)}
+                className="h-8 w-8 p-0 text-destructive hover:text-destructive"
+              >
+                취소
               </Button>
             </div>
           )
-        },
-        enableSorting: false,
-        enableHiding: false,
-        size: 120,
+        }
+
+        return (
+          <div className="flex items-center justify-center gap-1">
+            <Button
+              variant="ghost"
+              size="sm"
+              onClick={() => table.options.meta?.onAction?.("view-detail", { id: row.original.id })}
+              className="h-8 w-8 p-0"
+              title="상세보기"
+            >
+              <Eye className="h-4 w-4" />
+            </Button>
+          </div>
+        )
       },
-      ],
+      enableSorting: false,
+      enableHiding: false,
+      enableResizing: false,
+      size: 120,
+      minSize: 120,
+      maxSize: 120,
     },
   ]
 
-- 
cgit v1.2.3

