From c2672935caf9ce977840657cbff0da8af8e12f97 Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Thu, 4 Sep 2025 02:49:48 +0000 Subject: (김준회) 기준정보-자재그룹 메뉴 구현 - 기준정보 메뉴를 자재그룹코드(/material-groups)로 변경 - 기존 자재코드조회는 /materials 로 남겨둠 - 메뉴를 자재그룹코드로만 남기고, i18n 처리 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../table/material-group-table-columns.tsx | 61 +++++++ lib/material-groups/table/material-group-table.tsx | 178 +++++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 lib/material-groups/table/material-group-table-columns.tsx create mode 100644 lib/material-groups/table/material-group-table.tsx (limited to 'lib/material-groups/table') diff --git a/lib/material-groups/table/material-group-table-columns.tsx b/lib/material-groups/table/material-group-table-columns.tsx new file mode 100644 index 00000000..90df720d --- /dev/null +++ b/lib/material-groups/table/material-group-table-columns.tsx @@ -0,0 +1,61 @@ +"use client" + +import * as React from "react" +import { type ColumnDef } from "@tanstack/react-table" + +import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" + +// MaterialGroup 타입 정의 (서비스에서 반환되는 타입과 일치) +type MaterialGroup = { + materialGroupCode: string | null; + materialName: string | null; + displayText: string | null; +} + +/** + * MaterialGroup 테이블 컬럼 정의 + */ +export function getColumns(): ColumnDef[] { + // ---------------------------------------------------------------- + // 데이터 컬럼들 + // ---------------------------------------------------------------- + const dataColumns: ColumnDef[] = [ + { + accessorKey: "materialGroupCode", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const value = row.getValue("materialGroupCode") as string | null + return ( +
+ {value || "-"} +
+ ) + }, + enableSorting: true, + enableHiding: false, + }, + { + accessorKey: "materialName", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const value = row.getValue("materialName") as string | null + return ( +
+ {value || "-"} +
+ ) + }, + enableSorting: true, + enableHiding: false, + }, + ] + + // ---------------------------------------------------------------- + // 최종 컬럼 배열 + // ---------------------------------------------------------------- + return dataColumns +} diff --git a/lib/material-groups/table/material-group-table.tsx b/lib/material-groups/table/material-group-table.tsx new file mode 100644 index 00000000..21430c4f --- /dev/null +++ b/lib/material-groups/table/material-group-table.tsx @@ -0,0 +1,178 @@ +"use client" + +import * as React from "react" +import type { + DataTableAdvancedFilterField, + DataTableFilterField, +} from "@/types/table" + +import { useDataTable } from "@/hooks/use-data-table" +import { DataTable } from "@/components/data-table/data-table" +import { InfiniteDataTable } from "@/components/data-table/infinite-data-table" +import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar" +import { Button } from "@/components/ui/button" +import { Alert, AlertDescription } from "@/components/ui/alert" + +import { getMaterialGroups } from "../services" +import { getColumns } from "./material-group-table-columns" +import { ViewModeToggle } from "@/components/data-table/view-mode-toggle" + +// MaterialGroup 타입 정의 (서비스에서 반환되는 타입과 일치) +type MaterialGroup = { + materialGroupCode: string | null; + materialName: string | null; + displayText: string | null; +} + +interface MaterialGroupTableProps { + promises?: Promise< + [ + Awaited>, + ] + > +} + +export function MaterialGroupTable({ promises }: MaterialGroupTableProps) { + // 페이지네이션 모드 데이터 + const paginationData = promises ? React.use(promises) : null + const [{ data = [], pageCount = 0 }] = paginationData || [{ data: [], pageCount: 0 }] + + console.log('MaterialGroupTable data:', data.length, 'material groups') + + const columns = React.useMemo( + () => getColumns(), + [] + ) + + // 기존 필터 필드들 + const filterFields: DataTableFilterField[] = [ + { + id: "materialGroupCode", + label: "자재그룹코드", + }, + { + id: "materialName", + label: "자재그룹명", + }, + ] + + const advancedFilterFields: DataTableAdvancedFilterField[] = [ + { + id: "materialGroupCode", + label: "자재그룹코드", + type: "text", + }, + { + id: "materialName", + label: "자재그룹명", + type: "text", + }, + { + id: "displayText", + label: "표시텍스트", + type: "text", + }, + ] + + // 확장된 useDataTable 훅 사용 (pageSize 기반 자동 전환) + const { + table, + infiniteScroll, + isInfiniteMode, + handlePageSizeChange, + } = useDataTable({ + data, + columns, + pageCount, + filterFields, + enablePinning: true, + enableAdvancedFilter: true, + initialState: { + sorting: [{ id: "materialGroupCode", desc: false }], + }, + getRowId: (originalRow) => String(originalRow.materialGroupCode || 'unknown'), + shallow: false, + clearOnDefault: true, + // 무한 스크롤 설정 + infiniteScrollConfig: { + apiEndpoint: "/api/table/material-groups/infinite", + tableName: "material-groups", + maxPageSize: 100, + }, + }) + + return ( +
+ + {/* 모드 토글 */} +
+ +
+ + {/* 에러 상태 (무한 스크롤 모드) */} + {isInfiniteMode && infiniteScroll?.error && ( + + + 데이터를 불러오는 중 오류가 발생했습니다. + + + + )} + + {/* 로딩 상태가 아닐 때만 테이블 렌더링 */} + {!(isInfiniteMode && infiniteScroll?.isLoading && infiniteScroll?.isEmpty) ? ( + <> + {/* 도구 모음 */} + + + {/* 테이블 렌더링 */} + {isInfiniteMode ? ( + // 무한 스크롤 모드: InfiniteDataTable 사용 + + ) : ( + // 페이지네이션 모드: DataTable 사용 + + )} + + ) : ( + /* 로딩 스켈레톤 (무한 스크롤 초기 로딩) */ +
+
+ 무한 스크롤 모드로 데이터를 로드하고 있습니다... +
+ {Array.from({ length: 10 }).map((_, i) => ( +
+ ))} +
+ )} + +
+ ) +} -- cgit v1.2.3