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

Add cardinality check button to RACK UI #990

Merged
merged 5 commits into from
Aug 8, 2023
Merged
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
117 changes: 70 additions & 47 deletions rack-ui/pages/verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
DEFAULT_GRAPH_NAME = "uri://DefaultGraph"

# dialog confirming ASSIST verification done
verify_assist_done_dialog = dbc.Modal(
verify_assist_done_dialog = dbc.Spinner(dbc.Modal(
[
dbc.ModalBody("MESSAGE PLACEHOLDER", id="verify-assist-done-dialog-body"), # message
dbc.ModalFooter([
Expand All @@ -24,32 +24,32 @@
id="verify-assist-done-dialog",
is_open=False,
backdrop=False,
)
))

# div showing graphs list
verify_report_options_div = dbc.Spinner(html.Div(
select_graphs_div = dbc.Spinner(html.Div(
[
dcc.Markdown("Select graphs to include in report:"),
dcc.Markdown("Select graphs to include:"),
dcc.Checklist([], [], id="verify-graph-checklist", labelStyle={'display': 'block'}), # choose which graphs to verify
dbc.Row([
dbc.Col(html.Button("Continue", id="verify-report-continue-button", n_clicks=0), width="auto"), # button to open SPARQLgraph report
dbc.Col(html.Button("Cancel", id="verify-report-cancel-button", n_clicks=0), width="auto") # button to cancel
dbc.Col(html.Button("Continue", id="select-graphs-continue-button", n_clicks=0), width="auto"), # button to open SPARQLgraph
dbc.Col(html.Button("Cancel", id="select-graphs-cancel-button", n_clicks=0), width="auto") # button to cancel
])
],
id="verify-report-options-div",
id="select-graphs-div",
hidden=True,
style={"margin-top": "50px"},
))

# dialog indicating an error generating the SPARQLgraph report (e.g. no graphs selected)
verify_report_error_dialog = dbc.Modal(
# dialog indicating an error generating the SPARQLgraph link (e.g. no graphs selected)
sg_link_error_dialog = dbc.Modal(
[
dbc.ModalBody("MESSAGE PLACEHOLDER", id="verify-report-error-dialog-body"), # message
dbc.ModalBody("MESSAGE PLACEHOLDER", id="sg-link-error-dialog-body"), # message
dbc.ModalFooter([
html.Button("Close", id="verify-report-error-button", n_clicks=0) # close button
html.Button("Close", id="sg-link-error-button", n_clicks=0) # close button
]),
],
id="verify-report-error-dialog",
id="sg-link-error-dialog",
is_open=False,
backdrop=False,
)
Expand All @@ -59,17 +59,20 @@
html.H2('Verify Data'),
dcc.Markdown("_Run verification routines on the data loaded in RACK_"),
dbc.Row([
dbc.Col(html.Button("Verify using ASSIST", id="verify-assist-button", n_clicks=0), width="auto"), # button to verify using ASSIST
dbc.Col(html.Button("Verify using report", id="verify-report-button"), width="auto") # button to verify using SPARQLgraph report
dbc.Col(html.Button("Data verification report", id="verify-report-button"), width="auto"), # button to verify using SPARQLgraph data verification report
dbc.Col(html.Button("Cardinality checker", id="cardinality-button"), width="auto"), # button to check cardinality via SPARQLgraph
dbc.Col(html.Button("ASSIST-DV", id="verify-assist-button", n_clicks=0), width="auto") # button to verify using ASSIST
]),
dbc.Tooltip("Run the ASSIST tool and download an error report", target="verify-assist-button"),
dbc.Tooltip("Open SPARQLgraph and run data verification report on selected graphs", target="verify-report-button"),
verify_report_options_div,
dbc.Tooltip("Run the ASSIST-DV tool and download an error report", target="verify-assist-button"),
dbc.Tooltip("Run SPARQLgraph data verification report on selected graphs", target="verify-report-button"),
dbc.Tooltip("Run SPARQLgraph cardinality checker on selected graphs", target="cardinality-button"),
select_graphs_div,
html.Div(id="assist-status-div", className="scrollarea"), # displays status
verify_assist_done_dialog,
verify_report_error_dialog,
sg_link_error_dialog,
dcc.Store("assist-status-filepath"), # stores the filename of the temp file containing status
dcc.Store("sparqlgraph-url"), # stores the URL of the SPARQLgraph report
dcc.Store("report-vs-cardinality"), # stores user choice of SPARQLgraph report or cardinality
dbc.Spinner(dcc.Store("sparqlgraph-url")), # stores the SPARQLgraph URL. Show spinner while generating it.
dcc.Store(id="clientside-dummy-store"), # dummy store because callback needs an Output
dcc.Interval(id='assist-status-interval', interval=0.5*1000, n_intervals=0, disabled=True), # triggers updating the status display
])
Expand All @@ -84,6 +87,7 @@
running=[
(Output("verify-report-button", "disabled"), True, False), # disable the button while running
(Output("verify-assist-button", "disabled"), True, False), # disable the button while running
(Output("cardinality-button", "disabled"), True, False), # disable the button while running
],
prevent_initial_call=True
)
Expand All @@ -103,6 +107,7 @@ def create_assist_status_filepath(n_clicks):
running=[
(Output("verify-report-button", "disabled"), True, False), # disable the button while running
(Output("verify-assist-button", "disabled"), True, False), # disable the button while running
(Output("cardinality-button", "disabled"), True, False), # disable the button while running
(Output("assist-status-interval", "disabled"), False, True) # enable the interval component while running
],
prevent_initial_call=True
Expand Down Expand Up @@ -161,26 +166,37 @@ def download_assist_results(n_clicks, status_filepath):
return dict(content=file_content, filename="rack_verification_results.txt")


####### callbacks for SPARQLgraph report verification ######################################
####### callbacks for SPARQLgraph report / cardinality ######################################


@dash.callback(
output=[
Output("report-vs-cardinality", "data"), # remember whether user wanted SPARQLgraph report or cardinality
Output("verify-graph-checklist", "options"), # list of graphs populated in the triple store
Output("verify-graph-checklist", "value")], # list of graphs to pre-select (graphs recently loaded)
inputs=Input("verify-report-button", "n_clicks"), # triggered by user clicking button
inputs=[
Input("verify-report-button", "n_clicks"), # triggered by user clicking buttons
Input("cardinality-button", "n_clicks")],
state=State("last-loaded-graphs", "data"), # last loaded graphs
background=True, # background callback
running=[
(Output("verify-report-button", "disabled"), True, False), # disable the run button while running
(Output("verify-report-button", "disabled"), True, False), # disable the button while running
(Output("verify-assist-button", "disabled"), True, False), # disable the button while running
(Output("cardinality-button", "disabled"), True, False), # disable the button while running
],
prevent_initial_call=True
)
def show_report_options(button_clicks, last_loaded_graphs):
def show_graphs_checklist(report_button_clicks, cardinality_button_clicks, last_loaded_graphs):
"""
Show list of graphs for verification report, with the last loaded graphs pre-selected
Show list of graphs for generating SPARQLgraph link, with the last loaded graphs pre-selected
"""

# remember which button triggered this: report or cardinality
if (get_trigger() == "verify-report-button.n_clicks"):
report_vs_cardinality = True # user wants report
else:
report_vs_cardinality = False # user wants cardinality

# get list of graphs populated in the triple store
graphs_list_values = get_graph_info().get_column(0) # list of graphs, including uri://DefaultGraph
graphs_list_labels = list(map(lambda x: x.replace(DEFAULT_GRAPH_NAME, 'Optimized graph'), graphs_list_values.copy())) # display default graph as "Optimized graph"
Expand All @@ -190,24 +206,27 @@ def show_report_options(button_clicks, last_loaded_graphs):
if last_loaded_graphs is None:
last_loaded_graphs = []

return graphs_list, last_loaded_graphs
return report_vs_cardinality, graphs_list, last_loaded_graphs


@dash.callback(
output=[Output("sparqlgraph-url", "data"), # output SPARQLgraph report URL
Output("verify-report-error-dialog-body", "children")], # output error message
inputs=Input("verify-report-continue-button", "n_clicks"), # triggered by clicking continue button
state=State("verify-graph-checklist", "value"), # the currently selected graphs
output=[Output("sparqlgraph-url", "data"), # output SPARQLgraph URL
Output("sg-link-error-dialog-body", "children")], # output error message
inputs=Input("select-graphs-continue-button", "n_clicks"), # triggered by clicking continue button
state=[
State("report-vs-cardinality", "data"), # true for report, false for cardinality
State("verify-graph-checklist", "value")], # the currently selected graphs
background=True, # background callback
running=[
(Output("verify-report-button", "disabled"), True, False), # disable the button while running
(Output("verify-assist-button", "disabled"), True, False), # disable the button while running
(Output("cardinality-button", "disabled"), True, False), # disable the button while running
],
prevent_initial_call=True
)
def generate_report_link(sg_button_clicks, graphs_selected):
def generate_sg_link(sg_button_clicks, report_vs_cardinality, graphs_selected):
"""
Generate the SPARQLgraph report link
Generate the SPARQLgraph link
"""
# error if no graphs were selected
if len(graphs_selected) == 0:
Expand All @@ -219,14 +238,17 @@ def generate_report_link(sg_button_clicks, graphs_selected):
graphs.append(graph)
conn = semtk3.build_connection_str("Graphs To Verify", rack.DEFAULT_TRIPLE_STORE_TYPE, rack.DEFAULT_TRIPLE_STORE, graphs, graphs[0], graphs[1:]) # use all graphs for both model and data, to avoid either being empty

# construct SG report URL
sparqlgraph_verify_url_str = semtk3.get_sparqlgraph_url(SPARQLGRAPH_BASE_URL, conn_json_str=str(conn), report_id="report data verification")
# construct SG URL
if(report_vs_cardinality):
sparqlgraph_verify_url_str = semtk3.get_sparqlgraph_url(SPARQLGRAPH_BASE_URL, conn_json_str=str(conn), report_id="report data verification") # URL to generate report
else:
sparqlgraph_verify_url_str = semtk3.get_sparqlgraph_url(SPARQLGRAPH_BASE_URL, conn_json_str=str(conn), explore_restrictions=True) # URL to explore cardinality

# return SPARQLgraph report URL
# return SPARQLgraph URL
return sparqlgraph_verify_url_str, None


# Open a browser tab with SPARQLgraph report (this is a clientside callback written in JavaScript: https://dash.plotly.com/clientside-callbacks)
# Open a browser tab with SPARQLgraph link (this is a clientside callback written in JavaScript: https://dash.plotly.com/clientside-callbacks)
dash.clientside_callback(
"""
function(url) {
Expand All @@ -248,25 +270,26 @@ def generate_report_link(sg_button_clicks, graphs_selected):
@callback(Output("assist-status-div", "hidden"),
Input("verify-assist-button", "n_clicks"),
Input("verify-report-button", "n_clicks"),
Input("cardinality-button", "n_clicks"),
prevent_initial_call=True
)
def manage_assist_status_div(assist_clicks, report_clicks):
def manage_assist_status_div(assist_clicks, report_clicks, cardinality_clicks):
""" Show or hide the ASSIST status div """
if (get_trigger() in ["verify-assist-button.n_clicks"]):
return False # user clicked ASSIST, show the div
else:
return True # user clicked report, hide the div
return True # user clicked other button, hide the div


@callback(Output("verify-report-options-div", "hidden"),
@callback(Output("select-graphs-div", "hidden"),
Input("verify-graph-checklist", "options"),
Input("verify-assist-button", "n_clicks"),
Input("verify-report-cancel-button", "n_clicks"),
Input("select-graphs-cancel-button", "n_clicks"),
prevent_initial_call=True
)
def manage_verify_report_options_div(checklist_options, continue_clicks, cancel_clicks):
def manage_select_graphs_div(checklist_options, continue_clicks, cancel_clicks):
""" Show or hide the graph checklist div """
if (get_trigger() in ["verify-assist-button.n_clicks", "verify-report-cancel-button.n_clicks"]):
if (get_trigger() in ["verify-assist-button.n_clicks", "select-graphs-cancel-button.n_clicks"]):
return True # continue or cancel button pressed, hide div
elif checklist_options == []:
return True # no checklist options provided, don't show div
Expand All @@ -287,14 +310,14 @@ def manage_verify_assist_done_dialog(children, n_clicks):
return True # child added, show the dialog


@callback(Output("verify-report-error-dialog", "is_open"),
Input("verify-report-error-dialog-body", "children"),
Input("verify-report-error-button", "n_clicks"),
@callback(Output("sg-link-error-dialog", "is_open"),
Input("sg-link-error-dialog-body", "children"),
Input("sg-link-error-button", "n_clicks"),
prevent_initial_call=True
)
def manage_verify_report_error_dialog(children, n_clicks):
""" Show or hide the SPARQLgraph report error dialog (e.g. if no graphs selected) """
if (get_trigger() == "verify-report-error-button.n_clicks"):
def manage_sg_link_error_dialog(children, n_clicks):
""" Show or hide the SPARQLgraph link error dialog (e.g. if no graphs selected) """
if (get_trigger() == "sg-link-error-button.n_clicks"):
return False # button pressed, hide the dialog
else:
if children is None:
Expand Down