Rework MischLabs into service dashboard
All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 11s
All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 11s
This commit is contained in:
106
app.js
Normal file
106
app.js
Normal file
@@ -0,0 +1,106 @@
|
||||
const cards = [...document.querySelectorAll('.service-card')];
|
||||
const sections = [...document.querySelectorAll('.section')];
|
||||
const searchInput = document.querySelector('#serviceSearch');
|
||||
const segments = [...document.querySelectorAll('.segment')];
|
||||
const emptyState = document.querySelector('#emptyState');
|
||||
const onlineCount = document.querySelector('#onlineCount');
|
||||
const lastChecked = document.querySelector('#lastChecked');
|
||||
|
||||
let activeFilter = 'all';
|
||||
|
||||
function normalize(value) {
|
||||
return value.toLowerCase().trim();
|
||||
}
|
||||
|
||||
function updateVisibility() {
|
||||
const term = normalize(searchInput.value);
|
||||
let visibleCards = 0;
|
||||
|
||||
cards.forEach((card) => {
|
||||
const categoryMatches = activeFilter === 'all' || card.dataset.category === activeFilter;
|
||||
const searchMatches = !term || normalize(card.dataset.name).includes(term);
|
||||
const isVisible = categoryMatches && searchMatches;
|
||||
card.hidden = !isVisible;
|
||||
if (isVisible) visibleCards += 1;
|
||||
});
|
||||
|
||||
sections.forEach((section) => {
|
||||
const hasVisibleCards = [...section.querySelectorAll('.service-card')].some((card) => !card.hidden);
|
||||
section.hidden = !hasVisibleCards;
|
||||
});
|
||||
|
||||
emptyState.hidden = visibleCards !== 0;
|
||||
}
|
||||
|
||||
function setActiveFilter(nextFilter) {
|
||||
activeFilter = nextFilter;
|
||||
segments.forEach((segment) => {
|
||||
const isActive = segment.dataset.filter === nextFilter;
|
||||
segment.classList.toggle('is-active', isActive);
|
||||
segment.setAttribute('aria-selected', String(isActive));
|
||||
});
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
async function probeService(card) {
|
||||
const controller = new AbortController();
|
||||
const timeout = window.setTimeout(() => controller.abort(), 4500);
|
||||
|
||||
try {
|
||||
await fetch(card.dataset.url, {
|
||||
method: 'GET',
|
||||
mode: 'no-cors',
|
||||
cache: 'no-store',
|
||||
signal: controller.signal
|
||||
});
|
||||
card.classList.add('is-online');
|
||||
card.classList.remove('is-offline');
|
||||
card.querySelector('.status-dot').setAttribute('aria-label', 'Online');
|
||||
return true;
|
||||
} catch {
|
||||
card.classList.add('is-offline');
|
||||
card.classList.remove('is-online');
|
||||
card.querySelector('.status-dot').setAttribute('aria-label', 'Nicht erreichbar');
|
||||
return false;
|
||||
} finally {
|
||||
window.clearTimeout(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshStatus() {
|
||||
const results = await Promise.allSettled(cards.map(probeService));
|
||||
const online = results.filter((result) => result.status === 'fulfilled' && result.value).length;
|
||||
onlineCount.textContent = String(online);
|
||||
lastChecked.textContent = `Status geprueft: ${new Date().toLocaleTimeString('de-DE', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
})}`;
|
||||
}
|
||||
|
||||
segments.forEach((segment) => {
|
||||
segment.addEventListener('click', () => setActiveFilter(segment.dataset.filter));
|
||||
});
|
||||
|
||||
searchInput.addEventListener('input', updateVisibility);
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('/sw.js').catch(() => {});
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const run = () => refreshStatus().catch(() => {
|
||||
onlineCount.textContent = '--';
|
||||
lastChecked.textContent = 'Status aktuell nicht verfuegbar.';
|
||||
});
|
||||
|
||||
if ('requestIdleCallback' in window) {
|
||||
window.requestIdleCallback(run, { timeout: 2000 });
|
||||
} else {
|
||||
window.setTimeout(run, 600);
|
||||
}
|
||||
});
|
||||
|
||||
updateVisibility();
|
||||
|
||||
Reference in New Issue
Block a user