Skip to content

Commit

Permalink
Fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
antonymilne committed Nov 15, 2023
1 parent 54bdd47 commit c9a7d4a
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 33 deletions.
2 changes: 1 addition & 1 deletion vizro-core/src/vizro/_vizro.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Vizro:
def __init__(self):
"""Initializes Dash."""
_js, _css = _append_styles(self._lib_assets_folder, STATIC_URL_PREFIX)
_css.append("https://fonts.googleapis.com/css2?family=Material+Icons+Outlined")
_css.append("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined")

self.dash = dash.Dash(
use_pages=True,
Expand Down
4 changes: 3 additions & 1 deletion vizro-core/src/vizro/models/_navigation/_navigation_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from vizro.managers import model_manager


# AM: handle different dict/list types better - build in _pages property that is list? Or provide argumenyt to
# validator?
def _validate_pages(pages):
"""Reusable validator to check if provided Page IDs exist as registered pages."""
from vizro.models import Page
Expand All @@ -17,7 +19,7 @@ def _validate_pages(pages):
# if pages is None:
# return registered_pages
# AM: shouldn't be needed here? Only want to autopopulate at top-level.

#
if not pages_as_list:
raise ValueError("Ensure this value has at least 1 item.")

Expand Down
2 changes: 1 addition & 1 deletion vizro-core/src/vizro/models/_navigation/accordion.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import itertools
from collections.abc import Mapping
from typing import Dict, List, Literal
from typing import Dict, List, Literal, Optional

import dash
import dash_bootstrap_components as dbc
Expand Down
32 changes: 17 additions & 15 deletions vizro-core/src/vizro/models/_navigation/nav_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,41 +31,43 @@ class NavBar(VizroBaseModel):
items: Optional[List[NavItem]] = [] # AM: think about name

# validators
_validate_pages = validator("pages", allow_reuse=True, pre=True, always=True)(_validate_pages)
_validate_pages = validator("pages", allow_reuse=True, pre=True)(_validate_pages)

@validator("pages", pre=True)
def coerce_pages_type(cls, pages):
if isinstance(pages, Mapping):
return pages
return {page: [page] for page in pages}

@validator("items", always=True)
def set_items(cls, items, values):
# AM: Will this check work correctly when pages not set?
if "pages" not in values:
return values

items = items or [NavItem(text=group_title, pages=pages) for group_title, pages in values["pages"].items()]
@_log_call
def pre_build(self):
self.items = self.items or [NavItem(text=group_title, pages=pages) for group_title, pages in self.pages.items()]

# AM: test works if set some icons but not others
for position, item in enumerate(items):
# There are only 6 looks icons. If there are more than 6 items, the icons will repeat.
item.icon = item.icon or f"looks_{position % 6 + 1}"
for position, item in enumerate(self.items, 1):
item.icon = item.icon or f"filter_{position}" if position <= 9 else "filter_9+"

# Since models instantiated in pre_build do not themselves have pre_build called on them, we call it manually
# here.
for item in self.items:
item.pre_build()

return items
return self.items

@_log_call
def build(self, *, active_page_id=None):
# We always show all the navitem buttons, but only show the accordion for the active page. This works because
# item.build only returns the nav_panel_outer Div when the item is active.
# In future maybe we should do this by showing all navigation panels and then setting hidden=True for all but
# one using a clientside callback?
built_items = [item.build() for item in self.items]
buttons = [item[item.id] for item in built_items]
# Wrapping built_items into html.Div here is not for rendering purposes but so that we can look up the
# components by id easily instead of needing to iterate through a nested list.
built_items = html.Div([item.build(active_page_id=active_page_id) for item in self.items])
buttons = [built_items[item.id] for item in self.items]
if "nav_panel_outer" in built_items:
nav_panel_outer = built_items["nav_panel_outer"]
else:
# Active page is not in navigation, so hide navigation panel.
# Active page is not in navigation at all, so hide navigation panel.
nav_panel_outer = html.Div(hidden=True, id="nav_panel_outer")

return html.Div([html.Div(buttons, className="nav-bar", id="nav_bar_outer"), nav_panel_outer])
10 changes: 5 additions & 5 deletions vizro-core/src/vizro/models/_navigation/nav_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ class NavItem(VizroBaseModel):
_selector: Accordion = PrivateAttr()

# Re-used validators
_validate_pages = validator("pages", allow_reuse=True, always=True)(_validate_pages)
_validate_pages = validator("pages", allow_reuse=True)(_validate_pages)

@_log_call # can't do this in validator since it's private?
@_log_call
def pre_build(self):
from vizro.models._navigation.accordion import Accordion

Expand All @@ -64,7 +64,7 @@ def build(self, *, active_page_id=None):
# remove nesting nav-icon-text now no text?
button = dbc.Button(
[
html.Div(html.Span(self.icon, className="material-symbols-outlined"), className="nav-icon-text"),
html.Span(self.icon, className="material-symbols-outlined"),
dbc.Tooltip(html.P(self.text), target=self.id, placement="bottom", className="custom-tooltip"),
],
id=self.id,
Expand All @@ -75,6 +75,6 @@ def build(self, *, active_page_id=None):

# Only build the selector (id="nav_panel_outer") if the item is active.
if item_active:
return html.Div([button, item._selector.build(active_page_id=active_page_id)])
return html.Div([button, self._selector.build(active_page_id=active_page_id)])

return button
return html.Div(button)
19 changes: 9 additions & 10 deletions vizro-core/src/vizro/models/_navigation/navigation.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@ class Navigation(VizroBaseModel):
selector: Optional[NavSelectorType] = None # AM: yes

# validators
_validate_pages = validator("pages", allow_reuse=True, pre=True, always=True)(_validate_pages)
_validate_pages = validator("pages", allow_reuse=True, pre=True)(_validate_pages)

@validator("selector", always=True)
def set_selector(cls, selector, values):
# AM: Will this check work correctly when pages not set?
if "pages" not in values:
return values

selector = selector or Accordion()
selector.pages = selector.pages or values["pages"]
return selector
@_log_call
def pre_build(self):
# Since models instantiated in pre_build do not themselves have pre_build called on them, we call it manually
# here. Note that not all selectors have pre_build (Accordion does not).
self.selector = self.selector or Accordion()
self.selector.pages = self.selector.pages or self.pages
if hasattr(self.selector, "pre_build"):
self.selector.pre_build()

@_log_call
def build(self, *, active_page_id=None):
Expand Down

0 comments on commit c9a7d4a

Please sign in to comment.