tighten whitespace, DRY shell and buttons
This commit is contained in:
parent
0b3b1b2731
commit
a88eba7dd1
9 changed files with 439 additions and 225 deletions
|
|
@ -7,7 +7,7 @@ from datetime import UTC, datetime, timedelta
|
|||
from pathlib import Path
|
||||
from typing import Any, cast
|
||||
|
||||
from repub.components import status_badge, toggle_field
|
||||
from repub.components import action_button, status_badge, toggle_field
|
||||
from repub.datastar import RefreshBroker, render_sse_event, render_stream
|
||||
from repub.jobs import load_dashboard_view
|
||||
from repub.model import (
|
||||
|
|
@ -61,6 +61,52 @@ def test_toggle_field_active_state_utilities_exist_in_built_css() -> None:
|
|||
assert ".translate-x-5" in css
|
||||
|
||||
|
||||
def test_action_button_adds_cursor_pointer_for_active_buttons() -> None:
|
||||
markup = str(action_button(label="Run now"))
|
||||
|
||||
assert "cursor-pointer" in markup
|
||||
assert 'type="button"' in markup
|
||||
|
||||
|
||||
def test_action_button_omits_post_handler_when_disabled() -> None:
|
||||
markup = str(
|
||||
action_button(
|
||||
label="Queued",
|
||||
disabled=True,
|
||||
post_path="/actions/jobs/7/run-now",
|
||||
)
|
||||
)
|
||||
|
||||
assert "cursor-not-allowed" in markup
|
||||
assert "@post(" not in markup
|
||||
|
||||
|
||||
def test_action_button_supports_submit_variant() -> None:
|
||||
markup = str(
|
||||
action_button(
|
||||
label="Save settings",
|
||||
tone="dark",
|
||||
button_type="submit",
|
||||
)
|
||||
)
|
||||
|
||||
assert 'type="submit"' in markup
|
||||
assert "bg-slate-950" in markup
|
||||
assert "cursor-pointer" in markup
|
||||
|
||||
|
||||
def test_action_button_supports_datastar_pointerdown_post() -> None:
|
||||
markup = str(
|
||||
action_button(
|
||||
label="Delete",
|
||||
tone="danger",
|
||||
post_path="/actions/jobs/7/delete",
|
||||
)
|
||||
)
|
||||
|
||||
assert 'data-on:pointerdown="@post('/actions/jobs/7/delete')"' in markup
|
||||
|
||||
|
||||
def test_runs_page_renders_completed_execution_end_time_as_relative_hoverable_time() -> (
|
||||
None
|
||||
):
|
||||
|
|
@ -140,6 +186,8 @@ def test_root_get_serves_datastar_shim() -> None:
|
|||
assert "retryMaxCount: Infinity" in body
|
||||
assert "data-on:online__window=" in body
|
||||
assert '<main id="morph"' in body
|
||||
assert "lg:grid-cols-[14rem_minmax(0,1fr)]" in body
|
||||
assert "lg:px-5 lg:py-4" in body
|
||||
assert 'href="/sources"' in body
|
||||
assert 'href="/runs"' in body
|
||||
assert 'href="/settings"' in body
|
||||
|
|
@ -264,6 +312,8 @@ def test_render_dashboard_shows_dashboard_information_architecture(
|
|||
assert 'href="/sources"' in body
|
||||
assert 'href="/runs"' in body
|
||||
assert "Create source" in body
|
||||
assert "lg:grid-cols-[14rem_minmax(0,1fr)]" in body
|
||||
assert "lg:px-5 lg:py-4" in body
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
|
@ -694,6 +744,8 @@ def test_render_settings_shows_current_max_concurrent_jobs(
|
|||
assert "/actions/settings" in body
|
||||
assert 'value="3"' in body
|
||||
assert "Max concurrent jobs" in body
|
||||
assert 'type="submit"' in body
|
||||
assert "cursor-pointer" in body
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
|
@ -1110,6 +1162,23 @@ def test_render_runs_shows_running_upcoming_and_completed_tables(
|
|||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_render_runs_uses_compact_shell_and_table_classes(
|
||||
monkeypatch, tmp_path: Path
|
||||
) -> None:
|
||||
db_path = tmp_path / "runs-compact.db"
|
||||
monkeypatch.setenv("REPUBLISHER_DB_PATH", str(db_path))
|
||||
|
||||
async def run() -> None:
|
||||
app = create_app()
|
||||
body = str(await render_runs(app))
|
||||
|
||||
assert "lg:grid-cols-[14rem_minmax(0,1fr)]" in body
|
||||
assert "lg:px-5 lg:py-4" in body
|
||||
assert "min-w-[64rem]" in body
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_render_runs_shows_empty_state_rows(monkeypatch, tmp_path: Path) -> None:
|
||||
db_path = tmp_path / "runs-empty.db"
|
||||
monkeypatch.setenv("REPUBLISHER_DB_PATH", str(db_path))
|
||||
|
|
@ -1231,6 +1300,87 @@ def test_render_runs_shows_cancel_button_for_running_row_with_queued_follow_up(
|
|||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_render_runs_keeps_all_action_controls_visible_in_html_after_compaction() -> (
|
||||
None
|
||||
):
|
||||
body = str(
|
||||
runs_page(
|
||||
running_executions=(
|
||||
{
|
||||
"source": "Running source",
|
||||
"slug": "running-source",
|
||||
"job_id": 1,
|
||||
"execution_id": 11,
|
||||
"started_at": "2026-03-30 12:00 UTC",
|
||||
"runtime": "running for 10s",
|
||||
"status": "Running",
|
||||
"stats": "1 requests • 1 items • 1 byte",
|
||||
"worker": "streaming stats from worker",
|
||||
"log_href": "/job/1/execution/11/logs",
|
||||
"cancel_label": "Stop",
|
||||
"cancel_post_path": "/actions/executions/11/cancel",
|
||||
},
|
||||
),
|
||||
queued_executions=(
|
||||
{
|
||||
"source": "Queued source",
|
||||
"slug": "queued-source",
|
||||
"job_id": 2,
|
||||
"execution_id": 22,
|
||||
"queued_at": "2 minutes ago",
|
||||
"queued_at_iso": "2026-03-30T12:28:00+00:00",
|
||||
"queue_position": 1,
|
||||
"status": "Queued",
|
||||
"status_tone": "idle",
|
||||
"run_label": "Queued",
|
||||
"run_disabled": True,
|
||||
"run_post_path": "/actions/jobs/2/run-now",
|
||||
"cancel_post_path": "/actions/queued-executions/22/cancel",
|
||||
},
|
||||
),
|
||||
upcoming_jobs=(
|
||||
{
|
||||
"source": "Scheduled source",
|
||||
"slug": "scheduled-source",
|
||||
"job_id": 3,
|
||||
"next_run": "in 5 minutes",
|
||||
"next_run_at": "2026-03-30T12:35:00+00:00",
|
||||
"schedule": "*/5 * * * *",
|
||||
"enabled_label": "Enabled",
|
||||
"enabled_tone": "scheduled",
|
||||
"run_disabled": False,
|
||||
"run_reason": "Ready",
|
||||
"toggle_label": "Disable",
|
||||
"toggle_post_path": "/actions/jobs/3/toggle-enabled",
|
||||
"run_post_path": "/actions/jobs/3/run-now",
|
||||
"delete_post_path": "/actions/jobs/3/delete",
|
||||
},
|
||||
),
|
||||
completed_executions=(
|
||||
{
|
||||
"source": "Completed source",
|
||||
"slug": "completed-source",
|
||||
"job_id": 4,
|
||||
"execution_id": 44,
|
||||
"ended_at": "2 minutes ago",
|
||||
"ended_at_iso": "2026-03-30T12:28:00+00:00",
|
||||
"status": "Succeeded",
|
||||
"status_tone": "done",
|
||||
"stats": "1 requests • 1 items • 1 byte",
|
||||
"summary": "Worker exited successfully",
|
||||
"log_href": "/job/4/execution/44/logs",
|
||||
},
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
assert ">Stop<" in body
|
||||
assert ">Cancel<" in body
|
||||
assert ">Run now<" in body
|
||||
assert ">Disable<" in body
|
||||
assert "/job/4/execution/44/logs" in body
|
||||
|
||||
|
||||
def test_cancel_queued_execution_action_deletes_pending_row_without_touching_running_execution(
|
||||
monkeypatch, tmp_path: Path
|
||||
) -> None:
|
||||
|
|
@ -1327,6 +1477,24 @@ def test_toggle_job_enabled_action_removes_queued_execution(
|
|||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_render_create_source_uses_shared_submit_button(
|
||||
monkeypatch, tmp_path: Path
|
||||
) -> None:
|
||||
db_path = tmp_path / "create-source-shared-submit.db"
|
||||
monkeypatch.setenv("REPUBLISHER_DB_PATH", str(db_path))
|
||||
|
||||
async def run() -> None:
|
||||
app = create_app()
|
||||
body = str(await render_create_source(app))
|
||||
|
||||
assert 'type="submit"' in body
|
||||
assert "Create source" in body
|
||||
assert "cursor-pointer" in body
|
||||
assert "bg-slate-950" in body
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_render_execution_logs_uses_app_route(monkeypatch, tmp_path: Path) -> None:
|
||||
db_path = tmp_path / "logs-render.db"
|
||||
monkeypatch.setenv("REPUBLISHER_DB_PATH", str(db_path))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue