Add custom CSS styles and improve chat interface layout #77
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable
|
||||
import gradio as gr
|
||||
from app.agents.action_registry import get_user_friendly_action
|
||||
@@ -89,48 +90,61 @@ class ChatManager:
|
||||
|
||||
|
||||
def gradio_build_interface(self) -> gr.Blocks:
|
||||
with gr.Blocks(fill_height=True, fill_width=True) as interface:
|
||||
gr.Markdown("# 🤖 Agente di Analisi e Consulenza Crypto (Chat)")
|
||||
css_file_path = Path(__file__).parent / "styles" / "chat.css"
|
||||
|
||||
# --- Prepara le etichette di default per i dropdown
|
||||
model_labels = self.inputs.list_models_names()
|
||||
default_model_label = self.inputs.team_leader_model.label
|
||||
if default_model_label not in model_labels:
|
||||
default_model_label = model_labels[0] if model_labels else None
|
||||
with gr.Blocks(fill_height=True, fill_width=True, css_paths=[str(css_file_path)]) as interface:
|
||||
with gr.Column(elem_id="chat-wrapper-column"):
|
||||
gr.Markdown("# 🤖 Agente di Analisi e Consulenza Crypto")
|
||||
|
||||
strategy_labels = self.inputs.list_strategies_names()
|
||||
default_strategy_label = self.inputs.strategy.label
|
||||
if default_strategy_label not in strategy_labels:
|
||||
default_strategy_label = strategy_labels[0] if strategy_labels else None
|
||||
# --- Prepara le etichette di default per i dropdown
|
||||
model_labels = self.inputs.list_models_names()
|
||||
default_model_label = self.inputs.team_leader_model.label
|
||||
if default_model_label not in model_labels:
|
||||
default_model_label = model_labels[0] if model_labels else None
|
||||
|
||||
# Dropdown provider e stile
|
||||
with gr.Row():
|
||||
provider = gr.Dropdown(
|
||||
choices=model_labels,
|
||||
value=default_model_label,
|
||||
type="index",
|
||||
label="Modello da usare"
|
||||
strategy_labels = self.inputs.list_strategies_names()
|
||||
default_strategy_label = self.inputs.strategy.label
|
||||
if default_strategy_label not in strategy_labels:
|
||||
default_strategy_label = strategy_labels[0] if strategy_labels else None
|
||||
|
||||
# Dropdown provider e stile
|
||||
with gr.Row(elem_id="dropdown-row"):
|
||||
provider = gr.Dropdown(
|
||||
choices=model_labels,
|
||||
value=default_model_label,
|
||||
type="index",
|
||||
label="Modello da usare"
|
||||
)
|
||||
provider.change(fn=self.inputs.choose_team_leader, inputs=provider, outputs=None)
|
||||
|
||||
style = gr.Dropdown(
|
||||
choices=strategy_labels,
|
||||
value=default_strategy_label,
|
||||
type="index",
|
||||
label="Stile di investimento"
|
||||
)
|
||||
style.change(fn=self.inputs.choose_strategy, inputs=style, outputs=None)
|
||||
|
||||
chat = gr.ChatInterface(
|
||||
fn=self.gradio_respond,
|
||||
chatbot=gr.Chatbot(
|
||||
elem_classes=["borderless-chat"], # Applica la classe CSS
|
||||
scale=1 # Mantiene l'altezza completa
|
||||
),
|
||||
# Aggiungi un placeholder
|
||||
textbox=gr.Textbox(
|
||||
placeholder="Dimmi come posso aiutarti con le criptovalute...",
|
||||
scale=1, # Assicura che la textbox si allinei correttamente
|
||||
render=False # Importante: dice a Gradio di non renderizzarla due volte
|
||||
)
|
||||
)
|
||||
provider.change(fn=self.inputs.choose_team_leader, inputs=provider, outputs=None)
|
||||
|
||||
style = gr.Dropdown(
|
||||
choices=strategy_labels,
|
||||
value=default_strategy_label,
|
||||
type="index",
|
||||
label="Stile di investimento"
|
||||
)
|
||||
style.change(fn=self.inputs.choose_strategy, inputs=style, outputs=None)
|
||||
with gr.Row():
|
||||
clear_btn = gr.Button("🗑️ Reset Chat")
|
||||
save_btn = gr.Button("💾 Salva Chat")
|
||||
load_btn = gr.Button("📂 Carica Chat")
|
||||
|
||||
chat = gr.ChatInterface(
|
||||
fn=self.gradio_respond
|
||||
)
|
||||
|
||||
with gr.Row():
|
||||
clear_btn = gr.Button("🗑️ Reset Chat")
|
||||
save_btn = gr.Button("💾 Salva Chat")
|
||||
load_btn = gr.Button("📂 Carica Chat")
|
||||
|
||||
clear_btn.click(self.gradio_clear, inputs=None, outputs=[chat.chatbot, chat.chatbot_state])
|
||||
save_btn.click(self.gradio_save, inputs=None, outputs=None)
|
||||
load_btn.click(self.gradio_load, inputs=None, outputs=[chat.chatbot, chat.chatbot_state])
|
||||
clear_btn.click(self.gradio_clear, inputs=None, outputs=[chat.chatbot, chat.chatbot_state])
|
||||
save_btn.click(self.gradio_save, inputs=None, outputs=None)
|
||||
load_btn.click(self.gradio_load, inputs=None, outputs=[chat.chatbot, chat.chatbot_state])
|
||||
return interface
|
||||
|
||||
42
src/app/interface/styles/chat.css
Normal file
42
src/app/interface/styles/chat.css
Normal file
@@ -0,0 +1,42 @@
|
||||
/* --- Contenitore Principale --- */
|
||||
#chat-wrapper-column {width: 40% !important; max-width: 1200px !important; margin: 0 auto !important;}
|
||||
|
||||
/* --- Finestra Chat (Borderless) --- */
|
||||
.borderless-chat {border: none !important; box-shadow: none !important; background: none !important;}
|
||||
.borderless-chat .message.bot {border: none !important; box-shadow: none !important;}
|
||||
|
||||
/* --- Scrollbar --- */
|
||||
.borderless-chat ::-webkit-scrollbar-button { display: none; }
|
||||
.borderless-chat ::-webkit-scrollbar-track { background: #1f2937; border-radius: 4px; }
|
||||
.borderless-chat ::-webkit-scrollbar-thumb { background: #4b5563; border-radius: 4px; }
|
||||
.borderless-chat ::-webkit-scrollbar-thumb:hover { background: #6b7280; }
|
||||
.borderless-chat ::-webkit-scrollbar, #chat-wrapper-column textarea::-webkit-scrollbar { display: none; }
|
||||
.borderless-chat, #chat-wrapper-column textarea {
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE/Edge (vecchio) */
|
||||
}
|
||||
#chat-wrapper-column textarea::-webkit-scrollbar-button { display: none; }
|
||||
#chat-wrapper-column textarea::-webkit-scrollbar-track { background: #1f2937; border-radius: 4px; }
|
||||
#chat-wrapper-column textarea::-webkit-scrollbar-thumb { background: #4b5563; border-radius: 4px; }
|
||||
#chat-wrapper-column textarea::-webkit-scrollbar-thumb:hover { background: #6b7280; }
|
||||
|
||||
/* Rimuove i bordi dal gr.Group usato da ChatInterface per la textbox */
|
||||
#chat-wrapper-column .gr-group {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
/* La SOLUZIONE per il separatore dei dropdown */
|
||||
#dropdown-row > div {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* Stile "Pillola" per la Textbox interna (figlia del gr.Group di ChatInterface) */
|
||||
#chat-wrapper-column .gr-group textarea {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
min-height: 56px !important;
|
||||
padding: 18px 24px !important;
|
||||
}
|
||||
Reference in New Issue
Block a user