Compare commits
2
Commits
e41e2b38e3
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebf1b13f86 | ||
|
|
046e523352 |
No files matched your search
+34
-11
@@ -103,10 +103,13 @@ async function api(url, options = {}) {
|
|||||||
function switchView(id) {
|
function switchView(id) {
|
||||||
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
|
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
|
||||||
document.getElementById(id).classList.add('active');
|
document.getElementById(id).classList.add('active');
|
||||||
|
for (const btn of topbarNav.children) btn.classList.toggle('active', btn.dataset.view === id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showLogin() {
|
function showLogin() {
|
||||||
document.getElementById('header').style.display = 'none';
|
document.getElementById('header').style.display = 'none';
|
||||||
|
signedInName = null;
|
||||||
|
renderTopbar();
|
||||||
switchView('loginView');
|
switchView('loginView');
|
||||||
applyLoginMode();
|
applyLoginMode();
|
||||||
}
|
}
|
||||||
@@ -169,7 +172,8 @@ function renderCurrentUser() {
|
|||||||
const el = document.getElementById('currentUser');
|
const el = document.getElementById('currentUser');
|
||||||
el.textContent = name;
|
el.textContent = name;
|
||||||
el.title = u && u.email ? u.email : 'Angemeldet';
|
el.title = u && u.email ? u.email : 'Angemeldet';
|
||||||
renderTopbarSession(name);
|
signedInName = name || 'Angemeldet';
|
||||||
|
renderTopbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmLogout() {
|
function confirmLogout() {
|
||||||
@@ -194,24 +198,43 @@ async function logout() {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// topbar.js laeuft per defer erst nach diesem Skript, die Leiste steht also
|
// topbar.js laeuft per defer erst nach diesem Skript, die Leiste steht also
|
||||||
// fruehestens ab DOMContentLoaded im DOM. Die Sitzungsanzeige wird einmal
|
// fruehestens ab DOMContentLoaded im DOM. Navigation (slot="aktionen") und
|
||||||
// eingehaengt, sobald die Anmeldung steht, danach aendert sich nur ihr Text.
|
// Sitzungsanzeige (slot="benutzer") werden einmal eingehaengt, sobald die
|
||||||
|
// Anmeldung steht. Danach aendern sich nur Text und Sichtbarkeit. Ist die
|
||||||
|
// Leiste da, blendet das CSS den eigenen Header aus.
|
||||||
|
const topbarNav = document.createElement('div');
|
||||||
|
topbarNav.slot = 'aktionen';
|
||||||
|
topbarNav.className = 'topbar-nav';
|
||||||
|
for (const [view, icon, label, show] of [
|
||||||
|
['timerView', '⏱️', 'Timer', () => showTimer()],
|
||||||
|
['historyView', '📊', 'Historie', () => showHistory()],
|
||||||
|
['settingsView', '⚙️', 'Einstellungen', () => showSettings()],
|
||||||
|
]) {
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.type = 'button';
|
||||||
|
btn.dataset.view = view;
|
||||||
|
btn.title = label;
|
||||||
|
btn.append(icon, Object.assign(document.createElement('span'), { textContent: label }));
|
||||||
|
btn.addEventListener('click', show);
|
||||||
|
topbarNav.append(btn);
|
||||||
|
}
|
||||||
|
|
||||||
const topbarSession = document.createElement('div');
|
const topbarSession = document.createElement('div');
|
||||||
topbarSession.slot = 'benutzer';
|
topbarSession.slot = 'benutzer';
|
||||||
topbarSession.className = 'topbar-session';
|
topbarSession.className = 'topbar-session';
|
||||||
topbarSession.append(Object.assign(document.createElement('span'), { textContent: 'Timer – angemeldet als' }),
|
topbarSession.append(Object.assign(document.createElement('span'), { textContent: 'Timer – angemeldet als' }),
|
||||||
document.createElement('strong'));
|
document.createElement('strong'));
|
||||||
let topbarSessionName = null; // null = (noch) nicht angemeldet
|
let signedInName = null; // null = nicht angemeldet
|
||||||
|
|
||||||
function renderTopbarSession(name) {
|
function renderTopbar() {
|
||||||
topbarSessionName = name || 'Angemeldet';
|
const signedIn = signedInName !== null;
|
||||||
topbarSession.lastChild.textContent = topbarSessionName;
|
topbarNav.hidden = topbarSession.hidden = !signedIn;
|
||||||
if (!topbarSession.isConnected) document.querySelector('hi-topbar')?.append(topbarSession);
|
if (!signedIn) return;
|
||||||
|
topbarSession.lastChild.textContent = signedInName;
|
||||||
|
if (!topbarSession.isConnected) document.querySelector('hi-topbar')?.append(topbarNav, topbarSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', renderTopbar);
|
||||||
if (topbarSessionName !== null) renderTopbarSession(topbarSessionName);
|
|
||||||
});
|
|
||||||
|
|
||||||
// "Abmelden" in der Leiste: erst die eigene Sitzung beenden, danach meldet
|
// "Abmelden" in der Leiste: erst die eigene Sitzung beenden, danach meldet
|
||||||
// die Leiste bei Portal und Authentik ab. Abbrechen bei laufenden Timern
|
// die Leiste bei Portal und Authentik ab. Abbrechen bei laufenden Timern
|
||||||
|
|||||||
+31
-5
@@ -797,10 +797,36 @@
|
|||||||
hi-topbar { flex-shrink: 0; }
|
hi-topbar { flex-shrink: 0; }
|
||||||
@media print { hi-topbar { display: none !important; } }
|
@media print { hi-topbar { display: none !important; } }
|
||||||
|
|
||||||
/* Benutzername und Abmelden sitzen im Benutzer-Menue der Leiste. Die
|
/* Navigation, Benutzername und Abmelden sitzen in der Leiste. Der eigene
|
||||||
eigenen bleiben nur als Rueckfall, wenn topbar.js nicht laedt. */
|
Header bleibt nur als Rueckfall, wenn topbar.js nicht laedt
|
||||||
hi-topbar ~ .container #currentUser,
|
(!important, weil app.js ihn per style.display einblendet). */
|
||||||
hi-topbar ~ .container #logoutBtn { display: none; }
|
hi-topbar ~ .container #header { display: none !important; }
|
||||||
|
|
||||||
|
/* Navigation rechts in der Leiste (slot="aktionen"), Text erbt Weiss */
|
||||||
|
.topbar-nav { display: flex; gap: 2px; }
|
||||||
|
.topbar-nav[hidden] { display: none; }
|
||||||
|
.topbar-nav button {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 0.7rem;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: none;
|
||||||
|
color: inherit;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 13.5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.topbar-nav button:hover { background: rgba(255, 255, 255, 0.14); }
|
||||||
|
.topbar-nav button.active { background: rgba(255, 255, 255, 0.22); }
|
||||||
|
.topbar-nav button:focus-visible { outline: 2px solid #cbbdf7; outline-offset: 1px; }
|
||||||
|
/* Schmal: nur die Symbole, der Name steht im title */
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.topbar-nav button { padding: 0 0.55rem; font-size: 16px; }
|
||||||
|
.topbar-nav button span { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
/* Sitzungsanzeige im Benutzer-Menue (slot="benutzer"), Schriftfarbe kommt von der Leiste */
|
/* Sitzungsanzeige im Benutzer-Menue (slot="benutzer"), Schriftfarbe kommt von der Leiste */
|
||||||
.topbar-session { padding: 10px 16px; font-size: 13px; line-height: 1.4; }
|
.topbar-session { padding: 10px 16px; font-size: 13px; line-height: 1.4; }
|
||||||
@@ -1029,6 +1055,6 @@
|
|||||||
|
|
||||||
<div class="toast" id="toast"></div>
|
<div class="toast" id="toast"></div>
|
||||||
|
|
||||||
<script src="/app.js?v=20261025-topbar"></script>
|
<script src="/app.js?v=20261025-topbar-nav"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in new issue
Block a user