diff --git a/src/aiidalab_qe/app/main.py b/src/aiidalab_qe/app/main.py index 91681918c..554012884 100644 --- a/src/aiidalab_qe/app/main.py +++ b/src/aiidalab_qe/app/main.py @@ -112,6 +112,8 @@ def __init__(self, qe_auto_setup=True): self._wizard_app_widget.selected_index = None + self.structure_step.state = QeWizardStep.State.READY + self._update_blockers() @property diff --git a/src/aiidalab_qe/app/result/__init__.py b/src/aiidalab_qe/app/result/__init__.py index 3d06fd866..e81a80e50 100644 --- a/src/aiidalab_qe/app/result/__init__.py +++ b/src/aiidalab_qe/app/result/__init__.py @@ -140,7 +140,8 @@ def reset(self): self._model.reset() @tl.observe("state") - def _on_state_change(self, _): + def _on_state_change(self, change): + super()._on_state_change(change) self._update_kill_button_layout() def _on_previous_step_state_change(self, _): diff --git a/src/aiidalab_qe/app/static/styles/custom.css b/src/aiidalab_qe/app/static/styles/custom.css index 2cb2a76ac..89975761d 100644 --- a/src/aiidalab_qe/app/static/styles/custom.css +++ b/src/aiidalab_qe/app/static/styles/custom.css @@ -86,3 +86,25 @@ footer { text-align: right; } + +.p-Accordion-child:has(.qe-app-step-ready) > .p-Collapse-header { + background-color: var(--color-ready); +} + +.p-Accordion-child:has(.qe-app-step-configured) > .p-Collapse-header { + background-color: var(--color-ready); + filter: brightness(0.95); + -webkit-filter: brightness(0.95); +} + +.p-Accordion-child:has(.qe-app-step-active) > .p-Collapse-header { + background-color: var(--color-active); +} + +.p-Accordion-child:has(.qe-app-step-success) > .p-Collapse-header { + background-color: var(--color-success); +} + +.p-Accordion-child:has(.qe-app-step-fail) > .p-Collapse-header { + background-color: var(--color-failed); +} diff --git a/src/aiidalab_qe/app/static/styles/variables.css b/src/aiidalab_qe/app/static/styles/variables.css new file mode 100644 index 000000000..10c88fa72 --- /dev/null +++ b/src/aiidalab_qe/app/static/styles/variables.css @@ -0,0 +1,7 @@ +:root { + --color-init: #eee; + --color-ready: #fcf8e3; + --color-active: #d9edf7; + --color-success: #dff0d8; + --color-failed: #f2dede; +} diff --git a/src/aiidalab_qe/common/widgets.py b/src/aiidalab_qe/common/widgets.py index 353f69189..5b101eb7d 100644 --- a/src/aiidalab_qe/common/widgets.py +++ b/src/aiidalab_qe/common/widgets.py @@ -1160,6 +1160,7 @@ def __init__(self, model: QWSM, **kwargs): super().__init__(children=[self.loading_message], **kwargs) self._model = model self.rendered = False + self._background_class = "" def render(self): if self.rendered: @@ -1168,12 +1169,21 @@ def render(self): self.rendered = True self._post_render() + @traitlets.observe("state") + def _on_state_change(self, change): + self._update_background_color(change["new"]) + def _render(self): raise NotImplementedError() def _post_render(self): pass + def _update_background_color(self, state: WizardAppWidgetStep.State): + self.remove_class(self._background_class) + self._background_class = f"qe-app-step-{state.name.lower()}" + self.add_class(self._background_class) + class QeDependentWizardStep(QeWizardStep[QWSM]): missing_information_warning = "Missing information" diff --git a/tests_integration/test_app.py b/tests_integration/test_app.py index 3b446deaf..156522732 100755 --- a/tests_integration/test_app.py +++ b/tests_integration/test_app.py @@ -20,11 +20,15 @@ def test_qe_app_select_silicon_and_confirm( driver = selenium_driver("qe.ipynb", wait_time=30.0) driver.set_window_size(1920, 1485) + driver.find_element(By.CLASS_NAME, "qe-app-step-ready") # ready on start + # Open structure selection step element = WebDriverWait(driver, 60).until( EC.presence_of_element_located((By.CLASS_NAME, "p-Accordion-child")) ) element.click() + # check that element has CSS class + driver.find_element(By.CLASS_NAME, "qe-app-step-ready") # still ready # Select the Silicon example element = WebDriverWait(driver, 60 * 2).until( @@ -35,10 +39,14 @@ def test_qe_app_select_silicon_and_confirm( try: driver.find_element(By.XPATH, "//option[@value='Diamond']").click() time.sleep(10) + # Selection configures the step + driver.find_element(By.CLASS_NAME, "qe-app-step-configured") element = WebDriverWait(driver, 60).until( EC.element_to_be_clickable((By.XPATH, "//button[text()='Confirm']")) ) element.click() + # Confirming means step is successful + driver.find_element(By.CLASS_NAME, "qe-app-step-success") except Exception: driver.find_element(By.TAG_NAME, "summary").click() time.sleep(10)