Files
mono/events/sx/layouts.sx
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

454 lines
19 KiB
Plaintext

;; Events layout defcomps — fully self-contained via IO primitives.
;; Registered via register_sx_layout in helpers.py.
;; ---------------------------------------------------------------------------
;; Auto-fetching header macros — calendar, day, entry, slot, tickets
;; ---------------------------------------------------------------------------
(defmacro ~events-calendar-header-auto (oob)
"Calendar header row using (events-calendar-ctx)."
(quasiquote
(let ((__cal (events-calendar-ctx))
(__sc (select-colours)))
(when (get __cal "slug")
(~menu-row-sx :id "calendar-row" :level 3
:link-href (url-for "calendar.get"
:calendar-slug (get __cal "slug"))
:link-label-content (~events-calendar-label
:name (get __cal "name")
:description (get __cal "description"))
:nav (<>
(~nav-link :href (url-for "defpage_slots_listing"
:calendar-slug (get __cal "slug"))
:icon "fa fa-clock" :label "Slots"
:select-colours __sc)
(let ((__rights (app-rights)))
(when (get __rights "admin")
(~nav-link :href (url-for "defpage_calendar_admin"
:calendar-slug (get __cal "slug"))
:icon "fa fa-cog"
:select-colours __sc))))
:child-id "calendar-header-child"
:oob (unquote oob))))))
(defmacro ~events-calendar-admin-header-auto (oob)
"Calendar admin header row."
(quasiquote
(let ((__cal (events-calendar-ctx))
(__sc (select-colours)))
(when (get __cal "slug")
(~menu-row-sx :id "calendar-admin-row" :level 4
:link-label "admin" :icon "fa fa-cog"
:nav (<>
(~nav-link :href (url-for "defpage_slots_listing"
:calendar-slug (get __cal "slug"))
:label "slots" :select-colours __sc)
(~nav-link :href (url-for "calendar.admin.calendar_description_edit"
:calendar-slug (get __cal "slug"))
:label "description" :select-colours __sc))
:child-id "calendar-admin-header-child"
:oob (unquote oob))))))
(defmacro ~events-day-header-auto (oob)
"Day header row using (events-day-ctx)."
(quasiquote
(let ((__day (events-day-ctx))
(__cal (events-calendar-ctx)))
(when (get __day "date-str")
(~menu-row-sx :id "day-row" :level 4
:link-href (url-for "calendar.day.show_day"
:calendar-slug (get __cal "slug")
:year (get __day "year")
:month (get __day "month")
:day (get __day "day"))
:link-label-content (~events-day-label
:date-str (get __day "date-str"))
:nav (get __day "nav")
:child-id "day-header-child"
:oob (unquote oob))))))
(defmacro ~events-day-admin-header-auto (oob)
"Day admin header row."
(quasiquote
(let ((__day (events-day-ctx))
(__cal (events-calendar-ctx)))
(when (get __day "date-str")
(~menu-row-sx :id "day-admin-row" :level 5
:link-href (url-for "defpage_day_admin"
:calendar-slug (get __cal "slug")
:year (get __day "year")
:month (get __day "month")
:day (get __day "day"))
:link-label "admin" :icon "fa fa-cog"
:child-id "day-admin-header-child"
:oob (unquote oob))))))
(defmacro ~events-entry-header-auto (oob)
"Entry header row using (events-entry-ctx)."
(quasiquote
(let ((__ectx (events-entry-ctx)))
(when (get __ectx "id")
(~menu-row-sx :id "entry-row" :level 5
:link-href (get __ectx "link-href")
:link-label-content (~events-entry-label
:entry-id (get __ectx "id")
:title (~events-entry-title :name (get __ectx "name"))
:times (~events-entry-times :time-str (get __ectx "time-str")))
:nav (get __ectx "nav")
:child-id "entry-header-child"
:oob (unquote oob))))))
(defmacro ~events-entry-admin-header-auto (oob)
"Entry admin header row."
(quasiquote
(let ((__ectx (events-entry-ctx)))
(when (get __ectx "id")
(~menu-row-sx :id "entry-admin-row" :level 6
:link-href (get __ectx "admin-href")
:link-label "admin" :icon "fa fa-cog"
:nav (when (get __ectx "is-admin")
(~nav-link :href (get __ectx "ticket-types-href")
:label "ticket_types"
:select-colours (get __ectx "select-colours")))
:child-id "entry-admin-header-child"
:oob (unquote oob))))))
(defmacro ~events-slot-header-auto (oob)
"Slot detail header row using (events-slot-ctx)."
(quasiquote
(let ((__slot (events-slot-ctx)))
(when (get __slot "name")
(~menu-row-sx :id "slot-row" :level 5
:link-label-content (~events-slot-label
:name (get __slot "name")
:description (get __slot "description"))
:child-id "slot-header-child"
:oob (unquote oob))))))
(defmacro ~events-ticket-types-header-auto (oob)
"Ticket types header row."
(quasiquote
(let ((__ectx (events-entry-ctx))
(__cal (events-calendar-ctx)))
(when (get __ectx "id")
(~menu-row-sx :id "ticket_types-row" :level 7
:link-href (get __ectx "ticket-types-href")
:link-label-content (<>
(i :class "fa fa-ticket")
(div :class "shrink-0" "ticket types"))
:nav (~events-admin-placeholder-nav)
:child-id "ticket_type-header-child"
:oob (unquote oob))))))
(defmacro ~events-ticket-type-header-auto (oob)
"Single ticket type header row using (events-ticket-type-ctx)."
(quasiquote
(let ((__tt (events-ticket-type-ctx)))
(when (get __tt "id")
(~menu-row-sx :id "ticket_type-row" :level 8
:link-href (get __tt "link-href")
:link-label-content (div :class "flex flex-col md:flex-row md:gap-2 items-center"
(div :class "flex flex-row items-center gap-2"
(i :class "fa fa-ticket")
(div :class "shrink-0" (get __tt "name"))))
:nav (~events-admin-placeholder-nav)
:child-id "ticket_type-header-child-inner"
:oob (unquote oob))))))
(defmacro ~events-markets-header-auto (oob)
"Markets section header row."
(quasiquote
(~menu-row-sx :id "markets-row" :level 3
:link-href (url-for "defpage_events_markets")
:link-label-content (~events-markets-label)
:child-id "markets-header-child"
:oob (unquote oob))))
;; ---------------------------------------------------------------------------
;; OOB clear helpers — clear deeper header rows not present at this level
;; ---------------------------------------------------------------------------
(defcomp ~events-clear-oob-cal-admin ()
"Clear OOB divs for cal-admin level (keeps down to calendar-admin)."
(<>
(~clear-oob-div :id "entry-admin-row")
(~clear-oob-div :id "entry-admin-header-child")
(~clear-oob-div :id "entry-row")
(~clear-oob-div :id "entry-header-child")
(~clear-oob-div :id "day-admin-row")
(~clear-oob-div :id "day-admin-header-child")
(~clear-oob-div :id "day-row")
(~clear-oob-div :id "day-header-child")
(~clear-oob-div :id "calendars-row")
(~clear-oob-div :id "calendars-header-child")))
(defcomp ~events-clear-oob-slot ()
"Clear OOB divs for slot level."
(<>
(~clear-oob-div :id "entry-admin-row")
(~clear-oob-div :id "entry-admin-header-child")
(~clear-oob-div :id "entry-row")
(~clear-oob-div :id "entry-header-child")
(~clear-oob-div :id "day-admin-row")
(~clear-oob-div :id "day-admin-header-child")
(~clear-oob-div :id "day-row")
(~clear-oob-div :id "day-header-child")
(~clear-oob-div :id "calendars-row")
(~clear-oob-div :id "calendars-header-child")))
(defcomp ~events-clear-oob-day-admin ()
"Clear OOB divs for day-admin level."
(<>
(~clear-oob-div :id "entry-admin-row")
(~clear-oob-div :id "entry-admin-header-child")
(~clear-oob-div :id "entry-row")
(~clear-oob-div :id "entry-header-child")
(~clear-oob-div :id "calendars-row")
(~clear-oob-div :id "calendars-header-child")))
(defcomp ~events-clear-oob-entry ()
"Clear OOB divs for entry level (public, no admin rows)."
(<>
(~clear-oob-div :id "entry-admin-row")
(~clear-oob-div :id "entry-admin-header-child")
(~clear-oob-div :id "day-admin-row")
(~clear-oob-div :id "day-admin-header-child")
(~clear-oob-div :id "calendar-admin-row")
(~clear-oob-div :id "calendar-admin-header-child")
(~clear-oob-div :id "calendars-row")
(~clear-oob-div :id "calendars-header-child")
(~clear-oob-div :id "post-admin-row")
(~clear-oob-div :id "post-admin-header-child")))
(defcomp ~events-clear-oob-entry-admin ()
"Clear OOB divs for entry-admin level."
(<>
(~clear-oob-div :id "calendars-row")
(~clear-oob-div :id "calendars-header-child")))
;; ---------------------------------------------------------------------------
;; OOB clear helpers for renders.py — clear all deeper IDs except kept ones
;; ---------------------------------------------------------------------------
(defcomp ~events-clear-deeper-post ()
"Clear all events IDs deeper than post level."
(<>
(~clear-oob-div :id "entry-admin-row") (~clear-oob-div :id "entry-admin-header-child")
(~clear-oob-div :id "entry-row") (~clear-oob-div :id "entry-header-child")
(~clear-oob-div :id "day-admin-row") (~clear-oob-div :id "day-admin-header-child")
(~clear-oob-div :id "day-row") (~clear-oob-div :id "day-header-child")
(~clear-oob-div :id "calendar-admin-row") (~clear-oob-div :id "calendar-admin-header-child")
(~clear-oob-div :id "calendar-row") (~clear-oob-div :id "calendar-header-child")
(~clear-oob-div :id "calendars-row") (~clear-oob-div :id "calendars-header-child")
(~clear-oob-div :id "post-admin-row") (~clear-oob-div :id "post-admin-header-child")))
(defcomp ~events-clear-deeper-post-admin ()
"Clear all events IDs deeper than post-admin level."
(<>
(~clear-oob-div :id "entry-admin-row") (~clear-oob-div :id "entry-admin-header-child")
(~clear-oob-div :id "entry-row") (~clear-oob-div :id "entry-header-child")
(~clear-oob-div :id "day-admin-row") (~clear-oob-div :id "day-admin-header-child")
(~clear-oob-div :id "day-row") (~clear-oob-div :id "day-header-child")
(~clear-oob-div :id "calendar-admin-row") (~clear-oob-div :id "calendar-admin-header-child")
(~clear-oob-div :id "calendar-row") (~clear-oob-div :id "calendar-header-child")
(~clear-oob-div :id "calendars-row") (~clear-oob-div :id "calendars-header-child")))
(defcomp ~events-clear-deeper-calendar ()
"Clear all events IDs deeper than calendar level."
(<>
(~clear-oob-div :id "entry-admin-row") (~clear-oob-div :id "entry-admin-header-child")
(~clear-oob-div :id "entry-row") (~clear-oob-div :id "entry-header-child")
(~clear-oob-div :id "day-admin-row") (~clear-oob-div :id "day-admin-header-child")
(~clear-oob-div :id "day-row") (~clear-oob-div :id "day-header-child")
(~clear-oob-div :id "calendar-admin-row") (~clear-oob-div :id "calendar-admin-header-child")
(~clear-oob-div :id "calendars-row") (~clear-oob-div :id "calendars-header-child")
(~clear-oob-div :id "post-admin-row") (~clear-oob-div :id "post-admin-header-child")))
(defcomp ~events-clear-deeper-day ()
"Clear all events IDs deeper than day level."
(<>
(~clear-oob-div :id "entry-admin-row") (~clear-oob-div :id "entry-admin-header-child")
(~clear-oob-div :id "entry-row") (~clear-oob-div :id "entry-header-child")
(~clear-oob-div :id "day-admin-row") (~clear-oob-div :id "day-admin-header-child")
(~clear-oob-div :id "calendar-admin-row") (~clear-oob-div :id "calendar-admin-header-child")
(~clear-oob-div :id "calendars-row") (~clear-oob-div :id "calendars-header-child")
(~clear-oob-div :id "post-admin-row") (~clear-oob-div :id "post-admin-header-child")))
;; ---------------------------------------------------------------------------
;; Calendar admin layout: root + post + child(post-admin + cal + cal-admin)
;; ---------------------------------------------------------------------------
(defcomp ~events-cal-admin-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
:inner (<> (~post-header-auto nil)
(~post-admin-header-auto nil "calendars")
(~events-calendar-header-auto nil)
(~events-calendar-admin-header-auto nil)))))
(defcomp ~events-cal-admin-layout-oob ()
(<> (~post-admin-header-auto true "calendars")
(~events-calendar-header-auto true)
(~oob-header-sx :parent-id "calendar-header-child"
:row (~events-calendar-admin-header-auto nil))
(~events-clear-oob-cal-admin)
(~root-header-auto true)))
;; ---------------------------------------------------------------------------
;; Slots layout: same full as cal-admin
;; ---------------------------------------------------------------------------
(defcomp ~events-slots-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
:inner (<> (~post-header-auto nil)
(~post-admin-header-auto nil "calendars")
(~events-calendar-header-auto nil)
(~events-calendar-admin-header-auto nil)))))
(defcomp ~events-slots-layout-oob ()
(<> (~post-admin-header-auto true "calendars")
(~events-calendar-admin-header-auto true)
(~events-clear-oob-cal-admin)
(~root-header-auto true)))
;; ---------------------------------------------------------------------------
;; Slot detail layout: root + post + child(admin + cal + cal-admin + slot)
;; ---------------------------------------------------------------------------
(defcomp ~events-slot-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
:inner (<> (~post-header-auto nil)
(~post-admin-header-auto nil "calendars")
(~events-calendar-header-auto nil)
(~events-calendar-admin-header-auto nil)
(~events-slot-header-auto nil)))))
(defcomp ~events-slot-layout-oob ()
(<> (~post-admin-header-auto true "calendars")
(~events-calendar-admin-header-auto true)
(~oob-header-sx :parent-id "calendar-admin-header-child"
:row (~events-slot-header-auto nil))
(~events-clear-oob-slot)
(~root-header-auto true)))
;; ---------------------------------------------------------------------------
;; Day admin layout: root + post + child(admin + cal + day + day-admin)
;; ---------------------------------------------------------------------------
(defcomp ~events-day-admin-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
:inner (<> (~post-header-auto nil)
(~post-admin-header-auto nil "calendars")
(~events-calendar-header-auto nil)
(~events-day-header-auto nil)
(~events-day-admin-header-auto nil)))))
(defcomp ~events-day-admin-layout-oob ()
(<> (~post-admin-header-auto true "calendars")
(~events-calendar-header-auto true)
(~oob-header-sx :parent-id "day-header-child"
:row (~events-day-admin-header-auto nil))
(~events-clear-oob-day-admin)
(~root-header-auto true)))
;; ---------------------------------------------------------------------------
;; Entry layout: root + child(post + cal + day + entry) — public, no admin
;; ---------------------------------------------------------------------------
(defcomp ~events-entry-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
:inner (<> (~post-header-auto nil)
(~events-calendar-header-auto nil)
(~events-day-header-auto nil)
(~events-entry-header-auto nil)))))
(defcomp ~events-entry-layout-oob ()
(<> (~events-day-header-auto true)
(~oob-header-sx :parent-id "day-header-child"
:row (~events-entry-header-auto nil))
(~events-clear-oob-entry)
(~root-header-auto true)))
;; ---------------------------------------------------------------------------
;; Entry admin layout: root + post + child(admin + cal + day + entry + entry-admin)
;; ---------------------------------------------------------------------------
(defcomp ~events-entry-admin-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
:inner (<> (~post-header-auto nil)
(~post-admin-header-auto nil "calendars")
(~events-calendar-header-auto nil)
(~events-day-header-auto nil)
(~events-entry-header-auto nil)
(~events-entry-admin-header-auto nil)))))
(defcomp ~events-entry-admin-layout-oob ()
(<> (~post-admin-header-auto true "calendars")
(~events-entry-header-auto true)
(~oob-header-sx :parent-id "entry-header-child"
:row (~events-entry-admin-header-auto nil))
(~events-clear-oob-entry-admin)
(~root-header-auto true)))
;; ---------------------------------------------------------------------------
;; Ticket types layout: root + child(post + cal + day + entry + entry-admin + ticket-types)
;; ---------------------------------------------------------------------------
(defcomp ~events-ticket-types-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
:inner (<> (~post-header-auto nil)
(~events-calendar-header-auto nil)
(~events-day-header-auto nil)
(~events-entry-header-auto nil)
(~events-entry-admin-header-auto nil)
(~events-ticket-types-header-auto nil)))))
(defcomp ~events-ticket-types-layout-oob ()
(<> (~events-entry-admin-header-auto true)
(~oob-header-sx :parent-id "entry-admin-header-child"
:row (~events-ticket-types-header-auto nil))
(~root-header-auto true)))
;; ---------------------------------------------------------------------------
;; Ticket type layout: all headers down to ticket-type
;; ---------------------------------------------------------------------------
(defcomp ~events-ticket-type-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
:inner (<> (~post-header-auto nil)
(~events-calendar-header-auto nil)
(~events-day-header-auto nil)
(~events-entry-header-auto nil)
(~events-entry-admin-header-auto nil)
(~events-ticket-types-header-auto nil)
(~events-ticket-type-header-auto nil)))))
(defcomp ~events-ticket-type-layout-oob ()
(<> (~events-ticket-types-header-auto true)
(~oob-header-sx :parent-id "ticket_types-header-child"
:row (~events-ticket-type-header-auto nil))
(~root-header-auto true)))
;; ---------------------------------------------------------------------------
;; Markets layout: root + child(post + markets)
;; ---------------------------------------------------------------------------
(defcomp ~events-markets-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
:inner (<> (~post-header-auto nil)
(~events-markets-header-auto nil)))))
(defcomp ~events-markets-layout-oob ()
(<> (~post-header-auto true)
(~oob-header-sx :parent-id "post-header-child"
:row (~events-markets-header-auto nil))
(~root-header-auto true)))