update main to v0.10.0 #48

Merged
serversdown merged 32 commits from feature/sfm-integration into main 2026-05-14 16:56:43 -04:00
7 changed files with 85 additions and 36 deletions
Showing only changes of commit 2cf5bf47d3 - Show all commits
+13 -36
View File
@@ -109,45 +109,22 @@
Dashboard Dashboard
</a> </a>
<a href="/roster" class="flex items-center px-4 py-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 {% if request.url.path == '/roster' %}bg-gray-100 dark:bg-gray-700{% endif %}"> {# Fleet — single sidebar entry for all device-type pages.
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> The tab strip on each underlying page (Seismographs /
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path> Sound Level Meters / Modems / All Devices) handles
</svg> navigation between the device-type-specific layouts.
Devices Active when on any /seismographs, /sound-level-meters,
</a> /modems, /roster, /pair-devices, /unit/* page. #}
{% set _is_fleet = (
<a href="/seismographs" class="flex items-center px-4 py-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 {% if request.url.path == '/seismographs' %}bg-gray-100 dark:bg-gray-700{% endif %}"> request.url.path in ('/seismographs', '/sound-level-meters', '/modems', '/roster', '/pair-devices')
or request.url.path.startswith('/unit/')
or request.url.path.startswith('/slm/')
) %}
<a href="/seismographs" class="flex items-center px-4 py-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 {% if _is_fleet %}bg-gray-100 dark:bg-gray-700{% endif %}">
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
</svg> </svg>
Seismographs Fleet
</a>
<a href="/sfm" class="flex items-center px-4 py-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 {% if request.url.path == '/sfm' %}bg-gray-100 dark:bg-gray-700{% endif %}">
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
SFM Events
</a>
<a href="/sound-level-meters" class="flex items-center px-4 py-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 {% if request.url.path == '/sound-level-meters' %}bg-gray-100 dark:bg-gray-700{% endif %}">
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z"></path>
</svg>
Sound Level Meters
</a>
<a href="/modems" class="flex items-center px-4 py-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 {% if request.url.path == '/modems' %}bg-gray-100 dark:bg-gray-700{% endif %}">
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0"></path>
</svg>
Modems
</a>
<a href="/pair-devices" class="flex items-center px-4 py-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 {% if request.url.path == '/pair-devices' %}bg-gray-100 dark:bg-gray-700{% endif %}">
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path>
</svg>
Pair Devices
</a> </a>
<a href="/projects" class="flex items-center px-4 py-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 {% if request.url.path.startswith('/projects') %}bg-gray-100 dark:bg-gray-700{% endif %}"> <a href="/projects" class="flex items-center px-4 py-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 {% if request.url.path.startswith('/projects') %}bg-gray-100 dark:bg-gray-700{% endif %}">
+1
View File
@@ -3,6 +3,7 @@
{% block title %}Field Modems - Terra-View{% endblock %} {% block title %}Field Modems - Terra-View{% endblock %}
{% block content %} {% block content %}
{% include "partials/fleet_tab_strip.html" %}
<div class="mb-8"> <div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900 dark:text-white flex items-center"> <h1 class="text-3xl font-bold text-gray-900 dark:text-white flex items-center">
<svg class="w-8 h-8 mr-3 text-seismo-orange" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-8 h-8 mr-3 text-seismo-orange" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+54
View File
@@ -0,0 +1,54 @@
{# Fleet tab strip.
Shared header for every page under the "Fleet" sidebar section. Each
underlying page (/roster, /seismographs, /sound-level-meters, /modems)
keeps its own custom layout — this partial just provides the tab
navigation across the top so they feel like one logical area.
The active tab is detected from request.url.path so deep links work.
Usage at top of any Fleet-section template:
{% include 'partials/fleet_tab_strip.html' %}
#}
{% set _path = request.url.path %}
<div class="mb-6 border-b border-gray-200 dark:border-gray-700">
<div class="flex items-end justify-between flex-wrap gap-3 mb-0">
<nav class="flex gap-1">
<a href="/seismographs"
class="px-4 py-2 -mb-px border-b-2 text-sm font-medium transition-colors {% if _path == '/seismographs' %}border-seismo-orange text-seismo-orange{% else %}border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:border-gray-300 dark:hover:border-gray-600{% endif %}">
<svg class="w-4 h-4 inline -mt-0.5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M22 12h-4l-3 9L9 3l-3 9H2"/>
</svg>
Seismographs
</a>
<a href="/sound-level-meters"
class="px-4 py-2 -mb-px border-b-2 text-sm font-medium transition-colors {% if _path == '/sound-level-meters' %}border-seismo-orange text-seismo-orange{% else %}border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:border-gray-300 dark:hover:border-gray-600{% endif %}">
<svg class="w-4 h-4 inline -mt-0.5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.536 8.464a5 5 0 010 7.072M12 6v12M9 8.464a5 5 0 000 7.072"/>
</svg>
Sound Level Meters
</a>
<a href="/modems"
class="px-4 py-2 -mb-px border-b-2 text-sm font-medium transition-colors {% if _path == '/modems' %}border-seismo-orange text-seismo-orange{% else %}border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:border-gray-300 dark:hover:border-gray-600{% endif %}">
<svg class="w-4 h-4 inline -mt-0.5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0"/>
</svg>
Modems
</a>
<a href="/roster"
class="px-4 py-2 -mb-px border-b-2 text-sm font-medium transition-colors {% if _path == '/roster' %}border-seismo-orange text-seismo-orange{% else %}border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:border-gray-300 dark:hover:border-gray-600{% endif %}">
<svg class="w-4 h-4 inline -mt-0.5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16"/>
</svg>
All Devices
</a>
</nav>
<a href="/pair-devices"
class="mb-1 inline-flex items-center gap-1.5 px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
</svg>
Pair Devices
</a>
</div>
</div>
+1
View File
@@ -3,6 +3,7 @@
{% block title %}Devices - Seismo Fleet Manager{% endblock %} {% block title %}Devices - Seismo Fleet Manager{% endblock %}
{% block content %} {% block content %}
{% include "partials/fleet_tab_strip.html" %}
<div class="mb-8"> <div class="mb-8">
<div class="flex justify-between items-start"> <div class="flex justify-between items-start">
<div> <div>
+1
View File
@@ -3,6 +3,7 @@
{% block title %}Seismographs - Seismo Fleet Manager{% endblock %} {% block title %}Seismographs - Seismo Fleet Manager{% endblock %}
{% block content %} {% block content %}
{% include "partials/fleet_tab_strip.html" %}
<div class="mb-8"> <div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Seismographs</h1> <h1 class="text-3xl font-bold text-gray-900 dark:text-white">Seismographs</h1>
<p class="text-gray-600 dark:text-gray-400 mt-1">Manage and monitor seismograph units</p> <p class="text-gray-600 dark:text-gray-400 mt-1">Manage and monitor seismograph units</p>
+14
View File
@@ -561,6 +561,20 @@
</a> </a>
</div> </div>
<!-- SFM Admin (raw event database) -->
<div class="flex items-center justify-between p-4 bg-gray-50 dark:bg-slate-700 rounded-lg">
<div>
<div class="font-medium text-gray-900 dark:text-white">SFM Admin</div>
<div class="text-sm text-gray-500 dark:text-gray-400 mt-0.5">
Raw event database from SFM — cross-project event search, file downloads, debug view. Day-to-day event browsing lives on project / location / unit pages.
</div>
</div>
<a href="/sfm"
class="ml-6 px-4 py-2 bg-seismo-orange hover:bg-orange-600 text-white text-sm font-medium rounded-lg transition-colors whitespace-nowrap">
Open
</a>
</div>
<!-- Metadata Backfill (Phase 5a) --> <!-- Metadata Backfill (Phase 5a) -->
<div class="flex items-center justify-between p-4 bg-gray-50 dark:bg-slate-700 rounded-lg"> <div class="flex items-center justify-between p-4 bg-gray-50 dark:bg-slate-700 rounded-lg">
<div> <div>
+1
View File
@@ -3,6 +3,7 @@
{% block title %}Sound Level Meters - Seismo Fleet Manager{% endblock %} {% block title %}Sound Level Meters - Seismo Fleet Manager{% endblock %}
{% block content %} {% block content %}
{% include "partials/fleet_tab_strip.html" %}
<div class="mb-8"> <div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900 dark:text-white flex items-center"> <h1 class="text-3xl font-bold text-gray-900 dark:text-white flex items-center">
<svg class="w-8 h-8 mr-3 text-seismo-orange" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-8 h-8 mr-3 text-seismo-orange" fill="none" stroke="currentColor" viewBox="0 0 24 24">