Refine publisher dashboard layout
All checks were successful
buildbot/nix-eval Build done.
buildbot/nix-build Build done.
buildbot/nix-effects Build done.

This commit is contained in:
Abel Luck 2026-06-02 11:11:36 +02:00
parent 2147d9c999
commit 813f19f355
8 changed files with 350 additions and 53 deletions

View file

@ -161,8 +161,11 @@ def _live_status_cell(
status_tone: str,
clock_label: str,
calendar_label: Node,
compact_mobile: bool = False,
) -> Node:
return h.div(class_="min-w-[10rem]")[
return h.div(
class_=("min-w-0 md:min-w-[10rem]" if compact_mobile else "min-w-[10rem]")
)[
h.div(class_="flex items-center gap-2")[
h.span(class_="font-mono text-xs text-slate-500")[f"#{execution_id}"],
h.span(
@ -191,7 +194,10 @@ def _queue_row_attrs(execution: Mapping[str, object]) -> dict[str, str]:
def _running_row(
execution: Mapping[str, object], *, show_row_actions: bool = True
execution: Mapping[str, object],
*,
show_row_actions: bool = True,
compact_mobile: bool = False,
) -> tuple[Node, ...]:
started_at = _maybe_text(execution, "started_at_iso")
started_at_label: Node = h.p(class_="truncate")[_text(execution, "started_at")]
@ -205,6 +211,20 @@ def _running_row(
class_="truncate",
)[_text(execution, "started_at")]
mobile_details = (
h.div(class_="mt-2 grid gap-1 text-xs text-slate-500 md:hidden")[
h.p(class_="flex flex-wrap gap-x-1.5")[
h.span(class_="font-medium text-slate-600")["Stats"],
h.span[_text(execution, "stats")],
],
h.p(class_="flex flex-wrap gap-x-1.5")[
h.span(class_="font-medium text-slate-600")["Worker"],
h.span[_text(execution, "worker")],
],
]
if compact_mobile
else None
)
cells = (
_live_status_cell(
execution_id=_text(execution, "execution_id"),
@ -213,12 +233,14 @@ def _running_row(
clock_label=_maybe_text(execution, "duration")
or _text(execution, "runtime"),
calendar_label=started_at_label,
compact_mobile=compact_mobile,
),
h.div[
h.div(class_="font-semibold text-slate-950")[_text(execution, "source")],
h.p(class_="mt-0.5 font-mono text-xs text-slate-500")[
_text(execution, "slug")
],
mobile_details,
],
h.div(class_="max-w-xs whitespace-normal")[
h.p(class_="font-medium text-slate-900")[_text(execution, "stats")],
@ -245,7 +267,10 @@ def _running_row(
def _queued_row(
execution: Mapping[str, object], *, show_row_actions: bool = True
execution: Mapping[str, object],
*,
show_row_actions: bool = True,
compact_mobile: bool = False,
) -> tuple[Node, ...]:
queued_at = _maybe_text(execution, "queued_at_iso")
queued_label: Node = h.p(class_="truncate")[_text(execution, "queued_at")]
@ -259,6 +284,20 @@ def _queued_row(
class_="truncate",
)[_text(execution, "queued_at")]
mobile_details = (
h.div(class_="mt-2 grid gap-1 text-xs text-slate-500 md:hidden")[
h.p(class_="flex flex-wrap gap-x-1.5")[
h.span(class_="font-medium text-slate-600")["Queued"],
h.span[f"Queue position #{_text(execution, 'queue_position')}"],
],
h.p(class_="flex flex-wrap gap-x-1.5")[
h.span(class_="font-medium text-slate-600")["State"],
h.span["waiting for capacity"],
],
]
if compact_mobile
else None
)
cells = (
_live_status_cell(
execution_id=_text(execution, "execution_id"),
@ -266,12 +305,14 @@ def _queued_row(
status_tone="queued",
clock_label="Waiting",
calendar_label=queued_label,
compact_mobile=compact_mobile,
),
h.div[
h.div(class_="font-semibold text-slate-950")[_text(execution, "source")],
h.p(class_="mt-0.5 font-mono text-xs text-slate-500")[
_text(execution, "slug")
],
mobile_details,
],
h.div(class_="max-w-xs whitespace-normal")[
h.p(class_="font-medium text-slate-900")[
@ -525,21 +566,49 @@ def live_work_section(
queued_executions: tuple[Mapping[str, object], ...] | None = None,
actions: Node | None = None,
show_row_actions: bool = True,
compact_mobile: bool = False,
) -> Renderable:
running_items = running_executions or ()
queued_items = queued_executions or ()
running_rows = tuple(
_running_row(execution, show_row_actions=show_row_actions)
_running_row(
execution,
show_row_actions=show_row_actions,
compact_mobile=compact_mobile,
)
for execution in running_items
)
queued_rows = tuple(
_queued_row(execution, show_row_actions=show_row_actions)
_queued_row(
execution,
show_row_actions=show_row_actions,
compact_mobile=compact_mobile,
)
for execution in queued_items
)
live_rows = running_rows + queued_rows
live_row_attrs = tuple(
_queue_row_attrs(execution) for execution in running_items + queued_items
)
use_compact_columns = compact_mobile and not show_row_actions
header_classes = (
(
"w-[34%] px-3 py-2.5 text-left text-xs font-semibold uppercase tracking-[0.18em] whitespace-nowrap text-slate-500 md:w-[24%] sm:pl-4",
"w-[66%] px-2.5 py-2.5 text-left text-xs font-semibold uppercase tracking-[0.18em] whitespace-nowrap text-slate-500 md:w-[34%]",
"hidden px-2.5 py-2.5 text-left text-xs font-semibold uppercase tracking-[0.18em] whitespace-nowrap text-slate-500 md:table-cell md:w-[42%]",
)
if use_compact_columns
else None
)
cell_classes = (
(
"w-[34%] py-3 pr-3 pl-3 text-sm font-medium text-slate-950 md:w-[24%] sm:pl-4",
"w-[66%] px-2.5 py-3 align-top text-sm whitespace-normal text-slate-600 md:w-[34%]",
"hidden px-2.5 py-3 align-top text-sm whitespace-normal text-slate-600 md:table-cell md:w-[42%]",
)
if use_compact_columns
else None
)
return table_section(
eyebrow="Live work",
title="Running jobs",
@ -551,6 +620,13 @@ def live_work_section(
),
rows=live_rows,
row_attrs=live_row_attrs,
header_classes=header_classes,
cell_classes=cell_classes,
table_class=(
"relative w-full min-w-0 divide-y divide-slate-200 table-fixed"
if use_compact_columns
else "relative w-full min-w-[64rem] divide-y divide-slate-200 table-auto"
),
actions=actions,
)