Terminal UI: full-screen mode with collapsible navigation bar #71
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_router#71
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The terminal UI does not have a proper full-screen mode. When going
full screen, the navigation bar disappears entirely, losing access to
other hero_proc features. We need to maximize terminal real estate
while keeping navigation accessible.
Requirements
and closed without leaving full-screen
Relevant code
crates/hero_proc_ui/— Axum + Askama web dashboard templatesAcceptance Criteria
Implementation Spec — Issue #71: Terminal full-screen mode with collapsible navigation
Objective
Make the Terminal page's full-screen mode preserve access to the top-level navigation (Home / Router / Terminal / Admin / Docs) instead of hiding it permanently. In full-screen, the navbar and tabs are auto-collapsed by default (so the terminal gets all the screen real estate) but can be revealed/hidden at any time via a toolbar button or keybinding, without leaving full-screen and without causing xterm.js to refit.
Requirements
From the issue:
Hard constraint:
5. The navbar links Home, Router, Terminal, Admin, Docs (rendered by
partials/tabs.html) plus the topnav.navbar(rendered inbase.html) must stay structurally intact. Hide/show is allowed; deletion or restructure is not.Implicit / quality bar:
6. The current F11 keybinding and
Esc-to-exit behavior must keep working.7. The terminal-page sidebar polling and
term-fullscreenbody-class semantics must keep working.8. xterm.js fit-addon should not need to recompute on every show/hide of nav (overlay, not in flow).
9. Show/hide preference must persist across reloads (localStorage).
10. No layout shift / visible reflow when toggling.
Files to Modify / Create
crates/hero_router/templates/terminal.htmldisplay: none !importantrules in the page-local<style>block with overlay-based show/hide CSS keyed off a second body class (term-nav-revealed); add one toolbar button (#termNavToggle) next to#termFullscreen; add a row in the shortcuts modal describing the new key.crates/hero_router/static/js/terminal.jsrevealNav()/hideNav()/toggleNav(); wire them to the new button, to a keybinding (Ctrl+Shift+N), and to localStorage; onenterFullscreen()apply the persisted preference (default = hidden); onexitFullscreen()clear the reveal state so non-fullscreen rendering is untouched.No new files, no edits to
base.htmlorpartials/tabs.html.Implementation Plan
Step 1 — Replace the broken full-screen nav-hiding CSS with an overlay scheme
Files:
crates/hero_router/templates/terminal.html(page-local<style>block)position: fixed; z-index: 9500;) and translate them off-screen by default in full-screen:body.term-fullscreen nav.navbar { transform: translateY(-100%); transition: transform 0.18s ease; }body.term-fullscreen nav.navbar + .container-fluid { transform: translateY(-100%); transition: transform 0.18s ease; }body.term-fullscreen.term-nav-revealed nav.navbar { transform: translateY(0); }and the same for the sibling.display: none—transformkeeps layout stable, no reflow, no fit-addon hit.Dependencies: none.
Step 2 — Add the show/hide-nav toolbar button and shortcuts row
Files:
crates/hero_router/templates/terminal.html(term-toolbar + shortcuts modal)#termFullscreen:d-noneby default — JS toggles it visible only insideenterFullscreen().Dependencies: Step 1.
Step 3 — Wire show/hide nav in
terminal.jsFiles:
crates/hero_router/static/js/terminal.jsvar NAV_REVEAL_KEY = 'hero_router.term.fullscreen.navRevealed';enterFullscreen/exitFullscreen:revealNav()— addsterm-nav-revealedto<body>, swaps the toolbar icon, writes'1'to localStorage. NofitAllPanes()call.hideNav()— removes the class, swaps icon back, writes'0'.toggleNav()— flips based on current class state.enterFullscreen():document.getElementById('termNavToggle').classList.remove('d-none')).'1', callrevealNav(); else ensure the class is removed (default = hidden).exitFullscreen():term-nav-revealedfrom body..classList.add('d-none')).#termNavToggleclick →toggleNav().if (e.code === 'KeyN') { e.preventDefault(); if (isFullscreen) toggleNav(); return; }. Gate onisFullscreenso it's a no-op outside full-screen.fitAllPanes()fromrevealNav/hideNav— overlay = stable geometry.Dependencies: Steps 1 and 2.
Acceptance Criteria
#termNavToggle) andCtrl+Shift+Nreveal the navbar + tabs as an overlay; pressing again hides them. F11 /Esccontinues to exit full-screen entirely.?key) lists the new keybinding.Notes / Pitfalls
display: nonethe navbar. That's the existing bug; it's why nav is currently lost. Usetransform: translateY(-100%)so the elements stay in the accessibility tree and toggling them costs zero layout.term-layoutisposition: fixed; inset: 0in fullscreen and the navbar is overlaid (alsoposition: fixed), the terminal's box never changes size when the nav reveals/hides. NofitAllPanes()call is needed inrevealNav/hideNav.Escsemantics unchanged — exits fullscreen entirely; does NOT toggle nav. Toggling isCtrl+Shift+Nand the toolbar button only.body.term-fullscreen nav.navbar + .container-fluidworks becausepartials/tabs.htmlis{% include %}d immediately after the navbar inbase.html. A comment in the CSS will note this dependency.#fullscreen=1continues to enter fullscreen on load; the nav-revealed state is per-user preference (localStorage), not in the URL.var(--bs-body-bg)) so the overlay matches the active theme.base.html,partials/tabs.html,partials/sidebar.html, or any Rust handler. Total diff target: under 100 lines.Test Results
The changes in this branch are limited to
crates/hero_router/templates/terminal.htmlandcrates/hero_router/static/js/terminal.js(HTML/JS only). No Rust unit or integration test exercises these template/static assets directly, so the test suite confirms the Rust crate's build/test surface is unchanged but does not provide direct coverage of the terminal fullscreen / collapsible nav UI changes themselves.Implementation summary
Implemented the full-screen mode with a collapsible top navigation bar on the Terminal page. The five top-level navigation links (Home, Router, Terminal, Admin, Docs) are kept structurally intact in every mode — only their visibility while the page is in full-screen toggles, via an overlay scheme.
How it works
position: fixed,z-index: 9500) and translated off-screen (transform: translateY(-100%)). They are NOTdisplay: none, so they remain in the accessibility tree and toggling them costs zero layout.#termNavToggle) appears next to the existing fullscreen button while in full-screen, and a new keybindingCtrl+Shift+Ntoggles the navbar's visibility without leaving full-screen.localStorage(hero_router.term.fullscreen.navRevealed) so reload-then-re-enter restores the user's last choice. Default is hidden, maximizing terminal real estate.position: fixed; inset: 0) does not change because the navbar is overlaid on top of the terminal layer.Files modified
crates/hero_router/templates/terminal.html— replaced the brokendisplay: none !importantrules with an overlay-based show/hide CSS scheme keyed on a second body classterm-nav-revealed; added the#termNavTogglebutton to the toolbar; added a shortcuts-modal row forCtrl+Shift+N.crates/hero_router/static/js/terminal.js— addedrevealNav()/hideNav()/toggleNav()helpers, wired them to the new button, the newCtrl+Shift+Nkeybinding, andlocalStorage; updatedenterFullscreen()/exitFullscreen()to un-hide / re-hide the toolbar button and restore the persisted reveal state on entry.No changes to
base.html,partials/tabs.html,partials/sidebar.html, or any Rust handler.Test results
cargo build -p hero_router)Acceptance criteria
#termNavToggleandCtrl+Shift+N)display: none)Pull request opened: #82
This PR implements the changes discussed in this issue.