styles combine
This commit is contained in:
@@ -125,6 +125,11 @@ def index():
|
||||
<p class="muted">Vytváření záloh a kopírování příkazů pro obnovu. Obnova je záměrně ruční a chráněná.</p>
|
||||
<a class="btn" href="/portal/backups">Spravovat zálohy</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>Nasazení</h2>
|
||||
<p class="muted">Historie posledních běhů nasazení, stavů a výstupů z deploy procesu.</p>
|
||||
<a class="btn" href="/portal/deployments">Zobrazit nasazení</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
|
||||
+103
-18
@@ -1,30 +1,79 @@
|
||||
from fastapi import APIRouter, HTTPException, Request
|
||||
import html
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
from app.db.apps import get_deployment, get_deployments
|
||||
from app.templates.layout import page
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
templates = Jinja2Templates(directory="app/templates")
|
||||
|
||||
|
||||
@router.get("/deployments", response_class=HTMLResponse)
|
||||
async def deployments_page(request: Request):
|
||||
async def deployments_page():
|
||||
deployments = get_deployments()
|
||||
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"deployments.html",
|
||||
{
|
||||
"deployments": deployments,
|
||||
},
|
||||
rows = ""
|
||||
for deployment in deployments:
|
||||
deployment_id = html.escape(str(deployment.get("id", "")))
|
||||
app_id = html.escape(deployment.get("app_id", "") or "")
|
||||
kind = html.escape(deployment.get("kind", "") or "")
|
||||
status = html.escape(deployment.get("status", "") or "")
|
||||
started_at = html.escape(deployment.get("started_at", "") or "")
|
||||
finished_at = html.escape(deployment.get("finished_at", "") or "")
|
||||
returncode = deployment.get("returncode")
|
||||
returncode_label = "" if returncode is None else html.escape(str(returncode))
|
||||
|
||||
rows += f"""
|
||||
<tr>
|
||||
<td>
|
||||
<strong>#{deployment_id}</strong><br>
|
||||
<span class="muted">{started_at}</span>
|
||||
</td>
|
||||
<td>{app_id}</td>
|
||||
<td>{kind}</td>
|
||||
<td><span class="pill">{status}</span></td>
|
||||
<td>{returncode_label}</td>
|
||||
<td>{finished_at}</td>
|
||||
<td class="actions-cell">
|
||||
<a class="btn" href="/portal/deployments/{deployment_id}">Detail</a>
|
||||
</td>
|
||||
</tr>
|
||||
"""
|
||||
|
||||
if not rows:
|
||||
rows = '<tr><td colspan="7">Zatím nejsou evidovaná žádná nasazení.</td></tr>'
|
||||
|
||||
return page(
|
||||
"Nasazení",
|
||||
f"""
|
||||
<div class="card">
|
||||
<h2>Historie nasazení</h2>
|
||||
<p class="muted">Přehled posledních běhů nasazení a jejich výsledků.</p>
|
||||
<a class="btn" href="/portal">← Zpět na portál</a>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Nasazení</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Aplikace</th>
|
||||
<th>Typ</th>
|
||||
<th>Status</th>
|
||||
<th>Kód</th>
|
||||
<th>Dokončeno</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
{rows}
|
||||
</table>
|
||||
</div>
|
||||
""",
|
||||
)
|
||||
|
||||
|
||||
@router.get("/deployments/{deployment_id}", response_class=HTMLResponse)
|
||||
async def deployment_detail_page(
|
||||
request: Request,
|
||||
deployment_id: int,
|
||||
):
|
||||
deployment = get_deployment(deployment_id)
|
||||
@@ -32,10 +81,46 @@ async def deployment_detail_page(
|
||||
if not deployment:
|
||||
raise HTTPException(status_code=404, detail="Deployment not found")
|
||||
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"deployment-detail.html",
|
||||
{
|
||||
"deployment": deployment,
|
||||
},
|
||||
title = f"Nasazení #{html.escape(str(deployment.get('id', deployment_id)))}"
|
||||
app_id = html.escape(deployment.get("app_id", "") or "")
|
||||
kind = html.escape(deployment.get("kind", "") or "")
|
||||
status = html.escape(deployment.get("status", "") or "")
|
||||
started_at = html.escape(deployment.get("started_at", "") or "")
|
||||
finished_at = html.escape(deployment.get("finished_at", "") or "")
|
||||
returncode = deployment.get("returncode")
|
||||
returncode_label = "" if returncode is None else html.escape(str(returncode))
|
||||
stdout = html.escape(deployment.get("stdout", "") or "")
|
||||
stderr = html.escape(deployment.get("stderr", "") or "")
|
||||
|
||||
return page(
|
||||
title,
|
||||
f"""
|
||||
<div class="card">
|
||||
<h2>{title}</h2>
|
||||
<p class="muted">Detail běhu nasazení včetně výstupu procesu.</p>
|
||||
<p>
|
||||
<a class="btn" href="/portal/deployments">← Zpět na nasazení</a>
|
||||
<a class="btn btn-secondary" href="/portal">Zpět na portál</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Souhrn</h2>
|
||||
<table>
|
||||
<tr><th>Aplikace</th><td>{app_id}</td></tr>
|
||||
<tr><th>Typ</th><td>{kind}</td></tr>
|
||||
<tr><th>Status</th><td><span class="pill">{status}</span></td></tr>
|
||||
<tr><th>Návratový kód</th><td>{returncode_label}</td></tr>
|
||||
<tr><th>Spuštěno</th><td>{started_at}</td></tr>
|
||||
<tr><th>Dokončeno</th><td>{finished_at}</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Výstup</h2>
|
||||
<pre>{stdout}</pre>
|
||||
<h2>Chyba</h2>
|
||||
<pre>{stderr}</pre>
|
||||
</div>
|
||||
""",
|
||||
)
|
||||
|
||||
+13
-1
@@ -149,6 +149,18 @@ button:hover,
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn + .btn {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--secondary);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--secondary-dark);
|
||||
}
|
||||
|
||||
.danger {
|
||||
background: var(--danger);
|
||||
}
|
||||
@@ -247,4 +259,4 @@ pre {
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ def page(title: str, body: str) -> str:
|
||||
<nav>
|
||||
<a href="/portal">Aplikace</a>
|
||||
<a href="/portal/new-app">Nová aplikace</a>
|
||||
<a href="/portal/deployments">Nasazení</a>
|
||||
<a href="/portal/backups">Zálohy</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
Reference in New Issue
Block a user