Add status page quick actions

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Mathieu Moran
2026-08-10 18:40:22 -04:00
co-authored by Copilot
parent ef38ec92b4
commit 8907c51016
10 changed files with 202 additions and 2 deletions
+95
View File
@@ -12,6 +12,27 @@ function setText(id, value) {
}
}
function showActionMessage(text, kind) {
const banner = document.getElementById('status-action-message');
banner.textContent = text;
banner.className = `alert alert-${kind} py-2`;
banner.hidden = false;
}
function setActionButtonsDisabled(disabled) {
[
'status-action-test-server',
'status-action-sync-now',
'status-action-reconnect-uplink',
'status-action-restart-app',
].forEach((id) => {
const button = document.getElementById(id);
if (button) {
button.disabled = disabled;
}
});
}
function formatUptime(seconds) {
if (seconds == null) return 'Unavailable';
const days = Math.floor(seconds / 86400);
@@ -292,6 +313,80 @@ function showStatusError(error) {
banner.hidden = false;
}
async function runStatusAction(buttonId, requestFactory, successMessage, options = {}) {
const button = document.getElementById(buttonId);
const actionBanner = document.getElementById('status-action-message');
actionBanner.hidden = true;
button.disabled = true;
try {
const response = await requestFactory();
const result = await response.json();
if (!response.ok) {
throw new Error(result.error || result.message || `HTTP ${response.status}`);
}
showActionMessage(result.message || successMessage, options.successKind || 'success');
if (options.disableAllOnSuccess) {
setActionButtonsDisabled(true);
}
if (options.refreshAfter !== false) {
await refreshStatus();
}
} catch (error) {
showActionMessage(error.message, 'danger');
} finally {
if (!options.keepDisabled) {
button.disabled = false;
}
}
}
document.getElementById('status-action-test-server').addEventListener('click', function () {
runStatusAction(
'status-action-test-server',
function () {
return fetch('/api/remote-config/test', { method: 'POST' });
},
'Remote server connection looks good.'
);
});
document.getElementById('status-action-sync-now').addEventListener('click', function () {
runStatusAction(
'status-action-sync-now',
function () {
return fetch('/api/remote-config/sync-now', { method: 'POST' });
},
'Sync completed.'
);
});
document.getElementById('status-action-reconnect-uplink').addEventListener('click', function () {
runStatusAction(
'status-action-reconnect-uplink',
function () {
return fetch('/api/uplink/connect', { method: 'POST' });
},
'Waiting for the saved hotspot. This page may disconnect while networks switch.',
{ successKind: 'info' }
);
});
document.getElementById('status-action-restart-app').addEventListener('click', function () {
runStatusAction(
'status-action-restart-app',
function () {
return fetch('/api/status/restart-app', { method: 'POST' });
},
'App restart requested. The page may disconnect for a few seconds.',
{
successKind: 'warning',
refreshAfter: false,
keepDisabled: true,
disableAllOnSuccess: true,
}
);
});
refreshStatus().catch(showStatusError);
window.setInterval(function () {
refreshStatus().catch(showStatusError);