remove most subtitles

This commit is contained in:
Abel Luck 2026-03-30 15:25:10 +02:00
parent d8f2e03d36
commit 947ef8e833
7 changed files with 13 additions and 46 deletions

View file

@ -55,7 +55,6 @@ def admin_sidebar(*, current_path: str) -> Renderable:
h.p(
class_="text-xs font-semibold uppercase tracking-[0.24em] text-amber-300"
)["Republisher"],
h.p(class_="text-sm text-slate-300")["Admin spike"],
],
],
h.nav(class_="mt-10 space-y-2")[
@ -147,7 +146,7 @@ def page_shell(
current_path: str,
eyebrow: str,
title: str,
description: str,
description: str | None = None,
actions: Node | None = None,
content: Node,
) -> Renderable:
@ -190,7 +189,7 @@ def table_section(
*,
eyebrow: str | None = None,
title: str,
subtitle: str,
subtitle: str | None = None,
headers: tuple[str, ...],
rows: tuple[tuple[Node, ...], ...],
actions: Node | None = None,
@ -217,7 +216,7 @@ def table_section(
class_="text-xs font-semibold uppercase tracking-[0.22em] text-amber-600"
)[eyebrow],
h.h2(class_="mt-1 text-xl font-semibold text-slate-950")[title],
h.p(class_="mt-1 text-sm text-slate-600")[subtitle],
subtitle and h.p(class_="mt-1 text-sm text-slate-600")[subtitle],
],
actions,
],

View file

