@@ -544,8 +544,10 @@ def build_response_panel(result: Dict[str, Any], chips: Optional[List] = None) -
544544 html .Div ([
545545 dbc .Badge ([html .I (className = f"bi { icon } me-1" ), str (code ) if code else "Error" ],
546546 color = status_color , className = "status-badge" ),
547- html .Span (f"{ ms } ms" , className = "timing-label font-mono ms-2" ),
547+ html .Span (f"{ ms :, } ms" , className = "timing-label font-mono ms-2" ),
548548 html .Span (item_count , className = "timing-label" ) if item_count else None ,
549+ # Anchor point for the absolutely-positioned Load All button
550+ html .Span (id = "load-all-anchor" , className = "load-all-anchor" ),
549551 html .Span (result .get ("url" , "" ), className = "response-url ms-auto" ),
550552 ], className = "response-meta" ),
551553 html .Div (body_children , className = "response-body" ),
@@ -963,18 +965,16 @@ def _custom_section():
963965 html .Div ([
964966 html .Div (WELCOME , id = "endpoint-detail" , className = "form-panel" ),
965967 html .Div ([
966- html .Div ([
967- html .Div (id = "fetch-status-bar" , className = "fetch-status-bar" ),
968- html .Button (
969- [html .I (className = "bi bi-cloud-download me-1" ), "Load All" ],
970- id = "sp-load-all-btn" ,
971- n_clicks = 0 ,
972- className = "sp-load-all-btn" ,
973- title = "Fetch all remaining pages" ,
974- style = {"display" : "none" },
975- ),
976- ], className = "fetch-bar-row" ),
968+ html .Div (id = "fetch-status-bar" , className = "fetch-status-bar" ),
977969 html .Div (_RESPONSE_EMPTY , id = "response-container" , className = "response-container" ),
970+ html .Button (
971+ [html .I (className = "bi bi-cloud-download me-1" ), "Load All" ],
972+ id = "sp-load-all-btn" ,
973+ n_clicks = 0 ,
974+ className = "sp-load-all-btn" ,
975+ title = "Fetch all remaining pages" ,
976+ style = {"display" : "none" },
977+ ),
978978 ], className = "response-panel" ),
979979 ], className = "main-content" ),
980980 ], className = "app-body" ),
@@ -1887,13 +1887,23 @@ def poll_load_all(n_intervals, cache):
18871887 ], className = "fetch-status-inner loading" )
18881888 return no_update , no_update , no_update , status , False
18891889
1890- # Done or error — render final result
1890+ # Auto-dismiss: if finished_at was set, wait 5s then clear status bar
1891+ finished_at = state .get ("finished_at" )
1892+ if finished_at and not state .get ("done" ):
1893+ if time .time () - finished_at >= 5 :
1894+ state .pop ("finished_at" , None )
1895+ return no_update , no_update , no_update , "" , True # clear status, stop ticker
1896+ return NO # keep ticking, waiting to dismiss
1897+
1898+ if not state .get ("done" ):
1899+ return NO
1900+
1901+ # Done or error — render final result and set dismiss timer
18911902 if state .get ("error" ):
18921903 status = html .Div ([
18931904 html .I (className = "bi bi-exclamation-triangle-fill me-2" ),
18941905 f"Error after { pages } pages ({ total :,} items): { state ['error' ]} " ,
18951906 ], className = "fetch-status-inner error" )
1896- # Still render whatever we got
18971907 else :
18981908 status = html .Div ([
18991909 html .I (className = "bi bi-check-circle-fill me-2" ),
@@ -1921,10 +1931,10 @@ def poll_load_all(n_intervals, cache):
19211931 if ep_id :
19221932 new_cache [ep_id ] = {"result" : merged_result , "chips" : chips or None }
19231933
1924- # Reset state for next use
1925- _load_all_state .update ({"running " : False , "done " : False , "items " : [] })
1934+ # Mark done, set dismiss timer — keep ticker running for auto-dismiss
1935+ _load_all_state .update ({"done " : False , "items " : [] , "finished_at " : time . time () })
19261936
1927- return build_response_panel (merged_result , chips ), new_cache , chips or None , status , True
1937+ return build_response_panel (merged_result , chips ), new_cache , chips or None , status , False
19281938
19291939
19301940# 13. Search filter
@@ -2180,6 +2190,25 @@ def update_curl_display(last_req, conn_config):
21802190)
21812191
21822192
2193+ # Reparent the Load All button into the response-meta bar after each render
2194+ app .clientside_callback (
2195+ """
2196+ function(children, style) {
2197+ var anchor = document.getElementById('load-all-anchor');
2198+ var btn = document.getElementById('sp-load-all-btn');
2199+ if (anchor && btn) {
2200+ anchor.appendChild(btn);
2201+ }
2202+ return window.dash_clientside.no_update;
2203+ }
2204+ """ ,
2205+ Output ("sp-load-all-btn" , "className" ),
2206+ Input ("response-container" , "children" ),
2207+ Input ("sp-load-all-btn" , "style" ),
2208+ prevent_initial_call = True ,
2209+ )
2210+
2211+
21832212# ── Entry point ───────────────────────────────────────────────────────────────
21842213if __name__ == "__main__" :
21852214 port = int (os .getenv ("DATABRICKS_APP_PORT" , "8050" ))
0 commit comments