-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Highlight selected page #91
Changes from 7 commits
130250e
8e90389
2a309c4
67d03df
97ed155
1d1d5c5
85f6b4a
5f68432
2125048
6c5d216
f51148c
440da0e
5a3e539
430aad7
d09ed56
2956f34
da842f7
08e412d
8b84b07
14d3982
8a96460
e36f320
0c6b95d
ab85ae3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,18 +61,26 @@ | |
<div class="ui container"> | ||
{% for label, icon, link in menu %} | ||
{% if link is string %} | ||
<a class="mobile hidden item" href="{{ root_url }}/page/{{ link }}/"> | ||
<a class="mobile hidden item {% if '/page/' ~ link ~ '/' == current_url %}selected{% endif %}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, the page id should be used instead of the current url. As far as I see, it is currently not available to the template, but it can easily be added to the template data in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed moved the logic to python. Still need to use the url path to identify the current menu. I get this from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, you can simply access the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep this is perfect. But you mentioned the |
||
href="{{ root_url }}/page/{{ link }}/"> | ||
{% if icon %}<i class="{{ icon }} icon"></i>{% endif %} | ||
{{ label }} | ||
</a> | ||
{% else %} | ||
<div class="mobile hidden ui dropdown item"> | ||
{% set ns = namespace(isSelected=False) %} | ||
{% for sub_label, sub_icon, sub_link in link %} | ||
{% if not ns.isSelected %} | ||
{% set ns.isSelected = (current_url == '/page/' ~ sub_link ~ '/') %} | ||
{% endif %} | ||
{% endfor %} | ||
<div class="mobile hidden ui dropdown item {% if ns.isSelected %}selected{% endif %}"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually I would like to move all the logic from the jinja template to In my eyes the best place to temporarily store the [('Label', 'icon', 'page_name','is_selected'),
('Submenu label', None, [
('Label 2', 'icon', 'page_name2','is_selected'), ...
]),
...] What do you think? Any other proposal? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I'd also prefer to evaluate the active state of the submenu entry in the Python code (this kind of evaluation is one of the annoying things that are often required in Jinja templates but not simple to write due to the missing list comprehension / generator expressions in Jinja). However, I would probably refactor the code a bit to use a NamedTuple or a Dataclass instead of simple tuples in the list for better readability of both, the Python code and the template code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
{% if icon %}<i class="{{ icon }} icon"></i>{% endif %} | ||
{{ label }} | ||
<i class="dropdown icon"></i> | ||
<div class="menu"> | ||
{% for sub_label, sub_icon, sub_link in link %} | ||
<a class="item" href="{{ root_url }}/page/{{ sub_link }}/"> | ||
<a class="item {% if '/page/' ~ sub_link ~ '/' == current_url %}selected{% endif %}" | ||
href="{{ root_url }}/page/{{ sub_link }}/"> | ||
{% if sub_icon %}<i class="{{ sub_icon }} icon"></i>{% endif %} | ||
{{ sub_label }} | ||
</a> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -148,6 +148,53 @@ def test_main_menu(self) -> None: | |
self.assertEqual(submenu_entry_href.strip(), "http://localhost:42080/page/another_page/") | ||
submenu_entry.find_element(By.CSS_SELECTOR, 'i.bars.icon') | ||
|
||
def test_main_menu_selection(self) -> None: | ||
"""Test that the clicked menu item is selected thus highlighted.""" | ||
self.server.page('index', menu_entry="Home", menu_icon='home') | ||
self.server.page('overview', menu_entry="Foo", menu_icon='info') | ||
|
||
# add submenu | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is slightly inaccurate, as these method calls do not only add a submenu, but also new web pages. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
self.server.page('submenu1', "Sub1", menu_entry='Some Submenu', menu_icon='bell', | ||
menu_sub_label="Overview") | ||
self.server.page('submenu2', "Sub2", menu_entry='Some Submenu', | ||
menu_sub_label="Empty Submenu") | ||
self.server.page('submenu3', "Sub3", menu_entry='Some Submenu', | ||
menu_sub_label="Empty Submenu 2") | ||
|
||
self.server_runner.start() | ||
self.driver.get("http://localhost:42080") | ||
|
||
# test on startup only 1st item is selected | ||
container = self.driver.find_element(By.CSS_SELECTOR, '.pusher') | ||
selected_menus = container.find_elements(By.CLASS_NAME, 'selected') | ||
self.assertEqual(len(selected_menus), 1) | ||
self.assertIn("Home", selected_menus[0].text) | ||
|
||
# test after click on foo only the clicked item is selected | ||
foo_link = container.find_element(By.CSS_SELECTOR, 'i.info.icon').find_element(By.XPATH, '..') | ||
foo_link.click() | ||
|
||
container = self.driver.find_element(By.CSS_SELECTOR, '.pusher') | ||
selected_menus = container.find_elements(By.CLASS_NAME, 'selected') | ||
self.assertEqual(len(selected_menus), 1) | ||
self.assertIn("Foo", selected_menus[0].text) | ||
|
||
# click top level submenu item 1st to open submenu | ||
submenu = container.find_element(By.CSS_SELECTOR, 'i.bell.icon').find_element(By.XPATH, '..') | ||
submenu.click() | ||
|
||
# now select submenu item | ||
submenu_entry = submenu.find_element(By.XPATH, './/a[contains(@class, "item")]') | ||
submenu_entry.click() | ||
|
||
# test after selecting a submenu both are selected the submenu item and the menu item | ||
container = self.driver.find_element(By.CSS_SELECTOR, '.pusher') | ||
selected_menus = container.find_elements(By.CLASS_NAME, 'selected') | ||
self.assertEqual(len(selected_menus), 2) | ||
self.assertIn("Some Submenu", selected_menus[0].text) | ||
submenu_href: str = str(selected_menus[1].get_attribute("href")) | ||
self.assertTrue(submenu_href.endswith("/page/submenu1/")) | ||
|
||
|
||
class MonitoringTest(unittest.TestCase): | ||
def setUp(self) -> None: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,6 @@ window.SHC_WIDGET_TYPES = WIDGET_TYPES; | |
|
||
// Set up UI with Semantic UI components | ||
$(function() { | ||
$('.main-menu .ui.dropdown').dropdown(); | ||
$('.main-menu .ui.dropdown').dropdown({on: 'hover'}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personal preference, quicker for navigation. Let me know if you rather want to have it removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it work reasonably well with touch (or hybrid) devices? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feature removed, see above. |
||
$('.ui.sidebar').sidebar({transition: 'overlay'}).sidebar('attach events', '#mobile_item'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also create menu entries without creating actual pages, using
add_menu_entry()
.More specifically, I would suggest to add two links to the same page here for checking the correct behaviour in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Actually the WebServer API
page(...)
andadd_menu_entry(...)
is kind of confusing and not really obvious, e.g. that inadd_menu_entry()
the existing menu_entry is found by the label. Maybe we should align the attribute names in both methods.Not sure whether this would have avoided some of my confusion but we should fix it anyhow. Maybe not now since this is an API change or what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I'm actually quite happy with the current naming of these attributes: The
page()
method also takesmenu_entry=True
to simply create a menu entry with the page's title as label. This is why the parameter is called this way.Basically, the
page()
method only creates a WebPage and theadd_menu_entry()
only adds a menu entry. Both are completely independent from each other. As a shortcut, thepage()
method allows to create a matching menu entry for the new WebPage in addition to the WebPage itself, by using themenu_entry
parameter.Maybe, we should point out this relationship in the docstrings of both methods, with a reference to the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well this brings up another issue that we should clarify. Since I identify the current page by the path in that case both menu entries are marked:
This could be a feature or a bug depending on the point of view. From my perspective I would say that is something that could be benefical and that I could live with. Especially if the same page is referenced in different submenus this might be an interesting information being visualized like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.