@ -69,9 +69,6 @@ def dashboard_header() -> Renderable:
h.h1(class_="text-3xl font-semibold tracking-tight text-slate-950")[
"Republisher"
],
h.p(class_="mt-1 text-sm text-slate-600")[
"Operational status and live executions."
],
],
h.div(class_="flex flex-wrap gap-2")[
header_action_link(href="/sources/create", label="Create source"),
@ -98,7 +95,6 @@ def operational_snapshot(*, snapshot: Mapping[str, str] | None = None) -> Render
"Operational snapshot"
],
],
h.p(class_="text-xs text-slate-500")["Live values from the database"],
],
h.dl(class_="grid gap-3 md:grid-cols-2 xl:grid-cols-4")[
stat_card(
@ -156,9 +152,6 @@ def running_executions_table(
h.h2(class_="mt-1 text-xl font-semibold text-slate-950")[
"Running executions"
],
h.p(class_="mt-1 text-sm text-slate-600")[
"Dashboard keeps only the in-flight executions visible here. The full run history lives on the Runs page."
],
],
muted_action_link(href="/runs", label="Open runs"),
],
@ -232,7 +225,6 @@ def published_feeds_table(
return table_section(
eyebrow="Published feeds",
title="Published feeds",
subtitle="Per-source public feed paths under /feeds, with current availability and disk usage.",
headers=("Source", "Feed URL", "Status", "Last updated", "Disk usage"),
rows=rows,
actions=muted_action_link(href="/sources", label="Manage sources"),

View file

@ -206,13 +206,11 @@ def runs_page(
current_path="/runs",
eyebrow="Execution control",
title="Runs",
description="Running executions first, then the schedule queue, then completed history. Logs are routed through app URLs instead of direct file serving.",
actions=muted_action_link(href="/sources", label="Back to sources"),
content=(
table_section(
eyebrow="Live work",
title="Running job executions",
subtitle="Operators can inspect the live log stream, request a graceful stop, and escalate to a hard kill after the 15 second deadline if needed.",
headers=(
"Source",
"Execution",
@ -226,7 +224,6 @@ def runs_page(
table_section(
eyebrow="Queue",
title="Upcoming jobs",
subtitle="Scheduled work shows enable or disable state, run-now affordances, and destructive delete controls. Deleting removes the source-linked job and its execution history.",
headers=(
"Source",
"Next run",
@ -240,7 +237,6 @@ def runs_page(
table_section(
eyebrow="History",
title="Completed job executions",
subtitle="Recent execution history keeps the summary counters visible and links back to the plain text log view.",
headers=(
"Source",
"Execution",
@ -308,7 +304,7 @@ def execution_logs_page(
if log_view is None:
log_view = {
"title": f"Job {job_id} / execution {execution_id}",
"description": "Plain text log view routed through the app.",
"description": "",
"status_label": "Unavailable",
"status_tone": "failed",
"log_text": "",
@ -331,7 +327,6 @@ def execution_logs_page(
current_path=f"/job/{job_id}/execution/{execution_id}/logs",
eyebrow="Execution log",
title=_text(log_view, "title"),
description=_text(log_view, "description"),
actions=muted_action_link(href="/runs", label="Back to runs"),
content=(
section_card(
@ -344,9 +339,6 @@ def execution_logs_page(
h.h2(class_="mt-2 text-xl font-semibold text-slate-950")[
f"/job/{job_id}/execution/{execution_id}/logs"
],
h.p(class_="mt-2 text-sm text-slate-600")[
_text(log_view, "description")
],
],
status_badge(
label=_text(log_view, "status_label"),

View file

@ -51,9 +51,6 @@ def shim_page(
h.h1(
class_="mt-1 text-3xl font-semibold tracking-tight text-slate-950"
)["Loading page"],
h.p(class_="mt-1 text-sm text-slate-600")[
"Rendering the latest server view for this route."
],
],
]
],

View file

@ -92,7 +92,6 @@ def sources_table(
return table_section(
eyebrow="Inventory",
title="Sources",
subtitle="Configured feed and Pangea sources live here as tables, with clear schedule and job state visibility instead of card-based CRUD.",
headers=("Source", "Type", "Upstream", "Schedule", "Job state", "Actions"),
rows=rows,
actions=header_action_link(href="/sources/create", label="Create source"),
@ -106,7 +105,6 @@ def sources_page(
current_path="/sources",
eyebrow="Source management",
title="Sources",
description="Configured feed and Pangea sources live here as tables, with clear schedule and job state visibility instead of card-based CRUD.",
actions=header_action_link(href="/sources/create", label="Create source"),
content=sources_table(sources=sources),
)
@ -122,11 +120,6 @@ def source_form(
slug = _value(source, "slug")
title = "Source and job setup" if mode == "create" else "Edit source"
eyebrow = "Create" if mode == "create" else "Edit"
description = (
"Create the source and its paired job record."
if mode == "create"
else "Update the existing source and its paired job record."
)
status_label = "New source" if mode == "create" else "Existing source"
submit_label = "Create source" if mode == "create" else "Save changes"
initial_signals = "{sourceType: 'pangea'}"
@ -143,7 +136,6 @@ def source_form(
class_="text-xs font-semibold uppercase tracking-[0.22em] text-amber-600"
)[eyebrow],
h.h2(class_="mt-2 text-xl font-semibold text-slate-950")[title],
h.p(class_="mt-2 max-w-3xl text-sm text-slate-600")[description],
],
status_badge(label=status_label, tone="scheduled"),
],
@ -215,9 +207,6 @@ def source_form(
h.h3(class_="mt-2 text-lg font-semibold text-slate-950")[
"Feed settings"
],
h.p(class_="mt-2 text-sm text-slate-600")[
"Shown only when the source type is set to feed."
],
],
h.div(class_="grid gap-4 md:grid-cols-2")[
input_field(
@ -240,9 +229,6 @@ def source_form(
h.h3(class_="mt-2 text-lg font-semibold text-slate-950")[
"Pangea settings"
],
h.p(class_="mt-2 text-sm text-slate-600")[
"Shown only when the source type is set to pangea."
],
],
h.div(class_="grid gap-4 lg:grid-cols-3")[
input_field(
@ -414,7 +400,6 @@ def create_source_page(*, action_path: str = "/actions/sources/create") -> Rende
current_path="/sources/create",
eyebrow="Source creation",
title="Create source",
description="Create a new source and its paired job configuration.",
actions=actions,
content=source_form(mode="create", action_path=action_path),
)
@ -434,7 +419,6 @@ def edit_source_page(
current_path=f"/sources/{slug}/edit",
eyebrow="Source editing",
title="Edit source",
description="Update an existing source and its paired job configuration.",
actions=actions,
content=source_form(mode="edit", action_path=action_path, source=source),
)

View file

@ -1,5 +1,7 @@
import io
import logging
from types import SimpleNamespace
from typing import cast
from repub.entrypoint import FeedNameFilter, entrypoint, logger, parse_args
@ -32,14 +34,17 @@ def test_parse_args_uses_republisher_host_and_port_env_vars(monkeypatch) -> None
def test_entrypoint_rejects_invalid_republisher_port(monkeypatch) -> None:
monkeypatch.setenv("REPUBLISHER_PORT", "not-a-number")
stream = io.StringIO()
original_streams = [handler.stream for handler in logger.handlers]
for handler in logger.handlers:
handlers = [
cast(logging.StreamHandler[io.StringIO], handler) for handler in logger.handlers
]
original_streams = [handler.stream for handler in handlers]
for handler in handlers:
handler.stream = stream
try:
exit_code = entrypoint(["serve"])
finally:
for handler, original_stream in zip(logger.handlers, original_streams):
for handler, original_stream in zip(handlers, original_streams):
handler.stream = original_stream
assert exit_code == 2

View file

@ -388,7 +388,6 @@ def test_render_sources_shows_table_and_create_link() -> None:
async def run() -> None:
body = str(await render_sources())
assert "Configured feed and Pangea sources live here as tables" in body
assert ">Sources<" in body
assert 'href="/sources/create"' in body
assert "guardian-feed" not in body
@ -401,7 +400,7 @@ def test_render_create_source_shows_dedicated_form_page() -> None:
async def run() -> None:
body = str(await render_create_source())
assert "Create a new source and its paired job configuration." in body
assert ">Create source<" in body
assert "Source and job setup" in body
assert "data-signals__ifmissing" in body
assert "/actions/sources/create" in body
@ -890,7 +889,6 @@ def test_render_execution_logs_uses_app_route(monkeypatch, tmp_path: Path) -> No
assert f"Job {job.id} / execution {execution.get_id()}" in body
assert f"/job/{job.id}/execution/{execution.get_id()}/logs" in body
assert "Route: /job/" in body
assert "waiting for more log lines" in body
asyncio.run(run())