Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change select groups modal loading behaviour #208

Merged
merged 2 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
# callbacks.
external_scripts=[
"https://code.jquery.com/jquery-2.2.4.min.js",
"https://code.jquery.com/ui/1.12.1/jquery-ui.min.js",
"https://code.jquery.com/ui/1.11.4/jquery-ui.min.js",
],
# We can use bootstrap CSS.
# https://bit.ly/3tMqY0W for details.
Expand Down Expand Up @@ -590,54 +590,59 @@ def update_hidden_strains(_, deleted_strain, checkbox_ids, checkbox_vals,


@app.callback(
Output("select-lineages-modal", "is_open"),
Output("select-lineages-modal-body", "children"),
Input("get-data-args", "data"),
State("last-data-mtime", "data"),
prevent_initial_call=True
)
def update_select_lineages_modal_body(get_data_args, last_data_mtime):
"""Populate select lineages modal body.

This is triggered behind the scenes without opening the modal, and
whenever the data is updated.

:param get_data_args: Args for ``get_data``
:type get_data_args: dict
:param last_data_mtime: Last mtime across all data files
:type last_data_mtime: float
:return: Content representing the select lineages modal body
:rtype: list[dbc.FormGroup]
"""
data = read_data(get_data_args, last_data_mtime)
return toolbar_generator.get_select_lineages_modal_body(data)


@app.callback(
Output("select-lineages-modal", "is_open"),
Output("select-lineages-modal-loading", "children"),
Input("open-select-lineages-modal-btn", "n_clicks"),
Input("select-lineages-ok-btn", "n_clicks"),
Input("select-lineages-cancel-btn", "n_clicks"),
Input("deleted-strain", "data"),
State("get-data-args", "data"),
State("last-data-mtime", "data"),
prevent_initial_call=True
)
def toggle_select_lineages_modal(_, __, ___, ____, get_data_args,
last_data_mtime):
def toggle_select_lineages_modal(_, __, ___, ____):
"""Open or close select lineages modal.

Not only is this function in charge of opening or closing the
select lineages modal, it is also in charge of dynamically
populating the select lineages modal body when the modal is opened.

This is a little slow to open, so we return
``select-lineages-modal-loading`` to add a spinner.

:param _: Select lineages button in toolbar was clicked
:param __: OK button in select lineages modal was clicked
:param ___: Cancel button in select lineages modal was clicked
:param ____: OK button in confirm strain deletion modal was clicked
:param get_data_args: Args for ``get_data``
:type get_data_args: dict
:param last_data_mtime: Last mtime across all data files
:type last_data_mtime: float
:return: Boolean representing whether the select lineages modal is
open or closed, content representing the select lineages
modal body, and ``select-lineages-modal-loading`` children.
:rtype: (bool, list[dbc.FormGroup])
open or closed, and ``select-lineages-modal-loading`` children.
:rtype: (bool, bool)
"""
# Current ``get_data`` return val
data = read_data(get_data_args, last_data_mtime)

ctx = dash.callback_context
triggered_prop_id = ctx.triggered[0]["prop_id"]
# We only open the modal when the select lineages modal btn in the
# toolbar is clicked.
if triggered_prop_id == "open-select-lineages-modal-btn.n_clicks":
modal_body = toolbar_generator.get_select_lineages_modal_body(data)
return True, modal_body, None
return True, None
else:
# No need to populate modal body if the modal is closed
return False, None, None
return False, None


@app.callback(
Expand Down Expand Up @@ -1410,7 +1415,8 @@ def update_data(get_data_args, last_data_mtime):
function_name="makeSelectLineagesModalCheckboxesDraggable"
),
Output("make-select-lineages-modal-checkboxes-draggable", "data"),
Input({"type": "select-lineages-modal-checklist", "index": ALL}, "id"),
Input("select-lineages-modal", "is_open"),
State({"type": "select-lineages-modal-checklist", "index": ALL}, "id"),
prevent_initial_call=True
)
app.clientside_callback(
Expand Down
3 changes: 2 additions & 1 deletion assets/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ window.dash_clientside = Object.assign({}, window.dash_clientside, {
/**
* Make the checkboxes in the select lineage modal draggable within their
* respective form groups, using the JQuery UI sortable plugin.
* @param _ Select lineages modal was opened.
* @param {Array<Object>} idArray Dash pattern matching id values for
* checkboxes in select lineages modal.
* @return {Boolean} ``true`` if we successfully made the checkboxes
* draggable.
*/
makeSelectLineagesModalCheckboxesDraggable: (idArray) => {
makeSelectLineagesModalCheckboxesDraggable: (_, idArray) => {
// This function responds to all changes in the select lineages modal
// body. But the checkboxes disappear when the modal is closed, so we
// should do nothing when that happens.
Expand Down
10 changes: 6 additions & 4 deletions generators/toolbar_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def get_toolbar_row(data):
className="my-auto pl-xl-5",
width=2
),
get_select_lineages_modal(),
get_select_lineages_modal(data),
get_confirm_strain_del_modal(),
get_jump_to_modal()
],
Expand All @@ -87,19 +87,21 @@ def get_select_lineages_toolbar_btn():
className="mr-2")


def get_select_lineages_modal():
def get_select_lineages_modal(data):
"""Returns select lineages modal.

This modal is initially closed, and the body is empty.
This modal is initially closed.

:param data: ``get_data`` return value
:type data: dict
:return: Initially closed Dash Bootstrap Components modal for
selecting lineages.
:rtype: dbc.Modal
"""
return dbc.Modal([
dbc.ModalHeader("Select sample groups"),
# Empty at launch; populated when user opens modal
dbc.ModalBody(None,
dbc.ModalBody(get_select_lineages_modal_body(data),
id="select-lineages-modal-body",
style={"height": "50vh", "overflowY": "scroll"}),
dbc.ModalFooter(get_select_lineages_modal_footer())
Expand Down