From ea99e292d2decb4198061e590b3efadc06a93321 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 20 May 2026 23:11:06 +0000 Subject: [PATCH] feat(nav): group Home + Reconcile under a new "Analysis" section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Home now appears in the sidebar as "File Analysis" under a labeled "Analysis" section together with Reconcile Two Files — both pages are data-analysis workflows (importing/profiling files vs. matching across files), so grouping them clarifies the sidebar's mental model. - tools_registry: new ``analysis`` Section; reconcile moves out of automations into it. - i18n: ``nav.section_analysis`` + ``nav.file_analysis_title`` added to en.json and es.json. - app.py: home dropped from the unlabeled section and surfaced at the top of the Analysis group; ``default=True`` preserved so first-visit routing is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/gui/app.py | 24 ++++++++++++++++-------- src/gui/tools_registry.py | 5 +++-- src/i18n/packs/en.json | 2 ++ src/i18n/packs/es.json | 2 ++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/gui/app.py b/src/gui/app.py index 67b1057..9632a31 100644 --- a/src/gui/app.py +++ b/src/gui/app.py @@ -78,6 +78,7 @@ def _page_for(tool_id: str, *, page_slug: str, icon: str, title: str) -> "st.Pag def _build_navigation() -> dict[str, list]: by_section: dict[str, list] = { + "analysis": [], "cleaners": [], "transformations": [], "automations": [], @@ -95,10 +96,16 @@ def _build_navigation() -> dict[str, list]: ) ) + # Home is now surfaced under the new "Analysis" section as + # "File Analysis" — the home page's content (importing files, + # running the analyzer, browsing findings) is itself a data-analysis + # workflow, so grouping it next to Reconcile keeps the sidebar's + # mental model coherent. ``default=True`` still points at this + # page so first-visit lands here regardless of section placement. home = st.Page( _home_page, - title=_t("nav.home_page_title") or "Home", - icon=":material/home:", + title=_t("nav.file_analysis_title") or "File Analysis", + icon=":material/insert_chart_outlined:", default=True, url_path="home", ) @@ -129,13 +136,14 @@ def _build_navigation() -> dict[str, list]: url_path="close", ) - # Activate + Close are placed in the unlabeled section alongside - # Home (key ``""`` — Streamlit renders no header for it). The CSS - # in ``hide_streamlit_chrome`` then hides just their two links by - # ``href``, leaving Home visible and no orphan section header / - # drilldown marker in the sidebar. + # Activate / Logs / Close stay in the unlabeled section (key ``""``) + # so the CSS in ``hide_streamlit_chrome`` keeps hiding them by + # ``href``. Home moved out of that bucket into "Analysis" — the + # unlabeled section now contains ONLY hidden pages, so no orphan + # entry appears above the "Analysis" header in the sidebar. return { - "": [home, activate, logs, close], + "": [activate, logs, close], + section_label("analysis"): [home, *by_section["analysis"]], section_label("cleaners"): by_section["cleaners"], section_label("transformations"): by_section["transformations"], section_label("automations"): by_section["automations"], diff --git a/src/gui/tools_registry.py b/src/gui/tools_registry.py index 13abab0..603e6ed 100644 --- a/src/gui/tools_registry.py +++ b/src/gui/tools_registry.py @@ -24,7 +24,7 @@ Tier = Literal["core", "pro", "enterprise"] Status = Literal["Ready", "Coming Soon"] # Sidebar grouping. Tools are bucketed by what the user is trying to # accomplish rather than by implementation detail. -Section = Literal["cleaners", "transformations", "automations"] +Section = Literal["analysis", "cleaners", "transformations", "automations"] @dataclass(frozen=True) @@ -167,7 +167,7 @@ TOOLS: list[Tool] = [ ), page_slug="11_Reconciler", status="Ready", - section="automations", + section="analysis", ), ] @@ -175,6 +175,7 @@ TOOLS: list[Tool] = [ # Display labels for each sidebar section. Kept here so i18n falls back # to a sensible English string if a translation pack is missing the key. SECTION_LABELS: dict[Section, str] = { + "analysis": "Analysis", "cleaners": "Data Cleaners", "transformations": "Transformations", "automations": "Automations", diff --git a/src/i18n/packs/en.json b/src/i18n/packs/en.json index 020df22..21f74bf 100644 --- a/src/i18n/packs/en.json +++ b/src/i18n/packs/en.json @@ -168,11 +168,13 @@ }, "nav": { "section_review": "Data Review", + "section_analysis": "Analysis", "section_cleaners": "Data Cleaners", "section_transformations": "Transformations", "section_automations": "Automations", "review_page_title": "Review", "home_page_title": "Home", + "file_analysis_title": "File Analysis", "section_account": "Account", "activate_title": "Activate", "close_title": "Close", diff --git a/src/i18n/packs/es.json b/src/i18n/packs/es.json index 62ced16..1d12aa4 100644 --- a/src/i18n/packs/es.json +++ b/src/i18n/packs/es.json @@ -168,11 +168,13 @@ }, "nav": { "section_review": "Revisión de datos", + "section_analysis": "Análisis", "section_cleaners": "Limpiadores de datos", "section_transformations": "Transformaciones", "section_automations": "Automatizaciones", "review_page_title": "Revisión", "home_page_title": "Inicio", + "file_analysis_title": "Análisis de archivo", "section_account": "Cuenta", "activate_title": "Activar", "close_title": "Cerrar",