Files
cosma-qc/app/templates/_jobs_table.html
Flag 194c94b872 dashboard — thumb 48x27, step live, spin busy, live thumbnail refresh
- dispatcher: col step ajoutee (migration). set a chaque phase:
  scp N/M, ffmpeg N/M, trimming hors-eau, reconstruct demo.py
- _refresh_thumbnail() scp la DERNIERE frame extraite toutes les ~15s
  pendant ffmpeg pour que le preview colle a la progression live
- template: cache-bust thumbnail via ?t=mtime, step affiche sous
  progress bar, thumb revenue a 48x27
- CSS: .badge.busy -> animation spin (rotation infinie) au lieu de
  juste une couleur, .step-text italique mute
2026-04-22 23:00:11 +00:00

114 lines
5.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% if not acquisitions %}
<p class="muted">Aucune acquisition. Ingeste un dossier via <code>scripts/ingest.py</code>.</p>
{% else %}
<div class="acq-list">
{% for acq in acquisitions %}
<section class="acq">
<h3 class="acq-title">
{{ acq.name }} <span class="total">{{ acq.total_duration }}</span>
</h3>
<table class="jobs-table">
<thead>
<tr>
<th class="col-status"></th>
<th class="col-thumb">preview</th>
<th class="col-id">#</th>
<th class="col-auv">AUV · GP</th>
<th class="col-seg">label</th>
<th class="col-dur">durée</th>
<th class="col-frames">frames</th>
<th class="col-trim">hors-eau</th>
<th class="col-progress">progression</th>
<th class="col-elapsed">temps</th>
<th class="col-actions"></th>
</tr>
</thead>
<tbody>
{% for j in acq.jobs %}
<tr class="job-row {{ j.status }}">
<td class="col-status" title="{{ j.status }}">
{% if j.status == 'done' %}<span class="badge ok"></span>
{% elif j.status in ('running','extracting') %}<span class="badge busy"></span>
{% elif j.status == 'error' %}<span class="badge err"></span>
{% elif j.status == 'skipped' %}<span class="badge muted"></span>
{% else %}<span class="badge muted"></span>{% endif %}
</td>
<td class="col-thumb">
{% if j.has_thumbnail %}<img src="jobs/{{ j.id }}/thumbnail?t={{ j.thumb_ts }}" alt="" loading="lazy">{% else %}<span class="thumb-placeholder"></span>{% endif %}
</td>
<td class="col-id">#{{ j.id }}</td>
<td class="col-auv"><strong>{{ j.auv }}</strong> · <span title="{{ j.gopro_serial }}">{{ j.gp_label }}</span></td>
<td class="col-seg">{{ j.segment_label }}</td>
<td class="col-dur">{{ j.video_duration_fmt }}</td>
<td class="col-frames">{% if j.frame_count %}{{ j.frame_count }}{% else %}—{% endif %}</td>
<td class="col-trim">{% if j.trimmed_total %}{{ j.trimmed_total }}{% else %}—{% endif %}</td>
<td class="col-progress">
{% if j.status in ('extracting','running') %}
<div class="progress-wrap">
<span class="prog-bar"><span class="prog-fill" style="width:{{ j.progress }}%"></span></span>
<span class="prog-text">{{ j.progress }}%</span>
</div>
{% if j.step %}<div class="step-text">{{ j.step }}</div>{% endif %}
{% elif j.status == 'done' and j.viser_url %}
<a class="btn-viser" href="{{ j.viser_url }}" target="_blank" rel="noopener">viser ↗</a>
{% elif j.status == 'skipped' %}
<span class="muted">skipped</span>
{% elif j.status == 'error' %}
<span class="muted" title="{{ j.error }}">failed</span>
{% else %}
<span class="muted"></span>
{% endif %}
</td>
<td class="col-elapsed">{{ j._duration }}</td>
<td class="col-actions">
{% if j.status in ('queued','extracting','running') %}
<button class="mini" hx-post="jobs/{{ j.id }}/cancel" hx-target="#jobs-table" title="annuler">×</button>
{% elif j.status == 'error' %}
<button class="mini" hx-post="jobs/{{ j.id }}/retry" hx-target="#jobs-table" title="retry"></button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="stitch-section">
<div class="stitch-title">stitch</div>
{% if acq.stitches %}
<ul class="stitch-list">
{% for s in acq.stitches %}
<li class="stitch-item {{ s.status }}">
<span class="badge {% if s.status == 'done' %}ok{% elif s.status == 'running' %}busy{% elif s.status == 'error' %}err{% else %}muted{% endif %}">
{% if s.status == 'done' %}✓{% elif s.status == 'running' %}↻{% elif s.status == 'error' %}✕{% else %}■{% endif %}
</span>
<span class="stitch-label">
{% if s.level == 'per_auv' %}pair GP1↔GP2 {{ s.auv }}
{% else %}merge final{% endif %}
</span>
{% if s._duration %}<span class="muted"> · {{ s._duration }}</span>{% endif %}
{% if s.status == 'done' and s.output_ply %}
<button class="btn-viser" data-view-url="stitches/{{ s.id }}/view">viser ↗</button>
{% endif %}
{% if s.status in ('queued','running') %}
<button class="mini" hx-post="stitches/{{ s.id }}/cancel" hx-target="#jobs-table">×</button>
{% elif s.status == 'error' %}
<button class="mini" hx-post="stitches/{{ s.id }}/retry" hx-target="#jobs-table"></button>
{% endif %}
{% if s.error %}<div class="err-line">{{ s.error[:140] }}</div>{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<ul class="stitch-list">
<li class="stitch-item pending"><span class="badge muted"></span> <span class="muted">pair GP1↔GP2 per AUV</span></li>
<li class="stitch-item pending"><span class="badge muted"></span> <span class="muted">cross-AUV merge</span></li>
<li class="stitch-item pending"><span class="badge muted"></span> <span class="muted">final PLY</span></li>
</ul>
{% endif %}
</div>
</section>
{% endfor %}
</div>
{% endif %}