This commit is contained in:
@@ -632,21 +632,23 @@
|
||||
}
|
||||
|
||||
.dashboard-review-segments {
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
|
||||
gap: 8px;
|
||||
padding: 12px 20px;
|
||||
overflow-x: auto;
|
||||
overflow: visible;
|
||||
border-bottom: 1px solid var(--momo-border-light);
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.dashboard-review-segments a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
flex: 0 0 auto;
|
||||
min-width: 0;
|
||||
min-height: 30px;
|
||||
padding: 6px 10px;
|
||||
overflow: hidden;
|
||||
color: var(--momo-text-secondary);
|
||||
background: var(--momo-bg-paper);
|
||||
border: 1px solid var(--momo-border-light);
|
||||
@@ -656,6 +658,13 @@
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.dashboard-review-segments a span:first-child {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dashboard-review-segments a.is-active {
|
||||
color: var(--momo-text-inverse);
|
||||
background: var(--momo-ink);
|
||||
|
||||
@@ -76,23 +76,63 @@
|
||||
const link = document.getElementById('momo-obs-link');
|
||||
const badge = document.getElementById('momo-obs-badge');
|
||||
if (!link || !badge) return;
|
||||
async function refresh() {
|
||||
|
||||
const cacheKey = 'momoObsHealthIndicator:v1';
|
||||
const cacheTtlMs = 60000;
|
||||
|
||||
function applyIndicator(d) {
|
||||
if (!d || !d.ok) return;
|
||||
link.title = d.tooltip || 'AI 觀測台';
|
||||
if (d.alert_count > 0) {
|
||||
badge.textContent = d.alert_count;
|
||||
badge.hidden = false;
|
||||
link.classList.add('is-alert');
|
||||
} else {
|
||||
badge.hidden = true;
|
||||
link.classList.remove('is-alert');
|
||||
}
|
||||
}
|
||||
|
||||
function readCachedIndicator() {
|
||||
try {
|
||||
const r = await fetch('/observability/api/health_indicator', { credentials: 'same-origin' });
|
||||
if (!r.ok) return;
|
||||
const d = await r.json();
|
||||
if (!d.ok) return;
|
||||
link.title = d.tooltip || 'AI 觀測台';
|
||||
if (d.alert_count > 0) {
|
||||
badge.textContent = d.alert_count;
|
||||
badge.hidden = false;
|
||||
link.classList.add('is-alert');
|
||||
} else {
|
||||
badge.hidden = true;
|
||||
link.classList.remove('is-alert');
|
||||
}
|
||||
const cached = JSON.parse(sessionStorage.getItem(cacheKey) || 'null');
|
||||
if (!cached || !cached.data || Date.now() - cached.ts > cacheTtlMs) return null;
|
||||
return cached.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function writeCachedIndicator(data) {
|
||||
try {
|
||||
sessionStorage.setItem(cacheKey, JSON.stringify({ ts: Date.now(), data }));
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
async function refresh(useCache = true) {
|
||||
if (useCache) {
|
||||
const cached = readCachedIndicator();
|
||||
if (cached) {
|
||||
applyIndicator(cached);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), 2500);
|
||||
try {
|
||||
const r = await fetch('/observability/api/health_indicator', {
|
||||
credentials: 'same-origin',
|
||||
signal: controller.signal,
|
||||
});
|
||||
if (!r.ok) return;
|
||||
const d = await r.json();
|
||||
writeCachedIndicator(d);
|
||||
applyIndicator(d);
|
||||
} catch (e) {
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
setInterval(refresh, 60000);
|
||||
setInterval(() => refresh(false), 60000);
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user