diff options
Diffstat (limited to 'lib/b-rfq/summary-table/summary-rfq-table.tsx')
| -rw-r--r-- | lib/b-rfq/summary-table/summary-rfq-table.tsx | 285 |
1 files changed, 0 insertions, 285 deletions
diff --git a/lib/b-rfq/summary-table/summary-rfq-table.tsx b/lib/b-rfq/summary-table/summary-rfq-table.tsx deleted file mode 100644 index 83d50685..00000000 --- a/lib/b-rfq/summary-table/summary-rfq-table.tsx +++ /dev/null @@ -1,285 +0,0 @@ -"use client" - -import * as React from "react" -import { useRouter, useSearchParams } from "next/navigation" -import { Button } from "@/components/ui/button" -import { PanelLeftClose, PanelLeftOpen } from "lucide-react" -import type { - DataTableAdvancedFilterField, - DataTableFilterField, - DataTableRowAction, -} from "@/types/table" - -import { useDataTable } from "@/hooks/use-data-table" -import { DataTable } from "@/components/data-table/data-table" -import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar" -import { getRFQDashboard } from "../service" -import { cn } from "@/lib/utils" -import { useTablePresets } from "@/components/data-table/use-table-presets" -import { TablePresetManager } from "@/components/data-table/data-table-preset" -import { useMemo } from "react" -import { getRFQColumns } from "./summary-rfq-columns" -import { RfqDashboardView } from "@/db/schema" -import { RFQTableToolbarActions } from "./summary-rfq-table-toolbar-actions" -import { RFQFilterSheet } from "./summary-rfq-filter-sheet" - -interface RFQDashboardTableProps { - promises: Promise<[Awaited<ReturnType<typeof getRFQDashboard>>]> - className?: string -} - -export function RFQDashboardTable({ promises, className }: RFQDashboardTableProps) { - const [rowAction, setRowAction] = React.useState<DataTableRowAction<RfqDashboardView> | null>(null) - const [isFilterPanelOpen, setIsFilterPanelOpen] = React.useState(false) - - const router = useRouter() - const searchParams = useSearchParams() - - const containerRef = React.useRef<HTMLDivElement>(null) - const [containerTop, setContainerTop] = React.useState(0) - - const updateContainerBounds = React.useCallback(() => { - if (containerRef.current) { - const rect = containerRef.current.getBoundingClientRect() - setContainerTop(rect.top) - } - }, []) - - React.useEffect(() => { - updateContainerBounds() - - const handleResize = () => { - updateContainerBounds() - } - - window.addEventListener('resize', handleResize) - window.addEventListener('scroll', updateContainerBounds) - - return () => { - window.removeEventListener('resize', handleResize) - window.removeEventListener('scroll', updateContainerBounds) - } - }, [updateContainerBounds]) - - const [promiseData] = React.use(promises) - const tableData = promiseData - - console.log("RFQ Dashboard Table Data:", { - dataLength: tableData.data?.length, - pageCount: tableData.pageCount, - total: tableData.total, - sampleData: tableData.data?.[0] - }) - - const initialSettings = React.useMemo(() => ({ - page: parseInt(searchParams.get('page') || '1'), - perPage: parseInt(searchParams.get('perPage') || '10'), - sort: searchParams.get('sort') ? JSON.parse(searchParams.get('sort')!) : [{ id: "createdAt", desc: true }], - filters: searchParams.get('filters') ? JSON.parse(searchParams.get('filters')!) : [], - joinOperator: (searchParams.get('joinOperator') as "and" | "or") || "and", - basicFilters: searchParams.get('basicFilters') || searchParams.get('rfqBasicFilters') ? - JSON.parse(searchParams.get('basicFilters') || searchParams.get('rfqBasicFilters')!) : [], - basicJoinOperator: (searchParams.get('basicJoinOperator') as "and" | "or") || "and", - search: searchParams.get('search') || '', - columnVisibility: {}, - columnOrder: [], - pinnedColumns: { left: [], right: ["actions"] }, - groupBy: [], - expandedRows: [] - }), [searchParams]) - - const { - presets, - activePresetId, - hasUnsavedChanges, - isLoading: presetsLoading, - createPreset, - applyPreset, - updatePreset, - deletePreset, - setDefaultPreset, - renamePreset, - updateClientState, - getCurrentSettings, - } = useTablePresets<RfqDashboardView>('rfq-dashboard-table', initialSettings) - - const columns = React.useMemo( - () => getRFQColumns({ setRowAction, router }), - [setRowAction, router] - ) - - const filterFields: DataTableFilterField<RfqDashboardView>[] = [ - { id: "rfqCode", label: "RFQ 코드" }, - { id: "projectName", label: "프로젝트" }, - { id: "status", label: "상태" }, - ] - - const advancedFilterFields: DataTableAdvancedFilterField<RfqDashboardView>[] = [ - { id: "rfqCode", label: "RFQ 코드", type: "text" }, - { id: "description", label: "설명", type: "text" }, - { id: "projectName", label: "프로젝트명", type: "text" }, - { id: "projectCode", label: "프로젝트 코드", type: "text" }, - { id: "packageNo", label: "패키지 번호", type: "text" }, - { id: "packageName", label: "패키지명", type: "text" }, - { id: "picName", label: "담당자", type: "text" }, - { id: "status", label: "상태", type: "select", options: [ - { label: "초안", value: "DRAFT" }, - { label: "문서접수", value: "Doc. Received" }, - { label: "담당자배정", value: "PIC Assigned" }, - { label: "문서확인", value: "Doc. Confirmed" }, - { label: "초기RFQ발송", value: "Init. RFQ Sent" }, - { label: "초기RFQ회신", value: "Init. RFQ Answered" }, - { label: "TBE시작", value: "TBE started" }, - { label: "TBE완료", value: "TBE finished" }, - { label: "최종RFQ발송", value: "Final RFQ Sent" }, - { label: "견적접수", value: "Quotation Received" }, - { label: "업체선정", value: "Vendor Selected" }, - ]}, - { id: "overallProgress", label: "진행률", type: "number" }, - { id: "dueDate", label: "마감일", type: "date" }, - { id: "createdAt", label: "생성일", type: "date" }, - ] - - const currentSettings = useMemo(() => { - return getCurrentSettings() - }, [getCurrentSettings]) - - const initialState = useMemo(() => { - return { - sorting: initialSettings.sort.filter(sortItem => { - const columnExists = columns.some(col => col.accessorKey === sortItem.id) - return columnExists - }) as any, - columnVisibility: currentSettings.columnVisibility, - columnPinning: currentSettings.pinnedColumns, - } - }, [currentSettings, initialSettings.sort, columns]) - - const { table } = useDataTable({ - data: tableData.data, - columns, - pageCount: tableData.pageCount, - rowCount: tableData.total || tableData.data.length, - filterFields, - enablePinning: true, - enableAdvancedFilter: true, - initialState, - getRowId: (originalRow) => String(originalRow.rfqId), - shallow: false, - clearOnDefault: true, - }) - - const handleSearch = () => { - setIsFilterPanelOpen(false) - } - - const getActiveBasicFilterCount = () => { - try { - const basicFilters = searchParams.get('basicFilters') || searchParams.get('rfqBasicFilters') - return basicFilters ? JSON.parse(basicFilters).length : 0 - } catch (e) { - return 0 - } - } - - const FILTER_PANEL_WIDTH = 400; - - return ( - <> - {/* Filter Panel */} - <div - className={cn( - "fixed left-0 bg-background border-r z-50 flex flex-col transition-all duration-300 ease-in-out overflow-hidden", - isFilterPanelOpen ? "border-r shadow-lg" : "border-r-0" - )} - style={{ - width: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px', - top: `${containerTop}px`, - height: `calc(100vh - ${containerTop}px)` - }} - > - <div className="h-full"> - <RFQFilterSheet - isOpen={isFilterPanelOpen} - onClose={() => setIsFilterPanelOpen(false)} - onSearch={handleSearch} - isLoading={false} - /> - </div> - </div> - - {/* Main Content Container */} - <div - ref={containerRef} - className={cn("relative w-full overflow-hidden", className)} - > - <div className="flex w-full h-full"> - <div - className="flex flex-col min-w-0 overflow-hidden transition-all duration-300 ease-in-out" - style={{ - width: isFilterPanelOpen ? `calc(100% - ${FILTER_PANEL_WIDTH}px)` : '100%', - marginLeft: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px' - }} - > - {/* Header Bar */} - <div className="flex items-center justify-between p-4 bg-background shrink-0"> - <div className="flex items-center gap-3"> - <Button - variant="outline" - size="sm" - type='button' - onClick={() => setIsFilterPanelOpen(!isFilterPanelOpen)} - className="flex items-center shadow-sm" - > - {isFilterPanelOpen ? <PanelLeftClose className="size-4"/> : <PanelLeftOpen className="size-4"/>} - {getActiveBasicFilterCount() > 0 && ( - <span className="ml-2 bg-primary text-primary-foreground rounded-full px-2 py-0.5 text-xs"> - {getActiveBasicFilterCount()} - </span> - )} - </Button> - </div> - - <div className="text-sm text-muted-foreground"> - {tableData && ( - <span>총 {tableData.total || tableData.data.length}건</span> - )} - </div> - </div> - - {/* Table Content Area */} - <div className="flex-1 overflow-hidden" style={{ height: 'calc(100vh - 380px)' }}> - <div className="h-full w-full"> - <DataTable table={table} className="h-full"> - <DataTableAdvancedToolbar - table={table} - filterFields={advancedFilterFields} - shallow={false} - > - <div className="flex items-center gap-2"> - <TablePresetManager<RfqDashboardView> - presets={presets} - activePresetId={activePresetId} - currentSettings={currentSettings} - hasUnsavedChanges={hasUnsavedChanges} - isLoading={presetsLoading} - onCreatePreset={createPreset} - onUpdatePreset={updatePreset} - onDeletePreset={deletePreset} - onApplyPreset={applyPreset} - onSetDefaultPreset={setDefaultPreset} - onRenamePreset={renamePreset} - /> - - <RFQTableToolbarActions table={table} /> - </div> - </DataTableAdvancedToolbar> - </DataTable> - </div> - </div> - </div> - </div> - </div> - </> - ) -}
\ No newline at end of file |
