diff options
Diffstat (limited to 'components/form-data/form-data-table-columns.tsx')
| -rw-r--r-- | components/form-data/form-data-table-columns.tsx | 101 |
1 files changed, 75 insertions, 26 deletions
diff --git a/components/form-data/form-data-table-columns.tsx b/components/form-data/form-data-table-columns.tsx index a1fbcae1..de479efb 100644 --- a/components/form-data/form-data-table-columns.tsx +++ b/components/form-data/form-data-table-columns.tsx @@ -1,6 +1,7 @@ import type { ColumnDef, Row } from "@tanstack/react-table"; import { ClientDataTableColumnHeaderSimple } from "../client-data-table/data-table-column-simple-header"; import { Button } from "@/components/ui/button"; +import { Checkbox } from "@/components/ui/checkbox"; import { Ellipsis } from "lucide-react"; import { formatDate } from "@/lib/utils"; import { @@ -17,6 +18,7 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { toast } from 'sonner'; + /** row 액션 관련 타입 */ export interface DataTableRowAction<TData> { row: Row<TData>; @@ -39,8 +41,8 @@ export interface DataTableColumnJSON { uom?: string; uomId?: string; shi?: boolean; - } + /** * getColumns 함수에 필요한 props * - TData: 테이블에 표시할 행(Row)의 타입 @@ -52,20 +54,77 @@ interface GetColumnsProps<TData> { >; setReportData: React.Dispatch<React.SetStateAction<{ [key: string]: any }[]>>; tempCount: number; + // 체크박스 선택 관련 props + selectedRows?: Record<string, boolean>; + onRowSelectionChange?: (updater: Record<string, boolean> | ((prev: Record<string, boolean>) => Record<string, boolean>)) => void; } /** * getColumns 함수 * 1) columnsJSON 배열을 순회하면서 accessorKey / header / cell 등을 설정 - * 2) 마지막에 "Action" 칼럼(예: update 버튼) 추가 + * 2) 체크박스 컬럼 추가 (showBatchSelection이 true일 때) + * 3) 마지막에 "Action" 칼럼(예: update 버튼) 추가 */ export function getColumns<TData extends object>({ columnsJSON, setRowAction, setReportData, tempCount, + selectedRows = {}, + onRowSelectionChange, }: GetColumnsProps<TData>): ColumnDef<TData>[] { - // (1) 기본 컬럼들 + const columns: ColumnDef<TData>[] = []; + + // (1) 체크박스 컬럼 (항상 표시) + const selectColumn: ColumnDef<TData> = { + id: "select", + header: ({ table }) => ( + <Checkbox + checked={ + table.getIsAllPageRowsSelected() || + (table.getIsSomePageRowsSelected() && "indeterminate") + } + onCheckedChange={(value) => { + table.toggleAllPageRowsSelected(!!value); + + // 모든 행 선택/해제 + if (onRowSelectionChange) { + const allRowsSelection: Record<string, boolean> = {}; + table.getRowModel().rows.forEach((row) => { + allRowsSelection[row.id] = !!value; + }); + onRowSelectionChange(allRowsSelection); + } + }} + aria-label="Select all" + className="translate-y-[2px]" + /> + ), + cell: ({ row }) => ( + <Checkbox + checked={row.getIsSelected()} + onCheckedChange={(value) => { + row.toggleSelected(!!value); + + // 개별 행 선택 상태 업데이트 + if (onRowSelectionChange) { + onRowSelectionChange(prev => ({ + ...prev, + [row.id]: !!value + })); + } + }} + aria-label="Select row" + className="translate-y-[2px]" + /> + ), + enableSorting: false, + enableHiding: false, + size: 40, + }; + columns.push(selectColumn); + + // (2) 기본 컬럼들 const baseColumns: ColumnDef<TData>[] = columnsJSON.map((col) => ({ accessorKey: col.key, header: ({ column }) => ( @@ -82,7 +141,7 @@ export function getColumns<TData extends object>({ maxWidth: col.key === "TAG_NO" ? 120 : 150, isReadOnly: col.shi === true, // shi 정보를 메타데이터에 저장 }, - // (2) 실제 셀(cell) 렌더링: type에 따라 분기 가능 + // (3) 실제 셀(cell) 렌더링: type에 따라 분기 가능 cell: ({ row }) => { const cellValue = row.getValue(col.key); @@ -109,14 +168,6 @@ export function getColumns<TData extends object>({ </div> ); - // case "date": - // // 예: 날짜 포맷팅 - // // 실제론 dayjs / date-fns 등으로 포맷 - // if (!cellValue) return <div></div> - // const dateString = cellValue as string - // if (!dateString) return null - // return formatDate(new Date(dateString)) - case "LIST": // 예: select인 경우 label만 표시 return ( @@ -144,7 +195,9 @@ export function getColumns<TData extends object>({ }, })); - // (3) 액션 칼럼 - update 버튼 예시 + columns.push(...baseColumns); + + // (4) 액션 칼럼 - update 버튼 예시 const actionColumn: ColumnDef<TData> = { id: "update", header: "", @@ -162,12 +215,6 @@ export function getColumns<TData extends object>({ <DropdownMenuContent align="end" className="w-40"> <DropdownMenuItem onSelect={() => { - // 행에 있는 모든 필드가 읽기 전용인지 확인할 수도 있습니다 (선택 사항) - // const allColumnsReadOnly = columnsJSON.every(col => col.shi === true); - // if(allColumnsReadOnly) { - // toast.info("이 항목은 읽기 전용입니다."); - // return; - // } setRowAction({ row, type: "update" }); }} > @@ -176,11 +223,11 @@ export function getColumns<TData extends object>({ <DropdownMenuItem onSelect={() => { if(tempCount > 0){ - const { original } = row; - setReportData([original]); - } else { - toast.error("업로드된 Template File이 없습니다."); - } + const { original } = row; + setReportData([original]); + } else { + toast.error("업로드된 Template File이 없습니다."); + } }} > Create Document @@ -192,6 +239,8 @@ export function getColumns<TData extends object>({ enablePinning: true, }; - // (4) 최종 반환 - return [...baseColumns, actionColumn]; + columns.push(actionColumn); + + // (5) 최종 반환 + return columns; }
\ No newline at end of file |
