cz texty
This commit is contained in:
+54
-54
@@ -41,22 +41,22 @@ def index():
|
|||||||
|
|
||||||
memory_options = ""
|
memory_options = ""
|
||||||
for value, label in [
|
for value, label in [
|
||||||
("", "Default"),
|
("", "Výchozí"),
|
||||||
("256m", "256 MB - small service"),
|
("256m", "256 MB - malá služba"),
|
||||||
("512m", "512 MB - normal service"),
|
("512m", "512 MB - běžná služba"),
|
||||||
("1g", "1 GB - larger service"),
|
("1g", "1 GB - větší služba"),
|
||||||
("2g", "2 GB - heavy service"),
|
("2g", "2 GB - náročná služba"),
|
||||||
]:
|
]:
|
||||||
selected = "selected" if memory == value else ""
|
selected = "selected" if memory == value else ""
|
||||||
memory_options += f'<option value="{value}" {selected}>{label}</option>'
|
memory_options += f'<option value="{value}" {selected}>{label}</option>'
|
||||||
|
|
||||||
cpu_options = ""
|
cpu_options = ""
|
||||||
for value, label in [
|
for value, label in [
|
||||||
("", "Default"),
|
("", "Výchozí"),
|
||||||
("0.25", "0.25 CPU - very small"),
|
("0.25", "0,25 CPU - velmi malá služba"),
|
||||||
("0.50", "0.50 CPU - normal"),
|
("0.50", "0,50 CPU - běžná služba"),
|
||||||
("1.00", "1 CPU - full core"),
|
("1.00", "1 CPU - celé jádro"),
|
||||||
("2.00", "2 CPU - heavy"),
|
("2.00", "2 CPU - náročná služba"),
|
||||||
]:
|
]:
|
||||||
selected = "selected" if cpus == value else ""
|
selected = "selected" if cpus == value else ""
|
||||||
cpu_options += f'<option value="{value}" {selected}>{label}</option>'
|
cpu_options += f'<option value="{value}" {selected}>{label}</option>'
|
||||||
@@ -75,68 +75,68 @@ def index():
|
|||||||
<div class="inline-form">
|
<div class="inline-form">
|
||||||
<select name="memory">{memory_options}</select>
|
<select name="memory">{memory_options}</select>
|
||||||
<select name="cpus">{cpu_options}</select>
|
<select name="cpus">{cpu_options}</select>
|
||||||
<button type="submit">Apply</button>
|
<button type="submit">Použít</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="resource-help">
|
<div class="resource-help">
|
||||||
Memory is RAM limit. CPU is max compute share.
|
Paměť je limit RAM. CPU určuje maximální podíl výpočetního výkonu.
|
||||||
Example: 0.50 = half CPU core, 1.00 = one full core.
|
Příklad: 0,50 = polovina jádra, 1,00 = celé jádro.
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<details>
|
<details>
|
||||||
<summary>Clone commands</summary>
|
<summary>Příkazy pro klonování</summary>
|
||||||
<label class="muted">HTTP</label>
|
<label class="muted">HTTP</label>
|
||||||
<div class="cmd-row">
|
<div class="cmd-row">
|
||||||
<input readonly value="{http_clone}" id="http-{app_id}">
|
<input readonly value="{http_clone}" id="http-{app_id}">
|
||||||
<button onclick="copyValue('http-{app_id}')">Copy</button>
|
<button onclick="copyValue('http-{app_id}')">Kopírovat</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="muted">SSH</label>
|
<label class="muted">SSH</label>
|
||||||
<div class="cmd-row">
|
<div class="cmd-row">
|
||||||
<input readonly value="{ssh_clone}" id="ssh-{app_id}">
|
<input readonly value="{ssh_clone}" id="ssh-{app_id}">
|
||||||
<button onclick="copyValue('ssh-{app_id}')">Copy</button>
|
<button onclick="copyValue('ssh-{app_id}')">Kopírovat</button>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<form method="post" action="/portal/delete-app" onsubmit="return confirm('Delete {app_id}? This removes container, image, workspace, catalog entry and Gitea repo.');">
|
<form method="post" action="/portal/delete-app" onsubmit="return confirm('Smazat {app_id}? Tím se odstraní kontejner, image, workspace, záznam v katalogu a Gitea repozitář.');">
|
||||||
<input type="hidden" name="app_id" value="{app_id}">
|
<input type="hidden" name="app_id" value="{app_id}">
|
||||||
<button type="submit" class="danger">Delete</button>
|
<button type="submit" class="danger">Smazat</button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not rows:
|
if not rows:
|
||||||
rows = '<tr><td colspan="6">No apps deployed yet.</td></tr>'
|
rows = '<tr><td colspan="6">Zatím nejsou nasazené žádné aplikace.</td></tr>'
|
||||||
|
|
||||||
return page(
|
return page(
|
||||||
"Apps",
|
"Aplikace",
|
||||||
f"""
|
f"""
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Apps</h2>
|
<h2>Aplikace</h2>
|
||||||
<p class="muted">Create, deploy, clone, tune resources and delete services.</p>
|
<p class="muted">Vytváření, nasazení, klonování, nastavení prostředků a mazání služeb.</p>
|
||||||
<a class="btn" href="/portal/new-app">+ New App</a>
|
<a class="btn" href="/portal/new-app">+ Nová aplikace</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Backups</h2>
|
<h2>Zálohy</h2>
|
||||||
<p class="muted">Create backups and copy restore commands. Restore is intentionally manual and guarded.</p>
|
<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">Manage Backups</a>
|
<a class="btn" href="/portal/backups">Spravovat zálohy</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Deployed Apps</h2>
|
<h2>Nasazené aplikace</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>App</th>
|
<th>Aplikace</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>Docs</th>
|
<th>Dokumentace</th>
|
||||||
<th>Resources</th>
|
<th>Prostředky</th>
|
||||||
<th>Git</th>
|
<th>Git</th>
|
||||||
<th>Actions</th>
|
<th>Akce</th>
|
||||||
</tr>
|
</tr>
|
||||||
{rows}
|
{rows}
|
||||||
</table>
|
</table>
|
||||||
@@ -148,34 +148,34 @@ def index():
|
|||||||
@router.get("/new-app", response_class=HTMLResponse)
|
@router.get("/new-app", response_class=HTMLResponse)
|
||||||
def new_app_form():
|
def new_app_form():
|
||||||
return page(
|
return page(
|
||||||
"New App",
|
"Nová aplikace",
|
||||||
"""
|
"""
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Create New App</h2>
|
<h2>Vytvořit novou aplikaci</h2>
|
||||||
<p class="muted">This creates Gitea repo, webhook, local workspace, initial commit and deploys the service.</p>
|
<p class="muted">Vytvoří Gitea repozitář, webhook, lokální workspace, první commit a nasadí službu.</p>
|
||||||
|
|
||||||
<form method="post" action="/portal/new-app">
|
<form method="post" action="/portal/new-app">
|
||||||
<p>
|
<p>
|
||||||
<label>App ID</label><br>
|
<label>ID aplikace</label><br>
|
||||||
<input name="app_id" placeholder="gmail-service" required>
|
<input name="app_id" placeholder="gmail-service" required>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<label>App Name</label><br>
|
<label>Název aplikace</label><br>
|
||||||
<input name="app_name" placeholder="Gmail Service" required>
|
<input name="app_name" placeholder="Gmail služba" required>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<label>Template</label><br>
|
<label>Šablona</label><br>
|
||||||
<select name="template">
|
<select name="template">
|
||||||
<option value="python-fastapi">Python FastAPI</option>
|
<option value="python-fastapi">Python FastAPI</option>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button type="submit">Create App</button>
|
<button type="submit">Vytvořit aplikaci</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p><a href="/portal">← Back</a></p>
|
<p><a href="/portal">← Zpět</a></p>
|
||||||
</div>
|
</div>
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
@@ -184,7 +184,7 @@ def new_app_form():
|
|||||||
@router.post("/new-app", response_class=HTMLResponse)
|
@router.post("/new-app", response_class=HTMLResponse)
|
||||||
def create_app(app_id: str = Form(...), app_name: str = Form(...), template: str = Form(...)):
|
def create_app(app_id: str = Form(...), app_name: str = Form(...), template: str = Form(...)):
|
||||||
if template != "python-fastapi":
|
if template != "python-fastapi":
|
||||||
return HTMLResponse("Unsupported template", status_code=400)
|
return HTMLResponse("Nepodporovaná šablona", status_code=400)
|
||||||
|
|
||||||
create_result = run_command([NEW_APP_SCRIPT, app_id, app_name])
|
create_result = run_command([NEW_APP_SCRIPT, app_id, app_name])
|
||||||
deploy_result = run_command([DEPLOY_SCRIPT, app_id])
|
deploy_result = run_command([DEPLOY_SCRIPT, app_id])
|
||||||
@@ -192,16 +192,16 @@ def create_app(app_id: str = Form(...), app_name: str = Form(...), template: str
|
|||||||
status = "OK" if create_result.returncode == 0 and deploy_result.returncode == 0 else "FAILED"
|
status = "OK" if create_result.returncode == 0 and deploy_result.returncode == 0 else "FAILED"
|
||||||
|
|
||||||
return render_result(
|
return render_result(
|
||||||
title=f"Create App: {status}",
|
title=f"Vytvoření aplikace: {status}",
|
||||||
back_url="/portal",
|
back_url="/portal",
|
||||||
sections=[
|
sections=[
|
||||||
("Create Output", create_result.stdout),
|
("Výstup vytvoření", create_result.stdout),
|
||||||
("Create Error", create_result.stderr),
|
("Chyba vytvoření", create_result.stderr),
|
||||||
("Deploy Output", deploy_result.stdout),
|
("Výstup nasazení", deploy_result.stdout),
|
||||||
("Deploy Error", deploy_result.stderr),
|
("Chyba nasazení", deploy_result.stderr),
|
||||||
],
|
],
|
||||||
extra_link=f"/apps/{html.escape(app_id)}/docs",
|
extra_link=f"/apps/{html.escape(app_id)}/docs",
|
||||||
extra_label="Open Swagger",
|
extra_label="Otevřít Swagger",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -211,9 +211,9 @@ def delete_app(app_id: str = Form(...)):
|
|||||||
status = "OK" if result.returncode == 0 else "FAILED"
|
status = "OK" if result.returncode == 0 else "FAILED"
|
||||||
|
|
||||||
return render_result(
|
return render_result(
|
||||||
title=f"Delete App: {status}",
|
title=f"Smazání aplikace: {status}",
|
||||||
back_url="/portal",
|
back_url="/portal",
|
||||||
sections=[("Output", result.stdout), ("Error", result.stderr)],
|
sections=[("Výstup", result.stdout), ("Chyba", result.stderr)],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -244,12 +244,12 @@ def update_resources(app_id: str = Form(...), memory: str = Form(""), cpus: str
|
|||||||
status = "OK" if compose_result.returncode == 0 and deploy_result.returncode == 0 else "FAILED"
|
status = "OK" if compose_result.returncode == 0 and deploy_result.returncode == 0 else "FAILED"
|
||||||
|
|
||||||
return render_result(
|
return render_result(
|
||||||
title=f"Update Resources: {status}",
|
title=f"Úprava prostředků: {status}",
|
||||||
back_url="/portal",
|
back_url="/portal",
|
||||||
sections=[
|
sections=[
|
||||||
("Compose Output", compose_result.stdout),
|
("Výstup compose", compose_result.stdout),
|
||||||
("Compose Error", compose_result.stderr),
|
("Chyba compose", compose_result.stderr),
|
||||||
("Deploy Output", deploy_result.stdout),
|
("Výstup nasazení", deploy_result.stdout),
|
||||||
("Deploy Error", deploy_result.stderr),
|
("Chyba nasazení", deploy_result.stderr),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
+20
-20
@@ -35,52 +35,52 @@ def backups_page():
|
|||||||
<td>
|
<td>
|
||||||
<div class="copy-row">
|
<div class="copy-row">
|
||||||
<input readonly value="{backup_path}">
|
<input readonly value="{backup_path}">
|
||||||
<button type="button" class="copy-button" data-copy-value="{backup_path}" onclick="copyText(this)">Copy</button>
|
<button type="button" class="copy-button" data-copy-value="{backup_path}" onclick="copyText(this)">Kopírovat</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="copy-row">
|
<div class="copy-row">
|
||||||
<input readonly value="{restore_cmd}">
|
<input readonly value="{restore_cmd}">
|
||||||
<button type="button" class="copy-button" data-copy-value="{restore_cmd}" onclick="copyText(this)">Copy</button>
|
<button type="button" class="copy-button" data-copy-value="{restore_cmd}" onclick="copyText(this)">Kopírovat</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="muted">Restore is dangerous and must be run manually over SSH.</div>
|
<div class="muted">Obnova je nebezpečná a musí se spustit ručně přes SSH.</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="actions-cell">
|
<td class="actions-cell">
|
||||||
<form method="post" action="/portal/backups/delete" onsubmit="return confirm('Delete backup {backup_name}?');">
|
<form method="post" action="/portal/backups/delete" onsubmit="return confirm('Smazat zálohu {backup_name}?');">
|
||||||
<input type="hidden" name="backup_path" value="{backup_path}">
|
<input type="hidden" name="backup_path" value="{backup_path}">
|
||||||
<button type="submit" class="danger">Delete</button>
|
<button type="submit" class="danger">Smazat</button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not rows:
|
if not rows:
|
||||||
rows = '<tr><td colspan="4">No backups found.</td></tr>'
|
rows = '<tr><td colspan="4">Nebyly nalezeny žádné zálohy.</td></tr>'
|
||||||
|
|
||||||
return page(
|
return page(
|
||||||
"Backups",
|
"Zálohy",
|
||||||
f"""
|
f"""
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Backup Management</h2>
|
<h2>Správa záloh</h2>
|
||||||
<p class="muted">
|
<p class="muted">
|
||||||
Backups do not include the backup directory itself.
|
Zálohy neobsahují samotný adresář se zálohami.
|
||||||
Restoring an older backup should not delete newer .tar.gz files.
|
Obnova starší zálohy by neměla smazat novější soubory .tar.gz.
|
||||||
Restore remains manual to avoid accidental overwrite.
|
Obnova zůstává ruční, aby nedošlo k nechtěnému přepsání dat.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="post" action="/portal/backups/create">
|
<form method="post" action="/portal/backups/create">
|
||||||
<button type="submit">Create Backup</button>
|
<button type="submit">Vytvořit zálohu</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Available Backups</h2>
|
<h2>Dostupné zálohy</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Backup</th>
|
<th>Záloha</th>
|
||||||
<th>Path</th>
|
<th>Cesta</th>
|
||||||
<th>Restore Command</th>
|
<th>Příkaz pro obnovu</th>
|
||||||
<th>Actions</th>
|
<th>Akce</th>
|
||||||
</tr>
|
</tr>
|
||||||
{rows}
|
{rows}
|
||||||
</table>
|
</table>
|
||||||
@@ -95,9 +95,9 @@ def create_backup():
|
|||||||
status = "OK" if result.returncode == 0 else "FAILED"
|
status = "OK" if result.returncode == 0 else "FAILED"
|
||||||
|
|
||||||
return render_result(
|
return render_result(
|
||||||
title=f"Create Backup: {status}",
|
title=f"Vytvoření zálohy: {status}",
|
||||||
back_url="/portal/backups",
|
back_url="/portal/backups",
|
||||||
sections=[("Output", result.stdout), ("Error", result.stderr)],
|
sections=[("Výstup", result.stdout), ("Chyba", result.stderr)],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ def delete_backup(backup_path: str = Form(...)):
|
|||||||
target = Path(backup_path)
|
target = Path(backup_path)
|
||||||
|
|
||||||
if not is_backup_path(target):
|
if not is_backup_path(target):
|
||||||
return HTMLResponse("Invalid backup path", status_code=400)
|
return HTMLResponse("Neplatná cesta k záloze", status_code=400)
|
||||||
|
|
||||||
target = target.resolve()
|
target = target.resolve()
|
||||||
if target.exists():
|
if target.exists():
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ function copyText(button) {
|
|||||||
navigator.clipboard.writeText(value);
|
navigator.clipboard.writeText(value);
|
||||||
|
|
||||||
const label = button.textContent;
|
const label = button.textContent;
|
||||||
button.textContent = "Copied";
|
button.textContent = "Zkopírováno";
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
button.textContent = label;
|
button.textContent = label;
|
||||||
}, 1200);
|
}, 1200);
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ def page(title: str, body: str) -> str:
|
|||||||
<span>AppFactory</span>
|
<span>AppFactory</span>
|
||||||
</a>
|
</a>
|
||||||
<nav>
|
<nav>
|
||||||
<a href="/portal">Apps</a>
|
<a href="/portal">Aplikace</a>
|
||||||
<a href="/portal/new-app">New App</a>
|
<a href="/portal/new-app">Nová aplikace</a>
|
||||||
<a href="/portal/backups">Backups</a>
|
<a href="/portal/backups">Zálohy</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
@@ -50,7 +50,7 @@ def render_result(title, back_url, sections, extra_link=None, extra_label=None):
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>{html.escape(title)}</h2>
|
<h2>{html.escape(title)}</h2>
|
||||||
{extra}
|
{extra}
|
||||||
<p><a href="{back_url}">← Back</a></p>
|
<p><a href="{back_url}">← Zpět</a></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
{rendered_sections}
|
{rendered_sections}
|
||||||
|
|||||||
Reference in New Issue
Block a user