from dash import html, dcc, dash_table, callback, Input, Output, State from dash.exceptions import PreventUpdate from ..datalake import stages from ..libs.stage.stage import AbstractStage def layout(stage_name=None, schema_name=None, table_name=None): stage = stages[stage_name] df = stage.read(table=table_name, schema=schema_name) return html.Div([ dcc.Store(id="table_backup"), html.Div([ html.H2([ dcc.Link( f"{stage.name}", href=f"/stage/{stage.name}", className="hover:underline" ), html.Span(" > "), dcc.Link( f"{schema_name}", href=f"/stg/{stage.name}/schema/{schema_name}", className="hover:underline" ), html.Span(" > "), html.Span(table_name), ], className="text-2xl" ), html.Div([ html.Button( "Editer", id="btn_edit", className="rounded border px-2 py-1", style={"display": "block"} ), html.Button( "Sauver", id="btn_save", className="rounded border px-2 py-1 border-green-500 hover:bg-green-500", style={"display": "none"} ), html.Button( "Annuler", id="btn_cancel", className="rounded border px-2 py-1 border-red-500 hover:bg-red-500", style={"display": "none"} ), ], className="flex flex-row space-x-2", id="toolbar" ), ], className="flex flex-row justify-between p-4" ), html.Div([ html.Div([ dash_table.DataTable( id="datatable", data=df.to_dict('records'), columns=[{"name": i, "id": i} for i in df.columns], filter_action="native", sort_action="native", sort_mode="multi", editable=False ) ]) ], className="overflow-y-auto" ), ], className="p-2" ) @callback( Output("datatable", 'editable', allow_duplicate=True), Output("table_backup", 'data'), Input("btn_edit", "n_clicks"), State("datatable", 'data'), prevent_initial_call=True ) def activate_editable(n_clicks, df_src): if n_clicks is None: raise PreventUpdate if n_clicks > 0: df_backup = df_src.copy() return True, df_backup raise PreventUpdate @callback( Output("datatable", 'editable'), Output("datatable", 'data'), Input("btn_cancel", "n_clicks"), State("table_backup", 'data'), prevent_initial_call=True ) def cancel_modifications(n_clicks, data): if n_clicks is None: raise PreventUpdate if n_clicks > 0 and data is not None: return False, data.copy() raise PreventUpdate # @callback( # Output("datatable", 'editable'), # Input("btn_save", "n_clicks"), # State("datatable", 'editable'), # ) # def save_modifications(n_clicks, editable): # if n_clicks is None: # raise PreventUpdate # if n_clicks > 0: # return not editable # return editable @callback( Output("btn_edit", "style"), Output("btn_save", "style"), Output("btn_cancel", "style"), Input("datatable", "editable"), ) def toolbar(editable): if editable: return {"display": "none"}, {"display": "block"}, {"display": "block"} return {"display": "block"}, {"display": "none"}, {"display": "none"}