plesna/dashboard/pages/table.py

127 lines
3.8 KiB
Python
Raw Normal View History

2024-07-28 15:34:56 +00:00
from dash import html, dcc, dash_table, callback, Input, Output, State
from dash.exceptions import PreventUpdate
2024-07-27 17:19:36 +00:00
from ..datalake import stages
from ..libs.stage.stage import AbstractStage
def layout(stage_name=None, schema_name=None, table_name=None):
2024-07-28 10:29:14 +00:00
stage = stages[stage_name]
2024-07-28 15:34:56 +00:00
df = stage.read(table=table_name, schema=schema_name)
2024-07-27 17:19:36 +00:00
return html.Div([
2024-07-28 15:34:56 +00:00
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"
2024-07-28 10:29:14 +00:00
),
2024-07-28 15:34:56 +00:00
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"
2024-07-28 10:29:14 +00:00
),
],
2024-07-28 15:34:56 +00:00
className="flex flex-row justify-between p-4"
2024-07-28 10:29:14 +00:00
),
2024-07-28 15:34:56 +00:00
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
2024-07-27 17:19:36 +00:00
2024-07-28 15:34:56 +00:00
@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
2024-07-27 17:19:36 +00:00
2024-07-28 15:34:56 +00:00
# @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
2024-07-28 10:29:14 +00:00
2024-07-28 15:34:56 +00:00
@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"}