feat: polish alpine live page states

This commit is contained in:
a.tolmachev
2026-03-31 17:03:26 +03:00
parent 7aabf7077a
commit ffa9cc87eb
8 changed files with 130 additions and 19 deletions
+33 -7
View File
@@ -76,9 +76,19 @@ document.addEventListener('DOMContentLoaded', function () {
return 'Wk ' + (index + 1);
}
function renderEmpty(message) {
chartWrap.innerHTML = '<div style="padding:32px;color:var(--text-muted);text-align:center;width:100%;">' + message + '</div>';
tableBody.innerHTML = '<tr><td colspan="7" style="padding:24px;text-align:center;color:var(--text-muted);">' + message + '</td></tr>';
function renderEmpty(title, message) {
chartWrap.innerHTML =
'<div class="empty-state" style="width:100%;">' +
'<div class="empty-state-title">' + title + '</div>' +
'<div class="empty-state-text">' + message + '</div>' +
'</div>';
tableBody.innerHTML =
'<tr><td colspan="7" style="padding:24px;">' +
'<div class="empty-state" style="padding:0;">' +
'<div class="empty-state-title">' + title + '</div>' +
'<div class="empty-state-text">' + message + '</div>' +
'</div>' +
'</td></tr>';
}
function renderStats() {
@@ -119,7 +129,11 @@ document.addEventListener('DOMContentLoaded', function () {
chartWrap.innerHTML = '';
if (!timeline.length) {
chartWrap.innerHTML = '<div style="padding:32px;color:var(--text-muted);text-align:center;width:100%;">No usage data for selected period</div>';
chartWrap.innerHTML =
'<div class="empty-state" style="width:100%;">' +
'<div class="empty-state-title">No usage data yet</div>' +
'<div class="empty-state-text">Invocation metrics will appear here after tests or published tool calls in the selected period.</div>' +
'</div>';
return;
}
@@ -145,7 +159,13 @@ document.addEventListener('DOMContentLoaded', function () {
tableBody.innerHTML = '';
if (!operations.length) {
tableBody.innerHTML = '<tr><td colspan="7" style="padding:24px;text-align:center;color:var(--text-muted);">No operation usage data for selected period</td></tr>';
tableBody.innerHTML =
'<tr><td colspan="7" style="padding:24px;">' +
'<div class="empty-state" style="padding:0;">' +
'<div class="empty-state-title">No operation breakdown yet</div>' +
'<div class="empty-state-text">The selected period has no invocation samples to break down by operation.</div>' +
'</div>' +
'</td></tr>';
return;
}
@@ -194,12 +214,12 @@ document.addEventListener('DOMContentLoaded', function () {
function renderUsage() {
if (state.loading && !state.usage) {
renderEmpty('Loading usage...');
renderEmpty('Loading usage…', 'Aggregating invocation metrics for the selected workspace.');
return;
}
if (state.loadError) {
renderEmpty(state.loadError);
renderEmpty('Unable to load usage', state.loadError);
return;
}
@@ -241,6 +261,9 @@ document.addEventListener('DOMContentLoaded', function () {
function exportCsv() {
if (!state.usage) {
if (window.CrankUi) {
window.CrankUi.info('Load usage data before exporting the CSV snapshot.', 'No usage data loaded');
}
return;
}
@@ -268,6 +291,9 @@ document.addEventListener('DOMContentLoaded', function () {
link.download = 'crank-usage-' + state.period + '.csv';
link.click();
URL.revokeObjectURL(url);
if (window.CrankUi) {
window.CrankUi.success('The current usage snapshot was exported as CSV.', 'Usage exported');
}
}
if (periodSelect) {