summaryrefslogtreecommitdiff
path: root/lib/avl
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-09-24 17:36:08 +0900
committerjoonhoekim <26rote@gmail.com>2025-09-24 17:36:08 +0900
commitbf2db28586569499e44b58999f2e0f33ed4cdeb5 (patch)
tree9ef9305829fdec30ec7a442f2ba0547a62dba7a9 /lib/avl
parent1bda7f20f113737f4af32495e7ff24f6022dc283 (diff)
(김준회) 구매 요청사항 반영 - vendor-pool 및 avl detail (이진용 프로)
Diffstat (limited to 'lib/avl')
-rw-r--r--lib/avl/avl-itb-rfq-service.ts289
-rw-r--r--lib/avl/service.ts10
-rw-r--r--lib/avl/table/avl-detail-table.tsx70
-rw-r--r--lib/avl/table/avl-registration-area.tsx10
-rw-r--r--lib/avl/table/avl-table-columns.tsx16
-rw-r--r--lib/avl/table/avl-table.tsx26
-rw-r--r--lib/avl/table/project-avl-table.tsx33
-rw-r--r--lib/avl/table/standard-avl-table.tsx11
-rw-r--r--lib/avl/table/vendor-pool-table.tsx3
9 files changed, 58 insertions, 410 deletions
diff --git a/lib/avl/avl-itb-rfq-service.ts b/lib/avl/avl-itb-rfq-service.ts
deleted file mode 100644
index f7662c2e..00000000
--- a/lib/avl/avl-itb-rfq-service.ts
+++ /dev/null
@@ -1,289 +0,0 @@
-// AVL 기반 RFQ/ITB 생성 서비스
-'use server'
-
-import { getServerSession } from 'next-auth/next'
-import { authOptions } from '@/app/api/auth/[...nextauth]/route'
-import db from '@/db/db'
-import { users, rfqsLast, rfqPrItems } from '@/db/schema'
-import { eq, desc, sql, and } from 'drizzle-orm'
-import type { AvlDetailItem } from './types'
-
-// RFQ/ITB 코드 생성 헬퍼 함수
-async function generateAvlRfqItbCode(userCode: string, type: 'RFQ' | 'ITB'): Promise<string> {
- try {
- // 동일한 userCode를 가진 마지막 RFQ/ITB 번호 조회
- const lastRfq = await db
- .select({ rfqCode: rfqsLast.rfqCode })
- .from(rfqsLast)
- .where(
- and(
- eq(rfqsLast.picCode, userCode),
- type === 'RFQ'
- ? sql`${rfqsLast.prNumber} IS NOT NULL AND ${rfqsLast.prNumber} != ''`
- : sql`${rfqsLast.projectCompany} IS NOT NULL AND ${rfqsLast.projectCompany} != ''`
- )
- )
- .orderBy(desc(rfqsLast.createdAt))
- .limit(1);
-
- let nextNumber = 1;
-
- if (lastRfq.length > 0 && lastRfq[0].rfqCode) {
- // 마지막 코드에서 숫자 부분 추출 (ex: "RFQ001001" -> "001")
- const codeMatch = lastRfq[0].rfqCode.match(/([A-Z]{3})(\d{3})(\d{3})/);
- if (codeMatch) {
- const currentNumber = parseInt(codeMatch[3]);
- nextNumber = currentNumber + 1;
- }
- }
-
- // 코드 형식: RFQ/ITB + userCode(3자리) + 일련번호(3자리)
- const prefix = type === 'RFQ' ? 'RFQ' : 'ITB';
- const paddedNumber = nextNumber.toString().padStart(3, '0');
-
- return `${prefix}${userCode}${paddedNumber}`;
- } catch (error) {
- console.error('RFQ/ITB 코드 생성 오류:', error);
- // 오류 발생 시 기본 코드 생성
- const prefix = type === 'RFQ' ? 'RFQ' : 'ITB';
- return `${prefix}${userCode}001`;
- }
-}
-
-// AVL 기반 RFQ/ITB 생성을 위한 입력 타입
-export interface CreateAvlRfqItbInput {
- // AVL 정보
- avlItems: AvlDetailItem[]
- businessType: '조선' | '해양' // 조선: RFQ, 해양: ITB
-
- // RFQ/ITB 공통 정보
- rfqTitle: string
- dueDate: Date
- remark?: string
-
- // 담당자 정보
- picUserId: number
-
- // 추가 정보 (ITB용)
- projectCompany?: string
- projectFlag?: string
- projectSite?: string
- smCode?: string
-
- // PR 정보 (RFQ용)
- prNumber?: string
- prIssueDate?: Date
- series?: string
-}
-
-// RFQ/ITB 생성 결과 타입
-export interface CreateAvlRfqItbResult {
- success: boolean
- message?: string
- data?: {
- id: number
- rfqCode: string
- type: 'RFQ' | 'ITB'
- }
- error?: string
-}
-
-/**
- * AVL 기반 RFQ/ITB 생성 서비스
- * - 조선 사업: RFQ 생성
- * - 해양 사업: ITB 생성
- * - rfqLast 테이블에 직접 데이터 삽입
- */
-export async function createAvlRfqItbAction(input: CreateAvlRfqItbInput): Promise<CreateAvlRfqItbResult> {
- try {
- // 세션 확인
- const session = await getServerSession(authOptions)
- if (!session?.user?.id) {
- return {
- success: false,
- error: '로그인이 필요합니다.'
- }
- }
-
- // 입력 검증
- if (!input.avlItems || input.avlItems.length === 0) {
- return {
- success: false,
- error: '견적 요청할 AVL 아이템이 없습니다.'
- }
- }
-
- if (!input.businessType || !['조선', '해양'].includes(input.businessType)) {
- return {
- success: false,
- error: '올바른 사업 유형을 선택해주세요.'
- }
- }
-
- // 담당자 정보 확인
- const picUser = await db
- .select({
- id: users.id,
- name: users.name,
- userCode: users.userCode
- })
- .from(users)
- .where(eq(users.id, input.picUserId))
- .limit(1)
-
- if (!picUser || picUser.length === 0) {
- return {
- success: false,
- error: '담당자를 찾을 수 없습니다.'
- }
- }
-
- const userCode = picUser[0].userCode;
- if (!userCode || userCode.length !== 3) {
- return {
- success: false,
- error: '담당자의 userCode가 올바르지 않습니다 (3자리 필요)'
- }
- }
-
- // 사업 유형에 따른 RFQ/ITB 구분 및 데이터 준비
- const rfqType = input.businessType === '조선' ? 'RFQ' : 'ITB'
- const rfqTypeLabel = rfqType
-
- // RFQ/ITB 코드 생성
- const rfqCode = await generateAvlRfqItbCode(userCode, rfqType)
-
- // 대표 아이템 정보 추출 (첫 번째 아이템)
- const representativeItem = input.avlItems[0]
-
- // 트랜잭션으로 RFQ/ITB 생성
- const result = await db.transaction(async (tx) => {
- // 1. rfqsLast 테이블에 기본 정보 삽입
- const [newRfq] = await tx
- .insert(rfqsLast)
- .values({
- rfqCode,
- status: "RFQ 생성",
- dueDate: input.dueDate,
-
- // 대표 아이템 정보
- itemCode: representativeItem.materialGroupCode || `AVL-${representativeItem.id}`,
- itemName: representativeItem.materialNameCustomerSide || representativeItem.materialGroupName || 'AVL 아이템',
-
- // 담당자 정보
- pic: input.picUserId,
- picCode: userCode,
- picName: picUser[0].name || '',
-
- // 기타 정보
- remark: input.remark || null,
- createdBy: Number(session.user.id),
- updatedBy: Number(session.user.id),
- createdAt: new Date(),
- updatedAt: new Date(),
-
- // 사업 유형별 추가 필드
- ...(input.businessType === '조선' && {
- // RFQ 필드
- prNumber: input.prNumber || rfqCode, // PR 번호가 없으면 RFQ 코드 사용
- prIssueDate: input.prIssueDate || new Date(),
- series: input.series || null
- }),
-
- ...(input.businessType === '해양' && {
- // ITB 필드
- projectCompany: input.projectCompany || 'AVL 기반 프로젝트',
- projectFlag: input.projectFlag || null,
- projectSite: input.projectSite || null,
- smCode: input.smCode || null
- })
- })
- .returning()
-
- // 2. rfqPrItems 테이블에 AVL 아이템들 삽입
- const prItemsData = input.avlItems.map((item, index) => ({
- rfqsLastId: newRfq.id,
- rfqItem: `${index + 1}`.padStart(3, '0'), // 001, 002, ...
- prItem: `${index + 1}`.padStart(3, '0'),
- prNo: rfqCode,
-
- materialCode: item.materialGroupCode || `AVL-${item.id}`,
- materialDescription: item.materialNameCustomerSide || item.materialGroupName || `AVL 아이템 ${index + 1}`,
- materialCategory: item.materialGroupCode || null,
-
- quantity: 1, // AVL에서는 수량 정보가 없으므로 1로 설정
- uom: 'EA', // 기본 단위
-
- majorYn: index === 0, // 첫 번째 아이템을 주요 아이템으로 설정
-
- deliveryDate: input.dueDate, // 납기일은 RFQ 마감일과 동일하게 설정
- }))
-
- await tx.insert(rfqPrItems).values(prItemsData)
-
- return newRfq
- })
-
- // 성공 결과 반환
- return {
- success: true,
- message: `${rfqTypeLabel}가 성공적으로 생성되었습니다.`,
- data: {
- id: result.id,
- rfqCode: result.rfqCode!,
- type: rfqTypeLabel as 'RFQ' | 'ITB'
- }
- }
-
- } catch (error) {
- console.error('AVL RFQ/ITB 생성 오류:', error)
-
- if (error instanceof Error) {
- return {
- success: false,
- error: error.message
- }
- }
-
- return {
- success: false,
- error: '알 수 없는 오류가 발생했습니다.'
- }
- }
-}
-
-/**
- * AVL 데이터에서 RFQ/ITB 생성을 위한 기본값 설정 헬퍼 함수
- */
-export async function prepareAvlRfqItbInput(
- selectedItems: AvlDetailItem[],
- businessType: '조선' | '해양',
- defaultValues?: Partial<CreateAvlRfqItbInput>
-): Promise<CreateAvlRfqItbInput> {
- const now = new Date()
- const dueDate = new Date(now.getTime() + (30 * 24 * 60 * 60 * 1000)) // 30일 후
-
- // 선택된 아이템들의 대표 정보를 추출하여 제목 생성
- const representativeItem = selectedItems[0]
- const itemCount = selectedItems.length
- const titleSuffix = itemCount > 1 ? ` 외 ${itemCount - 1}건` : ''
- const defaultTitle = `${representativeItem?.materialNameCustomerSide || 'AVL 자재'}${titleSuffix}`
-
- return {
- avlItems: selectedItems,
- businessType,
- rfqTitle: defaultValues?.rfqTitle || `${businessType} - ${defaultTitle}`,
- dueDate: defaultValues?.dueDate || dueDate,
- remark: defaultValues?.remark || `AVL 기반 ${businessType} 견적 요청`,
- picUserId: defaultValues?.picUserId || 0, // 호출 측에서 설정 필요
- // ITB용 필드들
- projectCompany: defaultValues?.projectCompany,
- projectFlag: defaultValues?.projectFlag,
- projectSite: defaultValues?.projectSite,
- smCode: defaultValues?.smCode,
- // RFQ용 필드들
- prNumber: defaultValues?.prNumber,
- prIssueDate: defaultValues?.prIssueDate,
- series: defaultValues?.series
- }
-}
diff --git a/lib/avl/service.ts b/lib/avl/service.ts
index 0340f52c..1f781486 100644
--- a/lib/avl/service.ts
+++ b/lib/avl/service.ts
@@ -438,14 +438,8 @@ export async function handleAvlAction(
): Promise<ActionResult> {
try {
switch (action) {
- case "new-registration":
- return { success: true, message: "신규 AVL 등록 모드" };
-
- case "standard-registration":
- return { success: true, message: "표준 AVL 등재 모드" };
-
- case "project-registration":
- return { success: true, message: "프로젝트 AVL 등재 모드" };
+ case "avl-registration":
+ return { success: true, message: "AVL 등록 패널을 활성화했습니다." };
case "bulk-import":
if (!data?.file) {
diff --git a/lib/avl/table/avl-detail-table.tsx b/lib/avl/table/avl-detail-table.tsx
index 4408340a..22c503ff 100644
--- a/lib/avl/table/avl-detail-table.tsx
+++ b/lib/avl/table/avl-detail-table.tsx
@@ -6,12 +6,10 @@ import { useDataTable } from "@/hooks/use-data-table"
import { DataTable } from "@/components/data-table/data-table"
import { Button } from "@/components/ui/button"
import { toast } from "sonner"
-import { createAvlRfqItbAction, prepareAvlRfqItbInput } from "../avl-itb-rfq-service"
import { columns } from "./columns-detail"
import type { AvlDetailItem } from "../types"
import { BackButton } from "@/components/ui/back-button"
-import { useSession } from "next-auth/react"
interface AvlDetailTableProps {
data: AvlDetailItem[]
@@ -33,63 +31,11 @@ export function AvlDetailTable({
projectInfo,
businessType,
}: AvlDetailTableProps) {
- // 견적요청 처리 상태 관리
- const [isProcessingQuote, setIsProcessingQuote] = React.useState(false)
- const { data: session } = useSession()
-
- // 견적요청 처리 함수
- const handleQuoteRequest = React.useCallback(async () => {
- if (!businessType || !['조선', '해양'].includes(businessType)) {
- toast.error("공사구분이 올바르지 않습니다. 견적요청 처리 불가.")
- return
- }
- if (data.length === 0) {
- toast.error("견적요청할 AVL 데이터가 없습니다.")
- return
- }
-
- setIsProcessingQuote(true)
-
- try {
- // 현재 사용자 세션에서 ID 가져오기
- const currentUserId = session?.user?.id ? Number(session.user.id) : undefined
-
- // 견적요청 입력 데이터 준비 (전체 데이터를 사용)
- const quoteInput = await prepareAvlRfqItbInput(
- data, // 전체 데이터를 사용
- businessType as '조선' | '해양',
- {
- picUserId: currentUserId,
- rfqTitle: `${businessType} AVL 견적요청 - ${data[0]?.materialNameCustomerSide || 'AVL 아이템'}${data.length > 1 ? ` 외 ${data.length - 1}건` : ''}`
- }
- )
-
- // 견적요청 실행
- const result = await createAvlRfqItbAction(quoteInput)
-
- if (result.success) {
- toast.success(`${result.data?.type}가 성공적으로 생성되었습니다. (코드: ${result.data?.rfqCode})`)
- } else {
- toast.error(result.error || "견적요청 처리 중 오류가 발생했습니다.")
- }
-
- } catch (error) {
- console.error('견적요청 처리 오류:', error)
- toast.error("견적요청 처리 중 오류가 발생했습니다.")
- } finally {
- setIsProcessingQuote(false)
- }
- }, [businessType, data, session?.user?.id])
// 액션 핸들러
const handleAction = React.useCallback(async (action: string) => {
switch (action) {
-
- case 'quote-request':
- await handleQuoteRequest()
- break
-
case 'vendor-pool':
window.open('/evcp/vendor-pool', '_blank')
break
@@ -107,7 +53,7 @@ export function AvlDetailTable({
default:
toast.error(`알 수 없는 액션: ${action}`)
}
- }, [handleQuoteRequest])
+ }, [])
// 테이블 메타 설정
@@ -153,24 +99,10 @@ export function AvlDetailTable({
{/* 상단 버튼 영역 */}
<div className="flex items-center gap-2 ml-auto justify-end">
- {
- // 표준AVL로는 견적요청하지 않으며, 프로젝트 AVL로만 견적요청처리
- avlType === '프로젝트AVL' && businessType && ['조선', '해양'].includes(businessType) &&
- <Button
- variant="outline"
- size="sm"
- onClick={() => handleAction('quote-request')}
- disabled={data.length === 0 || isProcessingQuote}
- >
- {isProcessingQuote ? '처리중...' : `${businessType} 견적요청 (${businessType === '조선' ? 'RFQ' : 'ITB'})`}
- </Button>
- }
-
{/* 단순 이동 버튼 */}
<Button variant="outline" size="sm" onClick={() => handleAction('vendor-pool')}>
Vendor Pool
</Button>
-
</div>
{/* 데이터 테이블 */}
diff --git a/lib/avl/table/avl-registration-area.tsx b/lib/avl/table/avl-registration-area.tsx
index ba1c76d4..6c7eba9d 100644
--- a/lib/avl/table/avl-registration-area.tsx
+++ b/lib/avl/table/avl-registration-area.tsx
@@ -15,16 +15,6 @@ import { toast } from "sonner"
// 선택된 테이블 타입
type SelectedTable = 'project' | 'standard' | 'vendor' | null
-// TODO: 나머지 테이블들도 ref 지원 추가 시 인터페이스 추가 필요
-// interface StandardAvlTableRef {
-// getSelectedIds?: () => number[]
-// }
-//
-// interface VendorPoolTableRef {
-// getSelectedIds?: () => number[]
-// }
-
-
// 선택 상태 액션 타입
type SelectionAction =
| { type: 'SELECT_PROJECT'; count: number }
diff --git a/lib/avl/table/avl-table-columns.tsx b/lib/avl/table/avl-table-columns.tsx
index 6ec2c3db..06005d3d 100644
--- a/lib/avl/table/avl-table-columns.tsx
+++ b/lib/avl/table/avl-table-columns.tsx
@@ -45,9 +45,7 @@ export function getColumns({ selectedRows = [], onRowSelect }: GetColumnsProps):
enableSorting: false,
enableHiding: false,
enableResizing: false,
- size: 10,
- minSize: 10,
- maxSize: 10,
+ size: 50,
},
// No 컬럼
{
@@ -57,7 +55,7 @@ export function getColumns({ selectedRows = [], onRowSelect }: GetColumnsProps):
),
cell: ({ getValue }) => <div className="text-center">{getValue() as number}</div>,
enableResizing: true,
- size: 60,
+ size: 100,
},
// AVL 분류 컬럼
{
@@ -148,7 +146,7 @@ export function getColumns({ selectedRows = [], onRowSelect }: GetColumnsProps):
{
accessorKey: "htDivision",
header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="H/T 구분" />
+ <DataTableColumnHeaderSimple column={column} title="H/T" />
),
cell: ({ getValue }) => {
const value = getValue() as string
@@ -205,7 +203,7 @@ export function getColumns({ selectedRows = [], onRowSelect }: GetColumnsProps):
<DataTableColumnHeaderSimple column={column} title="자재그룹" />
),
enableResizing: true,
- size: 120,
+ size: 100,
},
// 협력업체 컬럼
{
@@ -214,7 +212,7 @@ export function getColumns({ selectedRows = [], onRowSelect }: GetColumnsProps):
<DataTableColumnHeaderSimple column={column} title="협력업체" />
),
enableResizing: true,
- size: 150,
+ size: 100,
},
// Tier 컬럼
{
@@ -280,7 +278,7 @@ export function getColumns({ selectedRows = [], onRowSelect }: GetColumnsProps):
return <div className="text-center text-sm">{date}</div>
},
enableResizing: true,
- size: 100,
+ size: 120,
},
// 최종변경자 컬럼
{
@@ -293,7 +291,7 @@ export function getColumns({ selectedRows = [], onRowSelect }: GetColumnsProps):
return <div className="text-center text-sm">{value}</div>
},
enableResizing: true,
- size: 100,
+ size: 120,
},
// 액션 컬럼
{
diff --git a/lib/avl/table/avl-table.tsx b/lib/avl/table/avl-table.tsx
index 61db658d..9b6ac90b 100644
--- a/lib/avl/table/avl-table.tsx
+++ b/lib/avl/table/avl-table.tsx
@@ -100,9 +100,9 @@ export function AvlTable({ data, pageCount, isLoading, onRegistrationModeChange,
const handleAction = React.useCallback(async (action: string, data?: Partial<AvlListItem>) => {
try {
switch (action) {
- case 'standard-registration':
- // 표준 AVL 등록
- const result = await handleAvlActionAction('standard-registration')
+ case 'avl-registration':
+ // AVL 등록 (통합된 기능)
+ const result = await handleAvlActionAction('avl-registration')
if (result.success) {
toast.success(result.message)
onRegistrationModeChange?.('standard') // 등록 모드 변경 콜백 호출
@@ -112,9 +112,10 @@ export function AvlTable({ data, pageCount, isLoading, onRegistrationModeChange,
break
case 'view-detail':
- // 상세 조회 (페이지 이동)
+ // 상세 조회 (페이지 이동) - 원래 방식으로 복원
if (data?.id && !String(data.id).startsWith('temp-')) {
- window.location.href = `/evcp/avl/${data.id}`
+ console.log('AVL 상세보기 이동:', data.id) // 디버깅용
+ window.location.href = `/ko/evcp/avl/${data.id}`
}
break
@@ -177,6 +178,9 @@ export function AvlTable({ data, pageCount, isLoading, onRegistrationModeChange,
columnSizing: {},
},
getRowId: (row) => String(row.id),
+ meta: {
+ onAction: handleAction,
+ },
})
return (
@@ -191,17 +195,9 @@ export function AvlTable({ data, pageCount, isLoading, onRegistrationModeChange,
<Button
variant="outline"
size="sm"
- onClick={() => handleAction('standard-registration')}
- >
- 표준AVL등록
- </Button>
-
- <Button
- variant="outline"
- size="sm"
- onClick={() => handleAction('project-registration')}
+ onClick={() => handleAction('avl-registration')}
>
- 프로젝트AVL등록
+ AVL 등록
</Button>
</div>
diff --git a/lib/avl/table/project-avl-table.tsx b/lib/avl/table/project-avl-table.tsx
index 9584c6f9..ad72b221 100644
--- a/lib/avl/table/project-avl-table.tsx
+++ b/lib/avl/table/project-avl-table.tsx
@@ -177,12 +177,40 @@ export const ProjectAvlTable = forwardRef<ProjectAvlTableRef, ProjectAvlTablePro
const projectData = await getProjectInfoByCode(projectCode.trim(), 'both')
if (projectData) {
+ // constructionSector 동적 결정
+ let constructionSector = "해양" // 기본값
+ if (projectData.source === 'projects') {
+ // projects 테이블의 경우: type='ship'이면 '조선', 그 외는 '해양'
+ constructionSector = projectData.type === 'ship' ? "조선" : "해양"
+ } else if (projectData.source === 'biddingProjects') {
+ // biddingProjects 테이블의 경우: sector가 'S'이면 '조선', 'M'이면 '해양'
+ constructionSector = projectData.sector === 'S' ? "조선" : "해양"
+ }
+
+ // htDivision 동적 결정
+ let htDivision = "" // 기본값
+ if (constructionSector === "조선") {
+ // constructionSector가 '조선'인 경우는 항상 H
+ htDivision = "H"
+ } else if (projectData.source === 'projects') {
+ // projects에서는 TYPE_MDG 컬럼이 Top이면 T, Hull이면 H
+ htDivision = projectData.typeMdg === 'Top' ? "T" : "H"
+ } else if (projectData.source === 'biddingProjects') {
+ if (projectData.sector === 'S') {
+ // biddingProjects에서 sector가 S이면 HtDivision은 항상 H
+ htDivision = "H"
+ } else if (projectData.sector === 'M') {
+ // biddingProjects에서 sector가 M인 경우: pjtType이 TOP이면 'T', HULL이면 'H'
+ htDivision = projectData.pjtType === 'TOP' ? "T" : "H"
+ }
+ }
+
// 프로젝트 정보 설정
setProjectInfo({
projectName: projectData.projectName || "",
- constructionSector: "조선", // 기본값으로 조선 설정 (필요시 로직 변경)
+ constructionSector: constructionSector,
shipType: projectData.shipType || projectData.projectMsrm || "",
- htDivision: projectData.projectHtDivision || ""
+ htDivision: htDivision
})
// 검색 상태 설정
@@ -307,6 +335,7 @@ export const ProjectAvlTable = forwardRef<ProjectAvlTableRef, ProjectAvlTablePro
getFilteredRowModel: getFilteredRowModel(),
manualPagination: true,
pageCount,
+ columnResizeMode: "onChange",
state: {
pagination,
},
diff --git a/lib/avl/table/standard-avl-table.tsx b/lib/avl/table/standard-avl-table.tsx
index bacb5812..06fa6931 100644
--- a/lib/avl/table/standard-avl-table.tsx
+++ b/lib/avl/table/standard-avl-table.tsx
@@ -123,6 +123,7 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
getFilteredRowModel: getFilteredRowModel(),
manualPagination: true,
pageCount,
+ columnResizeMode: "onChange",
state: {
pagination,
},
@@ -150,11 +151,8 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
},
})
- // 공사부문 변경 시 선종 초기화
const handleConstructionSectorChange = React.useCallback((value: string) => {
setSearchConstructionSector(value)
- // 공사부문이 변경되면 선종을 빈 값으로 초기화
- setSelectedShipType(undefined)
}, [])
// 검색 상태 변경 시 부모 컴포넌트에 전달
@@ -506,7 +504,7 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
<div className="space-y-2">
<label className="text-sm font-medium">공사부문</label>
<Select value={searchConstructionSector} onValueChange={handleConstructionSectorChange}>
- <SelectTrigger>
+ <SelectTrigger className="bg-background">
<SelectValue />
</SelectTrigger>
<SelectContent>
@@ -526,7 +524,6 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
selectedShipType={selectedShipType}
onShipTypeSelect={setSelectedShipType}
placeholder="선종을 선택하세요"
- disabled={!searchConstructionSector}
className="h-10"
/>
</div>
@@ -535,7 +532,7 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
<div className="space-y-2">
<label className="text-sm font-medium">AVL종류</label>
<Select value={searchAvlKind} onValueChange={setSearchAvlKind}>
- <SelectTrigger>
+ <SelectTrigger className="bg-background">
<SelectValue />
</SelectTrigger>
<SelectContent>
@@ -552,7 +549,7 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
<div className="space-y-2">
<label className="text-sm font-medium">H/T 구분</label>
<Select value={searchHtDivision} onValueChange={setSearchHtDivision}>
- <SelectTrigger>
+ <SelectTrigger className="bg-background">
<SelectValue />
</SelectTrigger>
<SelectContent>
diff --git a/lib/avl/table/vendor-pool-table.tsx b/lib/avl/table/vendor-pool-table.tsx
index 7ad9eb56..3ac67928 100644
--- a/lib/avl/table/vendor-pool-table.tsx
+++ b/lib/avl/table/vendor-pool-table.tsx
@@ -174,6 +174,7 @@ export const VendorPoolTable = forwardRef<VendorPoolTableRef, VendorPoolTablePro
getFilteredRowModel: getFilteredRowModel(),
manualPagination: !showAll, // 전체보기 시에는 수동 페이징 비활성화
pageCount: showAll ? 1 : pageCount, // 전체보기 시 1페이지, 일반 모드에서는 API에서 받은 pageCount 사용
+ columnResizeMode: "onChange",
state: {
pagination: showAll ? { pageIndex: 0, pageSize: data.length } : pagination,
},
@@ -262,7 +263,7 @@ export const VendorPoolTable = forwardRef<VendorPoolTableRef, VendorPoolTablePro
placeholder="설계공종, 업체명, 자재그룹 등으로 검색..."
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
- className="flex-1"
+ className="flex-1 bg-background"
onKeyPress={(e) => {
if (e.key === 'Enter') {
handleSearch()