Hi @benn0,
I made an update to your usage.py example that incorporates the ability of saving and loading the current layout.
I also added 3button in order to make use of the “addTabWithDragAndDrop”, “addTabWithDragAndDropIndirect” and “addTabToTabSet” methods but I did not find any wrapper inside your code. Is this correct? Is it possible to implement this methods?
import dash
import json
from dash import Input, Output, State, html
import dash_flexlayout as dfl
app = dash.Dash(__name__, suppress_callback_exceptions=True)
config = {
"global": {
"tabEnableClose":True,
"tabEnableDrag": True,
"tabEnableRename": True,
"tabEnableFloat": True,
"enableEdgeDock": True
},
"borders":[
{
"type": "border",
"id": 'bottom-border',
"location":"bottom",
"selected": 0,
"size": 120,
"children": [
{
"type": "tab",
"name": "Four",
"component": "text",
"id": "tab-4",
}
]
},
{
"type": "border",
"id": 'left-border',
"location":"left",
"selected": 0,
"size": 118,
"children": [
{
"type": "tab",
"name": "Utils",
"component": "text",
"id": "tab-utils",
}
]
}
],
"layout": {
"type": "row",
"weight": 100,
"children": [
{
"type": "tabset",
"weight": 25,
"children": [
{
"type": "tab",
"name": "One",
"component": "text",
"id": "tab-1",
}
]
},
{
"type": "tabset",
"weight": 75,
"children": [
{
"type": "tab",
"name": "Two",
"component": "text",
"id": "tab-2",
},
{
"type": "tab",
"name": "Three",
"component": "text",
"id": "tab-3",
},
]
}
]
}
}
nodes = [
dfl.Tab(id="tab-utils", children=[
"This is UTILS tab",
html.Button(id="button-1", children="Click Me"),
html.Button(id="button-2", children="Add Drag"),
html.Button(id="button-3", children="Add to Tab"),
html.Button(id="button-4", children="Add Indirect"),
html.Button(id="button-save", children="Save Layout"),
html.Button(id="button-load", children="Load Layout"),
]
),
dfl.Tab(id="tab-1",
children=[
"This is TAB 1",
html.Div(id="button-1-output"),
]
),
dfl.Tab(id="tab-2",
children=[
"This is the NODES layout",
html.Div(id="layout-nodes"),
]
),
dfl.Tab(id="tab-3",
children=[
"This is the ACTUAL layout",
html.Div(id="layout-actual"),
]
),
dfl.Tab(id="tab-4",
children=[
"This is the SAVED layout",
html.Div(id="layout-saved"),
]
),
]
app.layout = dfl.FlexLayout(id='flex-layout', model=config, children=nodes, useStateForModel=False)
@app.callback(
Output("layout-nodes", "children"),
[Input("flex-layout", "children")]
)
def show_children_layout(children):
return str(children)
@app.callback(
Output("layout-model", "children"),
[Input("flex-layout", "model")]
)
def show_model_layout(layout):
return str(layout)
@app.callback(
Output('button-1-output', 'children'),
[
Input("button-1", "n_clicks"),
],
)
def update_button_1_output(n_clicks):
return f"Clicked {n_clicks} times!"
@app.callback(
Output('layout-actual', 'children'),
[
Input("flex-layout", "model"),
],
)
def actual_layout(*args):
return json.dumps(args[-1])
@app.callback(
Output('layout-saved', 'children'),
[
Input("button-save", "n_clicks"),
],
[
State("flex-layout", "model")
],
prevent_initial_call=True,
)
def save_layout(*args):
return json.dumps(args[-1])
@app.callback(
Output('flex-layout', 'model'),
[
Input("button-load", "n_clicks"),
],
[
State("flex-layout", "model"),
State("layout-saved", "children")
],
prevent_initial_call=True,
)
def load_layout(*args):
if args[-1] is None: return args[-2]
return json.loads(args[-1])
if __name__ == '__main__':
app.run_server(debug=True)