Skip to content

Commit

Permalink
Humanized process status view (#1048)
Browse files Browse the repository at this point in the history
This PR implements a simplified process status tree that is
- human readable
- collapsible
- linked with advanced node viewer
- resettable (collapse all)
- lazy loaded
  • Loading branch information
edan-bainglass authored Jan 13, 2025
1 parent ede0480 commit 85b897b
Show file tree
Hide file tree
Showing 7 changed files with 873 additions and 30 deletions.
113 changes: 97 additions & 16 deletions src/aiidalab_qe/app/result/components/status/status.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import ipywidgets as ipw

from aiida import orm
Expand All @@ -7,6 +9,7 @@
from aiidalab_widgets_base.viewers import viewer as node_viewer

from .model import WorkChainStatusModel
from .tree import SimplifiedProcessTree, SimplifiedProcessTreeModel


class WorkChainStatusPanel(ResultsComponent[WorkChainStatusModel]):
Expand All @@ -15,14 +18,21 @@ def __init__(self, model: WorkChainStatusModel, **kwargs):
self.node_views = {} # node-view cache
self.node_view_loading_message = LoadingWidget("Loading node view")

def _on_monitor_counter_change(self, _):
self._update_process_tree()

def _on_node_selection_change(self, change):
self._update_node_view(change["new"])

def _render(self):
self.simplified_status_view = ipw.HTML("Coming soon")
model = SimplifiedProcessTreeModel()
self.simplified_process_tree = SimplifiedProcessTree(model=model)
ipw.dlink(
(self._model, "process_uuid"),
(model, "process_uuid"),
)
ipw.dlink(
(self._model, "monitor_counter"),
(model, "monitor_counter"),
)
model.observe(
self._on_calculation_link_click,
"clicked",
)

self.process_tree = ProcessNodesTreeWidget()
self.process_tree.observe(
Expand All @@ -34,19 +44,61 @@ def _render(self):
(self.process_tree, "value"),
)

self.node_view_container = ipw.VBox()
self.reset_button = ipw.Button(
description="Reset to root",
button_style="warning",
icon="refresh",
tooltip="Reseed the process tree with the root node",
layout=ipw.Layout(width="fit-content"),
)
self.reset_button.on_click(self._reset_process_tree)

self.node_view_container = ipw.VBox(layout=ipw.Layout(height="100%"))
self.node_view_container.add_class("node-view-container")

self.to_advanced_view_button = ipw.Button(
description="View in advanced panel",
button_style="primary",
icon="eye",
tooltip="Switch to the advanced view",
layout=ipw.Layout(width="fit-content"),
)
self.to_advanced_view_button.on_click(self._switch_to_advanced_view)

simplified_tree_container = ipw.VBox(
children=[self.simplified_process_tree],
)

simplified_tree_node_view_container = ipw.VBox(
children=[
self.to_advanced_view_button,
self.node_view_container,
],
)

simplified_view = ipw.Box(
children=[
simplified_tree_container,
simplified_tree_node_view_container,
]
)
simplified_view.add_class("simplified-view")

advanced_view = ipw.VBox(
children=[
self.reset_button,
self.process_tree,
self.node_view_container,
],
)
advanced_view.add_class("advanced-view")

self.accordion = ipw.Accordion(
children=[
self.simplified_status_view,
ipw.VBox(
children=[
self.process_tree,
self.node_view_container,
],
),
simplified_view,
advanced_view,
],
selected_index=1,
selected_index=None,
)
titles = [
"Status overview",
Expand All @@ -55,8 +107,32 @@ def _render(self):
for i, title in enumerate(titles):
self.accordion.set_title(i, title)

self.accordion.observe(
self._on_accordion_change,
"selected_index",
)

self.accordion.selected_index = 0

self.children = [self.accordion]

def _on_monitor_counter_change(self, _):
self._update_process_tree()

def _on_accordion_change(self, change):
if change["new"] == 0:
self.simplified_process_tree.render()

def _on_calculation_link_click(self, change):
if selected_node_uuid := change["new"]:
self.process_tree.value = selected_node_uuid

def _on_node_selection_change(self, change):
self._update_node_view(change["new"])

def _switch_to_advanced_view(self, _):
self.accordion.selected_index = 1

def _update_process_tree(self):
if self.rendered:
self.process_tree.update()
Expand Down Expand Up @@ -89,3 +165,8 @@ def _update_node_view(self, nodes, refresh=False):
self.node_view = ipw.HTML("No viewer available for this node.")

self.node_view_container.children = [self.node_view]

def _reset_process_tree(self, _):
if not self.rendered:
return
self.process_tree.value = self._model.process_uuid
Loading

0 comments on commit 85b897b

Please sign in to comment.