import type { Component, JSX } from 'solid-js' import type { TestNode, TestStatus } from '~/components/types' import { createMemo, createSignal, For, Show } from 'solid-js' import { StatusIcon } from '~/components' import { formatDuration, getAggregateStatus } from '~/components/utils' export interface TestTreeItemProps { id: string store: Record onSelect: (id: string) => void onRunTest?: (id: string) => void selectedId?: string | null depth?: number } function getStatusBgClass(status: TestStatus): string { switch (status) { case 'passed': return 'bg-emerald-500/10' case 'failed': return 'bg-red-500/10' case 'running': return 'bg-amber-500/10' case 'timeout': return 'bg-orange-500/10' default: return 'bg-white/5' } } const TestTreeItem: Component = (props) => { const node = createMemo(() => props.store[props.id]) const [expanded, setExpanded] = createSignal(true) const [hovered, setHovered] = createSignal(false) const isSelected = createMemo(() => props.selectedId === node()?.id) const depth = createMemo(() => props.depth ?? 0) const hasChildren = createMemo(() => (node()?.children.length ?? 0) > 0) const status = createMemo(() => { const n = node() if (!n) return 'idle' return getAggregateStatus(n, props.store) }) const handleRowClick: JSX.EventHandler = (e) => { if ((e.target as HTMLElement).closest('[data-play-btn]')) return props.onSelect(node()!.id) } const handleChevronClick: JSX.EventHandler = (e) => { e.stopPropagation() setExpanded(!expanded()) } const handlePlayClick: JSX.EventHandler = (e) => { e.stopPropagation() props.onRunTest?.(node()!.id) } return ( {current => (
setHovered(true)} onMouseLeave={() => setHovered(false)} >
{current.name || 'Test'} 0 && status() !== 'running'}> {formatDuration(current.duration)} 0}> {current.children.length}
{childId => ( )}
)}
) } export default TestTreeItem