import { html, nothing } from 'lit'; import { LightElement } from '../../lib/base.js'; import { formatDate, formatDuration } from './utils.js'; export class TaskHistorySection extends LightElement { static properties = { _runs: { state: true }, _error: { state: true }, _loading: { state: true }, _expanded: { state: true }, }; constructor() { super(); this._runs = []; this._error = null; this._loading = false; this._expanded = null; } async load() { this._error = null; this._loading = true; try { const res = await fetch('/api/cron/runs'); if (!res.ok) throw new Error(`HTTP ${res.status}`); this._runs = await res.json(); } catch (e) { this._error = e.message; } finally { this._loading = false; } } _statusClass(status) { return { completed: 'success', failed: 'danger', cancelled: 'warning' }[status] ?? 'secondary'; } _toggleExpand(id) { this._expanded = this._expanded === id ? null : id; } _renderRow(run) { const isExpanded = this._expanded === run.id; return html` this._toggleExpand(run.id)}> ${run.status} ${run.job_title ?? `Job #${run.job_id}`} ${run.agent_id ?? '—'} ${formatDate(run.completed_at)} ${formatDuration(run.duration_ms)} ${isExpanded ? html` ${run.session_id != null ? html`
View session #${run.session_id}
` : nothing} ${run.error ? html`
Error: ${run.error}
` : nothing} ${run.final_response ? html`
${run.final_response}
` : nothing} ${!run.error && !run.final_response ? html`
No output recorded.
` : nothing} ` : nothing} `; } render() { return html`

History

${this._runs.length} run${this._runs.length !== 1 ? 's' : ''}
${this._error ? html`
${this._error}
` : nothing} ${this._loading ? html`

Loading…

` : this._runs.length === 0 ? html`

No completed runs yet.

` : html`
${this._runs.map(r => this._renderRow(r))}
Status Task Agent Completed Duration
`}
`; } }