Files
HighCostDrugsDemo/dash_app/components/sidebar.py
T
Andrew Charlwood 7d51efc25e feat: add two-view architecture with sidebar navigation (Task 10.2)
- Add active_view and selected_comparison_directorate to app-state
- Sidebar: rename to Patient Pathways + add Trust Comparison nav item
- View container pattern: two view divs toggled by active_view
- Navigation callback: sidebar clicks switch views + update active state
- Trust Comparison placeholder landing page with tc-landing structure
2026-02-06 21:38:12 +00:00

76 lines
2.3 KiB
Python

"""Left sidebar navigation component matching 01_nhs_classic.html design."""
from urllib.parse import quote as url_quote
from dash import html
def _svg_icon(svg_body):
"""Wrap an SVG body string into an html.Img using a data URI."""
svg = (
f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" '
f'fill="none" stroke="currentColor" stroke-width="2">{svg_body}</svg>'
)
return html.Img(
src=f"data:image/svg+xml,{url_quote(svg)}",
className="sidebar__icon",
)
# SVG icon bodies (Feather-style)
_ICONS = {
"pathway": '<rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/>',
"compare": '<line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/>',
}
def make_sidebar():
"""Return the fixed left sidebar navigation."""
return html.Nav(
className="sidebar",
**{"aria-label": "Main navigation"},
children=[
html.Div(
className="sidebar__section",
children=[
html.Div("Analysis", className="sidebar__label"),
_sidebar_item(
"Patient Pathways", "pathway",
active=True, item_id="nav-patient-pathways",
),
_sidebar_item(
"Trust Comparison", "compare",
active=False, item_id="nav-trust-comparison",
),
],
),
html.Div(
className="sidebar__footer",
children=[
"NHS Norfolk & Waveney ICB",
html.Br(),
"High Cost Drugs Programme",
],
),
],
)
def _sidebar_item(label, icon_key, active=False, item_id=None):
"""Create a single sidebar navigation item."""
class_name = "sidebar__item"
if active:
class_name += " sidebar__item--active"
props = {"className": class_name}
if item_id:
props["id"] = item_id
props["n_clicks"] = 0
return html.A(
**props,
children=[
_svg_icon(_ICONS[icon_key]),
label,
],
)