Files
mono/events/sxc/pages/renders.py
giles 51ebf347ba
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 2m33s
Move events/market/blog composition from Python to .sx defcomps (Phase 9)
Continues the pattern of eliminating Python sx_call tree-building in favour
of data-driven .sx defcomps. POST/PUT/DELETE routes now pass plain data
(dicts, lists, scalars) and let .sx handle iteration, conditionals, and
layout via map/let/when/if. Single response components wrap OOB swaps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 08:17:09 +00:00

284 lines
11 KiB
Python

"""Top-level render_* functions — public API called from route handlers."""
from __future__ import annotations
from shared.sx.helpers import (
render_to_sx_with_env, sx_call,
post_admin_header_sx, oob_header_sx,
header_child_sx, full_page_sx, oob_page_sx,
)
from .utils import _ensure_container_nav
from .calendar import (
_post_header_sx, _calendars_header_sx,
_calendar_header_sx, _day_header_sx,
_calendars_main_panel_sx,
_calendar_main_panel_html, _day_main_panel_html,
_calendar_admin_main_panel_html,
_calendar_description_display_html,
_markets_main_panel_html,
)
from .entries import (
_events_main_panel_html, _entry_cards_html,
_entry_main_panel_html,
)
from .tickets import render_buy_form
# ---------------------------------------------------------------------------
# All events
# ---------------------------------------------------------------------------
async def render_all_events_page(ctx: dict, entries, has_more, pending_tickets,
page_info, page, view) -> str:
"""Full page: all events listing."""
from quart import url_for
from shared.utils import route_prefix
from shared.infrastructure.urls import events_url
prefix = route_prefix()
view_param = f"&view={view}" if view != "list" else ""
ticket_url = url_for("all_events.adjust_ticket")
next_url = prefix + url_for("all_events.entries_fragment", page=page + 1) + (f"?view={view}" if view != "list" else "")
content = _events_main_panel_html(
ctx, entries, has_more, pending_tickets, page_info,
page, view, ticket_url, next_url, events_url,
)
hdr = await render_to_sx_with_env("layout-root-full", {})
return await full_page_sx(ctx, header_rows=hdr, content=content)
async def render_all_events_oob(ctx: dict, entries, has_more, pending_tickets,
page_info, page, view) -> str:
"""OOB response: all events listing (htmx nav)."""
from quart import url_for
from shared.utils import route_prefix
from shared.infrastructure.urls import events_url
prefix = route_prefix()
ticket_url = url_for("all_events.adjust_ticket")
next_url = prefix + url_for("all_events.entries_fragment", page=page + 1) + (f"?view={view}" if view != "list" else "")
content = _events_main_panel_html(
ctx, entries, has_more, pending_tickets, page_info,
page, view, ticket_url, next_url, events_url,
)
return await oob_page_sx(content=content)
def render_all_events_cards(entries, has_more, pending_tickets,
page_info, page, view) -> str:
"""Pagination fragment: all events cards only."""
from quart import url_for
from shared.utils import route_prefix
from shared.infrastructure.urls import events_url
prefix = route_prefix()
ticket_url = url_for("all_events.adjust_ticket")
next_url = prefix + url_for("all_events.entries_fragment", page=page + 1) + (f"?view={view}" if view != "list" else "")
return _entry_cards_html(
entries, page_info, pending_tickets, ticket_url, events_url,
view, page, has_more, next_url,
)
# ---------------------------------------------------------------------------
# Page summary
# ---------------------------------------------------------------------------
async def render_page_summary_page(ctx: dict, entries, has_more, pending_tickets,
page_info, page, view) -> str:
"""Full page: page-scoped events listing."""
from quart import url_for
from shared.utils import route_prefix
from shared.infrastructure.urls import events_url
prefix = route_prefix()
post = ctx.get("post") or {}
ticket_url = url_for("page_summary.adjust_ticket")
next_url = prefix + url_for("page_summary.entries_fragment", page=page + 1) + (f"?view={view}" if view != "list" else "")
content = _events_main_panel_html(
ctx, entries, has_more, pending_tickets, page_info,
page, view, ticket_url, next_url, events_url,
is_page_scoped=True, post=post,
)
hdr = await render_to_sx_with_env("layout-root-full", {})
hdr += await header_child_sx(await _post_header_sx(ctx))
return await full_page_sx(ctx, header_rows=hdr, content=content)
async def render_page_summary_oob(ctx: dict, entries, has_more, pending_tickets,
page_info, page, view) -> str:
"""OOB response: page-scoped events (htmx nav)."""
from quart import url_for
from shared.utils import route_prefix
from shared.infrastructure.urls import events_url
prefix = route_prefix()
post = ctx.get("post") or {}
ticket_url = url_for("page_summary.adjust_ticket")
next_url = prefix + url_for("page_summary.entries_fragment", page=page + 1) + (f"?view={view}" if view != "list" else "")
content = _events_main_panel_html(
ctx, entries, has_more, pending_tickets, page_info,
page, view, ticket_url, next_url, events_url,
is_page_scoped=True, post=post,
)
oobs = await _post_header_sx(ctx, oob=True)
oobs += sx_call("events-clear-deeper-post")
return await oob_page_sx(oobs=oobs, content=content)
def render_page_summary_cards(entries, has_more, pending_tickets,
page_info, page, view, post) -> str:
"""Pagination fragment: page-scoped events cards only."""
from quart import url_for
from shared.utils import route_prefix
from shared.infrastructure.urls import events_url
prefix = route_prefix()
ticket_url = url_for("page_summary.adjust_ticket")
next_url = prefix + url_for("page_summary.entries_fragment", page=page + 1) + (f"?view={view}" if view != "list" else "")
return _entry_cards_html(
entries, page_info, pending_tickets, ticket_url, events_url,
view, page, has_more, next_url,
is_page_scoped=True, post=post,
)
# ---------------------------------------------------------------------------
# Calendars home
# ---------------------------------------------------------------------------
async def render_calendars_page(ctx: dict) -> str:
"""Full page: calendars listing."""
content = _calendars_main_panel_sx(ctx)
ctx = await _ensure_container_nav(ctx)
slug = (ctx.get("post") or {}).get("slug", "")
root_hdr = await render_to_sx_with_env("layout-root-full", {})
post_hdr = await _post_header_sx(ctx)
admin_hdr = await post_admin_header_sx(ctx, slug, selected="calendars")
return await full_page_sx(ctx, header_rows=root_hdr + post_hdr + admin_hdr, content=content)
async def render_calendars_oob(ctx: dict) -> str:
"""OOB response: calendars listing."""
content = _calendars_main_panel_sx(ctx)
ctx = await _ensure_container_nav(ctx)
slug = (ctx.get("post") or {}).get("slug", "")
oobs = await post_admin_header_sx(ctx, slug, oob=True, selected="calendars")
oobs += sx_call("events-clear-deeper-post-admin")
return await oob_page_sx(oobs=oobs, content=content)
# ---------------------------------------------------------------------------
# Calendar month view
# ---------------------------------------------------------------------------
async def render_calendar_page(ctx: dict) -> str:
"""Full page: calendar month view."""
content = _calendar_main_panel_html(ctx)
hdr = await render_to_sx_with_env("layout-root-full", {})
child = await _post_header_sx(ctx) + _calendar_header_sx(ctx)
hdr += await header_child_sx(child)
return await full_page_sx(ctx, header_rows=hdr, content=content)
async def render_calendar_oob(ctx: dict) -> str:
"""OOB response: calendar month view."""
content = _calendar_main_panel_html(ctx)
oobs = await _post_header_sx(ctx, oob=True)
oobs += await oob_header_sx("post-header-child", "calendar-header-child",
_calendar_header_sx(ctx))
oobs += sx_call("events-clear-deeper-calendar")
return await oob_page_sx(oobs=oobs, content=content)
# ---------------------------------------------------------------------------
# Day detail
# ---------------------------------------------------------------------------
async def render_day_page(ctx: dict) -> str:
"""Full page: day detail."""
content = _day_main_panel_html(ctx)
hdr = await render_to_sx_with_env("layout-root-full", {})
child = (await _post_header_sx(ctx)
+ _calendar_header_sx(ctx) + _day_header_sx(ctx))
hdr += await header_child_sx(child)
return await full_page_sx(ctx, header_rows=hdr, content=content)
async def render_day_oob(ctx: dict) -> str:
"""OOB response: day detail."""
content = _day_main_panel_html(ctx)
oobs = _calendar_header_sx(ctx, oob=True)
oobs += await oob_header_sx("calendar-header-child", "day-header-child",
_day_header_sx(ctx))
oobs += sx_call("events-clear-deeper-day")
return await oob_page_sx(oobs=oobs, content=content)
# ---------------------------------------------------------------------------
# Day main panel -- public API
# ---------------------------------------------------------------------------
def render_day_main_panel(ctx: dict) -> str:
"""Public wrapper for day main panel rendering."""
return _day_main_panel_html(ctx)
# ---------------------------------------------------------------------------
# Calendar description display + edit form
# ---------------------------------------------------------------------------
def render_calendar_description(calendar, *, oob: bool = False) -> str:
"""Render calendar description display with edit button, optionally with OOB title."""
from quart import url_for
from shared.sx.helpers import sx_call
cal_slug = getattr(calendar, "slug", "")
edit_url = url_for("calendar.admin.calendar_description_edit", calendar_slug=cal_slug)
html = _calendar_description_display_html(calendar, edit_url)
if oob:
desc = getattr(calendar, "description", "") or ""
html += sx_call("events-calendar-description-title-oob",
description=desc)
return html
def render_calendar_description_edit(calendar) -> str:
"""Render calendar description edit form."""
from quart import url_for
from shared.browser.app.csrf import generate_csrf_token
from shared.sx.helpers import sx_call
csrf = generate_csrf_token()
cal_slug = getattr(calendar, "slug", "")
desc = getattr(calendar, "description", "") or ""
save_url = url_for("calendar.admin.calendar_description_save", calendar_slug=cal_slug)
cancel_url = url_for("calendar.admin.calendar_description_view", calendar_slug=cal_slug)
return sx_call("events-calendar-description-edit-form",
save_url=save_url, cancel_url=cancel_url,
csrf=csrf, description=desc)
# ---------------------------------------------------------------------------
# Calendars / Markets list panels (for POST create / DELETE)
# ---------------------------------------------------------------------------
def render_calendars_list_panel(ctx: dict) -> str:
"""Render the calendars main panel HTML for POST/DELETE response."""
return _calendars_main_panel_sx(ctx)
def render_markets_list_panel(ctx: dict) -> str:
"""Render the markets main panel HTML for POST/DELETE response."""
return _markets_main_panel_html(ctx)