Skip to content

Commit

Permalink
Improve readability
Browse files Browse the repository at this point in the history
  • Loading branch information
edan-bainglass committed Dec 10, 2024
1 parent 42afcfd commit bb57f5c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 11 deletions.
35 changes: 30 additions & 5 deletions src/aiidalab_qe/common/guide_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@
from pathlib import Path

import traitlets as tl
from bs4 import BeautifulSoup
from bs4 import BeautifulSoup, PageElement

import aiidalab_qe
from aiidalab_qe.app.utils import get_entry_items


class GuideManager(tl.HasTraits):
"""A global guide manager that loads and manages guide sections."""

active_guide = tl.Unicode("none", allow_none=True)

def __init__(self, *args, **kwargs):
"""`GuideManager` constructor."""

super().__init__(*args, **kwargs)
guides = Path(aiidalab_qe.__file__).parent.joinpath("guides").glob("*")
self._guides = {guide.stem: guide.absolute() for guide in guides}
Expand All @@ -26,21 +30,42 @@ def __init__(self, *args, **kwargs):
)

@property
def has_guide(self):
def has_guide(self) -> bool:
return self.active_guide != "none"

def get_guides(self):
def get_guides(self) -> list[str]:
"""Return a list of available guides.
Returns
-------
`list[str]`
A list of the names of available guides.
"""
return [*self._guides.keys()]

def get_guide_section_by_id(self, content_id: str):
return self.content.find(attrs={"id": content_id})
def get_guide_section_by_id(self, content_id: str) -> PageElement | None:
"""Return a guide section by its HTML `id` attribute.
Parameters
----------
`content_id` : `str`
The HTML `id` attribute of the guide section.
Returns
-------
`PageElement` | `None`
The guide section or `None` if not found.
"""
return self.content.find(attrs={"id": content_id}) # type: ignore

def _on_active_guide_change(self, _):
"""Load the contents of the active guide."""
guide_path = self._guides.get(self.active_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("*"):
Expand Down
34 changes: 28 additions & 6 deletions src/aiidalab_qe/common/infobox.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,22 @@ def __init__(self, classes: list[str] | None = None, **kwargs):


class InAppGuide(InfoBox):
"""The `InfoAppGuide` is used to set up toggleable in-app guides."""
"""The `InAppGuide` is used to set up toggleable in-app guides.
Attributes
----------
`manager` : `GuideManager`
A local reference to the global guide manager.
`identifier` : `str`, optional
If content `children` are not provided directly, the `identifier`
is used to fetch the corresponding guide section from the guide
currently loaded by the guide manager.
Raises
------
`ValueError`
If neither content `children` or a guide section `identifier` are provided.
"""

def __init__(
self,
Expand All @@ -37,9 +52,11 @@ def __init__(
Parameters
----------
children : `list`, optional
The children of the guide.
`identifier` : `str`
The identifier used to load the guide file.
The content children of this guide section.
`identifier` : `str`, optional
If content `children` are not provided directly, the `identifier`
is used to fetch the corresponding guide section from the guide
currently loaded by the guide manager.
`classes` : `list[str]`, optional
One or more CSS classes.
"""
Expand Down Expand Up @@ -71,13 +88,18 @@ def __init__(
# This manual toggle call is necessary because the guide
# may be contained in a component that was not yet rendered
# when a guide was selected.
self._toggle_guide()
self._on_active_guide_change(None)

def _on_active_guide_change(self, _):
self._update_contents()
self._toggle_guide()

def _toggle_guide(self):
def _update_contents(self):
"""Update the contents of the guide section."""
if hasattr(self, "identifier"):
html = self.manager.get_guide_section_by_id(self.identifier)
self.children = [ipw.HTML(str(html))] if html else []

def _toggle_guide(self):
"""Toggle the visibility of the guide section."""
self.layout.display = "flex" if self.manager.has_guide else "none"

0 comments on commit bb57f5c

Please sign in to comment.