Skip to content

Commit

Permalink
Implement guide uniqueness
Browse files Browse the repository at this point in the history
  • Loading branch information
edan-bainglass committed Dec 11, 2024
1 parent bb57f5c commit bb33567
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 140 deletions.
59 changes: 48 additions & 11 deletions src/aiidalab_qe/app/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ def _on_guide_toggle(self, change: dict):
if change["new"]:
self._view.info_container.children = [
self._view.guide,
self._view.guide_selection,
ipw.HBox(
children=[
self._view.guide_category_selection,
self._view.guide_selection,
],
layout=ipw.Layout(align_items="baseline"),
),
]
self._view.info_container.layout.display = "flex"
self._view.job_history_toggle.value = False
Expand Down Expand Up @@ -94,21 +100,50 @@ def _on_job_history_toggle(self, change: dict):
else:
self._view.main.children = self._old_view

def _on_guide_select(self, change: dict):
def _on_guide_category_select(self, change: dict):
self._view.guide_selection.options = guide_manager.get_guides(change["new"])
self._update_active_guide()

def _on_guide_select(self, _):
self._update_active_guide()

def _update_active_guide(self):
"""Sets the current active guide."""
guide_manager.active_guide = change["new"]
category = self._view.guide_category_selection.value
guide = self._view.guide_selection.value
active_guide = f"{category}/{guide}" if category != "none" else category
guide_manager.active_guide = active_guide

def _set_guide_options(self, _):
def _set_guide_category_options(self, _):
"""Fetch the available guides."""
self._view.guide_selection.options = ["none", *guide_manager.get_guides()]
self._view.guide_category_selection.options = [
"none",
*guide_manager.get_guide_categories(),
]

def _set_event_handlers(self) -> None:
"""Set up event handlers."""
self._view.guide_toggle.observe(self._on_guide_toggle, "value")
self._view.about_toggle.observe(self._on_about_toggle, "value")
self._view.job_history_toggle.observe(self._on_job_history_toggle, "value")
self._view.guide_selection.observe(self._on_guide_select, "value")
self._view.on_displayed(self._set_guide_options)
self._view.guide_toggle.observe(
self._on_guide_toggle,
"value",
)
self._view.about_toggle.observe(
self._on_about_toggle,
"value",
)
self._view.job_history_toggle.observe(
self._on_job_history_toggle,
"value",
)
self._view.guide_category_selection.observe(
self._on_guide_category_select,
"value",
)
self._view.guide_selection.observe(
self._on_guide_select,
"value",
)
self._view.on_displayed(self._set_guide_category_options)


class AppWrapperModel(tl.HasTraits):
Expand Down Expand Up @@ -199,11 +234,13 @@ def __init__(self) -> None:
self.guide = ipw.HTML(env.from_string(guide_template).render())
self.about = ipw.HTML(env.from_string(about_template).render())

