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:
@@ -7,6 +7,7 @@
|
||||
| `GET /api/export/csv` | CSV | Serial-number export |
|
||||
| `GET /api/export/json` | raw-export ZIP bundle | Reopen and re-analyze later |
|
||||
| `GET /api/export/reanimator` | JSON | Reanimator hardware payload |
|
||||
| `GET /chart/current?print=true` | HTML (auto-print) | Print/PDF version of the report — opens in new tab, calls `window.print()` |
|
||||
| `POST /api/convert` | async ZIP artifact | Batch archive-to-Reanimator conversion |
|
||||
|
||||
## Raw export
|
||||
|
||||
Submodule internal/chart updated: 8105c7ec08...fddae50d64
@@ -84,7 +84,10 @@ func (s *Server) handleChartCurrent(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
html, err := chartviewer.RenderHTML(snapshotBytes, title)
|
||||
printMode := r.URL.Query().Get("print") == "true"
|
||||
html, err := chartviewer.RenderHTMLWithOptions(snapshotBytes, title, chartviewer.RenderOptions{
|
||||
PrintMode: printMode,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, "failed to render chart: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user