From 98d178c8fe20a61a87e5d8f20e7d310ff6fefd6b Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Sun, 2 Nov 2025 19:06:08 +0900 Subject: (김준회) dolce: 도면구분을 서버사이드에서 처리하도록 변경 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enhanced-document-service.ts | 18 +++++ .../ship/enhanced-documents-table.tsx | 87 +++++++++------------- lib/vendor-document-list/validations.ts | 4 + 3 files changed, 58 insertions(+), 51 deletions(-) (limited to 'lib/vendor-document-list') diff --git a/lib/vendor-document-list/enhanced-document-service.ts b/lib/vendor-document-list/enhanced-document-service.ts index e5cce1b1..96a5ecff 100644 --- a/lib/vendor-document-list/enhanced-document-service.ts +++ b/lib/vendor-document-list/enhanced-document-service.ts @@ -1059,12 +1059,30 @@ export async function getDocumentDetails(documentId: number) { ilike(simplifiedDocumentsView.vendorDocNumber, searchTerm), ) } + + // 4.5. B4 필터 처리 (drawingMoveGbn 기반) + let b4FilterWhere + if (input.b4FilterType && input.b4FilterType !== 'all') { + if (input.b4FilterType === 'gtt_deliverable') { + b4FilterWhere = eq(simplifiedDocumentsView.drawingMoveGbn, '도면입수') + } else if (input.b4FilterType === 'shi_input') { + b4FilterWhere = eq(simplifiedDocumentsView.drawingMoveGbn, '도면제출') + } + } + + // 4.6. Project Code 필터 처리 + let projectCodeWhere + if (input.projectCode && input.projectCode !== 'all') { + projectCodeWhere = eq(simplifiedDocumentsView.projectCode, input.projectCode) + } // 5. 최종 WHERE 조건 (계약 ID들로 필터링) const finalWhere = and( eq(simplifiedDocumentsView.vendorId, Number(companyId)), advancedWhere, globalWhere, + b4FilterWhere, + projectCodeWhere, ) // 6. 정렬 처리 diff --git a/lib/vendor-document-list/ship/enhanced-documents-table.tsx b/lib/vendor-document-list/ship/enhanced-documents-table.tsx index dabb05bb..663caeeb 100644 --- a/lib/vendor-document-list/ship/enhanced-documents-table.tsx +++ b/lib/vendor-document-list/ship/enhanced-documents-table.tsx @@ -18,6 +18,7 @@ import { DataTable } from "@/components/data-table/data-table" import { SimplifiedDocumentsView } from "@/db/schema" import { getSimplifiedDocumentColumns } from "./enhanced-doc-table-columns" import { EnhancedDocTableToolbarActions } from "./enhanced-doc-table-toolbar-actions" +import { useQueryStates, parseAsString, parseAsStringEnum, parseAsInteger } from "nuqs" // 🔥 Project Code 필터를 위한 Select 컴포넌트 import 추가 import { @@ -70,19 +71,31 @@ export function SimplifiedDocumentsTable({ const { data, pageCount, drawingKind } = documentData const { primaryDrawingKind, b4Stats: serverB4Stats } = statsData - // 🔥 B4 필터 상태 추가 - const [b4FilterType, setB4FilterType] = React.useState<'all' | 'gtt_deliverable' | 'shi_input'>('all') - - // 🔥 Project Code 필터 상태 추가 - const [selectedProjectCode, setSelectedProjectCode] = React.useState('all') + // 🔥 URL searchParams를 통한 필터 상태 관리 + const [{ b4FilterType, projectCode, page }, setQueryStates] = useQueryStates( + { + b4FilterType: parseAsStringEnum<'all' | 'gtt_deliverable' | 'shi_input'>(['all', 'gtt_deliverable', 'shi_input']).withDefault('all'), + projectCode: parseAsString.withDefault('all'), + page: parseAsInteger.withDefault(1), + }, + { + history: "push", + shallow: false, + } + ) + + // page 변수는 현재 사용하지 않지만, setQueryStates에서 page를 업데이트하기 위해 필요 + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _ensurePageIsInState = page - // 🔥 고유한 Project Code 목록 추출 및 카운트 메모이제이션 + // 🔥 통계 데이터를 위한 전체 데이터 조회 (필터링 없이) const projectCodeStats = React.useMemo(() => { + // statsData에서 전체 프로젝트 코드 목록을 가져옴 (향후 개선 가능) const projectMap = new Map() data.forEach(doc => { - const projectCode = doc.projectCode || 'Unknown' - projectMap.set(projectCode, (projectMap.get(projectCode) || 0) + 1) + const code = doc.projectCode || 'Unknown' + projectMap.set(code, (projectMap.get(code) || 0) + 1) }) // 정렬된 배열로 변환 (프로젝트 코드 알파벳순) @@ -91,40 +104,12 @@ export function SimplifiedDocumentsTable({ .map(([code, count]) => ({ code, count })) }, [data]) - // 🔥 데이터 로드 콜백을 useCallback으로 최적화 - const handleDataLoaded = React.useCallback((loadedData: SimplifiedDocumentsView[]) => { - onDataLoaded?.(loadedData) - }, [onDataLoaded]) - - // 🔥 B4 및 Project Code 필터링된 데이터 메모이제이션 - const filteredData = React.useMemo(() => { - let result: SimplifiedDocumentsView[] = data - - // B4 필터 적용 - if (b4FilterType !== 'all') { - if (b4FilterType === 'gtt_deliverable') { - result = result.filter(doc => doc.drawingMoveGbn === '도면입수') - } else if (b4FilterType === 'shi_input') { - result = result.filter(doc => doc.drawingMoveGbn === '도면제출') - } - } - - // Project Code 필터 적용 - if (selectedProjectCode !== 'all') { - result = result.filter(doc => - (doc.projectCode || 'Unknown') === selectedProjectCode - ) - } - - return result - }, [data, b4FilterType, selectedProjectCode]) - - // 🔥 데이터가 로드되면 콜백 호출 (필터링된 데이터 사용) + // 🔥 데이터 로드 콜백 (서버에서 이미 필터링되어 옴) React.useEffect(() => { - if (filteredData && handleDataLoaded) { - handleDataLoaded(filteredData) + if (data && onDataLoaded) { + onDataLoaded(data) } - }, [filteredData, handleDataLoaded]) + }, [data, onDataLoaded]) // 🔥 컬럼 메모이제이션 최적화 const columns = React.useMemo( @@ -268,7 +253,7 @@ export function SimplifiedDocumentsTable({ // 🔥 B4 문서 존재 여부 체크 메모이제이션 const hasB4Documents = React.useMemo(() => { - return data.some(doc => doc.drawingKind === 'B4') + return data.some((doc: SimplifiedDocumentsView) => doc.drawingKind === 'B4') }, [data]) // 🔥 최종 필터 필드 메모이제이션 @@ -286,7 +271,7 @@ export function SimplifiedDocumentsTable({ const getRowId = React.useCallback((originalRow: SimplifiedDocumentsView) => String(originalRow.documentId), []) const { table } = useDataTable({ - data: filteredData, + data, // 서버에서 이미 필터링된 데이터 사용 columns, pageCount, enablePinning: true, @@ -324,7 +309,7 @@ export function SimplifiedDocumentsTable({
- {filteredData.length} documents + {data.length} documents
@@ -339,8 +324,8 @@ export function SimplifiedDocumentsTable({ - {selectedProjectCode !== 'all' && ( + {projectCode !== 'all' && (