feat(ui): add PDF export via browser print

Adds a PDF button to the report header. Clicking it opens
/chart/current?print=true in a new tab, which auto-triggers
window.print() so the user can save to PDF via the browser dialog.

- chart submodule bumped: PrintMode support (no filter JS, auto-print,
  @media print CSS)
- handlers.go: passes PrintMode=true when ?print=true query param is set
- index.html: PDF button alongside Raw Data / Reanimator
- app.js: printReport() helper; button shown/hidden with other exports

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 12:24:01 +03:00
parent 10c381c8ec
commit 1c4a3b0c09
5 changed files with 13 additions and 2 deletions

View File

@@ -1410,6 +1410,7 @@ async function loadData(vendor, filename) {
document.getElementById('clear-btn').classList.remove('hidden');
document.getElementById('header-raw-btn').classList.remove('hidden');
document.getElementById('header-reanimator-btn').classList.remove('hidden');
document.getElementById('header-pdf-btn').classList.remove('hidden');
document.getElementById('header-log-meta').classList.remove('hidden');
loadAuditViewer();
@@ -1509,6 +1510,10 @@ function exportData(format) {
window.location.href = `/api/export/${format}`;
}
function printReport() {
window.open('/chart/current?print=true', '_blank');
}
// Clear data
async function clearData() {
try {
@@ -1518,6 +1523,7 @@ async function clearData() {
document.getElementById('clear-btn').classList.add('hidden');
document.getElementById('header-raw-btn').classList.add('hidden');
document.getElementById('header-reanimator-btn').classList.add('hidden');
document.getElementById('header-pdf-btn').classList.add('hidden');
document.getElementById('header-log-meta').classList.add('hidden');
document.getElementById('upload-status').textContent = '';
const frame = document.getElementById('audit-viewer-frame');

View File

@@ -18,6 +18,7 @@
<button id="clear-btn" class="header-action hidden" onclick="clearData()">Clear Data</button>
<button id="header-raw-btn" class="header-action hidden" onclick="exportData('json')">Raw Data</button>
<button id="header-reanimator-btn" class="header-action hidden" onclick="exportData('reanimator')">Reanimator</button>
<button id="header-pdf-btn" class="header-action hidden" onclick="printReport()">PDF</button>
<button id="restart-btn" class="header-action" onclick="restartApp()">Restart</button>
<button id="exit-btn" class="header-action" onclick="exitApp()">Exit</button>
</div>