feat(nav): group Home + Reconcile under a new "Analysis" section

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) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 23:11:06 +00:00
parent 0be59c0f03
commit ea99e292d2
4 changed files with 23 additions and 10 deletions

View File

@@ -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]: def _build_navigation() -> dict[str, list]:
by_section: dict[str, list] = { by_section: dict[str, list] = {
"analysis": [],
"cleaners": [], "cleaners": [],
"transformations": [], "transformations": [],
"automations": [], "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 = st.Page(
_home_page, _home_page,
title=_t("nav.home_page_title") or "Home", title=_t("nav.file_analysis_title") or "File Analysis",
icon=":material/home:", icon=":material/insert_chart_outlined:",
default=True, default=True,
url_path="home", url_path="home",
) )
@@ -129,13 +136,14 @@ def _build_navigation() -> dict[str, list]:
url_path="close", url_path="close",
) )
# Activate + Close are placed in the unlabeled section alongside # Activate / Logs / Close stay in the unlabeled section (key ``""``)
# Home (key ``""`` — Streamlit renders no header for it). The CSS # so the CSS in ``hide_streamlit_chrome`` keeps hiding them by
# in ``hide_streamlit_chrome`` then hides just their two links by # ``href``. Home moved out of that bucket into "Analysis" — the
# ``href``, leaving Home visible and no orphan section header / # unlabeled section now contains ONLY hidden pages, so no orphan
# drilldown marker in the sidebar. # entry appears above the "Analysis" header in the sidebar.
return { return {
"": [home, activate, logs, close], "": [activate, logs, close],
section_label("analysis"): [home, *by_section["analysis"]],
section_label("cleaners"): by_section["cleaners"], section_label("cleaners"): by_section["cleaners"],
section_label("transformations"): by_section["transformations"], section_label("transformations"): by_section["transformations"],
section_label("automations"): by_section["automations"], section_label("automations"): by_section["automations"],

View File

@@ -24,7 +24,7 @@ Tier = Literal["core", "pro", "enterprise"]
Status = Literal["Ready", "Coming Soon"] Status = Literal["Ready", "Coming Soon"]
# Sidebar grouping. Tools are bucketed by what the user is trying to # Sidebar grouping. Tools are bucketed by what the user is trying to
# accomplish rather than by implementation detail. # accomplish rather than by implementation detail.
Section = Literal["cleaners", "transformations", "automations"] Section = Literal["analysis", "cleaners", "transformations", "automations"]
@dataclass(frozen=True) @dataclass(frozen=True)
@@ -167,7 +167,7 @@ TOOLS: list[Tool] = [
), ),
page_slug="11_Reconciler", page_slug="11_Reconciler",
status="Ready", 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 # 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. # to a sensible English string if a translation pack is missing the key.
SECTION_LABELS: dict[Section, str] = { SECTION_LABELS: dict[Section, str] = {
"analysis": "Analysis",
"cleaners": "Data Cleaners", "cleaners": "Data Cleaners",
"transformations": "Transformations", "transformations": "Transformations",
"automations": "Automations", "automations": "Automations",

View File

@@ -168,11 +168,13 @@
}, },
"nav": { "nav": {
"section_review": "Data Review", "section_review": "Data Review",
"section_analysis": "Analysis",
"section_cleaners": "Data Cleaners", "section_cleaners": "Data Cleaners",
"section_transformations": "Transformations", "section_transformations": "Transformations",
"section_automations": "Automations", "section_automations": "Automations",
"review_page_title": "Review", "review_page_title": "Review",
"home_page_title": "Home", "home_page_title": "Home",
"file_analysis_title": "File Analysis",
"section_account": "Account", "section_account": "Account",
"activate_title": "Activate", "activate_title": "Activate",
"close_title": "Close", "close_title": "Close",

View File

@@ -168,11 +168,13 @@
}, },
"nav": { "nav": {
"section_review": "Revisión de datos", "section_review": "Revisión de datos",
"section_analysis": "Análisis",
"section_cleaners": "Limpiadores de datos", "section_cleaners": "Limpiadores de datos",
"section_transformations": "Transformaciones", "section_transformations": "Transformaciones",
"section_automations": "Automatizaciones", "section_automations": "Automatizaciones",
"review_page_title": "Revisión", "review_page_title": "Revisión",
"home_page_title": "Inicio", "home_page_title": "Inicio",
"file_analysis_title": "Análisis de archivo",
"section_account": "Cuenta", "section_account": "Cuenta",
"activate_title": "Activar", "activate_title": "Activar",
"close_title": "Cerrar", "close_title": "Cerrar",