Add: pair_devices.html template for device pairing interface
Fix: - Polling intervals for SLMM. -modem view now list - device pairing much improved. -various other tweaks through out UI.
This commit is contained in:
@@ -104,8 +104,13 @@
|
||||
{% if unit.phone_number %}
|
||||
<div>{{ unit.phone_number }}</div>
|
||||
{% endif %}
|
||||
{% if unit.hardware_model %}
|
||||
<div class="text-gray-500 dark:text-gray-500">{{ unit.hardware_model }}</div>
|
||||
{% if unit.deployed_with_unit_id %}
|
||||
<div>
|
||||
<span class="text-gray-500 dark:text-gray-500">Linked:</span>
|
||||
<a href="/unit/{{ unit.deployed_with_unit_id }}" class="text-seismo-orange hover:underline font-medium">
|
||||
{{ unit.deployed_with_unit_id }}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if unit.next_calibration_due %}
|
||||
@@ -126,7 +131,7 @@
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">{{ unit.last_seen }}</div>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400 last-seen-cell" data-iso="{{ unit.last_seen }}">{{ unit.last_seen }}</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm
|
||||
@@ -345,6 +350,39 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
// User's configured timezone from settings (defaults to America/New_York)
|
||||
const userTimezone = '{{ user_timezone | default("America/New_York") }}';
|
||||
|
||||
// Format ISO timestamp to human-readable format in user's timezone
|
||||
function formatLastSeenLocal(isoString) {
|
||||
if (!isoString || isoString === 'Never' || isoString === 'N/A') {
|
||||
return isoString || 'Never';
|
||||
}
|
||||
try {
|
||||
const date = new Date(isoString);
|
||||
if (isNaN(date.getTime())) return isoString;
|
||||
|
||||
// Format in user's configured timezone
|
||||
return date.toLocaleString('en-US', {
|
||||
timeZone: userTimezone,
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
hour12: true
|
||||
});
|
||||
} catch (e) {
|
||||
return isoString;
|
||||
}
|
||||
}
|
||||
|
||||
// Format all last-seen cells on page load
|
||||
document.querySelectorAll('.last-seen-cell').forEach(cell => {
|
||||
const isoDate = cell.getAttribute('data-iso');
|
||||
cell.textContent = formatLastSeenLocal(isoDate);
|
||||
});
|
||||
|
||||
// Update timestamp
|
||||
const timestampElement = document.getElementById('last-updated');
|
||||
if (timestampElement) {
|
||||
@@ -365,20 +403,23 @@
|
||||
};
|
||||
return acc;
|
||||
}, {});
|
||||
})();
|
||||
|
||||
// Sorting state
|
||||
let currentSort = { column: null, direction: 'asc' };
|
||||
// Sorting state (needs to persist across swaps)
|
||||
if (typeof window.currentSort === 'undefined') {
|
||||
window.currentSort = { column: null, direction: 'asc' };
|
||||
}
|
||||
|
||||
function sortTable(column) {
|
||||
const tbody = document.getElementById('roster-tbody');
|
||||
const rows = Array.from(tbody.getElementsByTagName('tr'));
|
||||
|
||||
// Determine sort direction
|
||||
if (currentSort.column === column) {
|
||||
currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc';
|
||||
if (window.currentSort.column === column) {
|
||||
window.currentSort.direction = window.currentSort.direction === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
currentSort.column = column;
|
||||
currentSort.direction = 'asc';
|
||||
window.currentSort.column = column;
|
||||
window.currentSort.direction = 'asc';
|
||||
}
|
||||
|
||||
// Sort rows
|
||||
@@ -406,8 +447,8 @@
|
||||
bVal = bVal.toLowerCase();
|
||||
}
|
||||
|
||||
if (aVal < bVal) return currentSort.direction === 'asc' ? -1 : 1;
|
||||
if (aVal > bVal) return currentSort.direction === 'asc' ? 1 : -1;
|
||||
if (aVal < bVal) return window.currentSort.direction === 'asc' ? -1 : 1;
|
||||
if (aVal > bVal) return window.currentSort.direction === 'asc' ? 1 : -1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
@@ -443,10 +484,10 @@
|
||||
});
|
||||
|
||||
// Set current indicator
|
||||
if (currentSort.column) {
|
||||
const indicator = document.querySelector(`.sort-indicator[data-column="${currentSort.column}"]`);
|
||||
if (window.currentSort.column) {
|
||||
const indicator = document.querySelector(`.sort-indicator[data-column="${window.currentSort.column}"]`);
|
||||
if (indicator) {
|
||||
indicator.className = `sort-indicator ${currentSort.direction}`;
|
||||
indicator.className = `sort-indicator ${window.currentSort.direction}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user