Archived
78 lines
3.8 KiB
Python
78 lines
3.8 KiB
Python
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="Create a new update URL" aria-label="New update URL for {hostname}">New update URL</button>
|
|
<button name="action" value="management" class="btn btn-sm btn-light px-3" title="Create a new dashboard link" aria-label="New dashboard link for {hostname}">New dashboard link</button>
|
|
<button name="action" value="password" class="btn btn-sm btn-light px-3" title="Create a new router password" aria-label="New password for {hostname}">New 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-outline-danger px-2" title="Delete hostname" aria-label="Delete {hostname}">Delete</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 _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>"
|