fix: add spinner to refresh button and show relative time

This commit is contained in:
stellarshenson
2026-01-20 17:16:00 +01:00
parent 5e563af39b
commit a0dee35bd6
2 changed files with 27 additions and 6 deletions

View File

@@ -3,7 +3,7 @@ PROJECT_NAME="stellars-jupyterhub-ds"
PROJECT_DESCRIPTION="Multi-user JupyterHub 4 deployment platform with data science stack, GPU auto-detection, NativeAuthenticator, and isolated per-user environments spawned via DockerSpawner"
# Version
VERSION="3.7.0_cuda-13.0.2_jh-5.4.2"
VERSION="3.7.1_cuda-13.0.2_jh-5.4.2"
VERSION_COMMENT="Activity Monitor: admin page with 3-state status, activity scoring, reset functionality"
RELEASE_TAG="RELEASE_3.2.11"
RELEASE_DATE="2025-11-09"

View File

@@ -71,7 +71,11 @@ require(["jquery"], function($) {
// Manual refresh button
$('#refresh-btn').on('click', function() {
fetchActivityData();
var btn = $(this);
btn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>');
fetchActivityData(function() {
btn.prop('disabled', false).html('<i class="fa fa-refresh" aria-hidden="true"></i> Refresh');
});
});
// Reset button
@@ -98,7 +102,7 @@ require(["jquery"], function($) {
});
});
function fetchActivityData() {
function fetchActivityData(callback) {
$.ajax({
url: '{{ base_url }}api/activity',
method: 'GET',
@@ -107,6 +111,7 @@ require(["jquery"], function($) {
},
success: function(data) {
renderActivityTable(data);
if (callback) callback();
},
error: function(xhr) {
$('#loading-indicator').hide();
@@ -115,6 +120,7 @@ require(["jquery"], function($) {
.removeClass('alert-info')
.addClass('alert-danger')
.html('<i class="fa fa-exclamation-circle"></i> Failed to load activity data');
if (callback) callback();
}
});
}
@@ -137,7 +143,7 @@ require(["jquery"], function($) {
// Update header info
$('#active-count').text(users.length + ' active server' + (users.length !== 1 ? 's' : ''));
$('#last-updated').text('Measured: ' + formatTimestamp(timestamp));
$('#last-updated').text('Measured ' + formatTimeAgo(timestamp));
// Show sampling status if available
if (samplingStatus) {
@@ -255,9 +261,24 @@ require(["jquery"], function($) {
return html;
}
function formatTimestamp(isoString) {
function formatTimeAgo(isoString) {
var date = new Date(isoString);
return date.toLocaleTimeString();
var now = new Date();
var diffMs = now - date;
var diffSec = Math.floor(diffMs / 1000);
var diffMin = Math.floor(diffSec / 60);
var diffHour = Math.floor(diffMin / 60);
if (diffMin < 1) {
return 'just now';
} else if (diffMin < 60) {
return diffMin + 'min ago';
} else if (diffHour < 24) {
return diffHour + 'h ago';
} else {
var diffDay = Math.floor(diffHour / 24);
return diffDay + 'd ago';
}
}
function getCookie(name) {