self.guide_selection = ipw.RadioButtons(
self.guide_category_selection = ipw.RadioButtons(
options=["none"],
description="Guides:",
value="none",
layout=ipw.Layout(width="max-content"),
)
self.guide_selection = ipw.RadioButtons(layout=ipw.Layout(margin="2px 20px"))

self.job_history = QueryInterface()

Expand Down
35 changes: 29 additions & 6 deletions src/aiidalab_qe/common/guide_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ def __init__(self, *args, **kwargs):

super().__init__(*args, **kwargs)
guides = Path(aiidalab_qe.__file__).parent.joinpath("guides").glob("*")
self._guides = {guide.stem: guide.absolute() for guide in guides}
self._guides = {
"general": {
guide.stem.split("_", maxsplit=1)[1]: guide.absolute()
for guide in sorted(guides, key=lambda x: x.stem.split("_")[0])
}
}

self._fetch_plugin_guides()

self.content = BeautifulSoup()
Expand All @@ -33,7 +39,7 @@ def __init__(self, *args, **kwargs):
def has_guide(self) -> bool:
return self.active_guide != "none"

def get_guides(self) -> list[str]:
def get_guide_categories(self) -> list[str]:
"""Return a list of available guides.
Returns
Expand All @@ -43,6 +49,16 @@ def get_guides(self) -> list[str]:
"""
return [*self._guides.keys()]

def get_guides(self, identifier: str) -> list[str]:
"""Return a list of available sub-guides.
Returns
-------
`list[str]`
A list of the names of available sub-guides.
"""
return [*self._guides[identifier].keys()] if identifier != "none" else []

def get_guide_section_by_id(self, content_id: str) -> PageElement | None:
"""Return a guide section by its HTML `id` attribute.
Expand All @@ -60,16 +76,23 @@ def get_guide_section_by_id(self, content_id: str) -> PageElement | None:

def _on_active_guide_change(self, _):
"""Load the contents of the active guide."""
guide_path = self._guides.get(self.active_guide)
if self.active_guide == "none":
self.content = BeautifulSoup()
return
category, guide = self.active_guide.split("/")
guide_path = self._guides[category][guide]
html = Path(guide_path).read_text() if guide_path else ""
self.content = BeautifulSoup(html, "html.parser")

def _fetch_plugin_guides(self):
"""Fetch guides from plugins."""
entries: dict[str, Path] = get_entry_items("aiidalab_qe.properties", "guides")
for guides in entries.values():
for guide in guides.glob("*"):
self._guides[guide.stem] = guide.absolute()
for identifier, guides in entries.items():
if identifier not in self._guides:
self._guides[identifier] = {}
for guide in sorted(guides.glob("*"), key=lambda x: x.stem.split("_")[0]):
stem = guide.stem.split("_", maxsplit=1)[1]
self._guides[identifier][stem] = guide.absolute()


guide_manager = GuideManager()
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div id="guide-warning">
You've activated an in-app guide. Follow along below to learn how to use the
Quantum ESPRESSO app.
You've activated the basic in-app guide. Follow along below to learn the basic
features of the Quantum ESPRESSO app.
</div>

<div id="structure-step">
Expand Down Expand Up @@ -101,7 +101,10 @@ <h4>Tasks</h4>
<div id="pdos-settings">
Here we configure the settings for computing the projected density of states,
or PDOS.
<div class="alert alert-success">???</div>
<div class="alert alert-warning">
In this walkthrough, we will not modify pdos settings and proceed with the
defaults.
</div>
</div>

<div id="submission-step">
Expand Down
10 changes: 10 additions & 0 deletions src/aiidalab_qe/guides/1_advanced.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div id="guide-warning">
You've activated the advanced in-app guide. Follow along below to learn how to
use the more advanced features of the Quantum ESPRESSO app.
</div>

<div id="structure-step">Advanced example</div>

<div id="configuration-step">Advanced example</div>

<div id="submission-step">Advanced example</div>
10 changes: 10 additions & 0 deletions src/aiidalab_qe/plugins/bands/guides/0_basic.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div id="guide-warning">
You've activated the basic bands in-app guide. Follow along below to learn how
to use the Quantum ESPRESSO app to run a simple band structure calculation.
</div>

<div id="structure-step">Bands example</div>

<div id="configuration-step">Bands example</div>

<div id="submission-step">Bands example</div>
119 changes: 0 additions & 119 deletions src/aiidalab_qe/plugins/bands/guides/bands.html

This file was deleted.

2 changes: 1 addition & 1 deletion tests/test_infobox.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ def test_in_app_guide():
)
assert in_app_guide.children[0].value == "Hello, World!"

guide_manager.active_guide = "basic"
guide_manager.active_guide = "general/basic"
in_app_guide = InAppGuide(identifier="guide-warning")
assert "You've activated an in-app guide" in in_app_guide.children[0].value

0 comments on commit bb33567

Please sign in to comment.