- Add comprehensive database migrations (001-024) for schema evolution - Enhance API schema with expanded type definitions and resolvers - Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth - Implement new services: AI optimization, billing, blockchain, compliance, marketplace - Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage) - Update Crossplane provider with enhanced VM management capabilities - Add comprehensive test suite for API endpoints and services - Update frontend components with improved GraphQL subscriptions and real-time updates - Enhance security configurations and headers (CSP, CORS, etc.) - Update documentation and configuration files - Add new CI/CD workflows and validation scripts - Implement design system improvements and UI enhancements
81 lines
2.1 KiB
TypeScript
81 lines
2.1 KiB
TypeScript
'use client'
|
|
|
|
import { useVirtualizer } from '@tanstack/react-virtual'
|
|
import { useRef } from 'react'
|
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
|
|
|
interface VirtualizedTableProps<T> {
|
|
data: T[]
|
|
columns: Array<{
|
|
key: string
|
|
header: string
|
|
render: (item: T) => React.ReactNode
|
|
width?: number
|
|
}>
|
|
rowHeight?: number
|
|
className?: string
|
|
}
|
|
|
|
export function VirtualizedTable<T extends { id: string }>({
|
|
data,
|
|
columns,
|
|
rowHeight = 50,
|
|
className,
|
|
}: VirtualizedTableProps<T>) {
|
|
const parentRef = useRef<HTMLDivElement>(null)
|
|
|
|
const virtualizer = useVirtualizer({
|
|
count: data.length,
|
|
getScrollElement: () => parentRef.current,
|
|
estimateSize: () => rowHeight,
|
|
overscan: 5,
|
|
})
|
|
|
|
return (
|
|
<div ref={parentRef} className={`overflow-auto ${className}`} style={{ height: '600px' }}>
|
|
<Table>
|
|
<TableHeader className="sticky top-0 bg-studio-dark z-10">
|
|
<TableRow>
|
|
{columns.map((column) => (
|
|
<TableHead
|
|
key={column.key}
|
|
style={{ width: column.width || 'auto' }}
|
|
>
|
|
{column.header}
|
|
</TableHead>
|
|
))}
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody
|
|
style={{
|
|
height: `${virtualizer.getTotalSize()}px`,
|
|
position: 'relative',
|
|
}}
|
|
>
|
|
{virtualizer.getVirtualItems().map((virtualRow) => {
|
|
const item = data[virtualRow.index]
|
|
return (
|
|
<TableRow
|
|
key={item.id}
|
|
style={{
|
|
position: 'absolute',
|
|
top: 0,
|
|
left: 0,
|
|
width: '100%',
|
|
height: `${virtualRow.size}px`,
|
|
transform: `translateY(${virtualRow.start}px)`,
|
|
}}
|
|
>
|
|
{columns.map((column) => (
|
|
<TableCell key={column.key}>{column.render(item)}</TableCell>
|
|
))}
|
|
</TableRow>
|
|
)
|
|
})}
|
|
</TableBody>
|
|
</Table>
|
|
</div>
|
|
)
|
|
}
|
|
|