feat: portal-wide device selector — session-based, all pages now use selected device
- _portal_device_id() reads from session, falls back to DEVICE_NAME env var - GET/POST /api/v1/portal/select-device for selector data + set - Dropdown in server base.html topbar, JS populates from API, page reloads on change - All portal pages (overview, trips, dashcam, DTC, device settings) now use selected device
This commit is contained in:
@@ -86,7 +86,12 @@
|
||||
<span class="fw-bold text-dark">Yaris OBD</span>
|
||||
<span class="badge bg-warning text-dark ms-1" style="font-size:.6rem;">Remote</span>
|
||||
</a>
|
||||
<div class="ms-auto d-flex align-items-center gap-2">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<select class="form-select form-select-sm" id="portal-device-selector" style="width:auto;min-width:10rem;" aria-label="Select device">
|
||||
<option value="">Loading…</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<span class="text-muted small d-none d-sm-inline">{{ current_user.username }}</span>
|
||||
<a href="{{ url_for('logout') }}" class="btn btn-outline-secondary btn-sm" title="Logout">
|
||||
<i class="fas fa-sign-out-alt fa-fw"></i>
|
||||
@@ -136,7 +141,34 @@
|
||||
<script src="{{ url_for('static', filename='js/bs-init.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/theme.js') }}"></script>
|
||||
|
||||
{# ── Shared confirmation helper ────────────────────────────────────────── #}
|
||||
{# ── Device selector ─────────────────────────────────────────────────── #}
|
||||
<script>
|
||||
(function () {
|
||||
const sel = document.getElementById("portal-device-selector");
|
||||
if (!sel) return;
|
||||
async function load() {
|
||||
const r = await fetch("/api/v1/portal/select-device");
|
||||
if (!r.ok) return;
|
||||
const d = await r.json();
|
||||
sel.innerHTML = d.devices.map(dev =>
|
||||
'<option value="' + dev.id + '"' + (dev.id === d.selected_device_id ? " selected" : "") + ">" +
|
||||
(dev.device_name || dev.name) + (dev.portal_default ? " (default)" : "") +
|
||||
"</option>"
|
||||
).join("");
|
||||
if (!d.devices.length) sel.innerHTML = '<option value="">No devices</option>';
|
||||
}
|
||||
load();
|
||||
sel.addEventListener("change", async function () {
|
||||
const id = sel.value ? parseInt(sel.value) : null;
|
||||
await fetch("/api/v1/portal/select-device", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify({device_id: id}),
|
||||
});
|
||||
location.reload();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
window.confirmDelete = function(message) {
|
||||
return Promise.resolve(window.confirm(message));
|
||||
|
||||
Reference in New Issue
Block a user