diff --git a/docker/routlin-dash/app/config_utils.py b/docker/routlin-dash/app/config_utils.py index cb64e17..2e83d3c 100644 --- a/docker/routlin-dash/app/config_utils.py +++ b/docker/routlin-dash/app/config_utils.py @@ -270,7 +270,8 @@ def _timing_status_msg(entry_ts, action_label): def _build_timing_msg(entry_ts, action_label='Configuration saved'): if not _apply_changes_immediately(): - return f'{action_label}. Visit Actions page to apply your changes.' + from markupsafe import Markup + return Markup(f'{action_label}. Visit Actions page to apply your changes.') return _timing_status_msg(entry_ts, action_label) diff --git a/docker/routlin-dash/app/view_page.py b/docker/routlin-dash/app/view_page.py index 28ba639..b0b6da4 100644 --- a/docker/routlin-dash/app/view_page.py +++ b/docker/routlin-dash/app/view_page.py @@ -1619,8 +1619,9 @@ def _load_datasource(spec): def render_layout(view_id, content_html, tokens): css = _load_css() level = _client_level() + has_pending_alert = not _apply_changes_immediately() and bool(get_dashboard_pending()) titlebar_html = f'
{WEB_APP_DISPLAY_NAME}
' - navbar_html = _render_navbar(view_id, level, tokens) + navbar_html = _render_navbar(view_id, level, tokens, pending_alert=has_pending_alert) footer_html = f'' page_hash = config_hash() @@ -1692,7 +1693,7 @@ def render_layout(view_id, content_html, tokens): fix_suffix = (f'Fix will be applied {timing}.' if timing else 'Fix pending. The processing service is not running.') else: - fix_suffix = 'Fix pending. Visit Actions page ASAP to apply fix.' + fix_suffix = 'Fix pending. Visit Actions page ASAP to apply fix.' for sev, items in grouped.items(): if not items: continue @@ -1701,7 +1702,7 @@ def render_layout(view_id, content_html, tokens): + ''.join(f'
  • {d}
  • ' for d in items) + '') uuid_attr = f' data-health-uuid="{e(fix_uuid)}"' if _apply_changes_immediately() else '' - fix_html = (f'
    {e(fix_suffix)}
    ' + fix_html = (f'
    {fix_suffix}
    ' if fix_suffix else '') content = ('
    ' '
    Health check - problems found:
    ' @@ -1711,6 +1712,12 @@ def render_layout(view_id, content_html, tokens): except Exception: pass + pending_bar = '' + if has_pending_alert: + pending_bar = ('
    ' + 'You have actions pending. Please visit Actions page.' + '
    \n') + return (f'\n\n\n' f' \n' f' \n' @@ -1719,14 +1726,14 @@ def render_layout(view_id, content_html, tokens): f'\n\n' f'{titlebar_html}\n' f'{navbar_html}\n' - f'
    \n{problem_bars}{other_bars}{content_html}\n
    \n' + f'
    \n{pending_bar}{problem_bars}{other_bars}{content_html}\n
    \n' f'{footer_html}\n' f'\n' f'\n' f'\n') -def _render_navbar(active_view, level, tokens): +def _render_navbar(active_view, level, tokens, pending_alert=False): navbar_data = _load_json(f'{DATA_DIR}/navbar_content.json') left, right = [], [] for item in navbar_data.get('items', []): @@ -1734,7 +1741,7 @@ def _render_navbar(active_view, level, tokens): align = item.get('align', 'left') if not _passes(req, level): continue - frag = _render_nav_item(item, active_view, level, in_dropdown=False, inherited_req=req) + frag = _render_nav_item(item, active_view, level, in_dropdown=False, inherited_req=req, pending_alert=pending_alert) (right if align == 'right' else left).append(frag) return (f'') -def _render_nav_item(item, active_view, level, in_dropdown=False, inherited_req=None): +def _render_nav_item(item, active_view, level, in_dropdown=False, inherited_req=None, pending_alert=False): req = item.get('client_requirement', inherited_req) t = item.get('type', '') @@ -1752,7 +1759,8 @@ def _render_nav_item(item, active_view, level, in_dropdown=False, inherited_req= map_to = item.get('map_to', '') action = item.get('action', '') is_active = ' active' if map_to and map_to == active_view else '' - cls = f'dropdown-item{is_active}' if in_dropdown else f'nav-item{is_active}' + pending = ' nav-item-pending' if pending_alert and map_to == 'view_actions' else '' + cls = f'dropdown-item{is_active}' if in_dropdown else f'nav-item{is_active}{pending}' if action: return (f'
    ' f'
    ') @@ -1770,7 +1778,7 @@ def _render_nav_item(item, active_view, level, in_dropdown=False, inherited_req= child_req = child.get('client_requirement', req) if not _passes(child_req, level): continue - children += _render_nav_item(child, active_view, level, in_dropdown=True, inherited_req=req) + children += _render_nav_item(child, active_view, level, in_dropdown=True, inherited_req=req, pending_alert=pending_alert) if not children: return '' return (f'