diff --git a/tests/views/test_parameter_selector.py b/tests/views/test_parameter_selector.py index 7721e948..201d6ed3 100644 --- a/tests/views/test_parameter_selector.py +++ b/tests/views/test_parameter_selector.py @@ -52,9 +52,7 @@ def test_parameter_selector( ) assert parameter_selector_container.is_displayed() is True - button_hide = dash_duo.find_element( - "#" + plugin.uuid("parameter-selector-button-param") - ) + button_hide = dash_duo.find_element("#" + plugin.uuid("parameter-selector-button")) button_hide.click() parameter_selector_container = dash_duo.wait_for_element_by_css_selector( ".ert-parameter-selector-container-hide" diff --git a/tests/views/test_plot_view.py b/tests/views/test_plot_view.py index 59f33420..20a5ccfc 100644 --- a/tests/views/test_plot_view.py +++ b/tests/views/test_plot_view.py @@ -1,4 +1,5 @@ import pytest +import dash from webviz_ert.plugins._response_comparison import ResponseComparison from tests.conftest import ( setup_plugin, @@ -7,6 +8,12 @@ select_response, wait_a_bit, ) +from webviz_ert.plugins import ( + ResponseComparison, + ObservationAnalyzer, + ParameterComparison, + ResponseCorrelation, +) def test_plot_view( @@ -155,3 +162,51 @@ def test_displaying_beta_warning(input: bool, dash_duo): plugin = setup_plugin(dash_duo, __name__, ResponseComparison, beta=input) beta_warning_element = dash_duo.find_element("#" + plugin.uuid("beta-warning")) assert beta_warning_element.is_displayed() == input + + +skip_responses = "resp" +skip_parameters = "param" + + +@pytest.mark.parametrize( + "plugin_class,skip", + [ + pytest.param(ResponseComparison, [], id="ResponseComparison"), + pytest.param( + ObservationAnalyzer, + [skip_responses, skip_parameters], + id="ObservationAnalyzer", + ), + pytest.param(ParameterComparison, [skip_responses], id="ParameterComparison"), + pytest.param(ResponseCorrelation, [], id="ResponseCorrelation"), + ], +) +def test_selectors_visibility_toggle_button(plugin_class, skip, mock_data, dash_duo): + # we test whether the selector visibility toggle button changes class on + # all selectors, as expected + + def check_element_is_hidden(find_by: str) -> None: + element = dash_duo.find_element(find_by) + assert "hide" in element.get_attribute("class") + + plugin = setup_plugin(dash_duo, __name__, plugin_class, (2048, 1536)) + app = dash.Dash(__name__) + + visibility_toggler = dash_duo.find_element( + "#" + plugin.uuid("parameter-selector-button") + ) + visibility_toggler.click() + + check_element_is_hidden("#" + plugin.uuid("container-ensemble-selector-multi")) + + if not skip_responses in skip: + check_element_is_hidden( + "#" + plugin.uuid("container-parameter-selector-multi-resp") + ) + + if not skip_parameters in skip: + check_element_is_hidden( + "#" + plugin.uuid("container-parameter-selector-multi-param") + ) + + # assert dash_duo.get_logs() == [], "browser console should contain no error" diff --git a/webviz_ert/assets/ert-style.css b/webviz_ert/assets/ert-style.css index b73e2712..023db029 100644 --- a/webviz_ert/assets/ert-style.css +++ b/webviz_ert/assets/ert-style.css @@ -4,10 +4,10 @@ .ert-plot-options { height: 84px !important; } -.ert-parameter-selector-container-hide { +.ert-parameter-selector-container-hide, .ert-ensemble-selector-container-hide { display: none; } -.ert-parameter-selector-container-show { +.ert-parameter-selector-container-show, .ert-ensemble-selector-container-show { display: block; } .ert-parameter-label-checkbox { @@ -61,3 +61,7 @@ background-color: rgba(191,91,23,0.8); color: black; } + +.webviz-config-select { + height: 15rem; +} diff --git a/webviz_ert/controllers/ensemble_selector_controller.py b/webviz_ert/controllers/ensemble_selector_controller.py index 014002e4..84fbcf5c 100644 --- a/webviz_ert/controllers/ensemble_selector_controller.py +++ b/webviz_ert/controllers/ensemble_selector_controller.py @@ -110,3 +110,35 @@ def set_callback( [], ensemble_selection_store, ] + + container_ensemble_selector_multi_id = parent.uuid( + "container-ensemble-selector-multi" + ) + parameter_selector_button_id = parent.uuid(f"parameter-selector-button") + + @app.callback( + [ + Output(container_ensemble_selector_multi_id, "className"), + Output(parameter_selector_button_id, "children"), + ], + [ + Input(parameter_selector_button_id, "n_clicks"), + Input(parameter_selector_button_id, "children"), + ], + [ + State(container_ensemble_selector_multi_id, "className"), + ], + ) + def toggle_selector_visibility( + _: int, button_text: str, class_name: str + ) -> List[str]: + ctx = dash.callback_context + triggered_id = ctx.triggered[0]["prop_id"].split(".")[0] + if triggered_id == parameter_selector_button_id: + if class_name == "ert-ensemble-selector-container-hide": + class_name = "ert-ensemble-selector-container-show" + button_text = "Hide Selectors" + else: + class_name = "ert-ensemble-selector-container-hide" + button_text = "Show Selectors" + return [class_name, button_text] diff --git a/webviz_ert/controllers/parameter_selector_controller.py b/webviz_ert/controllers/parameter_selector_controller.py index ddc8756e..e0ab710c 100644 --- a/webviz_ert/controllers/parameter_selector_controller.py +++ b/webviz_ert/controllers/parameter_selector_controller.py @@ -139,7 +139,7 @@ def update_parameter_options( container_parameter_selector_multi_id = parent.uuid( f"container-parameter-selector-multi-{data_type}" ) - parameter_selector_button_id = parent.uuid(f"parameter-selector-button-{data_type}") + parameter_selector_button_id = parent.uuid(f"parameter-selector-button") @app.callback( Output(container_parameter_selector_multi_id, "className"), diff --git a/webviz_ert/plugins/_parameter_comparison.py b/webviz_ert/plugins/_parameter_comparison.py index 8883ad16..4f99229e 100644 --- a/webviz_ert/plugins/_parameter_comparison.py +++ b/webviz_ert/plugins/_parameter_comparison.py @@ -1,8 +1,10 @@ import dash +import dash_bootstrap_components as dbc import webviz_ert.controllers import webviz_ert.models from dash.development.base_component import Component from typing import List, Dict + from webviz_ert.views import ( ensemble_selector_list, parallel_coordinates_view, @@ -36,19 +38,32 @@ def layout(self) -> Component: ], hidden=not self.beta, ), - dash.html.Div( - id=self.uuid("ensemble-content"), - children=ensemble_selector_list(parent=self), - ), - dash.html.Div( - id=self.uuid("parallel-coor-content"), - children=[ - dash.html.H5("Multi parameter selector:"), - parameter_selector_view( - parent=self, data_type=DataType.PARAMETER + dbc.Row( + [ + dbc.Col( + id=self.uuid("ensemble-content"), + children=ensemble_selector_list(parent=self), + width=6, ), - parallel_coordinates_view(parent=self), - ], + dbc.Col( + id=self.uuid("parameter-content"), + children=[ + parameter_selector_view( + parent=self, data_type=DataType.PARAMETER + ), + ], + width=6, + ), + ] + ), + dbc.Row( + dbc.Col( + id=self.uuid("parallel-coor-content"), + children=[ + parallel_coordinates_view(parent=self), + ], + width=12, + ) ), ] ) diff --git a/webviz_ert/plugins/_response_comparison.py b/webviz_ert/plugins/_response_comparison.py index 86d5bb0b..9e7bec4b 100644 --- a/webviz_ert/plugins/_response_comparison.py +++ b/webviz_ert/plugins/_response_comparison.py @@ -37,10 +37,6 @@ def layout(self) -> Component: ], hidden=not self.beta, ), - dash.html.Div( - id=self.uuid("ensemble-content"), - children=ensemble_selector_list(parent=self), - ), dash.html.Div( children=plot_view_header(parent=self), ), diff --git a/webviz_ert/plugins/_response_correlation.py b/webviz_ert/plugins/_response_correlation.py index c096ce57..6fb266b8 100644 --- a/webviz_ert/plugins/_response_correlation.py +++ b/webviz_ert/plugins/_response_correlation.py @@ -101,17 +101,19 @@ def layout(self) -> Component: ), storage_type="session", ), - dash.html.Div( - id=self.uuid("ensemble-content"), - children=ensemble_selector_list(parent=self), - ), dbc.Row( [ + dbc.Col( + id=self.uuid("ensemble-content"), + children=ensemble_selector_list(parent=self), + width=4, + ), dbc.Col( [ - dash.html.Label("Responses", className="ert-label"), parameter_selector_view( - self, data_type=DataType.RESPONSE + self, + data_type=DataType.RESPONSE, + titleLabel="Responses", ), dash.dcc.Checklist( id=self.uuid("response-observations-check"), @@ -125,16 +127,17 @@ def layout(self) -> Component: labelStyle={"display": "block"}, ), ], - width=6, + width=4, ), dbc.Col( [ - dash.html.Label("Parameters", className="ert-label"), parameter_selector_view( - self, data_type=DataType.PARAMETER + self, + data_type=DataType.PARAMETER, + titleLabel="Parameters", ), ], - width=6, + width=4, ), ], ), diff --git a/webviz_ert/views/ensemble_selector_view.py b/webviz_ert/views/ensemble_selector_view.py index fb14b04c..d53b90f5 100644 --- a/webviz_ert/views/ensemble_selector_view.py +++ b/webviz_ert/views/ensemble_selector_view.py @@ -11,37 +11,45 @@ def ensemble_selector_list(parent: WebvizErtPluginABC) -> List[Component]: return [ html.Div( - [ - dbc.Row( - [ - dbc.Col( - [ - html.Label("Ensembles", className="ert-label"), - wcc.Select( - id=parent.uuid("ensemble-multi-selector"), - multi=True, - size=10, - persistence=True, - persistence_type="session", - options=[], - value=[], - ), - ], - align="left", + dbc.Row( + [ + dbc.Col( + html.H6("Ensembles", className="ert-label"), + align="left", + width="auto", + ), + dbc.Col( + html.Button( + id=parent.uuid(f"ensemble-refresh-button"), + children="Refresh", + n_clicks=0, ), - dbc.Col( - html.Button( - id=parent.uuid(f"ensemble-refresh-button"), - children="Refresh", - n_clicks=0, - ), - align="right", - width=2, + align="right", + ), + dbc.Col( + html.Button( + id=parent.uuid(f"parameter-selector-button"), + children=("Hide Selectors"), ), - ], - ), - ], - id=parent.uuid("ensemble-multi-selector-container"), + align="right", + width="auto", + ), + ], + align="center", + ) + ), + html.Div( + wcc.Select( + id=parent.uuid("ensemble-multi-selector"), + multi=True, + size=10, + persistence=True, + persistence_type="session", + options=[], + value=[], + ), + id=parent.uuid("container-ensemble-selector-multi"), + className="ert-ensemble-selector-container-show", ), dcc.Dropdown( id=parent.uuid("selected-ensemble-dropdown"), diff --git a/webviz_ert/views/plot_view.py b/webviz_ert/views/plot_view.py index d249ccf0..55d7cba1 100644 --- a/webviz_ert/views/plot_view.py +++ b/webviz_ert/views/plot_view.py @@ -4,19 +4,29 @@ from dash import html from dash import dcc +import webviz_core_components as wcc import dash_bootstrap_components as dbc from .selector_view import parameter_selector_view from webviz_ert.models.data_model import DataType +from .ensemble_selector_view import ensemble_selector_list def plot_view_header(parent: WebvizErtPluginABC) -> List[Component]: return [ dbc.Row( [ + dbc.Col( + id=parent.uuid("ensemble-content"), + children=ensemble_selector_list(parent=parent), + width=4, + ), dbc.Col( [ - html.Label("Responses", className="ert-label"), - parameter_selector_view(parent, data_type=DataType.RESPONSE), + parameter_selector_view( + parent, + data_type=DataType.RESPONSE, + titleLabel="Responses", + ), dcc.Checklist( id=parent.uuid("response-observations-check"), options=[ @@ -34,15 +44,18 @@ def plot_view_header(parent: WebvizErtPluginABC) -> List[Component]: labelStyle={"display": "block"}, ), ], - width=6, + width=4, id=parent.uuid("response-section"), ), dbc.Col( [ - html.Label("Parameters", className="ert-label"), - parameter_selector_view(parent, data_type=DataType.PARAMETER), + parameter_selector_view( + parent, + data_type=DataType.PARAMETER, + titleLabel="Parameters", + ), ], - width=6, + width=4, id=parent.uuid("parameter-section"), ), ] diff --git a/webviz_ert/views/selector_view.py b/webviz_ert/views/selector_view.py index bf8ea689..8c10f575 100644 --- a/webviz_ert/views/selector_view.py +++ b/webviz_ert/views/selector_view.py @@ -10,37 +10,41 @@ def parameter_selector_view( - parent: WebvizErtPluginABC, data_type: DataType + parent: WebvizErtPluginABC, + data_type: DataType, + titleLabel: str = "Parameters", ) -> Component: return html.Div( [ dbc.Row( [ dbc.Col( - html.Label( - "Search", + html.H6( + titleLabel, className="ert-label", ), align="left", - width="auto", ), dbc.Col( - dcc.Input( - id=parent.uuid(f"parameter-selector-filter-{data_type}"), - type="search", - placeholder="Substring...", - persistence="session", - ), - align="left", - ), - dbc.Col( - html.Button( - id=parent.uuid(f"parameter-selector-button-{data_type}"), - children=("Toggle selector visibility"), - ), + [ + html.Label( + "Search: ", + className="ert-label", + ), + dcc.Input( + id=parent.uuid( + f"parameter-selector-filter-{data_type}" + ), + type="search", + placeholder="Substring...", + persistence="session", + ), + ], align="right", + width="auto", ), ], + align="center", ), html.Div( wcc.Select(