'use client' import React, { useLayoutEffect, useMemo, useRef, useState } from 'react' import { Checkbox } from '../checkbox' import { Skeleton } from '../skeleton' import { cn } from '../../../utils/cn' import { FileManagerTableRow } from './file-manager-table-row' import { FileManagerEmpty } from './file-manager-empty' import type { FileManagerTableProps } from './types' export function FileManagerTable({ files, selectedFiles, showCheckboxes = true, loading = false, isSearchResult = false, onSelectFile, onSelectAll, onFileClick, onFolderOpen, onFileAction, className }: FileManagerTableProps) { const allSelected = useMemo(() => { return files.length > 0 && selectedFiles.length === files.length }, [files.length, selectedFiles.length]) const someSelected = useMemo(() => { return selectedFiles.length > 0 && selectedFiles.length < files.length }, [files.length, selectedFiles.length]) const containerRef = useRef(null) const [tableHeight, setTableHeight] = useState(null) useLayoutEffect(() => { if (loading || files.length === 0) { setTableHeight(null) return } const handleResize = () => { const node = containerRef.current if (!node) return const rect = node.getBoundingClientRect() const availableHeight = window.innerHeight - rect.top setTableHeight(availableHeight > 0 ? availableHeight : null) } handleResize() window.addEventListener('resize', handleResize) window.addEventListener('scroll', handleResize, true) const resizeObserver = new ResizeObserver(handleResize) const parent = containerRef.current?.parentElement if (parent) { resizeObserver.observe(parent) } else if (containerRef.current) { resizeObserver.observe(containerRef.current) } return () => { window.removeEventListener('resize', handleResize) window.removeEventListener('scroll', handleResize, true) resizeObserver.disconnect() } }, [loading, files.length]) const handleSelectAll = (checked: boolean) => { onSelectAll?.(checked) } if (loading) { const skeletonRows = 8 return (
{/* Table header */}
{showCheckboxes && (
)}
NAME
SIZE
EDITED
{/* Space for action buttons */}
{/* Skeleton rows */}
{Array.from({ length: skeletonRows }).map((_, idx) => (
{showCheckboxes && (
)} {/* File icon and name column */}
{isSearchResult && ( )}
{/* Size column */}
{/* Modified date column */}
{/* Action buttons column */}
))}
) } if (files.length === 0) { return } return (
{showCheckboxes && (
)}
NAME
SIZE
EDITED
{/* Space for action buttons */}
{files.map((file) => ( onSelectFile?.(file.id, selected)} onClick={() => { if (isSearchResult) { onFileClick?.(file) } else if (file.type === 'folder') { onFolderOpen?.(file) } }} onDoubleClick={() => { if (file.type === 'folder' && !isSearchResult) { onFolderOpen?.(file) } }} onActionClick={(action) => onFileAction?.(action, file.id)} /> ))}
) }