Skip to content

Commit

Permalink
Update menu generator to better display existing schema
Browse files Browse the repository at this point in the history
  • Loading branch information
dgarros committed Oct 24, 2024
1 parent 4ab4ea3 commit 8d288ec
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 32 deletions.
2 changes: 1 addition & 1 deletion backend/infrahub/menu/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ class MenuSection(InfrahubStringEnum):


DEFAULT_MENU = "Other"
FULL_DEFAULT_MENU = "Builtin:Other"
FULL_DEFAULT_MENU = "BuiltinOther"
63 changes: 42 additions & 21 deletions backend/infrahub/menu/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@


def get_full_name(obj: CoreMenuItem) -> str:
return f"{obj.namespace.value}:{obj.name.value}"
return f"{obj.namespace.value}{obj.name.value}"


# pylint: disable=too-many-branches
# pylint: disable=too-many-branches,too-many-statements
async def generate_menu(
db: InfrahubDatabase, branch: Branch, menu_items: list[CoreMenuItem], account: AccountSession | None = None
) -> MenuDict:
Expand Down Expand Up @@ -67,33 +67,54 @@ async def generate_menu(
parent_item=parent_full_name,
)

default_menu = structure.find_item(name=FULL_DEFAULT_MENU)
if not default_menu:
raise ValueError("Unable to locate the default menu item")
items_to_add = {schema.kind: False for schema in full_schema.values() if schema.include_in_menu is True}

for schema in full_schema.values():
if schema.include_in_menu is False:
continue
nbr_remaining_items_last_round = len(items_to_add.values())

menu_item = MenuItemDict.from_schema(model=schema)
already_in_schema = bool(structure.find_item(name=menu_item.identifier))
if already_in_schema:
continue
while not all(items_to_add.values()):
nbr_remaining_items = len([value for value in items_to_add.values() if value is False])

for item_name, already_done in items_to_add.items():
if already_done:
continue

if schema.menu_placement:
menu_placement = structure.find_item(name=schema.menu_placement)
schema = full_schema[item_name]
menu_item = MenuItemDict.from_schema(model=schema)
already_in_schema = bool(structure.find_item(name=menu_item.identifier))
if already_in_schema:
items_to_add[item_name] = True
continue

if menu_placement:
if not schema.menu_placement:
structure.data[menu_item.identifier] = menu_item
items_to_add[item_name] = True
elif menu_placement := structure.find_item(name=schema.menu_placement):
menu_placement.children[menu_item.identifier] = menu_item
items_to_add[item_name] = True
continue

log.warning(
"new_menu_request: unable to find the menu_placement defined in the schema",
branch=branch.name,
item=schema.kind,
menu_placement=schema.menu_placement,
)
if nbr_remaining_items_last_round == nbr_remaining_items:
break

# ----------------------------------------------------------------------------
# Assign the remaining items for which we couldn't find the menu_placement to the default menu
# ----------------------------------------------------------------------------
default_menu = structure.find_item(name=FULL_DEFAULT_MENU)
if not default_menu:
raise ValueError("Unable to locate the default menu item")

for item_name, already_done in items_to_add.items():
if already_done:
continue
schema = full_schema[item_name]
menu_item = MenuItemDict.from_schema(model=schema)
log.warning(
"new_menu_request: unable to find the menu_placement defined in the schema",
branch=branch.name,
item=schema.kind,
menu_placement=schema.menu_placement,
)
default_menu.children[menu_item.identifier] = menu_item
items_to_add[item_name] = True

