Files
musicdl-catalog-sync-suite/catalog-sync/musicdl/catalogsync/templates/ops/job_detail.html
T

224 lines
6.5 KiB
HTML

{% extends "ops/base.html" %}
{% block content %}
<p><a href="/dashboard">Back to Dashboard</a></p>
<h1>Job {{ job.id }}</h1>
<div class="grid">
<div class="card">
<table>
<tr><th>Type</th><td>{{ job.job_type }}</td></tr>
<tr><th>Status</th><td>{{ job.status }}</td></tr>
<tr><th>Requested By</th><td>{{ job.requested_by or "-" }}</td></tr>
<tr><th>Created</th><td>{{ job.created_at or "-" }}</td></tr>
<tr><th>Started</th><td>{{ job.started_at or "-" }}</td></tr>
<tr><th>Ended</th><td>{{ job.ended_at or "-" }}</td></tr>
</table>
</div>
<div class="card">
<h2>Job Commands</h2>
<div class="button-grid">
<form action="{{ command_endpoint }}" method="post" data-json-form data-success="reload">
<input type="hidden" name="command_type" value="pause" />
<button type="submit">暂停任务</button>
</form>
<form action="{{ command_endpoint }}" method="post" data-json-form data-success="reload">
<input type="hidden" name="command_type" value="resume" />
<button type="submit">继续任务</button>
</form>
<form action="{{ command_endpoint }}" method="post" data-json-form data-success="reload">
<input type="hidden" name="command_type" value="cancel" />
<button type="submit" class="secondary">取消任务</button>
</form>
</div>
<form action="{{ command_endpoint }}" method="post" data-json-form data-success="reload">
<input type="hidden" name="command_type" value="retry_item" />
<label>
Retry Item Id
<input type="number" name="target_item_id" min="1" />
</label>
<button type="submit">Retry Item</button>
</form>
<form action="{{ command_endpoint }}" method="post" data-json-form data-success="reload">
<input type="hidden" name="command_type" value="force_retry_item" />
<label>
Force Retry Item Id
<input type="number" name="target_item_id" min="1" />
</label>
<button type="submit">Force Retry Item</button>
<p class="muted">Use this when a single item needs to be replayed from scratch.</p>
</form>
</div>
<div class="card">
<h2>Download Stats</h2>
<table>
<tr><th>Total Songs</th><td>{{ download_stats.total_songs }}</td></tr>
<tr><th>Downloaded Songs</th><td>{{ download_stats.downloaded_songs }}</td></tr>
<tr><th>Local Files</th><td>{{ download_stats.local_file_locations }}</td></tr>
<tr><th>Running Songs</th><td>{{ download_stats.running_song_items }}</td></tr>
</table>
</div>
</div>
<div class="card">
<h2>Stages</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>Stage</th>
<th>Status</th>
<th>Total</th>
<th>Pending</th>
<th>Running</th>
<th>Succeeded</th>
<th>Failed</th>
</tr>
</thead>
<tbody>
{% for stage in stages %}
<tr>
<td>{{ stage.id }}</td>
<td>{{ stage.stage_type }}</td>
<td>{{ stage.status }}</td>
<td>{{ stage.total_items }}</td>
<td>{{ stage.pending_items }}</td>
<td>{{ stage.running_items }}</td>
<td>{{ stage.success_items }}</td>
<td>{{ stage.failed_items }}</td>
</tr>
{% else %}
<tr><td colspan="8">No stages.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="card">
<h2>Playlist Progress</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>Playlist</th>
<th>Progress</th>
<th>Total Songs</th>
<th>Downloaded</th>
<th>Running</th>
<th>Pending</th>
<th>Failed</th>
<th>Skipped</th>
</tr>
</thead>
<tbody>
{% for playlist in playlist_progress %}
<tr>
<td>{{ playlist.playlist_id }}</td>
<td>{{ playlist.playlist_name }}</td>
<td class="progress-cell">
<div class="progress-meta">
<span>{{ playlist.downloaded_songs or 0 }} / {{ playlist.total_songs or 0 }}</span>
<strong>{{ playlist.progress_percent or 0 }}%</strong>
</div>
<div class="progress-bar">
<div class="progress-fill" style="width: {{ playlist.progress_percent or 0 }}%;"></div>
</div>
</td>
<td>{{ playlist.total_songs or 0 }}</td>
<td>{{ playlist.downloaded_songs or 0 }}</td>
<td>{{ playlist.running_songs or 0 }}</td>
<td>{{ playlist.pending_songs or 0 }}</td>
<td>{{ playlist.failed_songs or 0 }}</td>
<td>{{ playlist.skipped_songs or 0 }}</td>
</tr>
{% else %}
<tr><td colspan="9">No playlist-scoped progress for this job.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="card">
<h2>Workers</h2>
<table>
<thead>
<tr>
<th>Worker</th>
<th>Status</th>
<th>Stage</th>
<th>Current Song / Playlist</th>
<th>Progress</th>
</tr>
</thead>
<tbody>
{% for worker in workers %}
<tr>
<td>{{ worker.worker_name }}</td>
<td>{{ worker.status }}</td>
<td>{{ worker.stage_type or "-" }}</td>
<td>{{ worker.display_text or "-" }}</td>
<td>{{ worker.last_progress_text or "-" }}</td>
</tr>
{% else %}
<tr><td colspan="5">No workers recorded yet.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="card">
<h2>Running Items</h2>
<table>
<thead>
<tr>
<th>Worker</th>
<th>Stage</th>
<th>Item</th>
<th>Started</th>
</tr>
</thead>
<tbody>
{% for item in running_items %}
<tr>
<td>{{ item.worker_name or "-" }}</td>
<td>{{ item.stage_type }}</td>
<td>{{ item.display_name }}</td>
<td>{{ item.started_at or "-" }}</td>
</tr>
{% else %}
<tr><td colspan="4">No running items.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="card">
<h2>Commands</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>Type</th>
<th>Status</th>
<th>Created</th>
<th>Applied</th>
</tr>
</thead>
<tbody>
{% for command in commands %}
<tr>
<td>{{ command.id }}</td>
<td>{{ command.command_type }}</td>
<td>{{ command.status }}</td>
<td>{{ command.created_at }}</td>
<td>{{ command.applied_at or "-" }}</td>
</tr>
{% else %}
<tr><td colspan="5">No commands.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}