// TaskList — FilterBar + LocalTaskListItem recreation function FilterBar({ status, onStatus, search, onSearch, sort, onSort, counts, total }) { const columns = ['queued', 'running', 'waiting_human', 'waiting_subtasks', 'retry', 'succeeded', 'failed', 'cancelled']; const chipStyle = (active) => ({ flexShrink: 0, padding: '6px 10px', borderRadius: 9999, fontSize: 11, fontWeight: 700, whiteSpace: 'nowrap', cursor: 'pointer', border: '1px solid ' + (active ? '#2563eb' : '#e2e8f0'), background: active ? '#eff6ff' : '#fff', color: active ? '#1d4ed8' : '#64748b', fontFamily: 'inherit', }); return (
onSearch(e.target.value)} placeholder="検索..." style={{ flex: 1, border: 'none', outline: 'none', background: 'transparent', fontSize: 13, fontFamily: 'inherit', color: '#0f172a', minWidth: 0 }} />
{columns.map(s => ( ))}
); } function TaskItem({ task, active, onClick }) { return ( ); } function TaskList({ tasks, activeId, onSelect, filters, setFilters }) { const counts = {}; for (const s of ['queued', 'running', 'waiting_human', 'waiting_subtasks', 'retry', 'succeeded', 'failed', 'cancelled']) { counts[s] = tasks.filter(t => t.status === s).length; } const filtered = tasks .filter(t => filters.status === 'all' || t.status === filters.status) .filter(t => !filters.search || (t.title + t.body).toLowerCase().includes(filters.search.toLowerCase())) .sort((a, b) => filters.sort === 'title' ? a.title.localeCompare(b.title) : b.updatedAt - a.updatedAt); return (
setFilters(f => ({ ...f, status: s }))} search={filters.search} onSearch={(q) => setFilters(f => ({ ...f, search: q }))} sort={filters.sort} onSort={(s) => setFilters(f => ({ ...f, sort: s }))} counts={counts} total={tasks.length} />
{filtered.map(t => onSelect(t.id)} />)} {filtered.length === 0 &&
スレッドがありません
}
); } window.TaskList = TaskList;