diff options
Diffstat (limited to 'lib/vendor-document-list/ship-all/enhanced-documents-table.tsx')
| -rw-r--r-- | lib/vendor-document-list/ship-all/enhanced-documents-table.tsx | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/lib/vendor-document-list/ship-all/enhanced-documents-table.tsx b/lib/vendor-document-list/ship-all/enhanced-documents-table.tsx new file mode 100644 index 00000000..255aa56c --- /dev/null +++ b/lib/vendor-document-list/ship-all/enhanced-documents-table.tsx @@ -0,0 +1,296 @@ +// simplified-documents-table.tsx - 최적화된 버전 +"use client" + +import React from "react" +import type { + DataTableAdvancedFilterField, + DataTableFilterField, + DataTableRowAction, +} from "@/types/table" + +import { useDataTable } from "@/hooks/use-data-table" +import { getUserVendorDocumentsAll, getUserVendorDocumentStatsAll } from "@/lib/vendor-document-list/enhanced-document-service" +import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar" +import { toast } from "sonner" +import { Badge } from "@/components/ui/badge" +import { FileText } from "lucide-react" + +import { Label } from "@/components/ui/label" +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" + +// DrawingKind별 설명 매핑 +const DRAWING_KIND_INFO = { + B3: { + title: "B3 Vendor", + description: "Approval-focused drawings progressing through Approval → Work stages", + color: "bg-blue-50 text-blue-700 border-blue-200" + }, + B4: { + title: "B4 GTT", + description: "DOLCE-integrated drawings progressing through Pre → Work stages", + color: "bg-green-50 text-green-700 border-green-200" + }, + B5: { + title: "B5 FMEA", + description: "Sequential drawings progressing through First → Second stages", + color: "bg-purple-50 text-purple-700 border-purple-200" + } +} as const + +interface SimplifiedDocumentsTableProps { + allPromises: Promise<[ + Awaited<ReturnType<typeof getUserVendorDocumentsAll>>, + Awaited<ReturnType<typeof getUserVendorDocumentStatsAll>> + ]> + onDataLoaded?: (data: SimplifiedDocumentsView[]) => void +} + +export function SimplifiedDocumentsTable({ + allPromises, + onDataLoaded, +}: SimplifiedDocumentsTableProps) { + // 🔥 React.use() 결과를 안전하게 처리 + const promiseResults = React.use(allPromises) + const [documentResult, statsResult] = promiseResults + + // 🔥 데이터 구조분해를 메모이제이션 + const { data, pageCount, total, drawingKind, vendorInfo } = React.useMemo(() => documentResult, [documentResult]) + const { stats, totalDocuments, primaryDrawingKind } = React.useMemo(() => statsResult, [statsResult]) + + // 🔥 데이터 로드 콜백을 useCallback으로 최적화 + const handleDataLoaded = React.useCallback((loadedData: SimplifiedDocumentsView[]) => { + onDataLoaded?.(loadedData) + }, [onDataLoaded]) + + // 🔥 데이터가 로드되면 콜백 호출 (의존성 최적화) + React.useEffect(() => { + if (data && handleDataLoaded) { + handleDataLoaded(data) + } + }, [data, handleDataLoaded]) + + // 🔥 상태들을 안정적으로 관리 + const [rowAction, setRowAction] = React.useState<DataTableRowAction<SimplifiedDocumentsView> | null>(null) + const [expandedRows] = React.useState<Set<string>>(() => new Set()) + + // 🔥 컬럼 메모이제이션 최적화 + const columns = React.useMemo( + () => getSimplifiedDocumentColumns({ + setRowAction, + }), + [] // setRowAction은 항상 동일한 함수이므로 의존성에서 제외 + ) + + // 🔥 필터 필드들을 메모이제이션 + const advancedFilterFields: DataTableAdvancedFilterField<SimplifiedDocumentsView>[] = React.useMemo(() => [ + { + id: "docNumber", + label: "Document No", + type: "text", + }, + { + id: "title", + label: "Document Title", + type: "text", + }, + { + id: "drawingKind", + label: "Document Type", + type: "select", + options: [ + { label: "B3", value: "B3" }, + { label: "B4", value: "B4" }, + { label: "B5", value: "B5" }, + ], + }, + { + id: "projectCode", + label: "Project Code", + type: "text", + }, + { + id: "vendorName", + label: "Vendor Name", + type: "text", + }, + { + id: "vendorCode", + label: "Vendor Code", + type: "text", + }, + { + id: "pic", + label: "PIC", + type: "text", + }, + { + id: "status", + label: "Document Status", + type: "select", + options: [ + { label: "Active", value: "ACTIVE" }, + { label: "Inactive", value: "INACTIVE" }, + { label: "Pending", value: "PENDING" }, + { label: "Completed", value: "COMPLETED" }, + ], + }, + { + id: "firstStageName", + label: "First Stage", + type: "text", + }, + { + id: "secondStageName", + label: "Second Stage", + type: "text", + }, + { + id: "firstStagePlanDate", + label: "First Planned Date", + type: "date", + }, + { + id: "firstStageActualDate", + label: "First Actual Date", + type: "date", + }, + { + id: "secondStagePlanDate", + label: "Second Planned Date", + type: "date", + }, + { + id: "secondStageActualDate", + label: "Second Actual Date", + type: "date", + }, + { + id: "issuedDate", + label: "Issue Date", + type: "date", + }, + { + id: "createdAt", + label: "Created Date", + type: "date", + }, + { + id: "updatedAt", + label: "Updated Date", + type: "date", + }, + ], []) + + // 🔥 B4 전용 필드들 메모이제이션 + const b4FilterFields: DataTableAdvancedFilterField<SimplifiedDocumentsView>[] = React.useMemo(() => [ + { + id: "cGbn", + label: "C Category", + type: "text", + }, + { + id: "dGbn", + label: "D Category", + type: "text", + }, + { + id: "degreeGbn", + label: "Degree Category", + type: "text", + }, + { + id: "deptGbn", + label: "Dept Category", + type: "text", + }, + { + id: "jGbn", + label: "J Category", + type: "text", + }, + { + id: "sGbn", + label: "S Category", + type: "text", + }, + ], []) + + // 🔥 B4 문서 존재 여부 체크 메모이제이션 + const hasB4Documents = React.useMemo(() => { + return data.some(doc => doc.drawingKind === 'B4') + }, [data]) + + // 🔥 최종 필터 필드 메모이제이션 + const finalFilterFields = React.useMemo(() => { + return hasB4Documents ? [...advancedFilterFields, ...b4FilterFields] : advancedFilterFields + }, [hasB4Documents, advancedFilterFields, b4FilterFields]) + + // 🔥 테이블 초기 상태 메모이제이션 + const tableInitialState = React.useMemo(() => ({ + sorting: [{ id: "createdAt", desc: true }], + columnPinning: { right: ["actions"] }, + }), []) + + // 🔥 getRowId 함수 메모이제이션 + const getRowId = React.useCallback((originalRow: SimplifiedDocumentsView) => String(originalRow.documentId), []) + + const { table } = useDataTable({ + data, + columns, + pageCount, + enablePinning: true, + enableAdvancedFilter: true, + initialState: tableInitialState, + getRowId, + shallow: false, + clearOnDefault: true, + columnResizeMode: "onEnd", + }) + + // 🔥 활성 drawingKind 메모이제이션 + const activeDrawingKind = React.useMemo(() => { + return drawingKind || primaryDrawingKind + }, [drawingKind, primaryDrawingKind]) + + // 🔥 kindInfo 메모이제이션 + const kindInfo = React.useMemo(() => { + return activeDrawingKind ? DRAWING_KIND_INFO[activeDrawingKind] : null + }, [activeDrawingKind]) + + return ( + <div className="w-full space-y-4"> + {/* DrawingKind 정보 간단 표시 */} + {kindInfo && ( + <div className="flex items-center justify-between"> + <div className="flex items-center gap-4"> + {/* 주석 처리된 부분은 그대로 유지 */} + </div> + <div className="flex items-center gap-2"> + <Badge variant="outline"> + {total} documents + </Badge> + </div> + </div> + )} + + {/* 테이블 */} + <div className="overflow-x-auto"> + <DataTable table={table} compact> + <DataTableAdvancedToolbar + table={table} + filterFields={finalFilterFields} + shallow={false} + > + {/* <EnhancedDocTableToolbarActions + table={table} + projectType="ship" + /> */} + </DataTableAdvancedToolbar> + </DataTable> + </div> + </div> + ) +}
\ No newline at end of file |
