55from dash import Input , Output , callback , clientside_callback , dcc , html
66
77from .header import create_header
8+ from .notifications import NotificationsProvider
89from .sidebar import create_sidebar
910from .theme_manager import ThemeManager
1011
@@ -55,51 +56,53 @@ def create_layout(
5556 }
5657
5758 return dmc .MantineProvider (
58- html .Div (
59- [
60- # Theme and location management
61- ThemeManager () if include_theme_manager else None ,
62- # Global page stores for header + page config
63- dcc .Store (id = "page_header_config" , data = {}),
64- dcc .Store (id = "page_config" , data = {}),
65- # Sidebar
66- create_sidebar (
67- brand_name = sidebar_config ["brand_name" ],
68- brand_initial = sidebar_config ["brand_initial" ],
69- ),
70- # Right side: navbar + content (full width minus sidebar)
71- html .Div (
72- [
73- # Header/navbar - spans full width of content area
74- create_header (
75- page_title = header_config ["page_title" ],
76- page_icon = header_config ["page_icon" ],
77- search_placeholder = header_config .get (
78- "search_placeholder" , "Search..."
59+ NotificationsProvider (
60+ html .Div (
61+ [
62+ # Theme and location management
63+ ThemeManager () if include_theme_manager else None ,
64+ # Global page stores for header + page config
65+ dcc .Store (id = "page_header_config" , data = {}),
66+ dcc .Store (id = "page_config" , data = {}),
67+ # Sidebar
68+ create_sidebar (
69+ brand_name = sidebar_config ["brand_name" ],
70+ brand_initial = sidebar_config ["brand_initial" ],
71+ ),
72+ # Right side: navbar + content (full width minus sidebar)
73+ html .Div (
74+ [
75+ # Header/navbar - spans full width of content area
76+ create_header (
77+ page_title = header_config ["page_title" ],
78+ page_icon = header_config ["page_icon" ],
79+ search_placeholder = header_config .get (
80+ "search_placeholder" , "Search..."
81+ ),
82+ actions = header_config .get ("actions" ),
83+ filter_items = header_config .get ("filter_items" ),
7984 ),
80- actions = header_config .get ("actions" ),
81- filter_items = header_config .get ("filter_items" ),
82- ),
83- # Content with max-width constraint
84- html .Main (
85- [
86- html .Div (
87- [content ],
88- id = "main-content-container" ,
89- style = {
90- "maxWidth" : "calc(100vw - var(--dashkit-sidebar-width))" ,
91- "width" : "100%" ,
92- },
93- className = f"dark:text-white { content_padding } prose prose-sm dark:prose-invert" ,
94- )
95- ],
96- className = "flex-1 overflow-auto dark:bg-dashkit-surface " ,
97- ),
98- ],
99- className = "main-content-area flex-1 flex flex-col" ,
100- ),
101- ],
102- className = "flex h-screen bg-white dark:bg-dashkit-surface font-sans" ,
85+ # Content with max-width constraint
86+ html .Main (
87+ [
88+ html .Div (
89+ [content ],
90+ id = "main-content-container" ,
91+ style = {
92+ "maxWidth" : "calc(100vw - var(--dashkit-sidebar-width))" ,
93+ "width" : "100%" ,
94+ },
95+ className = f"dark:text-white { content_padding } prose prose-sm dark:prose-invert" ,
96+ )
97+ ],
98+ className = "flex-1 overflow-auto dark:bg-dashkit-surface " ,
99+ ),
100+ ],
101+ className = "main-content-area flex-1 flex flex-col" ,
102+ ),
103+ ],
104+ className = "flex h-screen bg-white dark:bg-dashkit-surface font-sans" ,
105+ )
103106 )
104107 )
105108
@@ -112,7 +115,7 @@ def create_layout(
112115 ],
113116 Input ("url" , "pathname" , allow_optional = True ),
114117)
115- def _update_page_config (pathname : str | None ):
118+ def _update_page_config (pathname : str | None ) -> tuple [ dict [ str , str ], dict [ str , str ]]: # pyright: ignore[reportUnusedFunction]
116119 """Update header + page config stores from Dash page registry.
117120
118121 This runs whenever the URL changes. If `url` isn't present, it will be
0 commit comments