summaryrefslogtreecommitdiff
path: root/lib/avl/table/vendor-pool-table.tsx
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-09-15 18:58:07 +0900
committerjoonhoekim <26rote@gmail.com>2025-09-15 18:58:07 +0900
commit2b490956c9752c1b756780a3461bc1c37b6fe0a7 (patch)
treeb0b8a03c8de5dfce4b6c7373a9d608306e9147c0 /lib/avl/table/vendor-pool-table.tsx
parente7818a457371849e29519497ebf046f385f05ab6 (diff)
(김준회) AVL 관리 및 상세 - 기능 구현 1차
+ docker compose 내 오류 수정
Diffstat (limited to 'lib/avl/table/vendor-pool-table.tsx')
-rw-r--r--lib/avl/table/vendor-pool-table.tsx241
1 files changed, 126 insertions, 115 deletions
diff --git a/lib/avl/table/vendor-pool-table.tsx b/lib/avl/table/vendor-pool-table.tsx
index 1a0a5fca..7ad9eb56 100644
--- a/lib/avl/table/vendor-pool-table.tsx
+++ b/lib/avl/table/vendor-pool-table.tsx
@@ -1,7 +1,8 @@
"use client"
import * as React from "react"
-import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, type ColumnDef } from "@tanstack/react-table"
+import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel } from "@tanstack/react-table"
+import { forwardRef, useImperativeHandle } from "react"
import { DataTable } from "@/components/data-table/data-table"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
@@ -10,114 +11,29 @@ import { Search } from "lucide-react"
import { getVendorPools } from "../../vendor-pool/service"
import { GetVendorPoolSchema } from "../../vendor-pool/validations"
import { VendorPool } from "../../vendor-pool/types"
+import { vendorPoolColumns } from "./vendor-pool-table-columns"
// Vendor Pool 데이터 타입 (실제 VendorPool 타입 사용)
export type VendorPoolItem = VendorPool
+// ref를 통해 외부에서 접근할 수 있는 메소드들
+export interface VendorPoolTableRef {
+ getSelectedIds: () => number[]
+}
+
interface VendorPoolTableProps {
onSelectionChange?: (count: number) => void
resetCounter?: number
+ reloadTrigger?: number
}
-// Vendor Pool 테이블 컬럼
-const vendorPoolColumns: ColumnDef<VendorPoolItem>[] = [
- {
- id: "select",
- header: ({ table }) => (
- <Checkbox
- checked={
- table.getIsAllPageRowsSelected() ||
- (table.getIsSomePageRowsSelected() && "indeterminate")
- }
- onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
- aria-label="Select all"
- />
- ),
- cell: ({ row, table }) => {
- // Vendor Pool 테이블의 단일 선택 핸들러
- const handleRowSelection = (checked: boolean) => {
- if (checked) {
- // 다른 모든 행의 선택 해제
- table.getRowModel().rows.forEach(r => {
- if (r !== row && r.getIsSelected()) {
- r.toggleSelected(false)
- }
- })
- }
- // 현재 행 선택/해제
- row.toggleSelected(checked)
- }
-
- return (
- <Checkbox
- checked={row.getIsSelected()}
- onCheckedChange={handleRowSelection}
- aria-label="Select row"
- />
- )
- },
- enableSorting: false,
- enableHiding: false,
- size: 50,
- },
- {
- accessorKey: "no",
- header: "No.",
- size: 60,
- },
- {
- accessorKey: "designCategory",
- header: "설계공종",
- size: 120,
- },
- {
- accessorKey: "avlVendorName",
- header: "AVL 등재업체명",
- size: 140,
- },
- {
- accessorKey: "materialGroupCode",
- header: "자재그룹코드",
- size: 130,
- },
- {
- accessorKey: "materialGroupName",
- header: "자재그룹명",
- size: 130,
- },
- {
- accessorKey: "vendorName",
- header: "협력업체 정보",
- size: 130,
- },
- {
- accessorKey: "tier",
- header: "업체분류",
- size: 100,
- },
- {
- accessorKey: "faStatus",
- header: "FA현황",
- size: 100,
- },
- {
- accessorKey: "recentQuoteNumber",
- header: "최근견적번호",
- size: 130,
- },
- {
- accessorKey: "recentOrderNumber",
- header: "최근발주번호",
- size: 130,
- },
-]
-
// 실제 데이터는 API에서 가져옴
-export function VendorPoolTable({
+export const VendorPoolTable = forwardRef<VendorPoolTableRef, VendorPoolTableProps>(({
onSelectionChange,
- resetCounter
-}: VendorPoolTableProps) {
+ resetCounter,
+ reloadTrigger
+}, ref) => {
const [data, setData] = React.useState<VendorPoolItem[]>([])
const [loading, setLoading] = React.useState(false)
const [pageCount, setPageCount] = React.useState(0)
@@ -126,18 +42,78 @@ export function VendorPoolTable({
const [searchText, setSearchText] = React.useState("")
const [showAll, setShowAll] = React.useState(false)
+ // 페이지네이션 상태
+ const [pagination, setPagination] = React.useState({
+ pageIndex: 0,
+ pageSize: 10,
+ })
+
// 데이터 로드 함수
- const loadData = React.useCallback(async (searchParams: Partial<GetVendorPoolSchema>) => {
+ const loadData = React.useCallback(async (searchParams: Partial<GetVendorPoolSchema> = {}) => {
try {
setLoading(true)
- const params: GetVendorPoolSchema = {
+
+ const params = {
page: searchParams.page ?? 1,
perPage: searchParams.perPage ?? 10,
sort: searchParams.sort ?? [{ id: "registrationDate", desc: true }],
+ flags: [],
search: searchText || "",
+ constructionSector: undefined,
+ shipType: undefined,
+ htDivision: undefined,
+ designCategoryCode: undefined,
+ designCategory: undefined,
+ equipBulkDivision: undefined,
+ packageCode: undefined,
+ packageName: undefined,
+ materialGroupCode: undefined,
+ materialGroupName: undefined,
+ vendorCode: undefined,
+ vendorName: undefined,
+ faTarget: undefined,
+ faStatus: undefined,
+ tier: undefined,
+ isAgent: undefined,
+ isBlacklist: undefined,
+ isBcc: undefined,
+ purchaseOpinion: undefined,
+ shipTypeCommon: undefined,
+ shipTypeAmax: undefined,
+ shipTypeSmax: undefined,
+ shipTypeVlcc: undefined,
+ shipTypeLngc: undefined,
+ shipTypeCont: undefined,
+ offshoreTypeCommon: undefined,
+ offshoreTypeFpso: undefined,
+ offshoreTypeFlng: undefined,
+ offshoreTypeFpu: undefined,
+ offshoreTypePlatform: undefined,
+ offshoreTypeWtiv: undefined,
+ offshoreTypeGom: undefined,
+ picName: undefined,
+ picEmail: undefined,
+ picPhone: undefined,
+ agentName: undefined,
+ agentEmail: undefined,
+ agentPhone: undefined,
+ recentQuoteDate: undefined,
+ recentQuoteNumber: undefined,
+ recentOrderDate: undefined,
+ recentOrderNumber: undefined,
+ registrationDate: undefined,
+ registrant: undefined,
+ lastModifiedDate: undefined,
+ lastModifier: undefined,
...searchParams,
}
- const result = await getVendorPools(params)
+ console.log('VendorPoolTable - API call params:', params)
+ const result = await getVendorPools(params as GetVendorPoolSchema)
+ console.log('VendorPoolTable - API result:', {
+ dataCount: result.data.length,
+ pageCount: result.pageCount,
+ requestedPage: params.page
+ })
setData(result.data)
setPageCount(result.pageCount)
} catch (error) {
@@ -155,9 +131,11 @@ export function VendorPoolTable({
// 전체보기 모드에서는 페이징 없이 전체 데이터 로드
loadData({ perPage: 1000 }) // 충분히 큰 숫자로 전체 데이터 가져오기
} else {
- loadData({})
+ // 검색 시 페이지를 1페이지로 리셋
+ setPagination(prev => ({ ...prev, pageIndex: 0 }))
+ loadData({ page: 1, perPage: pagination.pageSize })
}
- }, [loadData, showAll])
+ }, [loadData, showAll, pagination.pageSize])
// 전체보기 토글 핸들러
const handleShowAllToggle = React.useCallback((checked: boolean) => {
@@ -174,8 +152,18 @@ export function VendorPoolTable({
// 초기 데이터 로드
React.useEffect(() => {
- loadData({})
- }, [loadData])
+ // 초기 로드 시 페이지를 1페이지로 설정
+ setPagination(prev => ({ ...prev, pageIndex: 0 }))
+ loadData({ page: 1, perPage: pagination.pageSize })
+ }, [pagination.pageSize])
+
+ // reloadTrigger가 변경될 때마다 데이터 리로드
+ React.useEffect(() => {
+ if (reloadTrigger && reloadTrigger > 0) {
+ console.log('VendorPoolTable - reloadTrigger changed, reloading data')
+ loadData({})
+ }
+ }, [reloadTrigger, loadData])
const table = useReactTable({
data,
@@ -186,27 +174,48 @@ export function VendorPoolTable({
getFilteredRowModel: getFilteredRowModel(),
manualPagination: !showAll, // 전체보기 시에는 수동 페이징 비활성화
pageCount: showAll ? 1 : pageCount, // 전체보기 시 1페이지, 일반 모드에서는 API에서 받은 pageCount 사용
- initialState: {
- pagination: {
- pageSize: showAll ? data.length : 10, // 전체보기 시 모든 데이터 표시
- },
+ state: {
+ pagination: showAll ? { pageIndex: 0, pageSize: data.length } : pagination,
},
onPaginationChange: (updater) => {
if (!showAll) {
// 전체보기가 아닐 때만 페이징 변경 처리
- const newState = typeof updater === 'function' ? updater(table.getState().pagination) : updater
- loadData({
- page: newState.pageIndex + 1,
- perPage: newState.pageSize,
+ const newPaginationState = typeof updater === 'function' ? updater(pagination) : updater
+
+ console.log('VendorPoolTable - Pagination changed:', {
+ currentState: pagination,
+ newPaginationState,
+ showAll,
+ willLoadData: !showAll
})
+
+ setPagination(newPaginationState)
+
+ const apiParams = {
+ page: newPaginationState.pageIndex + 1,
+ perPage: newPaginationState.pageSize,
+ }
+ console.log('VendorPoolTable - Loading data with params:', apiParams)
+ loadData(apiParams)
}
},
})
+ // 외부에서 선택된 ID들을 가져올 수 있도록 ref에 메소드 노출
+ useImperativeHandle(ref, () => ({
+ getSelectedIds: () => {
+ const selectedRows = table.getFilteredSelectedRowModel().rows
+ return selectedRows.map(row => row.original.id)
+ }
+ }))
+
+ // 선택된 행 개수
+ const selectedRowCount = table.getFilteredSelectedRowModel().rows.length
+
// 선택 상태 변경 시 콜백 호출
React.useEffect(() => {
- onSelectionChange?.(table.getFilteredSelectedRowModel().rows.length)
- }, [table.getFilteredSelectedRowModel().rows.length, onSelectionChange])
+ onSelectionChange?.(selectedRowCount)
+ }, [selectedRowCount, onSelectionChange])
// 선택 해제 요청이 오면 모든 선택 해제
React.useEffect(() => {
@@ -287,4 +296,6 @@ export function VendorPoolTable({
</div>
</div>
)
-}
+})
+
+VendorPoolTable.displayName = "VendorPoolTable"