fix(gui): keep sidebar reopenable + add clean Quit button
The chrome-hiding CSS was removing the Streamlit header wholesale, which also took the sidebar's expand chevron with it — a collapsed sidebar became unreopenable. Make the header transparent instead and explicitly preserve the sidebar collapsed-control. Also add a Quit button in the app footer that signals the Streamlit server (SIGTERM, falling back to SIGINT) so closing the GUI returns the shell prompt cleanly instead of leaving Python hung. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,7 @@ from . import _legacy as _legacy # noqa: F401 (keep for direct access)
|
||||
__all__ = [
|
||||
# Shared chrome / pickup / gate
|
||||
"hide_streamlit_chrome",
|
||||
"quit_button",
|
||||
"pickup_or_upload",
|
||||
"require_normalization_gate",
|
||||
# Dedup widgets
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
import os
|
||||
import signal
|
||||
from typing import Optional
|
||||
|
||||
import pandas as pd
|
||||
@@ -30,25 +32,31 @@ from src.core.normalizers import NormalizerType
|
||||
|
||||
_HIDE_CHROME_CSS = """
|
||||
<style>
|
||||
/* Hide Streamlit header bar */
|
||||
/* Make the Streamlit header transparent and out of the way, but DO NOT
|
||||
`display: none` it — the sidebar's collapsed-state expand button is
|
||||
anchored in the header region, and removing the header makes a
|
||||
collapsed sidebar impossible to reopen. */
|
||||
header[data-testid="stHeader"] {
|
||||
background: transparent !important;
|
||||
height: 0 !important;
|
||||
}
|
||||
/* Hide main hamburger menu and deploy button explicitly (don't rely on
|
||||
hiding the whole header). */
|
||||
#MainMenu,
|
||||
[data-testid="stMainMenu"],
|
||||
[data-testid="stAppDeployButton"] {
|
||||
display: none !important;
|
||||
}
|
||||
/* Hide hamburger menu */
|
||||
button[kind="header"] {
|
||||
display: none !important;
|
||||
}
|
||||
#MainMenu {
|
||||
display: none !important;
|
||||
/* Keep the sidebar expand control visible and clickable above page content. */
|
||||
[data-testid="stSidebarCollapsedControl"] {
|
||||
display: flex !important;
|
||||
visibility: visible !important;
|
||||
z-index: 999 !important;
|
||||
}
|
||||
/* Hide footer */
|
||||
footer {
|
||||
display: none !important;
|
||||
}
|
||||
/* Hide deploy button */
|
||||
[data-testid="stAppDeployButton"] {
|
||||
display: none !important;
|
||||
}
|
||||
/* Reclaim top padding lost from hidden header */
|
||||
.stAppViewBlockContainer,
|
||||
[data-testid="stAppViewBlockContainer"] {
|
||||
@@ -67,6 +75,31 @@ def hide_streamlit_chrome() -> None:
|
||||
st.markdown(_HIDE_CHROME_CSS, unsafe_allow_html=True)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Clean shutdown
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def quit_button(label: str = "Quit app", *, key: str = "quit_app_button") -> None:
|
||||
"""Render a Quit button that terminates the Streamlit server.
|
||||
|
||||
Streamlit has no first-class shutdown hook, so closing the browser tab
|
||||
leaves the server (and the python process running it) alive — the user
|
||||
has to Ctrl+C in the shell. This helper signals the Streamlit process
|
||||
so the shell returns cleanly. SIGTERM lets Streamlit run its own
|
||||
shutdown handlers; if that's unavailable on the platform, fall back to
|
||||
SIGINT (the same signal Ctrl+C delivers).
|
||||
"""
|
||||
if st.session_state.get("_app_shutting_down"):
|
||||
st.success("App shut down. You can close this browser tab.")
|
||||
st.stop()
|
||||
|
||||
if st.button(label, key=key, type="secondary"):
|
||||
st.session_state["_app_shutting_down"] = True
|
||||
sig = getattr(signal, "SIGTERM", signal.SIGINT)
|
||||
os.kill(os.getpid(), sig)
|
||||
st.rerun()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Config panel (advanced options)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user