Split HTML5 projects renderer
This commit is contained in:
@@ -1,75 +1,9 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from html import escape
|
from html import escape
|
||||||
from typing import Iterable
|
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
|
|
||||||
|
|
||||||
def render_html5_index(projects: Iterable[object]) -> str:
|
|
||||||
project_list = list(projects)
|
|
||||||
return _page(
|
|
||||||
"SFERA HTML5",
|
|
||||||
f"""
|
|
||||||
<main class="shell" data-html5-page="projects">
|
|
||||||
<section class="hero">
|
|
||||||
<div>
|
|
||||||
<p class="eyebrow">SFERA HTML5</p>
|
|
||||||
<h1>Server-first рабочее место 1С</h1>
|
|
||||||
<p class="lead">Основной HTML собирает API-сервер. Браузер получает готовую страницу без React/Next runtime.</p>
|
|
||||||
</div>
|
|
||||||
<div class="hero-metrics">
|
|
||||||
<strong>{len(project_list)}</strong>
|
|
||||||
<span>проектов</span>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section class="band">
|
|
||||||
<div class="section-title">
|
|
||||||
<h2>Проекты</h2>
|
|
||||||
<div class="toolbar-links">
|
|
||||||
<a class="button" href="/html5/operations">Операции</a>
|
|
||||||
<a class="button" href="/docs">API docs</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{render_html5_project_create_form()}
|
|
||||||
<div class="table-wrap">
|
|
||||||
<table data-html5-projects>
|
|
||||||
<thead>
|
|
||||||
<tr><th>Проект</th><th>Статус</th><th>Snapshot</th><th></th></tr>
|
|
||||||
</thead>
|
|
||||||
<tbody data-html5-projects-body>{render_html5_project_rows(project_list)}</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def render_html5_project_create_form() -> str:
|
|
||||||
return """
|
|
||||||
<form
|
|
||||||
class="create-project"
|
|
||||||
method="post"
|
|
||||||
action="/html5/projects"
|
|
||||||
data-html5-project-create
|
|
||||||
hx-post="/html5/projects"
|
|
||||||
hx-target="[data-html5-projects-body]"
|
|
||||||
hx-swap="innerHTML"
|
|
||||||
>
|
|
||||||
<input name="project_id" placeholder="project_id" required />
|
|
||||||
<input name="name" placeholder="Название проекта" />
|
|
||||||
<button type="submit">Создать</button>
|
|
||||||
</form>
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def render_html5_project_rows(projects: Iterable[object]) -> str:
|
|
||||||
project_rows = "\n".join(_project_row(project) for project in projects)
|
|
||||||
if not project_rows:
|
|
||||||
return '<tr><td colspan="4" class="muted">Проекты пока не настроены</td></tr>'
|
|
||||||
return project_rows
|
|
||||||
|
|
||||||
|
|
||||||
def _page(title: str, body: str) -> str:
|
def _page(title: str, body: str) -> str:
|
||||||
return f"""<!doctype html>
|
return f"""<!doctype html>
|
||||||
<html lang="ru">
|
<html lang="ru">
|
||||||
@@ -85,34 +19,6 @@ def _page(title: str, body: str) -> str:
|
|||||||
</html>"""
|
</html>"""
|
||||||
|
|
||||||
|
|
||||||
def _project_row(project: object) -> str:
|
|
||||||
project_id = str(getattr(project, "project_id", ""))
|
|
||||||
name = str(getattr(project, "name", project_id))
|
|
||||||
status = str(getattr(project, "status", "unknown"))
|
|
||||||
has_snapshot = bool(getattr(project, "has_snapshot", False))
|
|
||||||
return f"""
|
|
||||||
<tr data-html5-project="{escape(project_id)}">
|
|
||||||
<td><strong>{escape(name)}</strong><small>{escape(project_id)}</small></td>
|
|
||||||
<td>{escape(status)}</td>
|
|
||||||
<td>{'yes' if has_snapshot else 'no'}</td>
|
|
||||||
<td>
|
|
||||||
<a class="button" href="/html5/projects/{quote(project_id)}/editor">IDE</a>
|
|
||||||
<a class="button" href="/html5/projects/{quote(project_id)}/setup">Setup</a>
|
|
||||||
<form
|
|
||||||
class="delete-project"
|
|
||||||
method="post"
|
|
||||||
action="/html5/projects/{quote(project_id)}/delete"
|
|
||||||
hx-post="/html5/projects/{quote(project_id)}/delete"
|
|
||||||
hx-target="[data-html5-projects-body]"
|
|
||||||
hx-swap="innerHTML"
|
|
||||||
>
|
|
||||||
<input name="confirmation" value="{escape(project_id)}" aria-label="confirmation" />
|
|
||||||
<button type="submit">Удалить</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>"""
|
|
||||||
|
|
||||||
|
|
||||||
def _project_link(project: object, active_project_id: str) -> str:
|
def _project_link(project: object, active_project_id: str) -> str:
|
||||||
project_id = str(getattr(project, "project_id", ""))
|
project_id = str(getattr(project, "project_id", ""))
|
||||||
name = str(getattr(project, "name", project_id))
|
name = str(getattr(project, "name", project_id))
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from html import escape
|
||||||
|
from typing import Iterable
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
|
from api_server.html5 import _page
|
||||||
|
|
||||||
|
|
||||||
|
def render_html5_index(projects: Iterable[object]) -> str:
|
||||||
|
project_list = list(projects)
|
||||||
|
return _page(
|
||||||
|
"SFERA HTML5",
|
||||||
|
f"""
|
||||||
|
<main class="shell" data-html5-page="projects">
|
||||||
|
<section class="hero">
|
||||||
|
<div>
|
||||||
|
<p class="eyebrow">SFERA HTML5</p>
|
||||||
|
<h1>Server-first рабочее место 1С</h1>
|
||||||
|
<p class="lead">Основной HTML собирает API-сервер. Браузер получает готовую страницу без React/Next runtime.</p>
|
||||||
|
</div>
|
||||||
|
<div class="hero-metrics">
|
||||||
|
<strong>{len(project_list)}</strong>
|
||||||
|
<span>проектов</span>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="band">
|
||||||
|
<div class="section-title">
|
||||||
|
<h2>Проекты</h2>
|
||||||
|
<div class="toolbar-links">
|
||||||
|
<a class="button" href="/html5/operations">Операции</a>
|
||||||
|
<a class="button" href="/docs">API docs</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{render_html5_project_create_form()}
|
||||||
|
<div class="table-wrap">
|
||||||
|
<table data-html5-projects>
|
||||||
|
<thead>
|
||||||
|
<tr><th>Проект</th><th>Статус</th><th>Snapshot</th><th></th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody data-html5-projects-body>{render_html5_project_rows(project_list)}</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def render_html5_project_create_form() -> str:
|
||||||
|
return """
|
||||||
|
<form
|
||||||
|
class="create-project"
|
||||||
|
method="post"
|
||||||
|
action="/html5/projects"
|
||||||
|
data-html5-project-create
|
||||||
|
hx-post="/html5/projects"
|
||||||
|
hx-target="[data-html5-projects-body]"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
>
|
||||||
|
<input name="project_id" placeholder="project_id" required />
|
||||||
|
<input name="name" placeholder="Название проекта" />
|
||||||
|
<button type="submit">Создать</button>
|
||||||
|
</form>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def render_html5_project_rows(projects: Iterable[object]) -> str:
|
||||||
|
project_rows = "\n".join(_project_row(project) for project in projects)
|
||||||
|
if not project_rows:
|
||||||
|
return '<tr><td colspan="4" class="muted">Проекты пока не настроены</td></tr>'
|
||||||
|
return project_rows
|
||||||
|
|
||||||
|
|
||||||
|
def _project_row(project: object) -> str:
|
||||||
|
project_id = str(getattr(project, "project_id", ""))
|
||||||
|
name = str(getattr(project, "name", project_id))
|
||||||
|
status = str(getattr(project, "status", "unknown"))
|
||||||
|
has_snapshot = bool(getattr(project, "has_snapshot", False))
|
||||||
|
return f"""
|
||||||
|
<tr data-html5-project="{escape(project_id)}">
|
||||||
|
<td><strong>{escape(name)}</strong><small>{escape(project_id)}</small></td>
|
||||||
|
<td>{escape(status)}</td>
|
||||||
|
<td>{'yes' if has_snapshot else 'no'}</td>
|
||||||
|
<td>
|
||||||
|
<a class="button" href="/html5/projects/{quote(project_id)}/editor">IDE</a>
|
||||||
|
<a class="button" href="/html5/projects/{quote(project_id)}/setup">Setup</a>
|
||||||
|
<form
|
||||||
|
class="delete-project"
|
||||||
|
method="post"
|
||||||
|
action="/html5/projects/{quote(project_id)}/delete"
|
||||||
|
hx-post="/html5/projects/{quote(project_id)}/delete"
|
||||||
|
hx-target="[data-html5-projects-body]"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
>
|
||||||
|
<input name="confirmation" value="{escape(project_id)}" aria-label="confirmation" />
|
||||||
|
<button type="submit">Удалить</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>"""
|
||||||
@@ -37,10 +37,7 @@ from fastapi.staticfiles import StaticFiles
|
|||||||
from neo4j import AsyncGraphDatabase
|
from neo4j import AsyncGraphDatabase
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from api_server.html5 import (
|
from api_server.html5_projects import render_html5_index, render_html5_project_rows
|
||||||
render_html5_index,
|
|
||||||
render_html5_project_rows,
|
|
||||||
)
|
|
||||||
from api_server.html5_inspector import (
|
from api_server.html5_inspector import (
|
||||||
render_html5_flowchart,
|
render_html5_flowchart,
|
||||||
render_html5_object_context,
|
render_html5_object_context,
|
||||||
|
|||||||
Reference in New Issue
Block a user