Feat: callback to toggle editing
This commit is contained in:
parent
74882ae572
commit
612df0a8eb
@ -7,7 +7,11 @@ external_scripts = [
|
||||
]
|
||||
# external_script = ["https://tailwindcss.com/", {"src": "https://cdn.tailwindcss.com"}]
|
||||
|
||||
app = Dash(__name__, use_pages=True, external_scripts=external_scripts)
|
||||
app = Dash(__name__,
|
||||
use_pages=True,
|
||||
external_scripts=external_scripts,
|
||||
suppress_callback_exceptions=True,
|
||||
)
|
||||
app.scripts.config.serve_locally = True
|
||||
dash.register_page(
|
||||
home.__name__,
|
||||
|
@ -1,5 +1,6 @@
|
||||
from .stage import AbstractStage
|
||||
from pathlib import Path
|
||||
import pandas as pd
|
||||
|
||||
class FSStage(AbstractStage):
|
||||
def __init__(self, name, basepath, metadata_engine=None):
|
||||
@ -40,9 +41,16 @@ class FSStage(AbstractStage):
|
||||
table_path = self.build_table_path(table, schema)
|
||||
pass
|
||||
|
||||
def read(self, table:str, schema:str='.'):
|
||||
def read(self, table:str, schema:str='.', read_options={}):
|
||||
table_path = self.build_table_path(table, schema)
|
||||
pass
|
||||
extension = table_path.suffix
|
||||
if extension == '.csv':
|
||||
return pd.read_csv(table_path, **read_options)
|
||||
|
||||
if extension == '.xlsx':
|
||||
return pd.read_excel(table_path, **read_options)
|
||||
|
||||
raise ValueError("Can't open the table")
|
||||
|
||||
def write(self, table:str, content, schema:str='.'):
|
||||
table_path = self.build_table_path(table, schema)
|
||||
|
@ -1,30 +1,126 @@
|
||||
from dash import html, dcc
|
||||
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([
|
||||
html.H2([
|
||||
dcc.Link(
|
||||
f"{stage.name}",
|
||||
href=f"/stage/{stage.name}",
|
||||
className="hover:underline"
|
||||
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.Span(" > "),
|
||||
dcc.Link(
|
||||
f"{schema_name}",
|
||||
href=f"/stg/{stage.name}/schema/{schema_name}",
|
||||
className="hover:underline"
|
||||
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"
|
||||
),
|
||||
html.Span(" > "),
|
||||
html.Span(table_name),
|
||||
],
|
||||
className="text-2xl p-4 py-2"
|
||||
|
||||
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"}
|
||||
|
Loading…
Reference in New Issue
Block a user