(e: React.ChangeEvent<HTMLInputElement>)
| 86 | }; |
| 87 | |
| 88 | const sorted = [...projects].sort((a, b) => { |
| 89 | const o: Record<string, number> = { running: 0, queued: 1, interrupted: 2, new: 3, completed: 4 }; |
| 90 | return (o[a.status] ?? 5) - (o[b.status] ?? 5); |
| 91 | }); |
| 92 | |
| 93 | const running = projects.filter(p => p.status === 'running').length; |
| 94 | const interrupted = projects.filter(p => p.status === 'interrupted').length; |
| 95 | |
| 96 | const goLabel = t('project.go_submit'); |
| 97 | |
| 98 | const toggleExpand = (projectId: string, e: React.MouseEvent) => { |
| 99 | e.stopPropagation(); |
| 100 | setExpandedId(prev => prev === projectId ? null : projectId); |
| 101 | }; |
| 102 | |
| 103 | return ( |
| 104 | <div className="project-panel"> |
| 105 | <div className="project-panel-header" onClick={() => setPanelOpen(!panelOpen)}> |
| 106 | <h3> |
| 107 | <span className="panel-icon">📋</span> {t('project.title')} |
| 108 | {projects.length > 0 && <span className="project-count">{projects.length}</span>} |
no test coverage detected