From 4b2bb9a9c99433b3e58184262186c82f64be176e Mon Sep 17 00:00:00 2001 From: serversdown Date: Fri, 29 May 2026 01:04:15 +0000 Subject: [PATCH] event-modal: inline PDF preview + .TXT link + review form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three additions to the shared event-detail modal, closing the gap versus the standalone SFM webapp: (1) "Show Event Report PDF" button toggles an inline iframe inside the modal (no second-layer modal, no new tab). Lazy-loaded — src isn't set until first reveal, so closing the modal without opening the PDF never spends bandwidth. Sibling "Download PDF" link for direct save. Iframe sized to 80vh / min 600px so the typical letter-portrait single-page report fits with browser-native zoom controls available. (2) "Original .TXT report" download link, rendered only when sidecar.source.txt_filename is present (post-2026-05-27 ingest events). Hidden for legacy events to avoid 404 dead links. (3) Inline Review form — false_trigger checkbox + reviewer text input + notes textarea + Save button. PATCH /api/sfm/db/events/{id}/sidecar with {"review": {...}}. On save, fires a CustomEvent 'sfm-event-review-saved' on window so table-owning pages (/sfm, /unit/{id}, /admin/events, /projects/{p}/nrl/{l}) can listen and refresh their FT badges without reload. Status line shows the last-reviewed timestamp + Save success/failure feedback. Smoke-tested end-to-end against a real BE12599 histogram event: PATCH round-trip lands in the sidecar, GET reflects the change, no 500s on /report.pdf or /sidecar paths through the proxy. Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/static/event-modal.js | 152 ++++++++++++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 9 deletions(-) diff --git a/backend/static/event-modal.js b/backend/static/event-modal.js index ec210cf..162bced 100644 --- a/backend/static/event-modal.js +++ b/backend/static/event-modal.js @@ -245,6 +245,47 @@ `; } + function _renderReview(s, eventId) { + const rev = s.review || {}; + const ft = !!rev.false_trigger; + const reviewer = rev.reviewer || ''; + const notes = rev.notes || ''; + const reviewedAt = rev.reviewed_at + ? rev.reviewed_at.replace('T', ' ').slice(0, 19) + : null; + return `
+
+ +
+ + +
+
+
+ + +
+
+ + ${reviewedAt ? `Last reviewed ${reviewedAt}` : 'Not yet reviewed.'} + + +
+
`; + } + // ── Waveform / histogram chart helpers ────────────────────────── async function _loadMicUnitPref() { @@ -527,27 +568,47 @@ const src = s.source || {}; const sizeKb = bw.filesize ? (bw.filesize / 1024).toFixed(1) : null; const canDownloadBinary = !!(bw.available && bw.filename && eventId); + const txtFilename = src && src.txt_filename; + const reportPdfUrl = `/api/sfm/db/events/${encodeURIComponent(eventId)}/report.pdf`; + const reportTxtUrl = `/api/sfm/db/events/${encodeURIComponent(eventId)}/ascii_report.txt`; const downloadButtons = ` +