Skip to content

Commit

Permalink
Start page: use ipw.VBox instead of ipw.Output to display apps (#185
Browse files Browse the repository at this point in the history
)

Also, remove the decorator used as a workaround.
  • Loading branch information
yakutovicha authored Dec 2, 2024
1 parent 71334e2 commit 045df2e
Showing 1 changed file with 12 additions and 46 deletions.
58 changes: 12 additions & 46 deletions home/start_page.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
"""Module to generate AiiDAlab home page."""

import json
from functools import wraps
from glob import glob
from os import path

import ipywidgets as ipw
import traitlets
from aiidalab.app import AiidaLabApp
from aiidalab.config import AIIDALAB_APPS
from IPython.display import display

from home.utils import load_widget
from home.widgets import AppStatusInfoWidget
Expand All @@ -30,37 +28,12 @@ def create_app_widget_move_buttons(name):
return app_widget_move_buttons


def _workaround_property_lock_issue(func):
"""Work-around for issue with the ipw.Accordion widget.
The widget does not report changes to the .selected_index trait when displayed
within a custom ipw.Output instance. However, the change is somewhat cryptic reported
by a change to the private '_property_lock' trait. We observe changes to that trait
and convert the change argument into a form that is more like the one expected by
downstream handlers.
"""

@wraps(func)
def _inner(self, change):
if change["name"] == "_property_lock":
if "selected_index" in change["old"]:
fixed_change = change.copy()
fixed_change["name"] = "selected_index"
fixed_change["new"] = change["old"]["selected_index"]
del fixed_change["old"]
return func(self, fixed_change)

return func(self, change)

return _inner


class AiidaLabHome:
"""Class that mananges the appearance of the AiiDAlab home page."""

def __init__(self):
self.config_fn = ".launcher.json"
self.output = ipw.Output()
self.output = ipw.VBox()
self._app_widgets = {}

def _create_app_widget(self, name):
Expand Down Expand Up @@ -98,17 +71,17 @@ def read_config(self):

def render(self):
"""Rendering all apps."""
self.output.clear_output()
apps = self.load_apps()

with self.output:
for name in apps:
# Create app widget if it has not been created yet.
if name not in self._app_widgets:
self._app_widgets[name] = self._create_app_widget(name)
displayed_apps = []
apps = self.load_apps()

display(self._app_widgets[name])
for name in apps:
# Create app widget if it has not been created yet.
if name not in self._app_widgets:
self._app_widgets[name] = self._create_app_widget(name)

displayed_apps.append(self._app_widgets[name])
self.output.children = displayed_apps
return self.output

def load_apps(self):
Expand Down Expand Up @@ -186,24 +159,17 @@ def __init__(self, app, allow_move=False, allow_manage=True):
class CollapsableAppWidget(ipw.Accordion):
"""Widget that represents a collapsable app as part of the home page."""

hidden = traitlets.Bool()
hidden = traitlets.Bool(None, allow_none=True)

def __init__(self, app, **kwargs):
self.app = app
app_widget = AppWidget(app, **kwargs)
super().__init__(children=[app_widget])
self.set_title(0, app.title)
# Need to observe all names here due to unidentified issue:
self.observe(
self._observe_accordion_selected_index
) # , names=['selected_index'])

@_workaround_property_lock_issue
@traitlets.observe("selected_index")
def _observe_accordion_selected_index(self, change):
if (
change["name"] == "selected_index"
): # Observing all names due to unidentified issue.
self.hidden = change["new"] is None
self.hidden = change["new"] is None

@traitlets.observe("hidden")
def _observe_hidden(self, change):
Expand Down

0 comments on commit 045df2e

Please sign in to comment.