scholarr/app/templates/runs.html
2026-02-17 14:51:25 +01:00

129 lines
4.1 KiB
HTML

{% extends "base.html" %}
{% block content %}
<section class="hero" data-test="runs-page">
<p class="eyebrow">Runs</p>
<h1>Run History</h1>
<p class="lede">Review execution outcomes and drill into run diagnostics when needed.</p>
</section>
<section class="sandbox" data-test="runs-filter-card">
<h2>Filters</h2>
<form method="get" action="/runs" class="inline-actions">
<label class="checkbox-row" for="failed_only">
<input id="failed_only" type="checkbox" name="failed_only" value="1" {% if failed_only %}checked{% endif %}>
<span>Failed / partial only</span>
</label>
<button type="submit" data-loading-text="Filtering...">Apply</button>
{% if failed_only %}
<a class="link-button" href="/runs">Clear</a>
{% endif %}
</form>
</section>
<section class="sandbox" data-test="runs-table-card">
<h2>Recent Runs</h2>
{% if runs %}
<table>
<thead>
<tr>
<th>ID</th>
<th>Started</th>
<th>Status</th>
<th>Trigger</th>
<th>Scholars</th>
<th>New Publications</th>
<th>Failures</th>
</tr>
</thead>
<tbody>
{% for run in runs %}
<tr>
<td><a href="/runs/{{ run.id }}">#{{ run.id }}</a></td>
<td>{{ run.started_at }}</td>
<td><span class="badge {{ run.status_badge }}">{{ run.status }}</span></td>
<td>{{ run.trigger_type }}</td>
<td>{{ run.scholar_count }}</td>
<td>{{ run.new_publication_count }}</td>
<td>{{ run.failed_count }} failed / {{ run.partial_count }} partial</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No runs match the current filter.</p>
{% endif %}
</section>
<section class="sandbox" data-test="runs-queue-card">
<div class="section-heading">
<h2>Continuation Queue</h2>
<a class="link-button" href="/runs?failed_only=1">Focus Failed Runs</a>
</div>
{% if queue_items %}
<table>
<thead>
<tr>
<th>Scholar</th>
<th>Status</th>
<th>Reason</th>
<th>Attempts</th>
<th>Next Attempt</th>
<th>Last Error</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for item in queue_items %}
<tr>
<td>
<a href="/publications?mode=new&scholar_profile_id={{ item.scholar_profile_id }}">{{ item.scholar_label }}</a>
<p class="helper-text">resume cstart: {{ item.resume_cstart }}</p>
</td>
<td><span class="badge {{ item.status_badge }}">{{ item.status }}</span></td>
<td>
{% if item.status == "dropped" and item.dropped_reason %}
<code>{{ item.dropped_reason }}</code>
{% else %}
<code>{{ item.reason }}</code>
{% endif %}
</td>
<td>{{ item.attempt_count }}</td>
<td>{{ item.next_attempt_at }}</td>
<td>
{% if item.last_error %}
<details>
<summary>show</summary>
<pre>{{ item.last_error }}</pre>
</details>
{% else %}
-
{% endif %}
</td>
<td>
<div class="inline-actions">
<form method="post" action="/runs/queue/{{ item.id }}/retry">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<button type="submit" data-loading-text="Retrying...">Retry Now</button>
</form>
{% if item.status != "dropped" %}
<form method="post" action="/runs/queue/{{ item.id }}/drop">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<button type="submit" class="danger-button" data-loading-text="Dropping...">Drop</button>
</form>
{% endif %}
<form method="post" action="/runs/queue/{{ item.id }}/clear">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<button type="submit" class="button-text" data-loading-text="Clearing...">Clear</button>
</form>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No queued continuation items.</p>
{% endif %}
</section>
{% endblock %}