Feat: put table's callback and layout in factory

This commit is contained in:
Bertrand Benjamin 2024-07-28 18:49:07 +02:00
parent 612df0a8eb
commit 7fb7bc6f5c
2 changed files with 121 additions and 117 deletions

View File

@ -1,6 +1,7 @@
import dash import dash
from dash import Dash, html, dcc from dash import Dash, html, dcc
from .pages import home, config, stage, schema, table from .pages import home, config, stage, schema, table
from .datalake import stages
external_scripts = [ external_scripts = [
{'src': 'https://cdn.tailwindcss.com'} {'src': 'https://cdn.tailwindcss.com'}
@ -36,8 +37,9 @@ dash.register_page(
dash.register_page( dash.register_page(
table.__name__, table.__name__,
path_template='/stg/<stage_name>/schm/<schema_name>/table/<table_name>', path_template='/stg/<stage_name>/schm/<schema_name>/table/<table_name>',
layout=table.layout layout=table.layout_factory(stages)
) )
table.callback_factory(app)
app.layout = html.Div([ app.layout = html.Div([
html.Div([ html.Div([

View File

@ -1,10 +1,9 @@
from dash import html, dcc, dash_table, callback, Input, Output, State from dash import html, dcc, dash_table, Input, Output, State
from dash.exceptions import PreventUpdate from dash.exceptions import PreventUpdate
from ..datalake import stages
from ..libs.stage.stage import AbstractStage from ..libs.stage.stage import AbstractStage
def layout_factory(stages: list[AbstractStage]):
def layout(stage_name=None, schema_name=None, table_name=None): def layout(stage_name=None, schema_name=None, table_name=None):
stage = stages[stage_name] stage = stages[stage_name]
df = stage.read(table=table_name, schema=schema_name) df = stage.read(table=table_name, schema=schema_name)
return html.Div([ return html.Div([
@ -71,16 +70,18 @@ def layout(stage_name=None, schema_name=None, table_name=None):
], ],
className="p-2" className="p-2"
) )
return layout
@callback( def callback_factory(app):
@app.callback(
Output("datatable", 'editable', allow_duplicate=True), Output("datatable", 'editable', allow_duplicate=True),
Output("table_backup", 'data'), Output("table_backup", 'data'),
Input("btn_edit", "n_clicks"), Input("btn_edit", "n_clicks"),
State("datatable", 'data'), State("datatable", 'data'),
prevent_initial_call=True prevent_initial_call=True
) )
def activate_editable(n_clicks, df_src): def activate_editable(n_clicks, df_src):
if n_clicks is None: if n_clicks is None:
raise PreventUpdate raise PreventUpdate
if n_clicks > 0: if n_clicks > 0:
@ -88,39 +89,40 @@ def activate_editable(n_clicks, df_src):
return True, df_backup return True, df_backup
raise PreventUpdate raise PreventUpdate
@callback( @app.callback(
Output("datatable", 'editable'), Output("datatable", 'editable', allow_duplicate=True),
Output("datatable", 'data'), Output("datatable", 'data', allow_duplicate=True),
Input("btn_cancel", "n_clicks"), Input("btn_cancel", "n_clicks"),
State("table_backup", 'data'), State("table_backup", 'data'),
prevent_initial_call=True prevent_initial_call=True
) )
def cancel_modifications(n_clicks, data): def cancel_modifications(n_clicks, data):
if n_clicks is None: if n_clicks is None:
raise PreventUpdate raise PreventUpdate
if n_clicks > 0 and data is not None: if n_clicks > 0 and data is not None:
return False, data.copy() return False, data.copy()
raise PreventUpdate raise PreventUpdate
# @callback( @app.callback(
# Output("datatable", 'editable'), Output("datatable", 'editable'),
# Input("btn_save", "n_clicks"), Output("datatable", 'data'),
# State("datatable", 'editable'), Input("btn_save", "n_clicks"),
# ) State("datatable", 'editable'),
# def save_modifications(n_clicks, editable): )
# if n_clicks is None: def save_modifications(n_clicks, editable):
# raise PreventUpdate if n_clicks is None:
# if n_clicks > 0: raise PreventUpdate
# return not editable if n_clicks > 0:
# return editable return not editable
return editable
@callback( @app.callback(
Output("btn_edit", "style"), Output("btn_edit", "style"),
Output("btn_save", "style"), Output("btn_save", "style"),
Output("btn_cancel", "style"), Output("btn_cancel", "style"),
Input("datatable", "editable"), Input("datatable", "editable"),
) )
def toolbar(editable): def toolbar(editable):
if editable: if editable:
return {"display": "none"}, {"display": "block"}, {"display": "block"} return {"display": "none"}, {"display": "block"}, {"display": "block"}
return {"display": "block"}, {"display": "none"}, {"display": "none"} return {"display": "block"}, {"display": "none"}, {"display": "none"}