Eliminate post sub-admin rows, highlight active nav on admin row
Remove the separate sub-admin header rows (data, entries, edit, settings) that caused duplicate/stale rows on HTMX navigation and font styling breaks. Instead, pass selected= to the admin row to highlight the active nav item via aria-selected styling. External nav items (calendars, markets, payments) also gain is-selected and select-colours support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,8 +10,12 @@
|
|||||||
(defcomp ~blog-admin-label ()
|
(defcomp ~blog-admin-label ()
|
||||||
(<> (i :class "fa fa-shield-halved" :aria-hidden "true") " admin"))
|
(<> (i :class "fa fa-shield-halved" :aria-hidden "true") " admin"))
|
||||||
|
|
||||||
(defcomp ~blog-admin-nav-item (&key href nav-btn-class label)
|
(defcomp ~blog-admin-nav-item (&key href nav-btn-class label is-selected select-colours)
|
||||||
(div :class "relative nav-group" (a :href href :class nav-btn-class label)))
|
(div :class "relative nav-group"
|
||||||
|
(a :href href
|
||||||
|
:aria-selected (when is-selected "true")
|
||||||
|
:class (str (or nav-btn-class "justify-center cursor-pointer flex flex-row items-center gap-2 rounded bg-stone-200 text-black p-3") " " (or select-colours ""))
|
||||||
|
label)))
|
||||||
|
|
||||||
(defcomp ~blog-sub-settings-label (&key icon label)
|
(defcomp ~blog-sub-settings-label (&key icon label)
|
||||||
(<> (i :class icon :aria-hidden "true") " " label))
|
(<> (i :class icon :aria-hidden "true") " " label))
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ def _post_header_html(ctx: dict, *, oob: bool = False) -> str:
|
|||||||
# Post admin header
|
# Post admin header
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _post_admin_header_html(ctx: dict, *, oob: bool = False) -> str:
|
def _post_admin_header_html(ctx: dict, *, oob: bool = False, selected: str = "") -> str:
|
||||||
"""Post admin header row with admin icon and nav links."""
|
"""Post admin header row with admin icon and nav links."""
|
||||||
from quart import url_for as qurl
|
from quart import url_for as qurl
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ def _post_admin_header_html(ctx: dict, *, oob: bool = False) -> str:
|
|||||||
admin_href = qurl("blog.post.admin.admin", slug=slug)
|
admin_href = qurl("blog.post.admin.admin", slug=slug)
|
||||||
label_html = render("blog-admin-label")
|
label_html = render("blog-admin-label")
|
||||||
|
|
||||||
nav_html = _post_admin_nav_html(ctx)
|
nav_html = _post_admin_nav_html(ctx, selected=selected)
|
||||||
|
|
||||||
return render("menu-row",
|
return render("menu-row",
|
||||||
id="post-admin-row", level=2,
|
id="post-admin-row", level=2,
|
||||||
@@ -109,7 +109,7 @@ def _post_admin_header_html(ctx: dict, *, oob: bool = False) -> str:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _post_admin_nav_html(ctx: dict) -> str:
|
def _post_admin_nav_html(ctx: dict, *, selected: str = "") -> str:
|
||||||
"""Post admin desktop nav: calendars, markets, payments, entries, data, edit, settings."""
|
"""Post admin desktop nav: calendars, markets, payments, entries, data, edit, settings."""
|
||||||
from quart import url_for as qurl
|
from quart import url_for as qurl
|
||||||
|
|
||||||
@@ -136,6 +136,7 @@ def _post_admin_nav_html(ctx: dict) -> str:
|
|||||||
href = url_fn(path)
|
href = url_fn(path)
|
||||||
parts.append(render("blog-admin-nav-item",
|
parts.append(render("blog-admin-nav-item",
|
||||||
href=href, nav_btn_class=nav_btn, label=label,
|
href=href, nav_btn_class=nav_btn, label=label,
|
||||||
|
is_selected=(label == selected), select_colours=select_colours,
|
||||||
))
|
))
|
||||||
|
|
||||||
# HTMX links
|
# HTMX links
|
||||||
@@ -148,6 +149,7 @@ def _post_admin_nav_html(ctx: dict) -> str:
|
|||||||
href = qurl(endpoint, slug=slug)
|
href = qurl(endpoint, slug=slug)
|
||||||
parts.append(render("nav-link",
|
parts.append(render("nav-link",
|
||||||
href=href, label=label, select_colours=select_colours,
|
href=href, label=label, select_colours=select_colours,
|
||||||
|
is_selected=(label == selected),
|
||||||
))
|
))
|
||||||
|
|
||||||
return "".join(parts)
|
return "".join(parts)
|
||||||
@@ -1415,32 +1417,16 @@ async def render_post_admin_oob(ctx: dict) -> str:
|
|||||||
async def render_post_data_page(ctx: dict) -> str:
|
async def render_post_data_page(ctx: dict) -> str:
|
||||||
root_hdr = root_header_html(ctx)
|
root_hdr = root_header_html(ctx)
|
||||||
post_hdr = _post_header_html(ctx)
|
post_hdr = _post_header_html(ctx)
|
||||||
admin_hdr = _post_admin_header_html(ctx)
|
admin_hdr = _post_admin_header_html(ctx, selected="data")
|
||||||
from quart import url_for as qurl
|
header_rows = root_hdr + post_hdr + admin_hdr
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
|
||||||
data_hdr = _post_sub_admin_header_html(
|
|
||||||
"post_data-row", "post_data-header-child",
|
|
||||||
qurl("blog.post.admin.data", slug=slug),
|
|
||||||
"database", "data", ctx,
|
|
||||||
)
|
|
||||||
header_rows = root_hdr + post_hdr + admin_hdr + data_hdr
|
|
||||||
content = ctx.get("data_html", "")
|
content = ctx.get("data_html", "")
|
||||||
return full_page(ctx, header_rows_html=header_rows, content_html=content)
|
return full_page(ctx, header_rows_html=header_rows, content_html=content)
|
||||||
|
|
||||||
|
|
||||||
async def render_post_data_oob(ctx: dict) -> str:
|
async def render_post_data_oob(ctx: dict) -> str:
|
||||||
admin_hdr_oob = _post_admin_header_html(ctx, oob=True)
|
admin_hdr_oob = _post_admin_header_html(ctx, oob=True, selected="data")
|
||||||
from quart import url_for as qurl
|
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
|
||||||
data_hdr = _post_sub_admin_header_html(
|
|
||||||
"post_data-row", "post_data-header-child",
|
|
||||||
qurl("blog.post.admin.data", slug=slug),
|
|
||||||
"database", "data", ctx,
|
|
||||||
)
|
|
||||||
data_oob = _oob_header_html("post-admin-header-child", "post_data-header-child",
|
|
||||||
data_hdr)
|
|
||||||
content = ctx.get("data_html", "")
|
content = ctx.get("data_html", "")
|
||||||
return oob_page(ctx, oobs_html=admin_hdr_oob + data_oob, content_html=content)
|
return oob_page(ctx, oobs_html=admin_hdr_oob, content_html=content)
|
||||||
|
|
||||||
|
|
||||||
# ---- Post entries ----
|
# ---- Post entries ----
|
||||||
@@ -1448,32 +1434,16 @@ async def render_post_data_oob(ctx: dict) -> str:
|
|||||||
async def render_post_entries_page(ctx: dict) -> str:
|
async def render_post_entries_page(ctx: dict) -> str:
|
||||||
root_hdr = root_header_html(ctx)
|
root_hdr = root_header_html(ctx)
|
||||||
post_hdr = _post_header_html(ctx)
|
post_hdr = _post_header_html(ctx)
|
||||||
admin_hdr = _post_admin_header_html(ctx)
|
admin_hdr = _post_admin_header_html(ctx, selected="entries")
|
||||||
from quart import url_for as qurl
|
header_rows = root_hdr + post_hdr + admin_hdr
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
|
||||||
entries_hdr = _post_sub_admin_header_html(
|
|
||||||
"post_entries-row", "post_entries-header-child",
|
|
||||||
qurl("blog.post.admin.entries", slug=slug),
|
|
||||||
"clock", "entries", ctx,
|
|
||||||
)
|
|
||||||
header_rows = root_hdr + post_hdr + admin_hdr + entries_hdr
|
|
||||||
content = ctx.get("entries_html", "")
|
content = ctx.get("entries_html", "")
|
||||||
return full_page(ctx, header_rows_html=header_rows, content_html=content)
|
return full_page(ctx, header_rows_html=header_rows, content_html=content)
|
||||||
|
|
||||||
|
|
||||||
async def render_post_entries_oob(ctx: dict) -> str:
|
async def render_post_entries_oob(ctx: dict) -> str:
|
||||||
admin_hdr_oob = _post_admin_header_html(ctx, oob=True)
|
admin_hdr_oob = _post_admin_header_html(ctx, oob=True, selected="entries")
|
||||||
from quart import url_for as qurl
|
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
|
||||||
entries_hdr = _post_sub_admin_header_html(
|
|
||||||
"post_entries-row", "post_entries-header-child",
|
|
||||||
qurl("blog.post.admin.entries", slug=slug),
|
|
||||||
"clock", "entries", ctx,
|
|
||||||
)
|
|
||||||
entries_oob = _oob_header_html("post-admin-header-child", "post_entries-header-child",
|
|
||||||
entries_hdr)
|
|
||||||
content = ctx.get("entries_html", "")
|
content = ctx.get("entries_html", "")
|
||||||
return oob_page(ctx, oobs_html=admin_hdr_oob + entries_oob, content_html=content)
|
return oob_page(ctx, oobs_html=admin_hdr_oob, content_html=content)
|
||||||
|
|
||||||
|
|
||||||
# ---- Post edit ----
|
# ---- Post edit ----
|
||||||
@@ -1481,15 +1451,8 @@ async def render_post_entries_oob(ctx: dict) -> str:
|
|||||||
async def render_post_edit_page(ctx: dict) -> str:
|
async def render_post_edit_page(ctx: dict) -> str:
|
||||||
root_hdr = root_header_html(ctx)
|
root_hdr = root_header_html(ctx)
|
||||||
post_hdr = _post_header_html(ctx)
|
post_hdr = _post_header_html(ctx)
|
||||||
admin_hdr = _post_admin_header_html(ctx)
|
admin_hdr = _post_admin_header_html(ctx, selected="edit")
|
||||||
from quart import url_for as qurl
|
header_rows = root_hdr + post_hdr + admin_hdr
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
|
||||||
edit_hdr = _post_sub_admin_header_html(
|
|
||||||
"post_edit-row", "post_edit-header-child",
|
|
||||||
qurl("blog.post.admin.edit", slug=slug),
|
|
||||||
"pen-to-square", "edit", ctx,
|
|
||||||
)
|
|
||||||
header_rows = root_hdr + post_hdr + admin_hdr + edit_hdr
|
|
||||||
content = ctx.get("edit_html", "")
|
content = ctx.get("edit_html", "")
|
||||||
body_end = ctx.get("body_end_html", "")
|
body_end = ctx.get("body_end_html", "")
|
||||||
return full_page(ctx, header_rows_html=header_rows, content_html=content,
|
return full_page(ctx, header_rows_html=header_rows, content_html=content,
|
||||||
@@ -1497,18 +1460,9 @@ async def render_post_edit_page(ctx: dict) -> str:
|
|||||||
|
|
||||||
|
|
||||||
async def render_post_edit_oob(ctx: dict) -> str:
|
async def render_post_edit_oob(ctx: dict) -> str:
|
||||||
admin_hdr_oob = _post_admin_header_html(ctx, oob=True)
|
admin_hdr_oob = _post_admin_header_html(ctx, oob=True, selected="edit")
|
||||||
from quart import url_for as qurl
|
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
|
||||||
edit_hdr = _post_sub_admin_header_html(
|
|
||||||
"post_edit-row", "post_edit-header-child",
|
|
||||||
qurl("blog.post.admin.edit", slug=slug),
|
|
||||||
"pen-to-square", "edit", ctx,
|
|
||||||
)
|
|
||||||
edit_oob = _oob_header_html("post-admin-header-child", "post_edit-header-child",
|
|
||||||
edit_hdr)
|
|
||||||
content = ctx.get("edit_html", "")
|
content = ctx.get("edit_html", "")
|
||||||
return oob_page(ctx, oobs_html=admin_hdr_oob + edit_oob, content_html=content)
|
return oob_page(ctx, oobs_html=admin_hdr_oob, content_html=content)
|
||||||
|
|
||||||
|
|
||||||
# ---- Post settings ----
|
# ---- Post settings ----
|
||||||
@@ -1516,32 +1470,16 @@ async def render_post_edit_oob(ctx: dict) -> str:
|
|||||||
async def render_post_settings_page(ctx: dict) -> str:
|
async def render_post_settings_page(ctx: dict) -> str:
|
||||||
root_hdr = root_header_html(ctx)
|
root_hdr = root_header_html(ctx)
|
||||||
post_hdr = _post_header_html(ctx)
|
post_hdr = _post_header_html(ctx)
|
||||||
admin_hdr = _post_admin_header_html(ctx)
|
admin_hdr = _post_admin_header_html(ctx, selected="settings")
|
||||||
from quart import url_for as qurl
|
header_rows = root_hdr + post_hdr + admin_hdr
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
|
||||||
settings_hdr = _post_sub_admin_header_html(
|
|
||||||
"post_settings-row", "post_settings-header-child",
|
|
||||||
qurl("blog.post.admin.settings", slug=slug),
|
|
||||||
"cog", "settings", ctx,
|
|
||||||
)
|
|
||||||
header_rows = root_hdr + post_hdr + admin_hdr + settings_hdr
|
|
||||||
content = ctx.get("settings_html", "")
|
content = ctx.get("settings_html", "")
|
||||||
return full_page(ctx, header_rows_html=header_rows, content_html=content)
|
return full_page(ctx, header_rows_html=header_rows, content_html=content)
|
||||||
|
|
||||||
|
|
||||||
async def render_post_settings_oob(ctx: dict) -> str:
|
async def render_post_settings_oob(ctx: dict) -> str:
|
||||||
admin_hdr_oob = _post_admin_header_html(ctx, oob=True)
|
admin_hdr_oob = _post_admin_header_html(ctx, oob=True, selected="settings")
|
||||||
from quart import url_for as qurl
|
|
||||||
slug = (ctx.get("post") or {}).get("slug", "")
|
|
||||||
settings_hdr = _post_sub_admin_header_html(
|
|
||||||
"post_settings-row", "post_settings-header-child",
|
|
||||||
qurl("blog.post.admin.settings", slug=slug),
|
|
||||||
"cog", "settings", ctx,
|
|
||||||
)
|
|
||||||
settings_oob = _oob_header_html("post-admin-header-child", "post_settings-header-child",
|
|
||||||
settings_hdr)
|
|
||||||
content = ctx.get("settings_html", "")
|
content = ctx.get("settings_html", "")
|
||||||
return oob_page(ctx, oobs_html=admin_hdr_oob + settings_oob, content_html=content)
|
return oob_page(ctx, oobs_html=admin_hdr_oob, content_html=content)
|
||||||
|
|
||||||
|
|
||||||
# ---- Settings home ----
|
# ---- Settings home ----
|
||||||
|
|||||||
Reference in New Issue
Block a user