fix: remove hamburger menu and logout button from server UI header (#256)

Replace with a direct theme toggle button matching the console UI
pattern. Dashboard remains accessible via Ctrl+D.
This commit is contained in:
Patrick Buckley
2026-03-30 05:52:04 -07:00
committed by GitHub
parent 8eacc4d632
commit 22245145db
3 changed files with 31 additions and 177 deletions
+21 -99
View File
@@ -2151,101 +2151,34 @@ window.onLogout = function () {
};
// ===========================================================================
// 7. Theme + hamburger menu
// 7. Theme toggle
// ===========================================================================
function updateThemeMenuItem() {
var isLight = document.documentElement.dataset.theme === "light";
document.getElementById("theme-menu-icon").textContent = isLight
? "\u263E"
: "\u2600";
document.getElementById("theme-menu-label").textContent = isLight
? "Dark mode"
: "Light mode";
document
.getElementById("theme-menu-item")
.setAttribute(
window.onThemeChange = function (next) {
var btn = document.getElementById("theme-toggle");
if (btn) {
var isLight = next === "light";
btn.textContent = isLight ? "\u2600" : "\u263E";
btn.title = isLight ? "Switch to dark theme" : "Switch to light theme";
btn.setAttribute(
"aria-label",
isLight
? "Switch to dark mode (currently light)"
: "Switch to light mode (currently dark)",
isLight ? "Switch to dark theme" : "Switch to light theme",
);
}
window.onThemeChange = function () {
updateThemeMenuItem();
}
reRenderAllMermaid();
};
updateThemeMenuItem();
function toggleHamburger() {
var menu = document.getElementById("hamburger-menu");
var btn = document.getElementById("hamburger-btn");
var open = menu.classList.toggle("open");
btn.setAttribute("aria-expanded", open ? "true" : "false");
if (open) {
updateThemeMenuItem();
var first = menu.querySelector(".hmenu-item");
if (first) first.focus();
(function () {
var btn = document.getElementById("theme-toggle");
if (btn) {
var isLight = document.documentElement.dataset.theme === "light";
btn.textContent = isLight ? "\u2600" : "\u263E";
btn.title = isLight ? "Switch to dark theme" : "Switch to light theme";
btn.setAttribute(
"aria-label",
isLight ? "Switch to dark theme" : "Switch to light theme",
);
}
}
function closeHamburger() {
document.getElementById("hamburger-menu").classList.remove("open");
document
.getElementById("hamburger-btn")
.setAttribute("aria-expanded", "false");
}
function hamburgerDashboard() {
closeHamburger();
toggleDashboard();
}
function hamburgerTheme() {
toggleTheme();
closeHamburger();
}
// Close on outside click
document.addEventListener("click", function (e) {
var wrap = document.getElementById("hamburger-wrap");
if (wrap && !wrap.contains(e.target)) closeHamburger();
});
// Keyboard nav within menu
document
.getElementById("hamburger-menu")
.addEventListener("keydown", function (e) {
var items = Array.from(this.querySelectorAll(".hmenu-item"));
var idx = items.indexOf(document.activeElement);
if (e.key === "ArrowDown") {
e.preventDefault();
items[(idx + 1) % items.length].focus();
} else if (e.key === "ArrowUp") {
e.preventDefault();
items[(idx - 1 + items.length) % items.length].focus();
} else if (e.key === "Home") {
e.preventDefault();
items[0].focus();
} else if (e.key === "End") {
e.preventDefault();
items[items.length - 1].focus();
} else if (e.key === "Escape") {
e.preventDefault();
closeHamburger();
document.getElementById("hamburger-btn").focus();
} else if (e.key === "Tab") {
closeHamburger();
}
});
// Escape when focus is on the button itself
document
.getElementById("hamburger-btn")
.addEventListener("keydown", function (e) {
if (
e.key === "Escape" &&
document.getElementById("hamburger-menu").classList.contains("open")
) {
e.preventDefault();
closeHamburger();
}
});
})();
// ===========================================================================
// 8. Tab bar
@@ -2641,7 +2574,6 @@ function closeWorkstream(wsId) {
function showDashboard() {
dashboardVisible = true;
closeHamburger();
document.getElementById("dashboard").classList.add("active");
document.getElementById("header").inert = true;
document.getElementById("tab-bar").inert = true;
@@ -3350,16 +3282,6 @@ document.addEventListener("keydown", function (e) {
var nwsOverlay = document.getElementById("new-ws-overlay");
if (nwsOverlay && nwsOverlay.style.display !== "none") return;
// Escape: close hamburger first, then dashboard
if (
e.key === "Escape" &&
document.getElementById("hamburger-menu").classList.contains("open")
) {
e.preventDefault();
closeHamburger();
document.getElementById("hamburger-btn").focus();
return;
}
if (e.key === "Escape" && dashboardVisible) {
e.preventDefault();
hideDashboard();
+2 -16
View File
@@ -13,24 +13,10 @@
</head>
<body>
<div id="header">
<div id="hamburger-wrap">
<button id="hamburger-btn" onclick="toggleHamburger()" aria-label="Menu" aria-haspopup="true" aria-expanded="false" aria-controls="hamburger-menu">
<span></span><span></span><span></span>
</button>
<div id="hamburger-menu" role="menu">
<button class="hmenu-item" role="menuitem" tabindex="-1" onclick="hamburgerDashboard()">
<span class="hmenu-icon">&#8962;</span> Dashboard
</button>
<div class="hmenu-sep" role="separator"></div>
<button class="hmenu-item" role="menuitem" tabindex="-1" id="theme-menu-item" onclick="hamburgerTheme()">
<span class="hmenu-icon" id="theme-menu-icon">&#9790;</span> <span id="theme-menu-label">Light mode</span>
</button>
</div>
</div>
<h1>turnstone</h1>
<span id="mcp-status" role="status" aria-live="polite"></span>
<span id="health-indicator" class="health-ok" role="status" aria-live="polite" aria-atomic="true"></span>
<button id="logout-btn" class="header-btn" onclick="logout()" style="display:none">logout</button>
<button id="theme-toggle" class="header-btn" onclick="toggleTheme()" aria-label="Toggle light/dark theme" title="Switch to light theme">&#9790;</button>
</div>
<div id="tab-bar" role="toolbar" aria-label="Workstreams">
@@ -132,7 +118,7 @@ window.TURNSTONE_KB_SHORTCUTS = [
]},
{ title: "Navigation", keys: [
{ desc: "Navigate table rows", badge: '<span class="kb-key">\u2191</span> <span class="kb-key">\u2193</span>' },
{ desc: "Close dashboard / menu", badge: '<span class="kb-key">Esc</span>' }
{ desc: "Close dashboard", badge: '<span class="kb-key">Esc</span>' }
]},
{ title: "General", keys: [
{ desc: "Show this help", badge: '<span class="kb-key">?</span>' }
+8 -62
View File
@@ -43,68 +43,14 @@
}
/* ==========================================================================
Hamburger menu
Theme toggle
========================================================================== */
#theme-toggle { color: var(--fg); margin-left: auto; font-size: 14px; line-height: 1; }
/* ==========================================================================
Mobile overrides
========================================================================== */
#hamburger-wrap { position: relative; }
#hamburger-btn {
background: none;
border: 1px solid var(--border-strong);
color: var(--fg);
border-radius: var(--radius-sm);
width: 32px;
height: 32px;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
padding: 0;
flex-shrink: 0;
transition: background 0.15s, border-color 0.15s;
}
#hamburger-btn:hover { background: var(--bg-highlight); border-color: var(--accent-dim); }
#hamburger-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
#hamburger-btn span { display: block; width: 14px; height: 2px; background: var(--fg); border-radius: 1px; }
#hamburger-menu {
display: none;
position: absolute;
top: calc(100% + 6px);
left: 0;
background: var(--bg-surface);
border: 1px solid var(--border-strong);
border-radius: var(--radius);
min-width: 180px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
z-index: 40;
overflow: hidden;
}
[data-theme="light"] #hamburger-menu { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); }
#hamburger-menu.open { display: block; }
.hmenu-item {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
padding: 10px 14px;
background: none;
border: none;
color: var(--fg);
font: inherit;
font-family: var(--font-display);
font-size: 13px;
cursor: pointer;
text-align: left;
white-space: nowrap;
transition: background 0.1s;
}
.hmenu-item:hover { background: var(--bg-highlight); }
.hmenu-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.hmenu-item .hmenu-icon { width: 16px; text-align: center; font-size: 14px; opacity: 0.8; }
.hmenu-sep { height: 1px; background: var(--border-strong); margin: 4px 0; }
@media (max-width: 600px) {
#hamburger-btn { width: 40px; height: 40px; }
.hmenu-item { padding: 12px 14px; }
.ws-tab .tab-close { opacity: 1; padding: 4px 6px; font-size: 16px; }
#split-btn { display: none; }
}
@@ -1514,11 +1460,11 @@ body { position: static; }
.judge-spinner-dot { animation: none; opacity: 1; }
.thinking-indicator::after { animation: none; content: '...'; }
.ws-tab, .ws-tab .tab-close, #new-tab-btn, #split-btn,
.hmenu-item, .dashboard-card,
.dashboard-card,
.approval-btn, .approval-feedback-input,
#plan-buttons button, .pane-input-area button,
.dashboard-new-btn, .dashboard-input,
#health-indicator, #hamburger-btn,
#health-indicator, #theme-toggle,
#mcp-status, .msg-assistant tbody tr,
.msg-assistant .img-placeholder,
#new-ws-cancel, #new-ws-submit,