This repository has been archived on 2026-10-28. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
karldns.de/router_dyndns/web/templates_admin_tables.py
T

103 lines
5.0 KiB
Python
Raw Normal View History

2026-05-20 23:55:27 +02:00
from __future__ import annotations
from .html_utils import attr, escape
def _account_row(account: dict[str, str | int | None], csrf: str = "", admin_path: str = "/admin") -> str:
hostname = escape(account["hostname"])
username = escape(account["username"])
ipv4 = escape(account.get("ipv4") or "-")
ipv6 = escape(account.get("ipv6") or "-")
updated = escape(account.get("updated_at") or "Never")
safe_admin_path = attr(admin_path)
return f"""
<tr>
<td>{hostname}</td><td>{username}</td><td>{ipv4}</td><td>{ipv6}</td><td>{updated}</td>
<td>
<form method="post" action="{safe_admin_path}/accounts/rotate" class="d-flex gap-2 flex-wrap">
<input type="hidden" name="csrf" value="{attr(csrf)}">
<input type="hidden" name="hostname" value="{hostname}">
<button name="action" value="update" class="btn btn-sm btn-light px-3" title="Rotate update URL" aria-label="Rotate update URL for {hostname}">Update URL</button>
<button name="action" value="management" class="btn btn-sm btn-light px-3" title="Rotate management link" aria-label="Rotate management link for {hostname}">Manage link</button>
<button name="action" value="password" class="btn btn-sm btn-light px-3" title="Rotate router password" aria-label="Rotate router password for {hostname}">Password</button>
</form>
</td>
<td>
<form method="post" action="{safe_admin_path}/accounts/delete">
<input type="hidden" name="csrf" value="{attr(csrf)}">
<input type="hidden" name="hostname" value="{hostname}">
<button class="btn btn-sm btn-light px-2 text-danger" title="Delete hostname" aria-label="Delete {hostname}">x</button>
</form>
</td>
</tr>
"""
def _admin_table_toolbar(table_id: str, search_label: str) -> str:
safe_id = attr(table_id)
safe_label = attr(search_label)
return f"""
<div class="admin-table-shell mt-3" data-admin-table>
<div class="d-flex align-items-center justify-content-between gap-3 flex-column flex-md-row mb-3">
<label class="w-100 mb-0" for="{safe_id}-search">
<span class="visually-hidden">{safe_label}</span>
<input id="{safe_id}-search" class="form-control" type="search" placeholder="{safe_label}" data-table-search autocomplete="off">
</label>
<div class="d-flex align-items-center gap-2 flex-shrink-0">
<span class="small text-secondary text-nowrap" data-table-count>0-0 of 0</span>
<label class="visually-hidden" for="{safe_id}-page-size">Rows per page</label>
<select id="{safe_id}-page-size" class="form-select form-select-sm table-page-size" data-table-page-size>
<option value="10">10</option>
<option value="25" selected>25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
</div>
"""
def _admin_table_pagination() -> str:
return """
<nav class="mt-3" aria-label="Table pagination">
<ul class="pagination pagination-sm justify-content-end mb-0" data-table-pagination></ul>
</nav>
</div>
"""
def _domain_claim_row(challenge: dict[str, str | None]) -> str:
domain = escape(challenge["domain"])
owner = escape(challenge.get("owner_hostname") or "-")
created = escape(challenge.get("created_at") or "-")
verified = escape(challenge.get("verified_at") or "-")
status = "Verified" if challenge.get("verified_at") else "Pending"
return f"<tr><td>{domain}</td><td>{owner}</td><td>{status}</td><td>{created}</td><td>{verified}</td></tr>"
def _cleanup_row(run: dict[str, str | int]) -> str:
created = escape(run.get("created_at") or "-")
domains = escape(run.get("domain_challenges_deleted") or 0)
accounts = escape(run.get("unused_accounts_deleted") or 0)
return f"<tr><td>{created}</td><td>{domains}</td><td>{accounts}</td></tr>"
def _scheduled_task_row(task: dict[str, str | int | None]) -> str:
name = escape(task.get("name") or "-")
status = escape(task.get("last_status") or "-")
next_run = escape(task.get("next_run_at") or "-")
lease_expires = escape(task.get("lease_expires_at") or "-")
last_finished = escape(task.get("last_finished_at") or "-")
last_error = escape(task.get("last_error") or "-")
return f"<tr><td>{name}</td><td>{status}</td><td>{next_run}</td><td>{lease_expires}</td><td>{last_finished}</td><td>{last_error}</td></tr>"
def _event_row(event: dict[str, str | int | None]) -> str:
created = escape(event.get("created_at") or "-")
hostname = escape(event.get("hostname") or "-")
status = escape(event.get("status") or "-")
ipv4 = escape(event.get("ipv4") or "-")
ipv6 = escape(event.get("ipv6") or "-")
count = escape(event.get("count") or 1)
detail = escape(event.get("detail") or "-")
return f"<tr><td>{created}</td><td>{hostname}</td><td>{status}</td><td>{ipv4}</td><td>{ipv6}</td><td>{count}</td><td>{detail}</td></tr>"