Files
ros_control/app/ui/templates/_jobs.html
T
ayurishchevandClaude Opus 5.5 5f7bd6588a Состояния «Upgrade FW» и осознанный откат прошивки RouterBOARD
Пункт 18 ревью 2026-09-28 21:32 (docs/changes/027): после отката ROS
плата остаётся на более новой прошивке, а приложение сравнивало версии
на неравенство и показывало откат как обновление.
- devices.fw_state: unknown/update/downgrade/current; has_fw_update и
  фильтры не считают откат обновлением; метка «в ROS: X».
- upgrade_firmware не понижает прошивку; общая запись — _flash_firmware.
- Задача fw_downgrade: проверка → обязательный бэкап → запись →
  перезагрузка; API POST /devices/{id}/firmware/downgrade и
  /batch/fw_downgrade (target_version обязателен).
- UI: «Откатить прошивку…» (строка и группа), общее окно отката с kind.

Тесты: 39 из 39. Стенд: временное недоступное устройство — 422/202,
задачи failed на проверке, бэкапов нет. Реальная запись прошивки при
откате и ручная проверка UI не выполнялись.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:04:51 +03:00

32 lines
1.9 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.
{% import "_ui.html" as ui %}
{% set running = jobs|selectattr("status", "in", ["pending", "running"])|list|length %}
{% set done = jobs|selectattr("status", "equalto", "done")|list|length %}
{% set failed = jobs|selectattr("status", "equalto", "failed")|list|length %}
<div class="section-head">
<h2>Задачи</h2>
{% if running %}<span class="badge run">{{ running }} выполняется</span>{% endif %}
{% if done %}<span class="badge">{{ done }} завершено</span>{% endif %}
{% if failed %}<span class="badge bad">{{ failed }} с ошибкой</span>{% endif %}
</div>
{% if flash %}<p class="err">{{ flash }}</p>{% endif %}
<div class="card">
<table class="grid jobs">
<colgroup><col style="width:96px"><col style="width:16%"><col style="width:16%"><col style="width:130px"><col><col style="width:150px"></colgroup>
<thead><tr><th>ID</th><th>Устройство</th><th>Операция</th><th>Статус</th><th>Сообщение</th><th>Создана (UTC)</th></tr></thead>
<tbody>
{% for j in jobs %}
<tr>
<td class="c-mono muted" title="{{ j.id }}">{{ j.id|short_id }}</td>
<td style="font-weight:500">{{ j.device_name }}</td>
<td>{{ {"backup": "Бэкап", "ros_update": "Обновление ROS", "fw_update": "Обновление FW", "set_channel": "Смена канала", "ros_downgrade": "Откат ROS", "fw_downgrade": "Откат FW"}.get(j.type, j.type) }}</td>
<td><span class="badge {{ {'running': 'run', 'done': 'ok', 'failed': 'bad'}.get(j.status, '') }}">{{ {"pending": "В очереди", "running": "Выполняется", "done": "Готово", "failed": "Ошибка"}.get(j.status, j.status) }}</span></td>
<td class="msg">{{ j.message }}</td>
<td class="c-small">{{ j.created_at|dt }}</td>
</tr>
{% else %}
<tr><td colspan="6" class="empty">Задач пока нет.</td></tr>
{% endfor %}
</tbody>
</table>
</div>