Skip to content

Commit

Permalink
improve namings for duplicating the filter accordion logic for the sc…
Browse files Browse the repository at this point in the history
…oring
  • Loading branch information
gcroci2 committed Oct 14, 2024
1 parent 4ed2571 commit e214374
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 93 deletions.
117 changes: 66 additions & 51 deletions app/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,19 @@ def process_bgc_class(bgc_class: tuple[str, ...] | None) -> list[str]:
@app.callback(
[
Output("gm-tab", "disabled"),
Output("gm-accordion-control", "disabled"),
Output("gm-filter-accordion-control", "disabled"),
Output("gm-filter-blocks-id", "data", allow_duplicate=True),
Output("gm-filter-blocks-container", "children", allow_duplicate=True),
Output("gm-table-card-header", "style"),
Output("gm-table-card-body", "style", allow_duplicate=True),
Output("mg-tab", "disabled"),
Output("blocks-id", "data", allow_duplicate=True),
Output("blocks-container", "children", allow_duplicate=True),
],
[Input("file-store", "data")],
prevent_initial_call=True,
)
def disable_tabs_and_reset_blocks(
file_path: Path | str | None,
) -> tuple[bool, bool, dict, dict[str, str], bool, list[str], list[dmc.Grid]]:
) -> tuple[bool, bool, list[str], list[dmc.Grid], dict, dict[str, str], bool]:
"""Manage tab states and reset blocks based on file upload status.
Args:
Expand All @@ -165,16 +165,24 @@ def disable_tabs_and_reset_blocks(
"""
if file_path is None:
# Disable the tabs, don't change blocks
return True, True, {}, {"display": "block"}, True, [], []
return True, True, [], [], {}, {"display": "block"}, True

# Enable the tabs and reset blocks
initial_block_id = [str(uuid.uuid4())]
new_blocks = [create_initial_block(initial_block_id[0])]

return False, False, {}, {"display": "block"}, False, initial_block_id, new_blocks
gm_filter_initial_block_id = [str(uuid.uuid4())]
gm_filter_new_blocks = [gm_filter_create_initial_block(gm_filter_initial_block_id[0])]

return (
False,
False,
gm_filter_initial_block_id,
gm_filter_new_blocks,
{},
{"display": "block"},
False,
)


