Add settings and live sidebar counts
This commit is contained in:
parent
2a99edeec3
commit
a809bde16c
16 changed files with 696 additions and 51 deletions
|
|
@ -1,5 +1,6 @@
|
|||
from repub.pages.dashboard import dashboard_page, dashboard_page_with_data
|
||||
from repub.pages.runs import execution_logs_page, runs_page
|
||||
from repub.pages.settings import settings_page
|
||||
from repub.pages.shim import shim_page
|
||||
from repub.pages.sources import create_source_page, edit_source_page, sources_page
|
||||
|
||||
|
|
@ -10,6 +11,7 @@ __all__ = [
|
|||
"edit_source_page",
|
||||
"execution_logs_page",
|
||||
"runs_page",
|
||||
"settings_page",
|
||||
"shim_page",
|
||||
"sources_page",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -251,17 +251,23 @@ def dashboard_page_with_data(
|
|||
running_executions: tuple[Mapping[str, object], ...] | None = None,
|
||||
source_feeds: tuple[Mapping[str, object], ...] | None = None,
|
||||
) -> Renderable:
|
||||
running_items = running_executions or ()
|
||||
source_items = source_feeds or ()
|
||||
return h.main(
|
||||
id="morph",
|
||||
class_="min-h-screen lg:grid lg:grid-cols-[18rem_minmax(0,1fr)]",
|
||||
)[
|
||||
admin_sidebar(current_path="/"),
|
||||
admin_sidebar(
|
||||
current_path="/",
|
||||
source_count=len(source_items),
|
||||
running_count=len(running_items),
|
||||
),
|
||||
h.div(class_="px-4 py-4 sm:px-5 lg:px-6 lg:py-5")[
|
||||
h.div(class_="mx-auto max-w-7xl space-y-5")[
|
||||
dashboard_header(),
|
||||
operational_snapshot(snapshot=snapshot),
|
||||
running_executions_table(running_executions=running_executions),
|
||||
published_feeds_table(source_feeds=source_feeds),
|
||||
running_executions_table(running_executions=running_items),
|
||||
published_feeds_table(source_feeds=source_items),
|
||||
]
|
||||
],
|
||||
]
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ def runs_page(
|
|||
running_executions: tuple[Mapping[str, object], ...] | None = None,
|
||||
upcoming_jobs: tuple[Mapping[str, object], ...] | None = None,
|
||||
completed_executions: tuple[Mapping[str, object], ...] | None = None,
|
||||
source_count: int = 0,
|
||||
) -> Renderable:
|
||||
running_items = running_executions or ()
|
||||
upcoming_items = upcoming_jobs or ()
|
||||
|
|
@ -207,6 +208,8 @@ def runs_page(
|
|||
eyebrow="Execution control",
|
||||
title="Runs",
|
||||
actions=muted_action_link(href="/sources", label="Back to sources"),
|
||||
source_count=source_count,
|
||||
running_count=len(running_items),
|
||||
content=(
|
||||
table_section(
|
||||
eyebrow="Live work",
|
||||
|
|
|
|||
82
repub/pages/settings.py
Normal file
82
repub/pages/settings.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
|
||||
import htpy as h
|
||||
from htpy import Renderable
|
||||
|
||||
from repub.components import input_field, muted_action_link, page_shell, section_card
|
||||
|
||||
|
||||
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": (
|
||||
"{"
|
||||
f"maxConcurrentJobs: '{_value(settings, 'max_concurrent_jobs', '1')}'"
|
||||
"}"
|
||||
),
|
||||
"data-on:submit": f"@post('{action_path}')",
|
||||
},
|
||||
class_="space-y-6 rounded-[1.5rem] bg-white p-6 shadow-sm ring-1 ring-slate-200",
|
||||
)[
|
||||
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",
|
||||
),
|
||||
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",
|
||||
),
|
||||
h.div(
|
||||
class_="flex flex-wrap justify-end gap-3 border-t border-slate-200 pt-6"
|
||||
)[
|
||||
muted_action_link(href="/", label="Back to dashboard"),
|
||||
h.button(
|
||||
type="submit",
|
||||
class_="rounded-full bg-slate-950 px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-slate-800",
|
||||
)["Save settings"],
|
||||
],
|
||||
],
|
||||
)
|
||||
),
|
||||
)
|
||||
|
|
@ -37,7 +37,11 @@ def shim_page(
|
|||
id="morph",
|
||||
class_="min-h-screen lg:grid lg:grid-cols-[18rem_minmax(0,1fr)]",
|
||||
)[
|
||||
admin_sidebar(current_path=current_path),
|
||||
admin_sidebar(
|
||||
current_path=current_path,
|
||||
source_count=0,
|
||||
running_count=0,
|
||||
),
|
||||
h.div(class_="px-4 py-4 sm:px-5 lg:px-6 lg:py-5")[
|
||||
h.div(class_="mx-auto max-w-7xl space-y-5")[
|
||||
h.section[
|
||||
|
|
|
|||
|
|
@ -128,13 +128,18 @@ def sources_table(
|
|||
|
||||
|
||||
def sources_page(
|
||||
*, sources: tuple[Mapping[str, object], ...] | None = None
|
||||
*,
|
||||
sources: tuple[Mapping[str, object], ...] | None = None,
|
||||
running_count: int = 0,
|
||||
) -> Renderable:
|
||||
source_items = sources or ()
|
||||
return page_shell(
|
||||
current_path="/sources",
|
||||
eyebrow="Source management",
|
||||
title="Sources",
|
||||
content=sources_table(sources=sources),
|
||||
source_count=len(source_items),
|
||||
running_count=running_count,
|
||||
content=sources_table(sources=source_items),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -398,6 +403,18 @@ def source_form(
|
|||
signal_name="jobEnabled",
|
||||
checked=_checked(source, "enabled", True),
|
||||
),
|
||||
toggle_field(
|
||||
label="Convert images",
|
||||
description="Normalize mirrored images through the image conversion pipeline for this source.",
|
||||
signal_name="convertImages",
|
||||
checked=_checked(source, "convert_images", True),
|
||||
),
|
||||
toggle_field(
|
||||
label="Convert video",
|
||||
description="Run mirrored videos through the video conversion pipeline for this source.",
|
||||
signal_name="convertVideo",
|
||||
checked=_checked(source, "convert_video", True),
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
|
|
@ -415,7 +432,12 @@ def source_form(
|
|||
)
|
||||
|
||||
|
||||
def create_source_page(*, action_path: str = "/actions/sources/create") -> Renderable:
|
||||
def create_source_page(
|
||||
*,
|
||||
action_path: str = "/actions/sources/create",
|
||||
source_count: int = 0,
|
||||
running_count: int = 0,
|
||||
) -> Renderable:
|
||||
actions = (
|
||||
muted_action_link(href="/sources", label="Back to sources"),
|
||||
header_action_link(href="/runs", label="View runs"),
|
||||
|
|
@ -425,6 +447,8 @@ def create_source_page(*, action_path: str = "/actions/sources/create") -> Rende
|
|||
eyebrow="Source creation",
|
||||
title="Create source",
|
||||
actions=actions,
|
||||
source_count=source_count,
|
||||
running_count=running_count,
|
||||
content=source_form(mode="create", action_path=action_path),
|
||||
)
|
||||
|
||||
|
|
@ -434,6 +458,8 @@ def edit_source_page(
|
|||
slug: str,
|
||||
source: Mapping[str, object],
|
||||
action_path: str,
|
||||
source_count: int = 0,
|
||||
running_count: int = 0,
|
||||
) -> Renderable:
|
||||
actions = (
|
||||
muted_action_link(href="/sources", label="Back to sources"),
|
||||
|
|
@ -444,5 +470,7 @@ def edit_source_page(
|
|||
eyebrow="Source editing",
|
||||
title="Edit source",
|
||||
actions=actions,
|
||||
source_count=source_count,
|
||||
running_count=running_count,
|
||||
content=source_form(mode="edit", action_path=action_path, source=source),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue