Add visualization_ui/js/ui.js
This commit is contained in:
parent
b0cc8652ed
commit
2bf072fd99
1 changed files with 100 additions and 0 deletions
100
visualization_ui/js/ui.js
Normal file
100
visualization_ui/js/ui.js
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* UI Rendering Module for Visualization UI
|
||||
* Handles rendering of Alerts table and Outlier summary panel.
|
||||
*
|
||||
* @module ui
|
||||
*/
|
||||
|
||||
/**
|
||||
* Renders the Max-only alert data into a table structure within #alert-dashboard.
|
||||
* @param {Array<Object>} alerts - Array of alert objects from /alert-data endpoint.
|
||||
*/
|
||||
export function renderAlertDashboard(alerts = []) {
|
||||
const container = document.getElementById('alert-dashboard');
|
||||
if (!container) return;
|
||||
|
||||
container.innerHTML = '';
|
||||
const status = document.createElement('div');
|
||||
status.className = 'visualization_ui__status';
|
||||
|
||||
if (!Array.isArray(alerts) || alerts.length === 0) {
|
||||
status.textContent = 'Keine Alert-Daten vorhanden.';
|
||||
container.appendChild(status);
|
||||
return;
|
||||
}
|
||||
|
||||
const table = document.createElement('table');
|
||||
table.className = 'visualization_ui__table';
|
||||
|
||||
const thead = document.createElement('thead');
|
||||
thead.innerHTML = `
|
||||
<tr>
|
||||
<th>corr_id</th>
|
||||
<th>stratum</th>
|
||||
<th>expires_at_dist_hours</th>
|
||||
<th>retry_total_overhead_ms</th>
|
||||
</tr>
|
||||
`;
|
||||
table.appendChild(thead);
|
||||
|
||||
const tbody = document.createElement('tbody');
|
||||
for (const alert of alerts) {
|
||||
const row = document.createElement('tr');
|
||||
row.innerHTML = `
|
||||
<td>${escapeHTML(alert.corr_id ?? '')}</td>
|
||||
<td>${escapeHTML(alert.stratum ?? '')}</td>
|
||||
<td>${escapeHTML(alert.expires_at_dist_hours ?? '')}</td>
|
||||
<td>${escapeHTML(alert.retry_total_overhead_ms ?? '')}</td>
|
||||
`;
|
||||
tbody.appendChild(row);
|
||||
}
|
||||
|
||||
table.appendChild(tbody);
|
||||
container.appendChild(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays outlier analysis summary metrics inside #outlier-summary panel.
|
||||
* @param {Object} report - Report object fetched from /outlier-report endpoint.
|
||||
*/
|
||||
export function renderOutlierSummary(report = {}) {
|
||||
const container = document.getElementById('outlier-summary');
|
||||
if (!container) return;
|
||||
container.innerHTML = '';
|
||||
|
||||
const summary = document.createElement('div');
|
||||
summary.className = 'visualization_ui__outlier-summary';
|
||||
|
||||
if (!Object.keys(report).length) {
|
||||
summary.textContent = 'Noch keine Outlier-Daten verfügbar.';
|
||||
container.appendChild(summary);
|
||||
return;
|
||||
}
|
||||
|
||||
const list = document.createElement('dl');
|
||||
for (const [key, value] of Object.entries(report)) {
|
||||
const term = document.createElement('dt');
|
||||
term.textContent = key;
|
||||
const desc = document.createElement('dd');
|
||||
desc.textContent = typeof value === 'number' ? value.toFixed(3) : String(value);
|
||||
list.appendChild(term);
|
||||
list.appendChild(desc);
|
||||
}
|
||||
|
||||
summary.appendChild(list);
|
||||
container.appendChild(summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes potential HTML in strings to prevent XSS injection.
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
function escapeHTML(str) {
|
||||
return String(str)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
Loading…
Reference in a new issue