129 lines
4.1 KiB
HTML
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 %}
|