Files
pxe-server/webapp/templates/updates_rollback.html
cproudlock cc1e76f3ab Webapp redesign phase 4: Updates overview and rollback review
- GET /updates/: one card per updater (Dell, iPXE, Blancco, BPRT) with
  its state, a Check now / Open action and details in accordions; the
  shared download cap is a small popover.
- Dell applies list: one line per apply titled by its first change
  ('Latitude 5350 pack A11 to A12', model looked up in the maps) and
  'and n more'; the chip says how many written files are unchanged since
  the apply. The body lists every change, skipped item, error and file.
- dell_updates.file_status(): per file an apply wrote, unchanged /
  changed / missing by content hash, the same test rollback uses.
  describe(), history_view() and rollback_preview() build on it.
- GET /updates/dell/rollback/<id>: review a rollback before doing it,
  with the files that would be restored and a diff of each. The POST
  route is unchanged; both forms can return to the overview.
2026-10-14 13:54:41 -04:00

69 lines
3.7 KiB
HTML

{% extends "base.html" %}
{% import '_ui.html' as ui %}
{% block title %}Review rollback - PXE Manager{% endblock %}
{% block extra_head %}
<style>
.rb-files { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.rb-files li { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; justify-content: space-between;
padding: 10px 12px; border: 1px solid var(--line-2); border-radius: 8px; font-size: 13px; }
.rb-files .mono { overflow-wrap: anywhere; min-width: 0; }
.rb-diff { border: 1px solid var(--line-2); border-radius: 10px; overflow: hidden; }
.rb-diff .h { padding: 8px 12px; background: var(--surface-2); border-bottom: 1px solid var(--line-2); font-size: 13px; font-weight: 600; }
.rb-diff pre { margin: 0; max-height: 50vh; overflow: auto; font-size: 12px; line-height: 1.45; font-family: var(--font-mono); }
.rb-diff pre span { display: block; padding: 0 12px; white-space: pre-wrap; word-break: break-all; }
.rb-diff .d-add { background: var(--add-bg); color: var(--add-text); }
.rb-diff .d-del { background: var(--del-bg); color: var(--del-text); }
.rb-diff .d-hunk { color: var(--accent); background: var(--surface-2); }
.rb-diff .d-meta { color: var(--muted); }
</style>
{% endblock %}
{% block content %}
{{ ui.head('Roll back the Dell apply of ' ~ (rec.at | local_dt), 'Updates', rec.title ~ ' | apply ' ~ rec.id) }}
<div class="ui-stack" style="max-width: 980px">
{% if rec.rolled_back %}
<div class="notice info">This apply was already rolled back {{ rec.rolled_back | local_dt }}.</div>
{% endif %}
<section class="panel" style="padding: 18px 22px; display: flex; flex-direction: column; gap: 12px" aria-labelledby="f-h">
<h2 id="f-h" class="sec" style="font-size: 15px">Files this apply wrote</h2>
<ul class="rb-files">
{% for f in rec.files %}
<li><span class="mono">{{ f.path }}</span>
{% if f.state == 'unchanged' %}{{ ui.chip('Unchanged since apply: will be restored', 'ok') }}
{% elif f.state == 'changed' %}{{ ui.chip('Changed since: left alone', 'off') }}
{% else %}{{ ui.chip('Missing: left alone', 'err') }}{% endif %}
</li>
{% endfor %}
</ul>
<p class="sub" style="margin: 0">"Unchanged" means the content still matches what the apply wrote. A file changed since keeps its current content.</p>
</section>
{% for f in rec.files if f.state == 'unchanged' and f.diff %}
<div class="rb-diff">
<div class="h">{{ f.label }}: now, then after rollback</div>
<pre>{% for line in f.diff.split('\n') %}<span class="{{ 'd-meta' if line[:3] in ('---', '+++') else ('d-hunk' if line[:2] == '@@' else ('d-add' if line[:1] == '+' else ('d-del' if line[:1] == '-' else ''))) }}">{{ line or ' ' }}</span>{% endfor %}</pre>
</div>
{% endfor %}
<ul class="rb-files">
<li><span>The current files are backed up first, as <span class="mono">.bak-[timestamp]-pre-rollback</span> next to each one.</span></li>
<li><span>The new driver zips and BIOS files stay on the share, unused.</span></li>
</ul>
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end">
<a class="ui-btn" href="{{ url_for('updates_overview') }}">Cancel</a>
{% if rec.unchanged and not rec.rolled_back %}
<form method="post" action="{{ url_for('dell_updates.rollback') }}" style="margin: 0">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<input type="hidden" name="apply_id" value="{{ rec.id }}">
<input type="hidden" name="next" value="overview">
<button type="submit" class="ui-btn pri">Roll back {{ rec.unchanged }} file{{ 's' if rec.unchanged != 1 }}</button>
</form>
{% endif %}
</div>
</div>
{% endblock %}