diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-08-21 06:57:36 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-08-21 06:57:36 +0000 |
| commit | 02b1cf005cf3e1df64183d20ba42930eb2767a9f (patch) | |
| tree | e932c54d5260b0e6fda2b46be2a6ba1c3ee30434 /lib/vendor-document-list/ship-all | |
| parent | d78378ecd7ceede1429359f8058c7a99ac34b1b7 (diff) | |
(대표님, 최겸) 설계메뉴추가, 작업사항 업데이트
설계메뉴 - 문서관리
설계메뉴 - 벤더 데이터
gtc 메뉴 업데이트
정보시스템 - 메뉴리스트 및 정보 업데이트
파일 라우트 업데이트
엑셀임포트 개선
기본계약 개선
벤더 가입과정 변경 및 개선
벤더 기본정보 - pq
돌체 오류 수정 및 개선
벤더 로그인 과정 이메일 오류 수정
Diffstat (limited to 'lib/vendor-document-list/ship-all')
| -rw-r--r-- | lib/vendor-document-list/ship-all/enhanced-doc-table-columns.tsx | 540 | ||||
| -rw-r--r-- | lib/vendor-document-list/ship-all/enhanced-documents-table.tsx | 296 |
2 files changed, 836 insertions, 0 deletions
diff --git a/lib/vendor-document-list/ship-all/enhanced-doc-table-columns.tsx b/lib/vendor-document-list/ship-all/enhanced-doc-table-columns.tsx new file mode 100644 index 00000000..6c9a9ab6 --- /dev/null +++ b/lib/vendor-document-list/ship-all/enhanced-doc-table-columns.tsx @@ -0,0 +1,540 @@ +// simplified-doc-table-columns.tsx +"use client" + +import * as React from "react" +import { ColumnDef } from "@tanstack/react-table" +import { formatDate, formatDateTime } from "@/lib/utils" +import { Checkbox } from "@/components/ui/checkbox" +import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" +import { DataTableRowAction } from "@/types/table" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { Button } from "@/components/ui/button" +import { + Ellipsis, + FileText, + Eye, + Edit, + Trash2, +} from "lucide-react" +import { cn } from "@/lib/utils" +import { SimplifiedDocumentsView } from "@/db/schema" + +// DocumentSelectionContext를 import (실제 파일 경로에 맞게 수정 필요) +// 예: import { DocumentSelectionContextAll } from "../user-vendor-document-display" +// 또는: import { DocumentSelectionContextAll } from "./user-vendor-document-display" +import { DocumentSelectionContextAll } from "@/components/ship-vendor-document-all/user-vendor-document-table-container" + +interface GetColumnsProps { + setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<SimplifiedDocumentsView> | null>> +} + +// 날짜 표시 컴포넌트 (간단 버전) +const DateDisplay = ({ date, isSelected = false }: { date: string | null, isSelected?: boolean }) => { + if (!date) return <span className="text-gray-400">-</span> + + return ( + <span className={cn( + "text-sm", + isSelected && "text-blue-600 font-semibold" + )}> + {formatDate(date)} + </span> + ) +} + +export function getSimplifiedDocumentColumns({ + setRowAction, +}: GetColumnsProps): ColumnDef<SimplifiedDocumentsView>[] { + + const columns: ColumnDef<SimplifiedDocumentsView>[] = [ + // 라디오 버튼 같은 체크박스 선택 + { + id: "select", + header: ({ table }) => ( + <div className="flex items-center justify-center"> + <span className="text-xs text-gray-500">Select</span> + </div> + ), + cell: ({ row }) => { + const doc = row.original + + return ( + <SelectCell documentId={doc.documentId} /> + ) + }, + size: 40, + enableSorting: false, + enableHiding: false, + }, + + // 문서번호 (선택된 행 하이라이트 적용) + { + accessorKey: "docNumber", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Document No" /> + ), + cell: ({ row }) => { + const doc = row.original + + return ( + <DocNumberCell doc={doc} /> + ) + }, + size: 120, + enableResizing: true, + meta: { + excelHeader: "Document No" + }, + }, + + // 문서명 (선택된 행 하이라이트 적용) + { + accessorKey: "title", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Title" /> + ), + cell: ({ row }) => { + const doc = row.original + + return ( + <TitleCell doc={doc} /> + ) + }, + enableResizing: true, + maxSize:300, + meta: { + excelHeader: "Title" + }, + }, + + // 프로젝트 코드 + { + accessorKey: "projectCode", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Project" /> + ), + cell: ({ row }) => { + const projectCode = row.original.projectCode + + return ( + <ProjectCodeCell projectCode={projectCode} documentId={row.original.documentId} /> + ) + }, + enableResizing: true, + maxSize:100, + meta: { + excelHeader: "Project" + }, + }, + + // 벤더명 + { + accessorKey: "vendorName", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Vendor Name" /> + ), + cell: ({ row }) => { + const vendorName = row.original.vendorName + + return ( + <VendorNameCell vendorName={vendorName} documentId={row.original.documentId} /> + ) + }, + enableResizing: true, + maxSize: 200, + meta: { + excelHeader: "Vendor Name" + }, + }, + + // 벤더 코드 + { + accessorKey: "vendorCode", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Vendor Code" /> + ), + cell: ({ row }) => { + const vendorCode = row.original.vendorCode + + return ( + <VendorCodeCell vendorCode={vendorCode} documentId={row.original.documentId} /> + ) + }, + enableResizing: true, + maxSize: 120, + meta: { + excelHeader: "Vendor Code" + }, + }, + + // 1차 스테이지 그룹 + { + id: "firstStageGroup", + header: ({ table }) => { + // 첫 번째 행의 firstStageName을 그룹 헤더로 사용 + const firstRow = table.getRowModel().rows[0]?.original + const stageName = firstRow?.firstStageName || "First Stage" + return ( + <div className="text-center font-medium text-gray-700"> + {stageName} + </div> + ) + }, + columns: [ + { + accessorKey: "firstStagePlanDate", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Planned Date" /> + ), + cell: ({ row }) => { + return <FirstStagePlanDateCell row={row} /> + }, + enableResizing: true, + meta: { + excelHeader: "First Planned Date" + }, + }, + { + accessorKey: "firstStageActualDate", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Actual Date" /> + ), + cell: ({ row }) => { + return <FirstStageActualDateCell row={row} /> + }, + enableResizing: true, + meta: { + excelHeader: "First Actual Date" + }, + }, + ], + }, + + // 2차 스테이지 그룹 + { + id: "secondStageGroup", + header: ({ table }) => { + // 첫 번째 행의 secondStageName을 그룹 헤더로 사용 + const firstRow = table.getRowModel().rows[0]?.original + const stageName = firstRow?.secondStageName || "Second Stage" + return ( + <div className="text-center font-medium text-gray-700"> + {stageName} + </div> + ) + }, + columns: [ + { + accessorKey: "secondStagePlanDate", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Planned Date" /> + ), + cell: ({ row }) => { + return <SecondStagePlanDateCell row={row} /> + }, + enableResizing: true, + meta: { + excelHeader: "Second Planned Date" + }, + }, + { + accessorKey: "secondStageActualDate", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Actual Date" /> + ), + cell: ({ row }) => { + return <SecondStageActualDateCell row={row} /> + }, + enableResizing: true, + meta: { + excelHeader: "Second Actual Date" + }, + }, + ], + }, + + // 첨부파일 수 + { + accessorKey: "attachmentCount", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Files" /> + ), + cell: ({ row }) => { + const count = row.original.attachmentCount || 0 + + return ( + <AttachmentCountCell count={count} documentId={row.original.documentId} /> + ) + }, + size: 60, + enableResizing: true, + meta: { + excelHeader: "Attachments" + }, + }, + + // 업데이트 일시 + { + accessorKey: "updatedAt", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="Updated" /> + ), + cell: ({ cell, row }) => { + return ( + <UpdatedAtCell updatedAt={cell.getValue() as Date} documentId={row.original.documentId} /> + ) + }, + enableResizing: true, + meta: { + excelHeader: "Updated" + }, + }, + + // 액션 버튼 + // { + // id: "actions", + // header: () => <span className="sr-only">Actions</span>, + // cell: ({ row }) => { + // const doc = row.original + // return ( + // <DropdownMenu> + // <DropdownMenuTrigger asChild> + // <Button variant="ghost" className="h-8 w-8 p-0"> + // <span className="sr-only">Open menu</span> + // <Ellipsis className="h-4 w-4" /> + // </Button> + // </DropdownMenuTrigger> + // <DropdownMenuContent align="end"> + // <DropdownMenuItem + // onClick={() => setRowAction({ type: "view", row: doc })} + // > + // <Eye className="mr-2 h-4 w-4" /> + // 보기 + // </DropdownMenuItem> + // <DropdownMenuItem + // onClick={() => setRowAction({ type: "edit", row: doc })} + // > + // <Edit className="mr-2 h-4 w-4" /> + // 편집 + // </DropdownMenuItem> + // <DropdownMenuSeparator /> + // <DropdownMenuItem + // onClick={() => setRowAction({ type: "delete", row: doc })} + // className="text-red-600" + // > + // <Trash2 className="mr-2 h-4 w-4" /> + // 삭제 + // <DropdownMenuShortcut>⌫</DropdownMenuShortcut> + // </DropdownMenuItem> + // </DropdownMenuContent> + // </DropdownMenu> + // ) + // }, + // size: 50, + // enableSorting: false, + // enableHiding: false, + // }, + ] + + return columns +} + +// 개별 셀 컴포넌트들 (Context 사용) +function SelectCell({ documentId }: { documentId: number }) { + const { selectedDocumentId, setSelectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + return ( + <div className="flex items-center justify-center"> + <input + type="radio" + checked={isSelected} + onChange={() => { + const newSelection = isSelected ? null : documentId; + setSelectedDocumentId(newSelection); + }} + className="cursor-pointer w-4 h-4" + /> + </div> + ); +} + +function DocNumberCell({ doc }: { doc: SimplifiedDocumentsView }) { + const { selectedDocumentId, setSelectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === doc.documentId; + + return ( + <div + className={cn( + "font-mono text-sm font-medium cursor-pointer px-2 py-1 rounded transition-colors", + isSelected + ? "text-blue-600 font-bold bg-blue-50" + : "hover:bg-gray-50" + )} + onClick={() => { + const newSelection = isSelected ? null : doc.documentId; + setSelectedDocumentId(newSelection); + }} + > + {doc.docNumber} + </div> + ); +} + +function TitleCell({ doc }: { doc: SimplifiedDocumentsView }) { + const { selectedDocumentId, setSelectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === doc.documentId; + + return ( + <div + className={cn( + "font-medium text-gray-900 truncate max-w-[300px] cursor-pointer px-2 py-1 rounded transition-colors", + isSelected + ? "text-blue-600 font-bold bg-blue-50" + : "hover:bg-gray-50" + )} + title={doc.title} + onClick={() => { + const newSelection = isSelected ? null : doc.documentId; + setSelectedDocumentId(newSelection); + }} + > + {doc.title} + </div> + ); +} + +function ProjectCodeCell({ projectCode, documentId }: { projectCode: string | null, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + if (!projectCode) return <span className="text-gray-400">-</span>; + + return ( + <span className={cn( + "text-sm font-medium", + isSelected && "text-blue-600 font-bold" + )}> + {projectCode} + </span> + ); +} + +function VendorNameCell({ vendorName, documentId }: { vendorName: string | null, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + if (!vendorName) return <span className="text-gray-400">-</span>; + + return ( + <div + className={cn( + "text-sm font-medium truncate max-w-[200px]", + isSelected && "text-blue-600 font-bold" + )} + title={vendorName} + > + {vendorName} + </div> + ); +} + +function VendorCodeCell({ vendorCode, documentId }: { vendorCode: string | null, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + if (!vendorCode) return <span className="text-gray-400">-</span>; + + return ( + <span className={cn( + "text-sm font-medium font-mono", + isSelected && "text-blue-600 font-bold" + )}> + {vendorCode} + </span> + ); +} + +function FirstStagePlanDateCell({ row }: { row: any }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === row.original.documentId; + + return <DateDisplay date={row.original.firstStagePlanDate} isSelected={isSelected} />; +} + +function FirstStageActualDateCell({ row }: { row: any }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === row.original.documentId; + const date = row.original.firstStageActualDate; + + return ( + <div className={cn( + date ? "text-green-600 font-medium" : "", + isSelected && date && "text-green-700 font-bold" + )}> + <DateDisplay date={date} isSelected={isSelected && !date} /> + {date && <span className="text-xs block">✓ 완료</span>} + </div> + ); +} + +function SecondStagePlanDateCell({ row }: { row: any }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === row.original.documentId; + + return <DateDisplay date={row.original.secondStagePlanDate} isSelected={isSelected} />; +} + +function SecondStageActualDateCell({ row }: { row: any }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === row.original.documentId; + const date = row.original.secondStageActualDate; + + return ( + <div className={cn( + date ? "text-green-600 font-medium" : "", + isSelected && date && "text-green-700 font-bold" + )}> + <DateDisplay date={date} isSelected={isSelected && !date} /> + {date && <span className="text-xs block">✓ 완료</span>} + </div> + ); +} + +function AttachmentCountCell({ count, documentId }: { count: number, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + return ( + <div className="flex items-center justify-center gap-1"> + <FileText className="w-4 h-4 text-gray-400" /> + <span className={cn( + "text-sm font-medium", + isSelected && "text-blue-600 font-bold" + )}> + {count} + </span> + </div> + ); +} + +function UpdatedAtCell({ updatedAt, documentId }: { updatedAt: Date, documentId: number }) { + const { selectedDocumentId } = React.useContext(DocumentSelectionContextAll); + const isSelected = selectedDocumentId === documentId; + + return ( + <span className={cn( + "text-sm text-gray-600", + isSelected && "text-blue-600 font-semibold" + )}> + {formatDateTime(updatedAt)} + </span> + ); +}
\ No newline at end of file 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 |
