webapp: fix a11y contrast, heading hierarchy, prefix-safe modal actions

- Accessibility: dark ink (#00003d) on warning/success buttons, badges, and success alert - white text on #ff9500/#0ad64f failed WCAG AA (~2:1); dark-on-bright now passes.
- Heading hierarchy: sidebar brand h1 -> div.brand-title (with matching CSS selector), and standardized all page-header titles to a single <h1> per page (8 templates were h2).
- Prefix-safe modal JS: dashboard/backups/reports/enrollment delete+clone actions now build their form action from url_for(...'__K__'/'__F__').replace(...) instead of hardcoded paths, so they survive a URL-prefix mount.
This commit is contained in:
cproudlock
2026-07-23 10:14:29 -04:00
parent 18db077475
commit 8fbae24b4d
10 changed files with 24 additions and 24 deletions

View File

@@ -3,7 +3,7 @@
{% block content %}
<div class="page-header">
<h2>Audit Log</h2>
<h1>Audit Log</h1>
<div class="header-actions">
<span class="badge badge-secondary badge-lg">{{ entries|length }} entries</span>
</div>

View File

@@ -3,7 +3,7 @@
{% block content %}
<div class="page-header">
<h2>Clonezilla Backups</h2>
<h1>Clonezilla Backups</h1>
<div class="header-actions">
<button class="pxe-btn pxe-btn-primary" data-bs-toggle="modal" data-bs-target="#uploadModal">
<i class="bi bi-upload"></i> Upload Backup
@@ -134,7 +134,7 @@ document.getElementById('deleteModal').addEventListener('show.bs.modal', functio
var filename = btn.getAttribute('data-filename');
var machine = btn.getAttribute('data-machine');
document.getElementById('deleteMachine').textContent = machine;
document.getElementById('deleteForm').action = '/backups/delete/' + encodeURIComponent(filename);
document.getElementById('deleteForm').action = "{{ url_for('clonezilla_delete', filename='__F__') }}".replace('__F__', encodeURIComponent(filename));
});
</script>
{% endblock %}

View File

@@ -31,7 +31,7 @@
<nav class="sidebar d-flex flex-column">
<div class="sidebar-header">
<img class="sidebar-logo" src="{{ url_for('static', filename='ge-aerospace-logo.svg') }}" alt="GE Aerospace">
<h1>PXE Manager</h1>
<div class="brand-title">PXE Manager</div>
</div>
<ul class="sidebar-nav nav flex-column mt-2">

View File

@@ -3,7 +3,7 @@
{% block content %}
<div class="page-header">
<h2>Dashboard</h2>
<h1>Dashboard</h1>
<div class="header-actions">
<a href="{{ url_for('images_import') }}" class="btn btn-outline-secondary btn-sm">
<i class="bi bi-box-arrow-in-down"></i> Image Import
@@ -267,11 +267,11 @@ document.addEventListener('show.bs.modal', function(e) {
if (e.target.id === 'cloneImageModal') {
e.target.querySelector('#cloneSrcKey').textContent = srcKey;
e.target.querySelector('#cloneSrcFriendly').textContent = srcFriendly;
document.getElementById('cloneForm').action = '/images/' + encodeURIComponent(srcKey) + '/clone';
document.getElementById('cloneForm').action = "{{ url_for('images_clone', image_type='__K__') }}".replace('__K__', encodeURIComponent(srcKey));
} else if (e.target.id === 'deleteImageModal') {
e.target.querySelector('#deleteSrcKey').textContent = srcKey;
e.target.querySelector('#deleteSrcFriendly').textContent = srcFriendly;
document.getElementById('deleteForm').action = '/images/' + encodeURIComponent(srcKey) + '/delete';
document.getElementById('deleteForm').action = "{{ url_for('images_delete', image_type='__K__') }}".replace('__K__', encodeURIComponent(srcKey));
}
});
</script>

View File

@@ -3,7 +3,7 @@
{% block content %}
<div class="page-header">
<h2><i class="bi bi-pc-display"></i> Enrollment Packages</h2>
<h1><i class="bi bi-pc-display"></i> Enrollment Packages</h1>
<div class="header-actions">
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadModal">
<i class="bi bi-upload"></i> Upload Package
@@ -132,7 +132,7 @@ document.getElementById('deleteModal').addEventListener('show.bs.modal', functio
var btn = event.relatedTarget;
var filename = btn.getAttribute('data-filename');
document.getElementById('deleteFilename').textContent = filename;
document.getElementById('deleteForm').action = '/enrollment/delete/' + encodeURIComponent(filename);
document.getElementById('deleteForm').action = "{{ url_for('enrollment_delete', filename='__F__') }}".replace('__F__', encodeURIComponent(filename));
});
</script>
{% endblock %}

View File

@@ -4,9 +4,9 @@
{% block content %}
<div class="page-header">
<div>
<h2>{{ session.serial }}
<h1>{{ session.serial }}
{% if session.hostname_target %}<span class="text-light" style="font-size:14px; font-weight:400;">{{ session.hostname_target }}</span>{% endif %}
</h2>
</h1>
<div style="margin-top:0.5rem; display:flex; gap:0.4rem; flex-wrap:wrap;">
{% if session.pctype %}<span class="badge badge-info">{{ session.pctype }}</span>{% endif %}
{% if session.machinenumber %}<span class="badge badge-secondary">#{{ session.machinenumber }}</span>{% endif %}

View File

@@ -30,7 +30,7 @@
<div class="page-header">
<div>
<h2>Drive Erasure Certificate</h2>
<h1>Drive Erasure Certificate</h1>
<code class="mono" style="color:var(--text-light);">{{ filename }}</code>
</div>
<div class="header-actions">

View File

@@ -3,7 +3,7 @@
{% block content %}
<div class="page-header">
<h2><i class="bi bi-shield-check"></i> Blancco Erasure Reports</h2>
<h1><i class="bi bi-shield-check"></i> Blancco Erasure Reports</h1>
<div class="header-actions">
<span class="badge badge-secondary badge-lg">{{ reports|length }} report{{ 's' if reports|length != 1 }}</span>
</div>
@@ -107,7 +107,7 @@ document.getElementById('deleteModal').addEventListener('show.bs.modal', functio
var btn = event.relatedTarget;
var filename = btn.getAttribute('data-filename');
document.getElementById('deleteFilename').textContent = filename;
document.getElementById('deleteForm').action = '/reports/delete/' + encodeURIComponent(filename);
document.getElementById('deleteForm').action = "{{ url_for('blancco_delete_report', filename='__F__') }}".replace('__F__', encodeURIComponent(filename));
});
</script>
{% endblock %}

View File

@@ -49,7 +49,7 @@
{% block content %}
<div class="page-header">
<h2>startnet.cmd Editor</h2>
<h1>startnet.cmd Editor</h1>
{% if wim_exists %}
<div class="header-actions">
<button type="submit" form="startnetForm" class="pxe-btn pxe-btn-primary">