Event modal (event-modal.js):
- Record Type now derived from Blastware filename's last-char code
(H=Histogram, W=Waveform, M=Manual, E=Event, C=Combo). Falls back to
whatever SFM reported if the code isn't recognized. Client-side
workaround — SFM still hardcodes "Waveform" server-side and needs a
proper fix in its sidecar parser.
- PSI mic tile dropped; mic section now renders 3 tiles (dB(L), ZC
Frequency, Time of Peak) instead of 4.
- New "View JSON" toggle exposes a prettified inline JSON viewer with
a Copy-to-clipboard button alongside the existing "Download sidecar
JSON" link.
- "Project Info" section header renamed to "User Notes" to reflect
that these are operator-typed fields, not the terra-view project
assignment.
Sortable tables (sfm.html + unit_detail.html):
- Both Events tables now have clickable column headers with ↕/↓/↑
indicators. Default sort is Timestamp DESC. Clicking the same
column toggles direction; clicking a different column switches and
resets to DESC. Sort is purely client-side over the cached rowset,
so no extra fetches.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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 <binary>.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 <noreply@anthropic.com>
Clicking any event row in any of the three event tables (/sfm Events,
project-location Events tab, unit detail SFM Events) now opens a modal
populated from the SFM .sfm.json sidecar. Previously the /sfm page had
a basic inline modal showing only the columns already in the table;
this rebuilds it as a shared component and exposes the rich fields
that the BW ASCII report unlocks.
Shared component:
- backend/static/event-modal.js — single ~250-line module. Public API:
showEventDetail(eventId) fetches /api/sfm/db/events/{id}/sidecar
live (no extra terra-view caching) and renders sections for:
• Event (serial, timestamp, record type, sample rate, rec time,
waveform key)
• Project Info (operator-typed user notes — project / client /
operator / sensor_location — flagged in the UI as "as typed
into the seismograph at session start", not the terra-view
assignment)
• Peak Particle Velocity (per-channel + vector sum, with the
time-of-vector-sum-peak when bw_report is available)
• Microphone (Peak dB(L) + psi, ZC frequency, time of peak)
• Sensor Self-Check table (per-channel freq + ratio/amplitude +
pass/fail)
• Device & Recording Metadata (firmware, battery, calibration
date + by-whom, geo range, stop mode, units)
• Source File (Blastware filename, size, SHA-256, capture time)
closeEventDetailModal() closes; Escape key also closes.
- templates/partials/event_detail_modal.html — modal shell partial
(sticky title bar, scrollable body, click-outside-to-close).
Wired into three pages:
- templates/sfm.html: removed the old inline modal + showEventDetail /
ppvCard / closeEventModal functions (replaced by the shared module).
Row onclick now passes just the event id instead of the full JSON.
- templates/vibration_location_detail.html: row click on the Events
tab opens the modal. The /unit/{serial} link inside the row has
event.stopPropagation() so the link navigates instead of opening
the modal.
- templates/unit_detail.html: row click on the SFM Events table opens
the modal. The attribution-cell project/location links also got
stopPropagation.
Graceful degradation: older events forwarded before the watcher's
_ASCII.TXT pairing fix don't have a bw_report block in their sidecar.
The modal renders an amber banner explaining that and shows just the
event + project_info + peak_values + source-file sections.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Created complete frontend structure with Jinja2 templates
- Implemented three main pages: Dashboard, Fleet Roster, and Unit Detail
- Added HTMX auto-refresh for real-time updates (10s interval)
- Integrated dark/light mode toggle with localStorage persistence
- Built responsive card-based UI with sidebar navigation
- Created API endpoints for status snapshot, roster, unit details, and photos
- Added mock data service for development (emit_status_snapshot)
- Implemented tabbed interface on unit detail page (Photos, Map, History)
- Integrated Leaflet maps for unit location visualization
- Configured static file serving and photo management
- Updated requirements.txt with Jinja2 and aiofiles
- Reorganized backend structure into routers and services
- Added comprehensive FRONTEND_README.md documentation
Frontend features:
- Auto-refreshing dashboard with fleet summary and alerts
- Sortable fleet roster table (prioritizes Missing > Pending > OK)
- Unit detail view with status, deployment info, and notes
- Photo gallery with thumbnail navigation
- Interactive maps showing unit coordinates
- Consistent styling with brand colors (orange, navy, burgundy)
Ready for integration with real Series3 emitter data.