2222from src .clients import list_providers
2323from src .core import ChatbotAgent , FinancialAdvisorAgent
2424from src .models import FinancialProfile , Portfolio
25+ from src .ui .pdf_generator import PDFGenerator # <-- NUOVO IMPORT
2526from src .ui .settings_page import show_settings_page
2627
2728MONTECARLO_MIN_ASSET_VOLATILITY = float (
@@ -292,26 +293,32 @@ def initialize_financial_advisor(
292293 raise
293294
294295
296+ # TODO: vedere se eliminare
297+ # Funzione per smooth scroll della pagina
295298def _scroll_to_bottom ():
296299 """
297300 Force scroll to bottom by targeting the specific Streamlit main container.
298301 """
299302 js = """
300303 <script>
301304 function forceScroll() {
305+ // Cerca il contenitore scrollabile principale di Streamlit
306+ // I selettori coprono varie versioni di Streamlit
302307 var scrollable_div = window.parent.document.querySelector('section.main') ||
303308 window.parent.document.querySelector('.main') ||
304309 window.parent.document.querySelector('[data-testid="stMain"]');
305310
306311 if (scrollable_div) {
312+ // Forza lo scroll alla fine dell'altezza totale del contenuto
307313 scrollable_div.scrollTop = scrollable_div.scrollHeight;
308314 }
309315 }
310316
317+ // Esegui più volte per "vincere" contro il rendering dinamico di Plotly e i Toast
311318 setTimeout(forceScroll, 100);
312319 setTimeout(forceScroll, 500);
313320 setTimeout(forceScroll, 1000);
314- setTimeout(forceScroll, 2000);
321+ setTimeout(forceScroll, 2000); // Un ultimo tentativo dopo 2 secondi per sicurezza
315322 </script>
316323 """
317324 components .html (js , height = 0 , width = 0 )
@@ -1850,8 +1857,11 @@ def main():
18501857 with st .chat_message (message ["role" ]):
18511858 st .markdown (message ["content" ])
18521859
1860+ # --- INPUT SEMPRE PRESENTE ---
1861+ # Manteniamo la chat input renderizzata ma disabilitata se la conversazione è finita.
1862+ # Questo impedisce al browser di perdere il focus e "saltare" in alto.
18531863 prompt = st .chat_input (
1854- "Assessment completed. See the results above ." ,
1864+ "Ask me about your finances.. ." ,
18551865 disabled = st .session_state .conversation_completed ,
18561866 )
18571867
@@ -1864,6 +1874,9 @@ def main():
18641874 duration = "long" ,
18651875 )
18661876
1877+ # TODO: vedere se elimanrla
1878+ _scroll_to_bottom ()
1879+
18671880 logger .debug ("Conversation is completed" )
18681881
18691882 # Generate and display portfolio
@@ -1931,6 +1944,9 @@ def main():
19311944 "Your financial profile and PAC metrics have been extracted and analyzed."
19321945 )
19331946
1947+ # TODO: vedere se eliminare
1948+ _scroll_to_bottom ()
1949+
19341950 # Financial Profile in an expanded section
19351951 with st .expander (
19361952 "📊 View Your Financial Profile & Summary" , expanded = False
@@ -1943,12 +1959,44 @@ def main():
19431959 "- Click 'Clear Conversation' to start a new assessment or 'Change Provider' to start over"
19441960 )
19451961
1962+ # --- AGGIUNGO QUI IL PULSANTE DI ESPORTAZIONE PDF ---
1963+
1964+ if (
1965+ st .session_state .financial_profile
1966+ and st .session_state .generated_portfolio
1967+ ):
1968+ # 1. Recupera la configurazione dell'Agente per il PDF
1969+ agent_config = chatbot_agent .get_config_summary ()
1970+
1971+ # 2. Genera l'istanza del PDF
1972+ pdf = PDFGenerator (
1973+ agent_config = agent_config ,
1974+ profile_data = st .session_state .financial_profile .model_dump (),
1975+ portfolio_data = st .session_state .generated_portfolio ,
1976+ )
1977+
1978+ # 3. Genera il file in memoria
1979+ pdf_output_bytes = pdf .generate ()
1980+
1981+ # 4. Mostra il pulsante di download Streamlit
1982+ st .download_button (
1983+ label = "⬇️ Esporta Report Portfolio (PDF)" ,
1984+ data = pdf_output_bytes ,
1985+ file_name = "Report_Finanziario.pdf" ,
1986+ mime = "application/pdf" ,
1987+ key = "download_pdf_button" ,
1988+ type = "primary" ,
1989+ )
1990+
1991+ # --- FINE PULSANTE DI ESPORTAZIONE PDF ---
1992+
1993+ # TODO: vedere se eliminare
19461994 _scroll_to_bottom ()
19471995
19481996 else :
19491997 logger .debug ("No financial profile available to display" )
19501998 else :
1951- # Handle user input ONLY if there is a prompt (i.e., not disabled )
1999+ # Gestiamo l' input dell'utente SOLO se c'è un prompt (quindi non è disabilitato )
19522000 if prompt :
19532001 logger .debug ("User input received: %s" , prompt [:100 ])
19542002
0 commit comments