republisher/repub/pages/settings.py

100 lines
3.8 KiB
Python
Raw Normal View History

2026-03-30 18:26:02 +02:00
from __future__ import annotations
from collections.abc import Mapping
import htpy as h
from htpy import Renderable
from repub.components import (
action_button,
input_field,
muted_action_link,
page_shell,
section_card,
)
2026-03-30 18:26:02 +02:00
def _value(settings: Mapping[str, object] | None, key: str, default: str = "") -> str:
if settings is None:
return default
return str(settings.get(key, default))
def settings_page(
*,
settings: Mapping[str, object] | None = None,
action_path: str = "/actions/settings",
source_count: int = 0,
running_count: int = 0,
) -> Renderable:
return page_shell(
current_path="/settings",
eyebrow="Configuration",
title="Settings",
description="Global runtime controls for the republisher.",
source_count=source_count,
running_count=running_count,
content=section_card(
content=(
h.form(
{
"data-signals": "{_formError: '', _formSuccess: ''}",
"data-signals__ifmissing": (
"{"
2026-03-31 12:14:47 +02:00
f"maxConcurrentJobs: '{_value(settings, 'max_concurrent_jobs', '1')}', "
f"feedUrl: '{_value(settings, 'feed_url')}'"
2026-03-30 18:26:02 +02:00
"}"
),
"data-on:submit": f"@post('{action_path}')",
},
2026-03-30 18:57:36 +02:00
class_="space-y-6",
2026-03-30 18:26:02 +02:00
)[
h.div[
h.p(
class_="text-xs font-semibold uppercase tracking-[0.22em] text-amber-600"
)["Scheduler"],
h.h2(class_="mt-2 text-xl font-semibold text-slate-950")[
"Runtime settings"
],
h.p(class_="mt-2 text-sm text-slate-600")[
"Limit how many jobs the scheduler and manual runs can execute at the same time."
],
],
h.div(
{
"data-show": "$_formError !== ''",
"data-text": "$_formError",
},
class_="rounded-2xl bg-rose-50 px-4 py-3 text-sm font-medium text-rose-800",
),
2026-03-30 18:57:36 +02:00
h.div(class_="rounded-[1.5rem] bg-stone-50 p-5")[
input_field(
label="Max concurrent jobs",
field_id="max-concurrent-jobs",
value=_value(settings, "max_concurrent_jobs", "1"),
help_text="Must be an integer greater than or equal to 1.",
signal_name="maxConcurrentJobs",
),
2026-03-31 12:14:47 +02:00
input_field(
label="Feed URL",
field_id="feed-domain",
value=_value(settings, "feed_url"),
placeholder="https://mirror.example",
help_text="Example: http://localhost:8080. Must include http:// or https:// and point at the public base URL that serves /feeds/.",
signal_name="feedUrl",
),
2026-03-30 18:57:36 +02:00
],
h.div(class_="flex flex-wrap justify-end gap-3 pt-2")[
2026-03-30 18:26:02 +02:00
muted_action_link(href="/", label="Back to dashboard"),
action_button(
label="Save settings",
tone="dark",
emphasis="regular",
button_type="submit",
),
2026-03-30 18:26:02 +02:00
],
],
)
),
)