- config.py: add temp_warn_c (46°C), temp_crit_c (55°C), bad_block_threshold (0), app_version - settings_store.py: expose all new fields + system settings (truenas_base_url, api_key, poll_interval, etc.) as editable; save to JSON for persistence; add validation for log_level, poll/stale intervals, temp range - renderer.py: _temp_class() now reads temp_warn_c/temp_crit_c from settings instead of hardcoded 40/50 - burnin.py: precheck uses settings.temp_crit_c; fix NameError bug (_execute_stages referenced 'profile' that was not in scope) - routes.py: add GET /api/v1/updates/check (Forgejo releases API); settings_page passes new editable fields; save_settings skips empty truenas_api_key like smtp_password - settings.html: move system settings from read-only card into editable form; add temp/bad-block fields to Burn-In Behavior; add Check for Updates button; restart-required indicator on save - history.html: add Completed (finished_at) column next to Started - app.css: toast container shifts up when drawer is open (body.drawer-open) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
95 lines
3.1 KiB
HTML
95 lines
3.1 KiB
HTML
{% extends "layout.html" %}
|
|
|
|
{% block title %}TrueNAS Burn-In — History{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="page-toolbar">
|
|
<h1 class="page-title">Burn-In History</h1>
|
|
<div class="toolbar-right">
|
|
<a class="btn-export" href="/api/v1/burnin/export.csv">Export CSV</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- State filter tabs -->
|
|
<div class="filter-bar" style="margin-bottom: 14px;">
|
|
{% set states = [('all','All'), ('passed','Passed'), ('failed','Failed'), ('cancelled','Cancelled'), ('running','Running'), ('unknown','Unknown')] %}
|
|
{% for val, label in states %}
|
|
<a class="filter-btn{% if active_state == val %} active{% endif %}"
|
|
href="/history?state={{ val }}&page=1">
|
|
{{ label }}
|
|
{% if val in counts %}<span class="badge">{{ counts[val] }}</span>{% endif %}
|
|
</a>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th class="col-job">#</th>
|
|
<th class="col-drive">Drive</th>
|
|
<th>Profile</th>
|
|
<th>State</th>
|
|
<th>Operator</th>
|
|
<th>Started</th>
|
|
<th>Completed</th>
|
|
<th>Duration</th>
|
|
<th>Error</th>
|
|
<th class="col-actions"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% if jobs %}
|
|
{% for j in jobs %}
|
|
<tr>
|
|
<td class="mono text-muted">{{ j.id }}</td>
|
|
<td class="col-drive">
|
|
<span class="drive-name">{{ j.devname }}</span>
|
|
<span class="drive-model">{{ j.serial }}</span>
|
|
</td>
|
|
<td>
|
|
<span class="chip chip-{{ 'red' if j.profile == 'full' else 'gray' }}">{{ j.profile }}</span>
|
|
</td>
|
|
<td>
|
|
<span class="chip chip-{{ j.state }}">{{ j.state }}</span>
|
|
</td>
|
|
<td class="text-muted">{{ j.operator or '—' }}</td>
|
|
<td class="mono text-muted">{{ j.started_at | format_dt_full }}</td>
|
|
<td class="mono text-muted">{{ j.finished_at | format_dt_full }}</td>
|
|
<td class="mono text-muted">{{ j.duration_seconds | format_duration }}</td>
|
|
<td class="error-cell">
|
|
{% if j.error_text %}
|
|
<span class="error-snippet" title="{{ j.error_text }}">{{ j.error_text[:60] }}{% if j.error_text | length > 60 %}…{% endif %}</span>
|
|
{% else %}—{% endif %}
|
|
</td>
|
|
<td>
|
|
<a class="btn-detail" href="/history/{{ j.id }}">Detail</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="10" class="empty-state">No burn-in jobs found.</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
{% if total_pages > 1 %}
|
|
<div class="pagination">
|
|
{% if page > 1 %}
|
|
<a class="page-btn" href="/history?state={{ active_state }}&page={{ page - 1 }}">← Prev</a>
|
|
{% endif %}
|
|
<span class="page-info">Page {{ page }} of {{ total_pages }} · {{ total_count }} jobs</span>
|
|
{% if page < total_pages %}
|
|
<a class="page-btn" href="/history?state={{ active_state }}&page={{ page + 1 }}">Next →</a>
|
|
{% endif %}
|
|
</div>
|
|
{% else %}
|
|
<div class="pagination">
|
|
<span class="page-info">{{ total_count }} job{% if total_count != 1 %}s{% endif %}</span>
|
|
</div>
|
|
{% endif %}
|
|
{% endblock %}
|