return structure
4 changes: 2 additions & 2 deletions backend/infrahub/menu/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ def get_full_name(obj: CoreMenuItem | NodeSchema | GenericSchema | ProfileSchema


def _get_full_name_node(obj: CoreMenuItem) -> str:
return f"{obj.namespace.value}:{obj.name.value}"
return f"{obj.namespace.value}{obj.name.value}"


def _get_full_name_schema(node: MainSchemaTypes) -> str:
return f"{node.namespace}:{node.name}"
return f"{node.namespace}{node.name}"


@dataclass
Expand Down
75 changes: 67 additions & 8 deletions backend/tests/unit/menu/test_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
from infrahub.core.protocols import CoreMenuItem
from infrahub.core.schema import SchemaRoot
from infrahub.database import InfrahubDatabase
from infrahub.menu.constants import MenuSection
from infrahub.menu.constants import FULL_DEFAULT_MENU, MenuSection
from infrahub.menu.generator import generate_menu
from infrahub.menu.models import MenuItemDefinition
from infrahub.menu.utils import create_menu_children


def generate_menu_fixtures(prefix: str = "Menu", depth: int = 1, nbr_item: int = 10) -> list[MenuItemDefinition]:
max_depth = 3
next_level_item: int = 5
next_level_item: int = 3

menu: list[MenuItemDefinition] = []

Expand All @@ -33,21 +33,21 @@ def generate_menu_fixtures(prefix: str = "Menu", depth: int = 1, nbr_item: int =
return menu


async def test_generate_menu(
async def test_generate_menu_placement(
db: InfrahubDatabase,
default_branch: Branch,
car_person_schema_generics: SchemaRoot,
helper,
):
schema_branch = registry.schema.get_schema_branch(name=default_branch.name)

schema_electriccar = schema_branch.get(name="TestElectricCar")
schema_electriccar.menu_placement = "Builtin:ObjectManagement"
schema_branch.set(name="TestElectricCar", schema=schema_electriccar)
schema_car = schema_branch.get(name="TestCar")
schema_car.menu_placement = "BuiltinObjectManagement"
schema_branch.set(name="TestCar", schema=schema_car)

await create_default_menu(db=db)

new_menu_items = generate_menu_fixtures(nbr_item=5)
new_menu_items = generate_menu_fixtures(nbr_item=2)

for item in new_menu_items:
obj = await item.to_node(db=db)
Expand All @@ -61,4 +61,63 @@ async def test_generate_menu(
menu = await generate_menu(db=db, branch=default_branch, menu_items=menu_items)

assert menu
assert "Test:Menu0" in menu.data.keys()
assert "TestMenu0" in menu.data.keys()
assert "BuiltinObjectManagement" in menu.data.keys()
assert "TestCar" in menu.data["BuiltinObjectManagement"].children.keys()


async def test_generate_menu_top_level(
db: InfrahubDatabase,
default_branch: Branch,
car_person_schema_generics: SchemaRoot,
helper,
):
await create_default_menu(db=db)

new_menu_items = generate_menu_fixtures(nbr_item=2)

for item in new_menu_items:
obj = await item.to_node(db=db)
await obj.save(db=db)
if item.children:
await create_menu_children(db=db, parent=obj, children=item.children)

menu_items = await registry.manager.query(
db=db, schema=CoreMenuItem, branch=default_branch, prefetch_relationships=True
)
menu = await generate_menu(db=db, branch=default_branch, menu_items=menu_items)

assert menu
assert "TestMenu0" in menu.data.keys()
assert "TestCar" in menu.data.keys()


async def test_generate_menu_default(
db: InfrahubDatabase,
default_branch: Branch,
car_person_schema_generics: SchemaRoot,
helper,
):
schema_branch = registry.schema.get_schema_branch(name=default_branch.name)
schema_car = schema_branch.get(name="TestCar")
schema_car.menu_placement = "DoesNotExist"
schema_branch.set(name="TestCar", schema=schema_car)

await create_default_menu(db=db)

new_menu_items = generate_menu_fixtures(nbr_item=2)

for item in new_menu_items:
obj = await item.to_node(db=db)
await obj.save(db=db)
if item.children:
await create_menu_children(db=db, parent=obj, children=item.children)

menu_items = await registry.manager.query(
db=db, schema=CoreMenuItem, branch=default_branch, prefetch_relationships=True
)
menu = await generate_menu(db=db, branch=default_branch, menu_items=menu_items)

assert menu
assert "TestMenu0" in menu.data.keys()
assert "TestCar" in menu.data[FULL_DEFAULT_MENU].children.keys()

0 comments on commit 8d288ec

Please sign in to comment.