import React, { useState } from 'react'; import { Group, Box, Text, ActionIcon, Checkbox, Divider, Menu, Badge, Loader } from '@mantine/core'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import DeleteIcon from '@mui/icons-material/Delete'; import DownloadIcon from '@mui/icons-material/Download'; import AddIcon from '@mui/icons-material/Add'; import HistoryIcon from '@mui/icons-material/History'; import { useTranslation } from 'react-i18next'; import { getFileSize, getFileDate } from '../../utils/fileUtils'; import { StoredFileMetadata } from '../../services/fileStorage'; import { useFileManagerContext } from '../../contexts/FileManagerContext'; import ToolChain from '../shared/ToolChain'; interface FileListItemProps { file: StoredFileMetadata; isSelected: boolean; isSupported: boolean; onSelect: (shiftKey?: boolean) => void; onRemove: () => void; onDownload?: () => void; onDoubleClick?: () => void; isLast?: boolean; isHistoryFile?: boolean; // Whether this is a history file (indented) isLatestVersion?: boolean; // Whether this is the latest version (shows chevron) } const FileListItem: React.FC = ({ file, isSelected, isSupported, onSelect, onRemove, onDownload, onDoubleClick, isHistoryFile = false, isLatestVersion = false }) => { const [isHovered, setIsHovered] = useState(false); const [isMenuOpen, setIsMenuOpen] = useState(false); const { t } = useTranslation(); const {expandedFileIds, onToggleExpansion, onAddToRecents } = useFileManagerContext(); // Keep item in hovered state if menu is open const shouldShowHovered = isHovered || isMenuOpen; // Get version information for this file const leafFileId = isLatestVersion ? file.id : (file.originalFileId || file.id); const hasVersionHistory = (file.versionNumber || 1) > 1; // Show history for any processed file (v2+) const currentVersion = file.versionNumber || 1; // Display original files as v1 const isExpanded = expandedFileIds.has(leafFileId); return ( <> onSelect(e.shiftKey)} onDoubleClick={onDoubleClick} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} > {/* Checkbox for all files */} {}} // Handled by parent onClick size="sm" pl="sm" pr="xs" styles={{ input: { cursor: 'pointer' } }} /> {file.name} 1 ? "blue" : "gray"}> v{currentVersion} {getFileSize(file)} • {getFileDate(file)} {/* Tool chain for processed files */} {file.toolHistory && file.toolHistory.length > 0 && ( )} {/* Three dots menu - fades in/out on hover */} setIsMenuOpen(true)} onClose={() => setIsMenuOpen(false)} > e.stopPropagation()} style={{ opacity: shouldShowHovered ? 1 : 0, transform: shouldShowHovered ? 'scale(1)' : 'scale(0.8)', transition: 'opacity 0.3s ease, transform 0.3s ease', pointerEvents: shouldShowHovered ? 'auto' : 'none' }} > {onDownload && ( } onClick={(e) => { e.stopPropagation(); onDownload(); }} > {t('fileManager.download', 'Download')} )} {/* Show/Hide History option for latest version files */} {isLatestVersion && hasVersionHistory && ( <> } onClick={(e) => { e.stopPropagation(); onToggleExpansion(leafFileId); }} > { (isExpanded ? t('fileManager.hideHistory', 'Hide History') : t('fileManager.showHistory', 'Show History') ) } )} {/* Add to Recents option for history files */} {isHistoryFile && ( <> } onClick={(e) => { e.stopPropagation(); onAddToRecents(file); }} > {t('fileManager.addToRecents', 'Add to Recents')} )} } onClick={(e) => { e.stopPropagation(); onRemove(); }} > {t('fileManager.delete', 'Delete')} { } ); }; export default FileListItem;