Migrate inspector and links pages to TDS lt.* APIs
Lint / Python (flake8) (push) Failing after 1m22s
Lint / JS (eslint) (push) Successful in 10s
Security / Python Security (bandit) (push) Failing after 49s
Lint / Notify on failure (push) Has been cancelled
Lint / Deploy (push) Has been cancelled
Test / Python Tests (pytest) (push) Has been cancelled
Lint / Python (flake8) (push) Failing after 1m22s
Lint / JS (eslint) (push) Successful in 10s
Security / Python Security (bandit) (push) Failing after 49s
Lint / Notify on failure (push) Has been cancelled
Lint / Deploy (push) Has been cancelled
Test / Python Tests (pytest) (push) Has been cancelled
- Add escHtml alias (lt.escHtml) to both pages so existing template strings work without touching 40+ call sites - Replace raw fetch() with lt.api.get/post in loadInspector, loadLinks, runDiagnostic, pollDiagnostic - Replace setInterval(load*, 60000) with lt.autoRefresh.start() for intelligent polling - Add lt.toast.error() to catch blocks for user-visible error feedback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script>
|
<script>
|
||||||
|
const escHtml = s => lt.escHtml(s);
|
||||||
|
|
||||||
// ── Switch layout config ─────────────────────────────────────────────────
|
// ── Switch layout config ─────────────────────────────────────────────────
|
||||||
// keys match the model field returned by the UniFi API
|
// keys match the model field returned by the UniFi API
|
||||||
// rows: array of rows, each row is an array of port_idx values
|
// rows: array of rows, each row is an array of port_idx values
|
||||||
@@ -451,18 +453,17 @@ function renderInspector(data) {
|
|||||||
// ── Fetch and render ─────────────────────────────────────────────────────
|
// ── Fetch and render ─────────────────────────────────────────────────────
|
||||||
async function loadInspector() {
|
async function loadInspector() {
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('/api/links');
|
const data = await lt.api.get('/api/links');
|
||||||
if (!resp.ok) throw new Error('API error');
|
|
||||||
const data = await resp.json();
|
|
||||||
renderInspector(data);
|
renderInspector(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
document.getElementById('inspector-main').innerHTML =
|
document.getElementById('inspector-main').innerHTML =
|
||||||
'<p class="empty-state">Failed to load inspector data.</p>';
|
'<p class="empty-state">Failed to load inspector data.</p>';
|
||||||
|
lt.toast.error('Failed to load inspector data');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadInspector();
|
loadInspector();
|
||||||
setInterval(loadInspector, 60000);
|
lt.autoRefresh.start(loadInspector, 60000);
|
||||||
|
|
||||||
// ── Link Diagnostics ─────────────────────────────────────────────────
|
// ── Link Diagnostics ─────────────────────────────────────────────────
|
||||||
let _diagPollTimer = null;
|
let _diagPollTimer = null;
|
||||||
@@ -478,22 +479,13 @@ function runDiagnostic(swName, portIdx) {
|
|||||||
statusEl.textContent = 'Submitting to Pulse...';
|
statusEl.textContent = 'Submitting to Pulse...';
|
||||||
resultsEl.innerHTML = '';
|
resultsEl.innerHTML = '';
|
||||||
|
|
||||||
fetch('/api/diagnose', {
|
lt.api.post('/api/diagnose', {switch_name: swName, port_idx: portIdx})
|
||||||
method: 'POST',
|
|
||||||
headers: {'Content-Type': 'application/json'},
|
|
||||||
body: JSON.stringify({switch_name: swName, port_idx: portIdx}),
|
|
||||||
})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
if (resp.error) {
|
|
||||||
statusEl.textContent = 'Error: ' + resp.error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
statusEl.textContent = 'Collecting diagnostics via Pulse...';
|
statusEl.textContent = 'Collecting diagnostics via Pulse...';
|
||||||
pollDiagnostic(resp.job_id, statusEl, resultsEl);
|
pollDiagnostic(resp.job_id, statusEl, resultsEl);
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
statusEl.textContent = 'Request failed: ' + e;
|
statusEl.textContent = 'Error: ' + (e.message || 'Request failed');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,8 +498,7 @@ function pollDiagnostic(jobId, statusEl, resultsEl) {
|
|||||||
statusEl.textContent = 'Timed out waiting for results.';
|
statusEl.textContent = 'Timed out waiting for results.';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fetch(`/api/diagnose/${jobId}`)
|
lt.api.get(`/api/diagnose/${jobId}`)
|
||||||
.then(r => r.json())
|
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
if (resp.status === 'done') {
|
if (resp.status === 'done') {
|
||||||
clearInterval(_diagPollTimer);
|
clearInterval(_diagPollTimer);
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script>
|
<script>
|
||||||
|
const escHtml = s => lt.escHtml(s);
|
||||||
|
|
||||||
// ── Formatting helpers ────────────────────────────────────────────
|
// ── Formatting helpers ────────────────────────────────────────────
|
||||||
function fmtRate(bytesPerSec) {
|
function fmtRate(bytesPerSec) {
|
||||||
if (bytesPerSec === null || bytesPerSec === undefined) return '–';
|
if (bytesPerSec === null || bytesPerSec === undefined) return '–';
|
||||||
@@ -480,13 +482,7 @@ function checkLinksStale(updatedStr) {
|
|||||||
// ── Fetch + render ────────────────────────────────────────────────
|
// ── Fetch + render ────────────────────────────────────────────────
|
||||||
async function loadLinks() {
|
async function loadLinks() {
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('/api/links');
|
const data = await lt.api.get('/api/links');
|
||||||
if (!resp.ok) {
|
|
||||||
document.getElementById('links-container').innerHTML =
|
|
||||||
'<div class="error-state">Failed to load link statistics.</div>';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const data = await resp.json();
|
|
||||||
if (!data.hosts && !data.unifi_switches) {
|
if (!data.hosts && !data.unifi_switches) {
|
||||||
document.getElementById('links-container').innerHTML =
|
document.getElementById('links-container').innerHTML =
|
||||||
'<div class="link-no-data">No link data yet — monitor has not completed a full cycle.</div>';
|
'<div class="link-no-data">No link data yet — monitor has not completed a full cycle.</div>';
|
||||||
@@ -501,10 +497,11 @@ async function loadLinks() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
document.getElementById('links-container').innerHTML =
|
document.getElementById('links-container').innerHTML =
|
||||||
'<div class="error-state">Network error loading link statistics.</div>';
|
'<div class="error-state">Network error loading link statistics.</div>';
|
||||||
|
lt.toast.error('Failed to load link statistics');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadLinks();
|
loadLinks();
|
||||||
setInterval(loadLinks, 60000);
|
lt.autoRefresh.start(loadLinks, 60000);
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user