def create_initial_block(block_id: str) -> dmc.Grid:
def gm_filter_create_initial_block(block_id: str) -> dmc.Grid:
"""Create the initial block component with the given ID.
Args:
Expand All @@ -184,12 +192,12 @@ def create_initial_block(block_id: str) -> dmc.Grid:
A Grid component with nested elements.
"""
return dmc.Grid(
id={"type": "gm-block", "index": block_id},
id={"type": "gm-filter-block", "index": block_id},
children=[
dmc.GridCol(
dbc.Button(
[html.I(className="fas fa-plus")],
id={"type": "gm-add-button", "index": block_id},
id={"type": "gm-filter-add-button", "index": block_id},
className="btn-primary",
),
span=2,
Expand All @@ -198,20 +206,20 @@ def create_initial_block(block_id: str) -> dmc.Grid:
dcc.Dropdown(
options=GM_DROPDOWN_MENU_OPTIONS,
value="GCF_ID",
id={"type": "gm-dropdown-menu", "index": block_id},
id={"type": "gm-filter-dropdown-menu", "index": block_id},
clearable=False,
),
span=4,
),
dmc.GridCol(
[
dmc.TextInput(
id={"type": "gm-dropdown-ids-text-input", "index": block_id},
id={"type": "gm-filter-dropdown-ids-text-input", "index": block_id},
placeholder="1, 2, 3, ...",
className="custom-textinput",
),
dcc.Dropdown(
id={"type": "gm-dropdown-bgc-class-dropdown", "index": block_id},
id={"type": "gm-filter-dropdown-bgc-class-dropdown", "index": block_id},
options=GM_DROPDOWN_BGC_CLASS_OPTIONS,
multi=True,
style={"display": "none"},
Expand All @@ -227,7 +235,7 @@ def create_initial_block(block_id: str) -> dmc.Grid:
@app.callback(
Output("gm-graph", "figure"),
Output("gm-graph", "style"),
Output("file-content-mg", "children"),
Output("mg-file-content", "children"),
[Input("processed-data-store", "data")],
)
def gm_plot(stored_data: str | None) -> tuple[dict | go.Figure, dict, str]:
Expand Down Expand Up @@ -273,11 +281,11 @@ def gm_plot(stored_data: str | None) -> tuple[dict | go.Figure, dict, str]:


@app.callback(
Output("blocks-id", "data"),
Input({"type": "gm-add-button", "index": ALL}, "n_clicks"),
State("blocks-id", "data"),
Output("gm-filter-blocks-id", "data"),
Input({"type": "gm-filter-add-button", "index": ALL}, "n_clicks"),
State("gm-filter-blocks-id", "data"),
)
def add_block(n_clicks: list[int], blocks_id: list[str]) -> list[str]:
def gm_filter_add_block(n_clicks: list[int], blocks_id: list[str]) -> list[str]:
"""Add a new block to the layout when the add button is clicked.
Args:
Expand All @@ -296,11 +304,13 @@ def add_block(n_clicks: list[int], blocks_id: list[str]) -> list[str]:


@app.callback(
Output("blocks-container", "children"),
Input("blocks-id", "data"),
State("blocks-container", "children"),
Output("gm-filter-blocks-container", "children"),
Input("gm-filter-blocks-id", "data"),
State("gm-filter-blocks-container", "children"),
)
def display_blocks(blocks_id: list[str], existing_blocks: list[dmc.Grid]) -> list[dmc.Grid]:
def gm_filter_display_blocks(
blocks_id: list[str], existing_blocks: list[dmc.Grid]
) -> list[dmc.Grid]:
"""Display the blocks for the input block IDs.
Args:
Expand All @@ -314,19 +324,19 @@ def display_blocks(blocks_id: list[str], existing_blocks: list[dmc.Grid]) -> lis
new_block_id = blocks_id[-1]

new_block = dmc.Grid(
id={"type": "gm-block", "index": new_block_id},
id={"type": "gm-filter-block", "index": new_block_id},
children=[
dmc.GridCol(
html.Div(
[
dbc.Button(
[html.I(className="fas fa-plus")],
id={"type": "gm-add-button", "index": new_block_id},
id={"type": "gm-filter-add-button", "index": new_block_id},
className="btn-primary",
),
html.Label(
"OR",
id={"type": "gm-or-label", "index": new_block_id},
id={"type": "gm-filter-or-label", "index": new_block_id},
className="ms-2 px-2 py-1 rounded",
style={
"color": "green",
Expand All @@ -347,20 +357,23 @@ def display_blocks(blocks_id: list[str], existing_blocks: list[dmc.Grid]) -> lis
dcc.Dropdown(
options=GM_DROPDOWN_MENU_OPTIONS,
value="GCF_ID",
id={"type": "gm-dropdown-menu", "index": new_block_id},
id={"type": "gm-filter-dropdown-menu", "index": new_block_id},
clearable=False,
),
span=4,
),
dmc.GridCol(
[
dmc.TextInput(
id={"type": "gm-dropdown-ids-text-input", "index": new_block_id},
id={"type": "gm-filter-dropdown-ids-text-input", "index": new_block_id},
placeholder="1, 2, 3, ...",
className="custom-textinput",
),
dcc.Dropdown(
id={"type": "gm-dropdown-bgc-class-dropdown", "index": new_block_id},
id={
"type": "gm-filter-dropdown-bgc-class-dropdown",
"index": new_block_id,
},
options=GM_DROPDOWN_BGC_CLASS_OPTIONS,
multi=True,
style={"display": "none"},
Expand All @@ -387,15 +400,15 @@ def display_blocks(blocks_id: list[str], existing_blocks: list[dmc.Grid]) -> lis


@app.callback(
Output({"type": "gm-dropdown-ids-text-input", "index": MATCH}, "style"),
Output({"type": "gm-dropdown-bgc-class-dropdown", "index": MATCH}, "style"),
Output({"type": "gm-dropdown-ids-text-input", "index": MATCH}, "placeholder"),
Output({"type": "gm-dropdown-bgc-class-dropdown", "index": MATCH}, "placeholder"),
Output({"type": "gm-dropdown-ids-text-input", "index": MATCH}, "value"),
Output({"type": "gm-dropdown-bgc-class-dropdown", "index": MATCH}, "value"),
Input({"type": "gm-dropdown-menu", "index": MATCH}, "value"),
Output({"type": "gm-filter-dropdown-ids-text-input", "index": MATCH}, "style"),
Output({"type": "gm-filter-dropdown-bgc-class-dropdown", "index": MATCH}, "style"),
Output({"type": "gm-filter-dropdown-ids-text-input", "index": MATCH}, "placeholder"),
Output({"type": "gm-filter-dropdown-bgc-class-dropdown", "index": MATCH}, "placeholder"),
Output({"type": "gm-filter-dropdown-ids-text-input", "index": MATCH}, "value"),
Output({"type": "gm-filter-dropdown-bgc-class-dropdown", "index": MATCH}, "value"),
Input({"type": "gm-filter-dropdown-menu", "index": MATCH}, "value"),
)
def update_placeholder(
def gm_filter_update_placeholder(
selected_value: str,
) -> tuple[dict[str, str], dict[str, str], str, str, str, list[Any]]:
"""Update the placeholder text and style of input fields based on the dropdown selection.
Expand Down Expand Up @@ -425,7 +438,7 @@ def update_placeholder(
return {"display": "none"}, {"display": "none"}, "", "", "", []


def apply_filters(
def gm_filter_apply(
df: pd.DataFrame,
dropdown_menus: list[str],
text_inputs: list[str],
Expand Down Expand Up @@ -470,16 +483,16 @@ def apply_filters(
Output("gm-table", "tooltip_data"),
Output("gm-table-card-body", "style"),
Output("gm-table", "selected_rows", allow_duplicate=True),
Output("select-all-checkbox", "value"),
Output("gm-table-select-all-checkbox", "value"),
Input("processed-data-store", "data"),
Input("apply-filters-button", "n_clicks"),
State({"type": "gm-dropdown-menu", "index": ALL}, "value"),
State({"type": "gm-dropdown-ids-text-input", "index": ALL}, "value"),
State({"type": "gm-dropdown-bgc-class-dropdown", "index": ALL}, "value"),
State("select-all-checkbox", "value"),
Input("gm-filter-apply-button", "n_clicks"),
State({"type": "gm-filter-dropdown-menu", "index": ALL}, "value"),
State({"type": "gm-filter-dropdown-ids-text-input", "index": ALL}, "value"),
State({"type": "gm-filter-dropdown-bgc-class-dropdown", "index": ALL}, "value"),
State("gm-table-select-all-checkbox", "value"),
prevent_initial_call=True,
)
def update_datatable(
def gm_table_update_datatable(
processed_data: str | None,
n_clicks: int | None,
dropdown_menus: list[str],
Expand Down Expand Up @@ -509,9 +522,9 @@ def update_datatable(
except (json.JSONDecodeError, KeyError, pd.errors.EmptyDataError):
return [], [], [], {"display": "none"}, [], []

if ctx.triggered_id == "apply-filters-button":
if ctx.triggered_id == "gm-filter-apply-button":
# Apply filters only when the button is clicked
filtered_df = apply_filters(df, dropdown_menus, text_inputs, bgc_class_dropdowns)
filtered_df = gm_filter_apply(df, dropdown_menus, text_inputs, bgc_class_dropdowns)
# Reset the checkbox when filters are applied
new_checkbox_value = []
else:
Expand Down Expand Up @@ -550,12 +563,12 @@ def update_datatable(

@app.callback(
Output("gm-table", "selected_rows", allow_duplicate=True),
Input("select-all-checkbox", "value"),
Input("gm-table-select-all-checkbox", "value"),
State("gm-table", "data"),
State("gm-table", "derived_virtual_data"),
prevent_initial_call=True,
)
def toggle_selection(
def gm_table_toggle_selection(
value: list | None,
original_rows: list,
filtered_rows: list | None,
Expand Down Expand Up @@ -588,7 +601,9 @@ def toggle_selection(
Input("gm-table", "derived_virtual_data"),
Input("gm-table", "derived_virtual_selected_rows"),
)
def select_rows(rows: list[dict[str, Any]], selected_rows: list[int] | None) -> tuple[str, str]:
def gm_table_select_rows(
rows: list[dict[str, Any]], selected_rows: list[int] | None
) -> tuple[str, str]:
"""Display the total number of rows and the number of selected rows in the table.
Args:
Expand Down
27 changes: 13 additions & 14 deletions app/layouts.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,35 +73,34 @@


# ------------------ Tabs ------------------ #
# dropdown menu items
initial_block_id = str(uuid.uuid4())
gm_input_group = html.Div(
# gm filter dropdown menu items
gm_filter_input_group = html.Div(
[
dcc.Store(id="blocks-id", data=[]), # Start with one block
dcc.Store(id="gm-filter-blocks-id", data=[]), # Start with one block
html.Div(
id="blocks-container",
id="gm-filter-blocks-container",
children=[],
),
]
)
# gm accordion (filter) card
gm_accordion = dmc.Accordion(
# gm filter (accordion) card
gm_filter_accordion = dmc.Accordion(
[
dmc.AccordionItem(
[
dmc.AccordionControl(
"Genomics filter",
disabled=True,
id="gm-accordion-control",
id="gm-filter-accordion-control",
className="mt-5 mb-3",
),
dmc.AccordionPanel(
[
gm_input_group,
gm_filter_input_group,
html.Div(
dbc.Button(
"Apply Filters",
id="apply-filters-button",
id="gm-filter-apply-button",
color="primary",
className="mt-3",
),
Expand All @@ -110,7 +109,7 @@
]
),
],
value="gm-accordion",
value="gm-filter-accordion",
),
],
className="mt-5 mb-3",
Expand All @@ -132,7 +131,7 @@
html.Div(
dcc.Checklist(
options=[{"label": "", "value": "disabled"}],
id="select-all-checkbox",
id="gm-table-select-all-checkbox",
style={
"position": "absolute",
"top": "4px",
Expand Down Expand Up @@ -204,7 +203,7 @@
# gm tab content
gm_content = dbc.Row(
[
dbc.Col(gm_accordion, width=10, className="mx-auto dbc"),
dbc.Col(gm_filter_accordion, width=10, className="mx-auto dbc"),
dbc.Col(gm_graph, width=10, className="mx-auto"),
dbc.Col(gm_table, width=10, className="mx-auto"),
]
Expand All @@ -213,7 +212,7 @@
mg_content = dbc.Row(
dbc.Col(
dbc.Card(
dbc.CardBody([html.Div(id="file-content-mg")]),
dbc.CardBody([html.Div(id="mg-file-content")]),
)
),
)
Expand Down
Loading

0 comments on commit e214374

Please sign in to comment.