feat: make ops cards collapsible, hide notice and user display, increase button sizes
All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 12s

This commit is contained in:
Kroonk
2026-05-21 18:21:47 +02:00
parent 995a397b2e
commit 76b7a96673
3 changed files with 74 additions and 12 deletions

View File

@@ -6,7 +6,7 @@
<title>MischLabs Admin</title>
<meta name="description" content="MischLabs dashboard administration.">
<meta name="theme-color" content="#0f172a">
<link rel="stylesheet" href="/style.css?v=21">
<link rel="stylesheet" href="/style.css?v=22">
</head>
<body>
<header class="shell hero admin-hero">
@@ -48,11 +48,7 @@
</div>
</div>
<div class="notice">
Hinweis: Betriebsdaten kommen aus dem MischLabs-Statusproxy. Kachel-Aenderungen werden aktuell lokal im Browser gespeichert oder als `services.json` exportiert; fuer globale Live-Aenderungen folgt spaeter ein Gitea-Commit-Workflow.
</div>
<div class="admin-user" id="adminUser"></div>
<div id="adminUser" style="display: none;"></div>
<div class="ops-grid" id="opsGrid">
<section class="ops-card ops-card-wide">
<div class="ops-card-head">
@@ -94,6 +90,6 @@
</section>
</main>
<script src="/admin.js?v=14" defer></script>
<script src="/admin.js?v=15" defer></script>
</body>
</html>

View File

@@ -695,6 +695,32 @@ function startOpsAutoRefresh() {
}, 60000);
}
function initCollapsibleCards() {
document.querySelectorAll('.ops-card-head').forEach((head) => {
const card = head.closest('.ops-card');
if (!card) return;
const bodyEl = card.querySelector('.services-status-board, .ops-list');
const id = bodyEl ? bodyEl.id : null;
const storageKey = id ? `ops-card-collapsed-${id}` : null;
if (storageKey) {
const isCollapsed = localStorage.getItem(storageKey) === 'true';
card.classList.toggle('is-collapsed', isCollapsed);
}
head.addEventListener('click', (event) => {
if (event.target.closest('button')) {
return;
}
card.classList.toggle('is-collapsed');
if (storageKey) {
localStorage.setItem(storageKey, card.classList.contains('is-collapsed'));
}
});
});
}
async function boot() {
await handleCallback();
tokenSet = getStoredTokens();
@@ -717,6 +743,7 @@ async function boot() {
logoutButton.hidden = false;
adminUser.textContent = `Angemeldet als ${claims.preferred_username || claims.email}`;
renderEditor();
initCollapsibleCards();
refreshOps();
startOpsAutoRefresh();
}

View File

@@ -423,14 +423,16 @@ main {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 38px;
padding: 0 13px;
min-height: 42px;
padding: 0 18px;
color: var(--text);
font-size: 0.92rem;
text-decoration: none;
background: rgba(17, 22, 36, 0.86);
border: 1px solid var(--border);
border-radius: var(--radius);
cursor: pointer;
transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.ghost-button:hover,
@@ -542,12 +544,49 @@ main {
margin-bottom: 10px;
color: #fff;
font-weight: 700;
cursor: pointer;
user-select: none;
transition: color 0.15s ease;
}
.ops-card-head:hover {
color: #67e8f9;
}
.ops-card-head > div:first-child,
.ops-card-head > span:first-child {
display: inline-flex;
align-items: center;
gap: 8px;
}
.ops-card-head > div:first-child::before,
.ops-card-head > span:first-child::before {
content: '▾';
display: inline-block;
font-size: 0.92rem;
color: var(--dim);
transition: transform 0.22s cubic-bezier(0.175, 0.885, 0.32, 1.275);
transform: rotate(0deg);
}
.ops-card.is-collapsed .ops-card-head > div:first-child::before,
.ops-card.is-collapsed .ops-card-head > span:first-child::before {
transform: rotate(-90deg);
}
.ops-card.is-collapsed .ops-card-head {
margin-bottom: 0;
}
.ops-card.is-collapsed > *:not(.ops-card-head) {
display: none !important;
}
.ghost-button.mini {
min-height: 30px;
padding: 0 10px;
font-size: 0.78rem;
min-height: 34px;
padding: 0 14px;
font-size: 0.82rem;
}
.ops-list {