Fix NIL leaking into Python service calls, add mobile navigation menu
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m10s

Strip NIL values at I/O primitive boundaries (frag, query, action, service)
to prevent _Nil objects from reaching Python code that expects None. Add
mobile_nav_sx() helper that auto-populates the hamburger menu from nav_tree
and auth_menu context fragments when no menu slot is provided.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-03 10:45:52 +00:00
parent a8c0741f54
commit 5b4cacaf19
2 changed files with 38 additions and 5 deletions

View File

@@ -102,6 +102,26 @@ def root_header_sx(ctx: dict, *, oob: bool = False) -> str:
)
def mobile_nav_sx(ctx: dict) -> str:
"""Build mobile navigation panel from context fragments (nav_tree, auth_menu)."""
nav_tree = ctx.get("nav_tree") or ""
auth_menu = ctx.get("auth_menu") or ""
if not nav_tree and not auth_menu:
return ""
parts: list[str] = []
if nav_tree:
nav_tree_sx = _as_sx(nav_tree)
parts.append(
f'(div :class "flex flex-col gap-2 p-3 text-sm" {nav_tree_sx})'
)
if auth_menu:
auth_sx = _as_sx(auth_menu)
parts.append(
f'(div :class "p-3 border-t border-stone-200" {auth_sx})'
)
return "(<> " + " ".join(parts) + ")" if parts else ""
def search_mobile_sx(ctx: dict) -> str:
"""Build mobile search input as sx call string."""
return sx_call("search-mobile",
@@ -279,6 +299,9 @@ def full_page_sx(ctx: dict, *, header_rows: str,
meta_html: raw HTML injected into the <head> shell (legacy).
meta: sx source for meta tags — auto-hoisted to <head> by sx.js.
"""
# Auto-generate mobile nav from context when no menu provided
if not menu:
menu = mobile_nav_sx(ctx)
body_sx = sx_call("app-body",
header_rows=SxExpr(f"(<> {header_rows})") if header_rows else None,
filter=SxExpr(filter) if filter else None,