From 21844b4d651a486b37ac28cbc4b501daf26956cc Mon Sep 17 00:00:00 2001 From: serversdown Date: Tue, 12 May 2026 04:05:28 +0000 Subject: [PATCH] feat(sfm): download buttons in event-detail modal (Blastware binary + sidecar JSON) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two new action buttons at the top of the Source File section of the event-detail modal: 1. Download Blastware file — primary orange button. Pulls the raw .AB0 /.G10/.6R0/etc. binary from SFM (/db/events/{id}/blastware_file) via terra-view's /api/sfm proxy. The browser saves it with the original on-disk filename (using the HTML5 `download` attribute pointed at sidecar.blastware.filename). Operator can then open the file directly in Blastware on a Windows box for full waveform analysis, archive it, or attach it to a compliance report. Greyed-out "Blastware file unavailable" placeholder shown when sidecar.blastware.available is false (rare — would mean SFM stored the metadata but lost the binary). 2. Download sidecar JSON — secondary outlined button. Pulls the same .sfm.json the modal renders from. Saved as .sfm.json. Useful for ops/diagnostics and for the future metadata-driven project parser (Phase 5) which can chew on these directly. End-to-end verified through the proxy: 8882-byte Blastware binary intact with "Instantel" magic header preserved. Co-Authored-By: Claude Opus 4.7 --- backend/static/event-modal.js | 43 +++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/backend/static/event-modal.js b/backend/static/event-modal.js index 51d56fd..28a97d8 100644 --- a/backend/static/event-modal.js +++ b/backend/static/event-modal.js @@ -197,11 +197,46 @@ `; } - function _renderFileInfo(s) { + function _renderFileInfo(s, eventId) { const bw = s.blastware || {}; const src = s.source || {}; - return `
-
Blastware file ${_esc(bw.filename || '—')} ${bw.filesize ? `(${(bw.filesize / 1024).toFixed(1)} KB)` : ''}
+ const sizeKb = bw.filesize ? (bw.filesize / 1024).toFixed(1) : null; + const canDownloadBinary = !!(bw.available && bw.filename && eventId); + + const downloadButtons = ` + + `; + + return `${downloadButtons} +
+
Blastware file ${_esc(bw.filename || '—')} ${sizeKb ? `(${sizeKb} KB)` : ''}
SHA-256 ${_esc(bw.sha256 || '—')}
Captured at ${_esc(src.captured_at ? src.captured_at.slice(0, 19).replace('T', ' ') : '—')}
Tool version ${_esc(src.tool_version || '—')}
@@ -279,7 +314,7 @@ ` : ''} ${_sectionHeader('Source File')} - ${_renderFileInfo(s)} + ${_renderFileInfo(s, eventId)} `; };