import { useState } from 'react'; import { formatTimestamp, formatBytes, valueText, sourceIconSvg } from '../utils'; import { fetchEntryChildren } from '../api'; function ChildRow({ entry, index, onRowClick, selectedUids }) { const isSelected = (selectedUids?.size === 1) && selectedUids.has(entry.entry_uid); const isMultiSelected = (selectedUids?.size >= 2) && selectedUids.has(entry.entry_uid); const cls = ['child-entry-row', index % 2 === 0 ? 'child-entry-row--light' : 'child-entry-row--dark', isSelected && 'is-selected', isMultiSelected && 'is-multi-selected', ].filter(Boolean).join(' '); return (
{ if (e.shiftKey) e.preventDefault(); }} onClick={e => onRowClick(entry, e)} onKeyDown={e => { if (e.key === 'Enter') onRowClick(entry, e); }} > ); } export default function EntryRow({ entry, archiveId, rowIndex, isSelected, isMultiSelected, onRowClick, selectedUids, deletedUids, isPublicSession }) { const [favFailed, setFavFailed] = useState(false); const [expanded, setExpanded] = useState(false); const [children, setChildren] = useState(null); const [childrenLoading, setChildrenLoading] = useState(false); const showFavicon = entry.source_kind === 'web' && entry.entity_kind === 'page' && entry.has_favicon && archiveId && !favFailed; const icon = showFavicon ? ( setFavFailed(true)} style={{ objectFit: 'contain' }} /> ) : ( ); const checked = isSelected || isMultiSelected; const hasChildren = entry.child_count > 0 && !isPublicSession; function handleCheckboxClick(e) { e.stopPropagation(); onRowClick(entry, { ctrlKey: true, metaKey: false, shiftKey: false, preventDefault() {} }); } async function handleExpandClick(e) { e.stopPropagation(); if (expanded) { setExpanded(false); return; } setExpanded(true); if (children === null && !childrenLoading) { setChildrenLoading(true); try { const result = await fetchEntryChildren(archiveId, entry.entry_uid); setChildren(result); } catch (_) { setChildren([]); } finally { setChildrenLoading(false); } } } const outerClass = [ 'entry-row-outer', rowIndex % 2 === 0 ? 'entry-row-outer--light' : 'entry-row-outer--dark', isSelected && 'is-selected', isMultiSelected && 'is-multi-selected', ].filter(Boolean).join(' '); return (
{ if (e.shiftKey) e.preventDefault(); }} onClick={e => onRowClick(entry, e)} onKeyDown={e => { if (e.key === 'Enter') onRowClick(entry, e); }} >
{formatTimestamp(entry.archived_at)}
{hasChildren && (
{valueText(entry.entity_kind)}
{formatBytes(entry.total_artifact_bytes)} {entry.cached_bytes > 0 && entry.cacheable_bytes > 0 && ( {Math.round(entry.cached_bytes / entry.cacheable_bytes * 100)}% cached )}
{valueText(entry.original_url)}
{expanded && ( <> {childrenLoading &&
Loading…
}
{children && children .filter(c => !deletedUids?.has(c.entry_uid)) .map((child, idx) => ( ))}
)}
); }