Add publisher dashboard routes
This commit is contained in:
parent
96551c2788
commit
e4a5246ab3
31 changed files with 1603 additions and 516 deletions
|
|
@ -190,7 +190,9 @@ def _queue_row_attrs(execution: Mapping[str, object]) -> dict[str, str]:
|
|||
}
|
||||
|
||||
|
||||
def _running_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
|
||||
def _running_row(
|
||||
execution: Mapping[str, object], *, show_row_actions: bool = True
|
||||
) -> tuple[Node, ...]:
|
||||
started_at = _maybe_text(execution, "started_at_iso")
|
||||
started_at_label: Node = h.p(class_="truncate")[_text(execution, "started_at")]
|
||||
if started_at is not None:
|
||||
|
|
@ -203,7 +205,7 @@ def _running_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
|
|||
class_="truncate",
|
||||
)[_text(execution, "started_at")]
|
||||
|
||||
return (
|
||||
cells = (
|
||||
_live_status_cell(
|
||||
execution_id=_text(execution, "execution_id"),
|
||||
status=_text(execution, "status"),
|
||||
|
|
@ -222,6 +224,11 @@ def _running_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
|
|||
h.p(class_="font-medium text-slate-900")[_text(execution, "stats")],
|
||||
h.p(class_="mt-0.5 text-xs text-slate-500")[_text(execution, "worker")],
|
||||
],
|
||||
)
|
||||
if not show_row_actions:
|
||||
return cells
|
||||
return (
|
||||
*cells,
|
||||
h.div(class_="flex flex-wrap items-center gap-2")[
|
||||
inline_link(
|
||||
href=_text(execution, "log_href"),
|
||||
|
|
@ -237,7 +244,9 @@ def _running_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
|
|||
)
|
||||
|
||||
|
||||
def _queued_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
|
||||
def _queued_row(
|
||||
execution: Mapping[str, object], *, show_row_actions: bool = True
|
||||
) -> tuple[Node, ...]:
|
||||
queued_at = _maybe_text(execution, "queued_at_iso")
|
||||
queued_label: Node = h.p(class_="truncate")[_text(execution, "queued_at")]
|
||||
if queued_at is not None:
|
||||
|
|
@ -250,7 +259,7 @@ def _queued_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
|
|||
class_="truncate",
|
||||
)[_text(execution, "queued_at")]
|
||||
|
||||
return (
|
||||
cells = (
|
||||
_live_status_cell(
|
||||
execution_id=_text(execution, "execution_id"),
|
||||
status="Queued",
|
||||
|
|
@ -270,6 +279,11 @@ def _queued_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
|
|||
],
|
||||
h.p(class_="mt-0.5 text-xs text-slate-500")["waiting for capacity"],
|
||||
],
|
||||
)
|
||||
if not show_row_actions:
|
||||
return cells
|
||||
return (
|
||||
*cells,
|
||||
h.div(class_="flex flex-wrap items-center gap-2")[
|
||||
action_button(
|
||||
label=_queue_icon("up"),
|
||||
|
|
@ -362,8 +376,8 @@ def _completed_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
|
|||
)
|
||||
|
||||
|
||||
def _completed_page_action_path(page: int) -> str:
|
||||
return f"/actions/runs/completed-page/{page}"
|
||||
def _completed_page_action_path(page: int, *, path_prefix: str = "/admin") -> str:
|
||||
return f"{path_prefix}/actions/runs/completed-page/{page}"
|
||||
|
||||
|
||||
def _pagination_button(
|
||||
|
|
@ -372,9 +386,12 @@ def _pagination_button(
|
|||
page: int,
|
||||
current: bool = False,
|
||||
class_name: str,
|
||||
path_prefix: str = "/admin",
|
||||
) -> Renderable:
|
||||
attributes = {
|
||||
"data-on:pointerdown": f"@post('{_completed_page_action_path(page)}')",
|
||||
"data-on:pointerdown": (
|
||||
f"@post('{_completed_page_action_path(page, path_prefix=path_prefix)}')"
|
||||
),
|
||||
}
|
||||
if current:
|
||||
attributes["aria-current"] = "page"
|
||||
|
|
@ -391,6 +408,7 @@ def _completed_history_pagination(
|
|||
completed_page_size: int,
|
||||
completed_total_count: int,
|
||||
completed_total_pages: int,
|
||||
path_prefix: str = "/admin",
|
||||
) -> Renderable | None:
|
||||
if completed_total_count <= completed_page_size:
|
||||
return None
|
||||
|
|
@ -410,6 +428,7 @@ def _completed_history_pagination(
|
|||
_pagination_button(
|
||||
label="Previous",
|
||||
page=max(1, completed_page - 1),
|
||||
path_prefix=path_prefix,
|
||||
class_name=(
|
||||
"relative inline-flex items-center rounded-xl border border-slate-200 "
|
||||
"bg-white px-4 py-2 text-sm font-medium text-slate-700 hover:bg-stone-50"
|
||||
|
|
@ -418,6 +437,7 @@ def _completed_history_pagination(
|
|||
_pagination_button(
|
||||
label="Next",
|
||||
page=min(completed_total_pages, completed_page + 1),
|
||||
path_prefix=path_prefix,
|
||||
class_name=(
|
||||
"relative ml-3 inline-flex items-center rounded-xl border border-slate-200 "
|
||||
"bg-white px-4 py-2 text-sm font-medium text-slate-700 hover:bg-stone-50"
|
||||
|
|
@ -443,6 +463,7 @@ def _completed_history_pagination(
|
|||
label=str(page_number),
|
||||
page=page_number,
|
||||
current=page_number == completed_page,
|
||||
path_prefix=path_prefix,
|
||||
class_name=(
|
||||
"relative z-10 inline-flex items-center bg-amber-500 px-4 py-2 text-sm font-semibold text-slate-950"
|
||||
if page_number == completed_page
|
||||
|
|
@ -463,12 +484,14 @@ def _completed_history_section(
|
|||
completed_page_size: int,
|
||||
completed_total_count: int,
|
||||
completed_total_pages: int,
|
||||
path_prefix: str = "/admin",
|
||||
) -> Renderable:
|
||||
pagination = _completed_history_pagination(
|
||||
completed_page=completed_page,
|
||||
completed_page_size=completed_page_size,
|
||||
completed_total_count=completed_total_count,
|
||||
completed_total_pages=completed_total_pages,
|
||||
path_prefix=path_prefix,
|
||||
)
|
||||
return h.section[
|
||||
table_section(
|
||||
|
|
@ -486,7 +509,7 @@ def _completed_history_section(
|
|||
action_button(
|
||||
label="Clear history",
|
||||
tone="danger",
|
||||
post_path="/actions/completed-executions/clear",
|
||||
post_path=f"{path_prefix}/actions/completed-executions/clear",
|
||||
)
|
||||
if completed_total_count > 0
|
||||
else None
|
||||
|
|
@ -501,11 +524,18 @@ def live_work_section(
|
|||
running_executions: tuple[Mapping[str, object], ...] | None = None,
|
||||
queued_executions: tuple[Mapping[str, object], ...] | None = None,
|
||||
actions: Node | None = None,
|
||||
show_row_actions: bool = True,
|
||||
) -> Renderable:
|
||||
running_items = running_executions or ()
|
||||
queued_items = queued_executions or ()
|
||||
running_rows = tuple(_running_row(execution) for execution in running_items)
|
||||
queued_rows = tuple(_queued_row(execution) for execution in queued_items)
|
||||
running_rows = tuple(
|
||||
_running_row(execution, show_row_actions=show_row_actions)
|
||||
for execution in running_items
|
||||
)
|
||||
queued_rows = tuple(
|
||||
_queued_row(execution, show_row_actions=show_row_actions)
|
||||
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
|
||||
|
|
@ -515,10 +545,9 @@ def live_work_section(
|
|||
title="Running jobs",
|
||||
empty_message="No jobs are running or queued.",
|
||||
headers=(
|
||||
"State",
|
||||
"Source",
|
||||
"Details",
|
||||
"Actions",
|
||||
("State", "Source", "Details", "Actions")
|
||||
if show_row_actions
|
||||
else ("State", "Source", "Details")
|
||||
),
|
||||
rows=live_rows,
|
||||
row_attrs=live_row_attrs,
|
||||
|
|
@ -585,6 +614,7 @@ def runs_page(
|
|||
completed_total_count: int | None = None,
|
||||
completed_total_pages: int | None = None,
|
||||
source_count: int = 0,
|
||||
path_prefix: str = "/admin",
|
||||
) -> Renderable:
|
||||
upcoming_items = upcoming_jobs or ()
|
||||
completed_items = completed_executions or ()
|
||||
|
|
@ -598,10 +628,13 @@ def runs_page(
|
|||
)
|
||||
|
||||
return page_shell(
|
||||
current_path="/runs",
|
||||
current_path=f"{path_prefix}/runs",
|
||||
eyebrow="Execution control",
|
||||
title="Runs",
|
||||
actions=muted_action_link(href="/sources", label="Back to sources"),
|
||||
actions=muted_action_link(
|
||||
href=f"{path_prefix}/sources",
|
||||
label="Back to sources",
|
||||
),
|
||||
source_count=source_count,
|
||||
running_count=len(running_executions or ()),
|
||||
content=(
|
||||
|
|
@ -629,6 +662,7 @@ def runs_page(
|
|||
completed_page_size=completed_page_size,
|
||||
completed_total_count=resolved_completed_total_count,
|
||||
completed_total_pages=resolved_completed_total_pages,
|
||||
path_prefix=path_prefix,
|
||||
),
|
||||
relative_time_formatter_script(),
|
||||
),
|
||||
|
|
@ -640,6 +674,7 @@ def execution_logs_page(
|
|||
job_id: int,
|
||||
execution_id: int,
|
||||
log_view: Mapping[str, object] | None = None,
|
||||
path_prefix: str = "/admin",
|
||||
) -> Renderable:
|
||||
if log_view is None:
|
||||
log_view = {
|
||||
|
|
@ -664,10 +699,10 @@ def execution_logs_page(
|
|||
)
|
||||
|
||||
return page_shell(
|
||||
current_path=f"/job/{job_id}/execution/{execution_id}/logs",
|
||||
current_path=f"{path_prefix}/job/{job_id}/execution/{execution_id}/logs",
|
||||
eyebrow="Execution log",
|
||||
title=_text(log_view, "title"),
|
||||
actions=muted_action_link(href="/runs", label="Back to runs"),
|
||||
actions=muted_action_link(href=f"{path_prefix}/runs", label="Back to runs"),
|
||||
content=(
|
||||
section_card(
|
||||
content=(
|
||||
|
|
@ -677,7 +712,7 @@ def execution_logs_page(
|
|||
class_="text-xs font-semibold uppercase tracking-[0.22em] text-amber-600"
|
||||
)["Route"],
|
||||
h.h2(class_="mt-2 text-xl font-semibold text-slate-950")[
|
||||
f"/job/{job_id}/execution/{execution_id}/logs"
|
||||
f"{path_prefix}/job/{job_id}/execution/{execution_id}/logs"
|
||||
],
|
||||
],
|
||||
status_badge(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue