diff options
Diffstat (limited to 'lib/vendor-document-list/ship')
3 files changed, 52 insertions, 38 deletions
diff --git a/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx b/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx index 43788c8a..3ff2f467 100644 --- a/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx +++ b/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx @@ -52,7 +52,6 @@ import { FileText, } from "lucide-react" -import { SimplifiedDocumentsView } from "@/db/schema" import { bulkUploadB4Documents } from "../enhanced-document-service" // 파일명 파싱 유틸리티 @@ -94,10 +93,15 @@ const formSchema = z.object({ files: z.array(z.instanceof(File)).min(1, "Please select files"), }) +export interface ProjectOption { + id: string + code: string +} + interface BulkB4UploadDialogProps { open: boolean onOpenChange: (open: boolean) => void - allDocuments: SimplifiedDocumentsView[] + projectOptions: ProjectOption[] } interface ParsedFile { @@ -110,8 +114,8 @@ interface ParsedFile { export function BulkB4UploadDialog({ open, - onOpenChange, - allDocuments + onOpenChange, + projectOptions }: BulkB4UploadDialogProps) { const [isUploading, setIsUploading] = React.useState(false) const [parsedFiles, setParsedFiles] = React.useState<ParsedFile[]>([]) @@ -121,15 +125,6 @@ export function BulkB4UploadDialog({ const [pendingProjectId, setPendingProjectId] = React.useState<string>("") const router = useRouter() - // 프로젝트 ID 추출 - const projectOptions = React.useMemo(() => { - const projectIds = [...new Set(allDocuments.map(doc => doc.projectId).filter(Boolean))] - return projectIds.map(id => ({ - id: String(id), - code: allDocuments.find(doc => doc.projectId === id)?.projectCode || `Project ${id}` - })) - }, [allDocuments]) - const form = useForm<z.infer<typeof formSchema>>({ resolver: zodResolver(formSchema), defaultValues: { diff --git a/lib/vendor-document-list/ship/enhanced-doc-table-toolbar-actions.tsx b/lib/vendor-document-list/ship/enhanced-doc-table-toolbar-actions.tsx index 94252db5..846eb5b2 100644 --- a/lib/vendor-document-list/ship/enhanced-doc-table-toolbar-actions.tsx +++ b/lib/vendor-document-list/ship/enhanced-doc-table-toolbar-actions.tsx @@ -13,20 +13,28 @@ import { SendToSHIButton } from "./send-to-shi-button" import { ImportFromDOLCEButton } from "./import-from-dolce-button" import { BulkB4UploadDialog } from "./bulk-b4-upload-dialog" +interface ProjectCodeStat { + code: string + count: number + projectId: number | null +} + interface EnhancedDocTableToolbarActionsProps { table: Table<SimplifiedDocumentsView> projectType: "ship" | "plant" b4: boolean + projectCodeStats?: ProjectCodeStat[] } export function EnhancedDocTableToolbarActions({ table, projectType, - b4 + b4, + projectCodeStats = [] }: EnhancedDocTableToolbarActionsProps) { const [bulkUploadDialogOpen, setBulkUploadDialogOpen] = React.useState(false) - // 🔥 메모이제이션으로 불필요한 재계산 방지 + // 메모이제이션으로 불필요한 재계산 방지 const allDocuments = React.useMemo(() => { return table.getFilteredRowModel().rows.map(row => row.original) }, [ @@ -35,20 +43,30 @@ export function EnhancedDocTableToolbarActions({ table.getState().globalFilter, // 전역 필터가 변경될 때만 재계산 ]) - // 🔥 projectIds 메모이제이션 (ImportFromDOLCEButton에서 중복 계산 방지) + // projectIds 메모이제이션 (ImportFromDOLCEButton에서 중복 계산 방지) const projectIds = React.useMemo(() => { const uniqueIds = [...new Set(allDocuments.map(doc => doc.projectId).filter(Boolean))] return uniqueIds.sort() }, [allDocuments]) - // 🔥 핸들러들을 useCallback으로 메모이제이션 + // 프로젝트 옵션 생성 (전체 프로젝트 목록) + const projectOptions = React.useMemo(() => { + return projectCodeStats + .filter(stat => stat.code !== 'Unknown' && stat.projectId) + .map(stat => ({ + id: String(stat.projectId), + code: stat.code + })) + }, [projectCodeStats]) + + // 핸들러들을 useCallback으로 메모이제이션 const handleSyncComplete = React.useCallback(() => { table.resetRowSelection() }, [table]) const handleDocumentAdded = React.useCallback(() => { table.resetRowSelection() - // 🔥 강제 새로고침 대신 더 효율적인 방법 사용 + // 강제 새로고침 대신 더 효율적인 방법 사용 setTimeout(() => { // 상태 업데이트만으로 충분한 경우가 많음 window.location.reload() @@ -62,7 +80,7 @@ export function EnhancedDocTableToolbarActions({ }, 500) }, [table]) - // 🔥 Export 핸들러 메모이제이션 + // Export 핸들러 메모이제이션 const handleExport = React.useCallback(() => { exportTableToExcel(table, { filename: "Document-list", @@ -76,7 +94,7 @@ export function EnhancedDocTableToolbarActions({ {/* SHIP: DOLCE에서 목록 가져오기 */} <ImportFromDOLCEButton allDocuments={allDocuments} - projectIds={projectIds} // 🔥 미리 계산된 projectIds 전달 + projectIds={projectIds} // 미리 계산된 projectIds 전달 onImportComplete={handleImportComplete} /> @@ -117,7 +135,7 @@ export function EnhancedDocTableToolbarActions({ <BulkB4UploadDialog open={bulkUploadDialogOpen} onOpenChange={setBulkUploadDialogOpen} - allDocuments={allDocuments} + projectOptions={projectOptions} /> )} </> diff --git a/lib/vendor-document-list/ship/enhanced-documents-table.tsx b/lib/vendor-document-list/ship/enhanced-documents-table.tsx index d92f16dd..3eda0ffb 100644 --- a/lib/vendor-document-list/ship/enhanced-documents-table.tsx +++ b/lib/vendor-document-list/ship/enhanced-documents-table.tsx @@ -20,7 +20,7 @@ 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 추가 +// Project Code 필터를 위한 Select 컴포넌트 import 추가 import { Select, SelectContent, @@ -60,18 +60,18 @@ export function SimplifiedDocumentsTable({ allPromises, onDataLoaded, }: SimplifiedDocumentsTableProps) { - // 🔥 React.use() 결과를 안전하게 처리 + // React.use() 결과를 안전하게 처리 const promiseResults = React.use(allPromises) const [documentResult, statsResult] = promiseResults - // 🔥 데이터 구조분해를 메모이제이션 + // 데이터 구조분해를 메모이제이션 const documentData = React.useMemo(() => documentResult as Awaited<ReturnType<typeof getUserVendorDocuments>>, [documentResult]) const statsData = React.useMemo(() => statsResult as Awaited<ReturnType<typeof getUserVendorDocumentStats>>, [statsResult]) const { data, pageCount, drawingKind } = documentData const { primaryDrawingKind, projectCodeStats: serverProjectCodeStats, projectB4Stats: serverProjectB4Stats } = statsData - // 🔥 URL searchParams를 통한 필터 상태 관리 + // URL searchParams를 통한 필터 상태 관리 const [{ b4FilterType, projectCode, page }, setQueryStates] = useQueryStates( { b4FilterType: parseAsStringEnum<'all' | 'gtt_deliverable' | 'shi_input'>(['all', 'gtt_deliverable', 'shi_input']).withDefault('all'), @@ -88,25 +88,25 @@ export function SimplifiedDocumentsTable({ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _ensurePageIsInState = page - // 🔥 서버에서 받아온 프로젝트 코드 통계 사용 (필터링과 무관한 전체 통계) + // 서버에서 받아온 프로젝트 코드 통계 사용 (필터링과 무관한 전체 통계) const projectCodeStats = React.useMemo(() => { return serverProjectCodeStats || [] }, [serverProjectCodeStats]) - // 🔥 데이터 로드 콜백 (서버에서 이미 필터링되어 옴) + // 데이터 로드 콜백 (서버에서 이미 필터링되어 옴) React.useEffect(() => { if (data && onDataLoaded) { onDataLoaded(data) } }, [data, onDataLoaded]) - // 🔥 컬럼 메모이제이션 최적화 (b4FilterType에 따라 동적 변경) + // 컬럼 메모이제이션 최적화 (b4FilterType에 따라 동적 변경) const columns = React.useMemo( () => getSimplifiedDocumentColumns({ b4FilterType }), [b4FilterType] ) - // 🔥 필터 필드들을 메모이제이션 + // 필터 필드들을 메모이제이션 const advancedFilterFields: DataTableAdvancedFilterField<SimplifiedDocumentsView>[] = React.useMemo(() => [ { id: "docNumber", @@ -206,7 +206,7 @@ export function SimplifiedDocumentsTable({ }, ], []) - // 🔥 B4 전용 필드들 메모이제이션 + // B4 전용 필드들 메모이제이션 const b4FilterFields: DataTableAdvancedFilterField<SimplifiedDocumentsView>[] = React.useMemo(() => [ { id: "cGbn", @@ -240,23 +240,23 @@ export function SimplifiedDocumentsTable({ }, ], []) - // 🔥 B4 문서 존재 여부 체크 메모이제이션 + // B4 문서 존재 여부 체크 메모이제이션 const hasB4Documents = React.useMemo(() => { return data.some((doc: SimplifiedDocumentsView) => doc.drawingKind === 'B4') }, [data]) - // 🔥 최종 필터 필드 메모이제이션 + // 최종 필터 필드 메모이제이션 const finalFilterFields = React.useMemo(() => { return hasB4Documents ? [...advancedFilterFields, ...b4FilterFields] : advancedFilterFields }, [hasB4Documents, advancedFilterFields, b4FilterFields]) - // 🔥 테이블 초기 상태 메모이제이션 + // 테이블 초기 상태 메모이제이션 const tableInitialState = React.useMemo(() => ({ sorting: [{ id: "createdAt" as const, desc: true }], columnPinning: { right: ["actions"] }, }), []) - // 🔥 getRowId 함수 메모이제이션 + // getRowId 함수 메모이제이션 const getRowId = React.useCallback((originalRow: SimplifiedDocumentsView) => String(originalRow.documentId), []) const { table } = useDataTable({ @@ -272,17 +272,17 @@ export function SimplifiedDocumentsTable({ columnResizeMode: "onEnd", }) - // 🔥 활성 drawingKind 메모이제이션 + // 활성 drawingKind 메모이제이션 const activeDrawingKind = React.useMemo(() => { return drawingKind || primaryDrawingKind }, [drawingKind, primaryDrawingKind]) - // 🔥 kindInfo 메모이제이션 + // kindInfo 메모이제이션 const kindInfo = React.useMemo(() => { return activeDrawingKind ? DRAWING_KIND_INFO[activeDrawingKind] : null }, [activeDrawingKind]) - // 🔥 B4 문서 통계 - 프로젝트 필터링에 따라 동적으로 계산 (서버에서 받아온 전체 통계 기반) + // B4 문서 통계 - 프로젝트 필터링에 따라 동적으로 계산 (서버에서 받아온 전체 통계 기반) const b4Stats = React.useMemo(() => { if (!hasB4Documents || !serverProjectB4Stats) return null @@ -324,7 +324,7 @@ export function SimplifiedDocumentsTable({ </div> )} - {/* 🔥 필터 섹션 - Project Code 필터와 B4 필터를 함께 배치 */} + {/* 필터 섹션 - Project Code 필터와 B4 필터를 함께 배치 */} <div className="space-y-3"> {/* Project Code 필터 드롭다운 */} <div className="flex items-center gap-3 p-4 bg-muted/30 rounded-lg"> @@ -425,6 +425,7 @@ export function SimplifiedDocumentsTable({ table={table} projectType="ship" b4={hasB4Documents && b4FilterType === 'gtt_deliverable'} + projectCodeStats={projectCodeStats} /> </DataTableAdvancedToolbar> </DataTable> |
