Source code for q2_sdk.hq.db.nav_node

from argparse import _SubParsersAction
from functools import partial
from typing import List, Optional
from enum import IntEnum
from lxml.objectify import Element, IntElement, StringElement, BoolElement

from q2_sdk.ardent.refresh_cache import RefreshCache
from q2_sdk.core.cli.cli_tools import SelectMenu, MenuOption
from q2_sdk.core.cli import textui, validators
from q2_sdk.core.configuration import settings
from q2_sdk.core.dynamic_imports import (
    api_ExecuteStoredProcedure as ExecuteStoredProcedure,
)
from q2_sdk.entrypoints import invalidate_hq_cache
from q2_sdk.hq.db.navigation_style import NavigationStyle
from q2_sdk.hq.db.ui_text import UiText
from q2_sdk.hq.exceptions import MissingNavNodeError
from q2_sdk.hq.models.hq_credentials import HqCredentials
from q2_sdk.tools import utils
from .db_object import DbObject, DEFAULT
from .representation_row_base import RepresentationRowBase
from ..models.hq_params.stored_procedure import Param

D_TYPES = ExecuteStoredProcedure.DataType






[docs] def prompt_for_route(navigation_style): if navigation_style.ShortName.text == "DirectLink": route = _prompt_for_url() else: route = textui.query( "What would you like to put in the Route column?", validators=[validators.RegexValidator(r".*")], ) return route
[docs] def prompt_for_display_name(default=None): display_name = textui.query("\nNav item text?", default=default) return display_name
def _prompt_for_url(): url = textui.query("\nURL to associate with this Nav Item?") if not url.startswith("http"): url = "http://{}".format(url) return url
[docs] def prompt_for_order(nav_nodes, parent_node): if parent_node is not None: choice_sub_nodes = [ x for x in nav_nodes if x.find("ParentNavigationNodeID") == parent_node.NavigationNodeID ] textui.puts(textui.colored.cyan("\n--{}--".format(parent_node.TextValue))) else: choice_sub_nodes = [ x for x in nav_nodes if not hasattr(x, "ParentNavigationNodeID") ] textui.puts( textui.colored.cyan( "-\n-{}--".format("--Online Top Level Navigation Menu--") ) ) counter = 1 for node in choice_sub_nodes: textui.puts( textui.colored.blue("{}) ".format(counter)) + textui.colored.yellow("-> here") ) textui.puts(textui.colored.cyan("\t{}".format(node.TextValue))) counter += 1 textui.puts( textui.colored.blue("{}) ".format(counter)) + textui.colored.yellow("-> here") ) choice = ( int( textui.query( "\nWhere should this nav node appear in the submenu? ", validators=[ validators.OptionValidator([str(x) for x in range(1, counter + 1)]) ], ) ) - 1 ) if choice == 0: lower_bound = 0 else: lower_bound = choice_sub_nodes[choice - 1].Order order = lower_bound + 1 return order
[docs] def prompt_for_central_order(nav_nodes, parent_node): if parent_node is not None: choice_sub_nodes = [ x for x in nav_nodes if x.find("ParentNavigationID") == parent_node.NavigationID ] textui.puts(textui.colored.cyan("\n--{}--".format(parent_node.TextValue))) else: choice_sub_nodes = [ x for x in nav_nodes if not hasattr(x, "ParentNavigationID") ] textui.puts( textui.colored.cyan( "-\n-{}--".format("--Online Top Level Navigation Menu--") ) ) counter = 1 for node in choice_sub_nodes: textui.puts( textui.colored.blue("{}) ".format(counter)) + textui.colored.yellow("-> here") ) textui.puts(textui.colored.cyan("\t{}".format(node.TextValue))) counter += 1 textui.puts( textui.colored.blue("{}) ".format(counter)) + textui.colored.yellow("-> here") ) choice = ( int( textui.query( "\nWhere should this nav node appear in the submenu? ", validators=[ validators.OptionValidator([str(x) for x in range(1, counter + 1)]) ], ) ) - 1 ) if choice == 0: lower_bound = 0 else: lower_bound = choice_sub_nodes[choice - 1].Order if choice == len(choice_sub_nodes): upper_bound = lower_bound + 200 else: upper_bound = choice_sub_nodes[choice].Order order = round((upper_bound + lower_bound) / 2) return order
[docs] def prompt_for_parent_node_id(top_level_nodes): choice = SelectMenu( [MenuOption(x.TextValue, x.NavigationNodeID.pyval) for x in top_level_nodes], "\nWhich menu should this nav node live under? (Leave blank to insert at top level nav)", subheaders=["--Online Top Level Navigation Menu--"], allow_blank=True, ).prompt() return choice
[docs] def prompt_for_central_parent_node_id(top_level_nodes): choice = SelectMenu( [MenuOption(x.TextValue, x.NavigationID.pyval) for x in top_level_nodes], "\nWhich menu should this nav node live under?", subheaders=["--Central Top Level Navigation Menu--"], allow_blank=False, ).prompt() return choice
[docs] def prompt_for_css_class(default=None): css_classes = NavNode.AVAILABLE_ICONS choice = SelectMenu( [MenuOption("{}".format(x), x) for x in css_classes], "Which Icon should be displayed? (Leave blank for default)", subheaders=["--Current list of icons--"], default=default, allow_blank=True, ).prompt() return choice
[docs] def prompt_for_nav_node(nav_nodes): nav_node = SelectMenu( [MenuOption(x.TextValue.text, x) for x in nav_nodes], "Which Nav Node?" ).prompt() return nav_node
[docs] def prompt_for_device_bitflag(default="7"): device_bitflag = textui.query( "\nDevice Bitflag?", default=default, validators=[ validators.OptionValidator( [str(x) for x in range(0, 8)], message="Device Bitflag must be between 0 and 7", ) ], ) return device_bitflag
[docs] def prompt_for_enable_nav(default="1") -> str: enable_nav = textui.query( "\nEnabled?", default=default, validators=[ validators.BooleanValidator(message="Please enter a valid boolean value.") ], ) return enable_nav
[docs] def prompt_for_route_params(): route_params = textui.query( "\nRoute Params? (Formatted as a json string)", validators=[validators.RegexValidator(r".*")], ) return route_params
[docs] class CentralNavMenu: def __init__(self, nodes: List[Element]): self.nodes = nodes self._sorted_nodes = None self._child_nodes = None self._top_level_nodes = None
[docs] def clear_saved_properties(self): self._sorted_nodes = None self._top_level_nodes = None self._child_nodes = None
[docs] def remove_node(self, short_name): for item in self.nodes: if item.ShortName == short_name: self.nodes.remove(item) break self.clear_saved_properties()
[docs] def update_node( self, nav_node_id: int, ui_text: str, order: int, css_class: Optional[str] = None, parent_nav_node_id: Optional[int] = None, form_id: Optional[int] = None, ): for item in self.nodes: if item.NavigationID == nav_node_id: item.ParentNavigationId = parent_nav_node_id item.CssClass = css_class item.Order = order item.TextValue = ui_text item.FormID = form_id self.clear_saved_properties()
@property def top_level_nodes(self) -> List[Element]: if not self._top_level_nodes: parent_nodes = [ x.NavigationID.text for x in self.nodes if x.find("ParentNavigationID") is None ] nodes = [ x for x in self.nodes if x.find("ParentNavigationID") and x.ParentNavigationID.text in parent_nodes ] top_level_nodes = sorted(nodes, key=lambda x: x.Order.pyval) self._top_level_nodes = top_level_nodes return self._top_level_nodes @property def child_nodes(self) -> List[Element]: if not self._child_nodes: root_nodes = [x for x in self.nodes if x.find("ParentNavigationID") is None] nodes = [ x for x in self.nodes if x not in self.top_level_nodes and x not in root_nodes ] child_nodes = sorted(nodes, key=lambda x: x.Order.pyval) self._child_nodes = child_nodes return self._child_nodes
[docs] def get_node_by_id(self, node_id: int) -> Element: """Returns None if no ID matches""" node_id = int(node_id) for nav_node in self.nodes: if nav_node.NavigationID == node_id: return nav_node return None
@property def sorted_nodes(self) -> List[Element]: if not self._sorted_nodes: sorted_nodes = [] for row in self.top_level_nodes: sorted_nodes.append(row) for child in self.child_nodes: if child.ParentNavigationID != row.NavigationID: continue sorted_nodes.append(child) self._sorted_nodes = sorted_nodes return self._sorted_nodes
[docs] class CentralNavNodeRow(RepresentationRowBase): NavigationID: IntElement = "NavigationID" TextValue: StringElement = "TextValue" ParentNavigationID: IntElement = "ParentNavigationID" Order: IntElement = "Order" ShortName: StringElement = "ShortName" FormID: IntElement = "FormID" CssClass: StringElement = "CssClass"