from typing import Any, Dict, Tuple from dash import ( Dash, Input, Output, State, callback, dcc, get_asset_url, html, no_update, ) from dash.exceptions import PreventUpdate from .app_styles import header_style from .data_chat import send_message external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"] app = Dash(__name__, external_stylesheets=external_stylesheets) app.index_string = header_style err_style = { "height": "0px", "overflow": "hidden", "transition": "height 0.5s ease-in-out", "border-radius": "15px", "background-color": "#FFCCCB", "text-align": "center", "color": "#FF6B6B", "margin-top": "20px", "margin-left": "20px", "margin-right": "20px", "font-weight": "bold", "display": "flex", "justify-content": "center", "align-items": "center", } start_value = "Stelle deine Frage an die Datenbank..." app.layout = html.Div( [ html.Div( [ html.H1("Datenbank-Chat", className="heading"), html.Img(src=get_asset_url("logo.png"), className="logo"), ], className="header-container", ), # Header dcc.Store( id="tmp-value", data=start_value, storage_type="session" ), # Store previous prompt dcc.Textarea( id="input-field", value=start_value, style={"width": "96%", "height": 200, "margin-left": "20px"}, ), # Input field html.Div([]), # Needed for keeping the layout clean html.Button( "Abschicken", id="submit-button", n_clicks=0, disabled=False, style={"margin-left": "20px"}, ), # Submit button html.Div( [html.P("Bitte eine neue Anfrage eingeben.")], id="error", style=err_style ), # Error message (only visible if input is not updated but submit button is clicked) dcc.Loading( id="loading", type="default", children=[ html.Div( "Hier erscheint die Antwort der Datenbank.", id="text-output", style={ "whiteSpace": "pre-line", "margin-top": "30px", "margin-left": "20px", "margin-right": "20px", "border": "2px solid #86bc25", "border-radius": "15px", "padding": "20px", }, ) ], ), ], # Output field className="container", ) @callback( Output("text-output", "children"), Output("tmp-value", "data"), Output("error", "style"), Input("submit-button", "n_clicks"), State("input-field", "value"), State("tmp-value", "data"), prevent_initial_call=True, running=[ (Output("submit-button", "disabled"), True, False), ( Output("submit-button", "style"), {"opacity": 0.5, "margin-left": "20px"}, {"opacity": 1.0, "margin-left": "20px"}, ), ], ) def update_output(n_clicks: int, value: str, data: str) -> Tuple[str, str, Dict[str, Any]]: """Update the output based on user input and button clicks. Parameters ---------- n_clicks : int Number of times the submit button has been clicked. value : str Current value of the input field. data : str Previously stored value. Returns ------- Tuple[str, str, Dict[str, Any]] Updated output text, new stored value, and error style. """ global err_style if n_clicks > 0 and value != data: result = send_message(value) err_style["height"] = "0px" return result, value, err_style elif value == data: err_style["height"] = "50px" return no_update, no_update, err_style raise PreventUpdate server = app.server if __name__ == "__main__": app.run(debug=True)