Fix duplicate menu rows on HTMX navigation between depth levels
When navigating from a deeper page (e.g. day) to a shallower one (e.g. calendar) via HTMX, orphaned header rows from the deeper page persisted in the DOM because OOB swaps only replaced specific child divs, not siblings. Fix by sending empty OOB swaps to clear all header row IDs not present at the current depth. Applied to events (calendars/calendar/day/entry/admin/slots) and market (market_home/browse/product/admin). Also restore app_label in root header. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,25 @@ from shared.sexp.helpers import (
|
||||
load_service_components(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# OOB orphan cleanup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
_MARKET_DEEP_IDS = [
|
||||
"product-admin-row", "product-admin-header-child",
|
||||
"product-row", "product-header-child",
|
||||
"market-admin-row", "market-admin-header-child",
|
||||
"market-row", "market-header-child",
|
||||
"post-admin-row", "post-admin-header-child",
|
||||
]
|
||||
|
||||
|
||||
def _clear_deeper_oob(*keep_ids: str) -> str:
|
||||
"""Clear all market header rows/children NOT in keep_ids."""
|
||||
to_clear = [i for i in _MARKET_DEEP_IDS if i not in keep_ids]
|
||||
return "".join(f'<div id="{i}" hx-swap-oob="outerHTML"></div>' for i in to_clear)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Price helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -1285,6 +1304,8 @@ async def render_market_home_oob(ctx: dict) -> str:
|
||||
oobs = _oob_header_html("post-header-child", "market-header-child",
|
||||
_market_header_html(ctx))
|
||||
oobs += _post_header_html(ctx, oob=True)
|
||||
oobs += _clear_deeper_oob("post-row", "post-header-child",
|
||||
"market-row", "market-header-child")
|
||||
menu = _mobile_nav_panel_html(ctx)
|
||||
return oob_page(ctx, oobs_html=oobs, content_html=content, menu_html=menu)
|
||||
|
||||
@@ -1334,6 +1355,8 @@ async def render_browse_oob(ctx: dict) -> str:
|
||||
oobs = _oob_header_html("post-header-child", "market-header-child",
|
||||
_market_header_html(ctx))
|
||||
oobs += _post_header_html(ctx, oob=True)
|
||||
oobs += _clear_deeper_oob("post-row", "post-header-child",
|
||||
"market-row", "market-header-child")
|
||||
menu = _mobile_nav_panel_html(ctx)
|
||||
filter_html = _mobile_filter_summary_html(ctx)
|
||||
aside_html = _desktop_filter_html(ctx)
|
||||
@@ -1369,6 +1392,9 @@ async def render_product_oob(ctx: dict, d: dict) -> str:
|
||||
oobs = _market_header_html(ctx, oob=True)
|
||||
oobs += _oob_header_html("market-header-child", "product-header-child",
|
||||
_product_header_html(ctx, d))
|
||||
oobs += _clear_deeper_oob("post-row", "post-header-child",
|
||||
"market-row", "market-header-child",
|
||||
"product-row", "product-header-child")
|
||||
menu = _mobile_nav_panel_html(ctx)
|
||||
return oob_page(ctx, oobs_html=oobs, content_html=content, menu_html=menu)
|
||||
|
||||
@@ -1395,6 +1421,10 @@ async def render_product_admin_oob(ctx: dict, d: dict) -> str:
|
||||
oobs = _product_header_html(ctx, d, oob=True)
|
||||
oobs += _oob_header_html("product-header-child", "product-admin-header-child",
|
||||
_product_admin_header_html(ctx, d))
|
||||
oobs += _clear_deeper_oob("post-row", "post-header-child",
|
||||
"market-row", "market-header-child",
|
||||
"product-row", "product-header-child",
|
||||
"product-admin-row", "product-admin-header-child")
|
||||
return oob_page(ctx, oobs_html=oobs, content_html=content)
|
||||
|
||||
|
||||
@@ -1433,6 +1463,9 @@ async def render_market_admin_oob(ctx: dict) -> str:
|
||||
oobs = _market_header_html(ctx, oob=True)
|
||||
oobs += _oob_header_html("market-header-child", "market-admin-header-child",
|
||||
_market_admin_header_html(ctx, selected="markets"))
|
||||
oobs += _clear_deeper_oob("post-row", "post-header-child",
|
||||
"market-row", "market-header-child",
|
||||
"market-admin-row", "market-admin-header-child")
|
||||
return oob_page(ctx, oobs_html=oobs, content_html=content)
|
||||
|
||||
|
||||
@@ -1461,6 +1494,8 @@ async def render_page_admin_oob(ctx: dict) -> str:
|
||||
"""OOB response: page-level market admin."""
|
||||
slug = (ctx.get("post") or {}).get("slug", "")
|
||||
oobs = post_admin_header_html(ctx, slug, oob=True, selected="markets")
|
||||
oobs += _clear_deeper_oob("post-row", "post-header-child",
|
||||
"post-admin-row", "post-admin-header-child")
|
||||
content = '<div id="main-panel"><div class="p-4 text-stone-500">Market admin</div></div>'
|
||||
return oob_page(ctx, oobs_html=oobs, content_html=content)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user