feat(gui): one-click Close in its own bottom sidebar section
Close is now a direct shutdown trigger: visiting the Close page (the sidebar entry) fires shutdown_app() immediately — no confirm step, no intermediate body. The farewell overlay paints and os._exit(0) lands ~1s later from a daemon thread. Layout: Close moved into its own bottom-of-sidebar section so the destructive action is visually separated from Account/Activate. - New shutdown_app() in components/_legacy.py replaces quit_button. os._exit thread is skipped when "pytest" is in sys.modules so the test suite doesn't suicide on rendering 99_Close. - pages/99_Close.py shrinks to set_page_config + chrome + shutdown_app. - app.py nav grows a new "Close" section header (new nav.section_close key in en/es packs) pinned at the bottom of the navigation dict. Tests updated: - TestQuitButtonRenders → TestClosePageShutsDownImmediately. Assert the shutdown caption renders + no confirm button exists. - test_smoke EXPECTED_SUBSTRINGS["99_Close"] now pins "Shutting down" / "Cerrando" (the visible page body) instead of the removed page title. 2008 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
"""Close — shut the DataTools server down cleanly.
|
||||
"""Close — shut the DataTools server down immediately on visit.
|
||||
|
||||
Lives in the sidebar nav alongside the tool pages so users have a
|
||||
discoverable way to terminate the local Streamlit process without
|
||||
having to Ctrl+C in the shell. An explicit confirm step prevents an
|
||||
accidental sidebar click from killing a session mid-work.
|
||||
Sidebar nav entry. Clicking it routes here, and the page's render
|
||||
fires :func:`shutdown_app` directly — there is no confirm step. The
|
||||
browser sees the farewell overlay; the Python process terminates a
|
||||
moment later via ``os._exit``.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -17,7 +17,7 @@ _project_root = Path(__file__).resolve().parent.parent.parent.parent
|
||||
if str(_project_root) not in sys.path:
|
||||
sys.path.insert(0, str(_project_root))
|
||||
|
||||
from src.gui.components import hide_streamlit_chrome, quit_button
|
||||
from src.gui.components import hide_streamlit_chrome, shutdown_app
|
||||
from src.i18n import t
|
||||
|
||||
st.set_page_config(
|
||||
@@ -25,14 +25,6 @@ st.set_page_config(
|
||||
page_icon="🛑",
|
||||
layout="wide",
|
||||
)
|
||||
|
||||
hide_streamlit_chrome()
|
||||
|
||||
st.title(t("close_page.title"))
|
||||
st.caption(t("close_page.caption"))
|
||||
st.divider()
|
||||
|
||||
st.markdown(t("close_page.body"))
|
||||
|
||||
st.write("")
|
||||
quit_button(label=t("close_page.button"), key="quit_app_button_page")
|
||||
shutdown_app()
|
||||
|
||||
Reference in New Issue
Block a user