113 lines
5.5 KiB
Python
113 lines
5.5 KiB
Python
import html
|
|
|
|
from ..config import PORTAL_PREFIX
|
|
|
|
APP_NAME = "CSBot Services Portal"
|
|
|
|
|
|
def page(title: str, body: str, user=None) -> str:
|
|
nav = ""
|
|
user_panel = ""
|
|
|
|
if user:
|
|
username = html.escape(user.get("username", ""))
|
|
display_name = html.escape(user.get("display_name") or user.get("username", ""))
|
|
admin_menu = ""
|
|
if (user.get("role") or "").lower() == "admin":
|
|
admin_menu = """
|
|
<details class="nav-menu">
|
|
<summary class="nav-menu-button"><i class="fa-solid fa-screwdriver-wrench" aria-hidden="true"></i> Admin</summary>
|
|
<div class="nav-menu-panel">
|
|
<a href="/portal/operations"><i class="fa-solid fa-gauge-high" aria-hidden="true"></i> Přehled</a>
|
|
<a href="/portal/apps"><i class="fa-solid fa-server" aria-hidden="true"></i> Služby</a>
|
|
<a href="/portal/jobs"><i class="fa-solid fa-list-check" aria-hidden="true"></i> Úlohy</a>
|
|
<a href="/portal/scheduled-scripts"><i class="fa-solid fa-calendar-days" aria-hidden="true"></i> Plánované skripty</a>
|
|
<a href="/portal/alerting/rules"><i class="fa-solid fa-bell" aria-hidden="true"></i> Alerting</a>
|
|
<a href="/portal/migration-readiness"><i class="fa-solid fa-diagram-project" aria-hidden="true"></i> Migration Readiness</a>
|
|
<a href="/portal/deployments"><i class="fa-solid fa-rocket" aria-hidden="true"></i> Nasazení</a>
|
|
<a href="/portal/incidents"><i class="fa-solid fa-triangle-exclamation" aria-hidden="true"></i> Incidenty</a>
|
|
<a href="/portal/workers"><i class="fa-solid fa-gears" aria-hidden="true"></i> Workery</a>
|
|
<a href="/portal/admin/runtime"><i class="fa-solid fa-server" aria-hidden="true"></i> Runtime Management</a>
|
|
<a href="/portal/admin/environment"><i class="fa-solid fa-sliders" aria-hidden="true"></i> Environment</a>
|
|
<a href="/portal/admin/users"><i class="fa-solid fa-users" aria-hidden="true"></i> Users</a>
|
|
<a href="/portal/audit"><i class="fa-solid fa-clipboard-list" aria-hidden="true"></i> Audit</a>
|
|
<a href="/portal/backups"><i class="fa-solid fa-box-archive" aria-hidden="true"></i> Zálohy</a>
|
|
</div>
|
|
</details>
|
|
"""
|
|
nav = f"""
|
|
<button type="button" class="nav-toggle" aria-label="Otevřít menu" onclick="togglePortalNav()"><i class="fa-solid fa-bars" aria-hidden="true"></i></button>
|
|
<div class="nav-wrap" id="portal-nav">
|
|
<nav>
|
|
<a class="nav-link" href="/portal/apps"><i class="fa-solid fa-server" aria-hidden="true"></i> Služby</a>
|
|
<a class="nav-link" href="/portal/jobs"><i class="fa-solid fa-list-check" aria-hidden="true"></i> Úlohy</a>
|
|
<a class="nav-link" href="/portal/scheduled-scripts"><i class="fa-solid fa-calendar-days" aria-hidden="true"></i> Plánované skripty</a>
|
|
<a class="nav-link" href="/portal/alerting/rules"><i class="fa-solid fa-bell" aria-hidden="true"></i> Alerting</a>
|
|
<a class="nav-link" href="/portal/developers"><i class="fa-solid fa-code" aria-hidden="true"></i> Pro vývojáře</a>
|
|
{admin_menu}
|
|
<div class="user-menu">
|
|
<span class="user-name">{display_name}</span>
|
|
<span class="muted">@{username}</span>
|
|
<form method="post" action="/portal/logout">
|
|
<button type="submit" class="btn-secondary"><i class="fa-solid fa-right-from-bracket" aria-hidden="true"></i> Odhlásit</button>
|
|
</form>
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
"""
|
|
user_panel = ""
|
|
|
|
return f"""
|
|
<html>
|
|
<head>
|
|
<title>{APP_NAME} - {html.escape(title)}</title>
|
|
<link rel="stylesheet" href="{PORTAL_PREFIX}/static/vendor/fontawesome/css/fontawesome.min.css">
|
|
<link rel="stylesheet" href="{PORTAL_PREFIX}/static/vendor/fontawesome/css/solid.min.css">
|
|
<link rel="stylesheet" href="{PORTAL_PREFIX}/static/styles.css">
|
|
<script src="{PORTAL_PREFIX}/static/portal.js"></script>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<a class="brand" href="/portal/apps" aria-label="{APP_NAME}">
|
|
<img src="{PORTAL_PREFIX}/static/csbot-logo.svg" alt="CSBOT">
|
|
<span>{APP_NAME}</span>
|
|
</a>
|
|
{nav}
|
|
{user_panel}
|
|
</header>
|
|
<main>
|
|
{body}
|
|
</main>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
|
|
def render_result(title, back_url, sections, extra_link=None, extra_label=None, user=None):
|
|
rendered_sections = ""
|
|
|
|
for section_title, content in sections:
|
|
rendered_sections += f"""
|
|
<h2>{html.escape(section_title)}</h2>
|
|
<pre>{html.escape(content)}</pre>
|
|
"""
|
|
|
|
extra = ""
|
|
if extra_link and extra_label:
|
|
extra = f'<p><a class="btn" href="{extra_link}">{html.escape(extra_label)}</a></p>'
|
|
|
|
return page(
|
|
title,
|
|
f"""
|
|
<div class="card">
|
|
<h2>{html.escape(title)}</h2>
|
|
{extra}
|
|
<p><a href="{back_url}">← Zpět</a></p>
|
|
</div>
|
|
<div class="card">
|
|
{rendered_sections}
|
|
</div>
|
|
""",
|
|
user=user,
|
|
)
|