Add HTML5 project panel SSE updates
This commit is contained in:
@@ -284,6 +284,7 @@ def render_html5_flowchart(
|
||||
normalized_depth = min(max(depth, 1), 3)
|
||||
hx_url = _flowchart_url(project_id, focus, normalized_depth)
|
||||
oob_attr = ' hx-swap-oob="outerHTML"' if oob else ""
|
||||
live_attr = ' sse-swap="project-flowchart"' if focus is None else ""
|
||||
if flowchart is None:
|
||||
return f"""
|
||||
<div
|
||||
@@ -293,6 +294,7 @@ def render_html5_flowchart(
|
||||
hx-trigger="load"
|
||||
hx-swap="outerHTML"
|
||||
{oob_attr}
|
||||
{live_attr}
|
||||
>
|
||||
<div class="panel-title">Карта связей</div>
|
||||
<p class="muted padded">Сервер собирает граф проекта.</p>
|
||||
@@ -311,7 +313,7 @@ def render_html5_flowchart(
|
||||
class="flowchart-panel"
|
||||
data-html5-flowchart
|
||||
hx-get="{hx_url}"
|
||||
hx-trigger="every 30s"
|
||||
{live_attr}
|
||||
hx-swap="outerHTML"
|
||||
{oob_attr}
|
||||
>
|
||||
@@ -336,6 +338,7 @@ def render_html5_project_report(project_id: str, report: dict | None) -> str:
|
||||
data-html5-project-report
|
||||
hx-get="/html5/projects/{quote(project_id)}/report"
|
||||
hx-trigger="load"
|
||||
sse-swap="project-report"
|
||||
hx-swap="outerHTML"
|
||||
>
|
||||
<div class="panel-title">Отчет проекта</div>
|
||||
@@ -357,7 +360,7 @@ def render_html5_project_report(project_id: str, report: dict | None) -> str:
|
||||
class="report-panel"
|
||||
data-html5-project-report
|
||||
hx-get="/html5/projects/{quote(project_id)}/report"
|
||||
hx-trigger="every 15s"
|
||||
sse-swap="project-report"
|
||||
hx-swap="outerHTML"
|
||||
>
|
||||
<div class="panel-title">Отчет проекта</div>
|
||||
@@ -424,9 +427,6 @@ def render_html5_object_report(
|
||||
<div
|
||||
class="report-panel"
|
||||
data-html5-project-report
|
||||
hx-get="/html5/projects/{quote(project_id)}/report"
|
||||
hx-trigger="every 15s"
|
||||
hx-swap="outerHTML"
|
||||
{oob_attr}
|
||||
>
|
||||
<div class="panel-title">Отчет объекта</div>
|
||||
@@ -487,6 +487,7 @@ def render_html5_review(
|
||||
oob: bool = False,
|
||||
) -> str:
|
||||
oob_attr = ' hx-swap-oob="outerHTML"' if oob else ""
|
||||
live_attr = ' sse-swap="project-review"' if title == "Review" and not oob else ""
|
||||
if findings is None:
|
||||
return f"""
|
||||
<div
|
||||
@@ -494,6 +495,7 @@ def render_html5_review(
|
||||
data-html5-review
|
||||
hx-get="/html5/projects/{quote(project_id)}/review"
|
||||
hx-trigger="load"
|
||||
{live_attr}
|
||||
hx-swap="outerHTML"
|
||||
{oob_attr}
|
||||
>
|
||||
@@ -510,7 +512,7 @@ def render_html5_review(
|
||||
class="review-panel"
|
||||
data-html5-review
|
||||
hx-get="/html5/projects/{quote(project_id)}/review"
|
||||
hx-trigger="every 20s"
|
||||
{live_attr}
|
||||
hx-swap="outerHTML"
|
||||
{oob_attr}
|
||||
>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import asyncio
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
@@ -1694,21 +1695,33 @@ async def html5_project_editor(project_id: str, q: str = "") -> Response:
|
||||
|
||||
@app.get("/html5/projects/{project_id}/events")
|
||||
async def html5_project_events(project_id: str, once: bool = False) -> StreamingResponse:
|
||||
def stream_status():
|
||||
async def stream_status():
|
||||
while True:
|
||||
try:
|
||||
snapshot = _project_snapshot_or_404(project_id)
|
||||
fragment = render_html5_status(project_id, snapshot)
|
||||
report = await project_report(project_id)
|
||||
findings = await get_review(project_id)
|
||||
flowchart = await project_flowchart(project_id, focus=None, depth=1, limit=80)
|
||||
except HTTPException as error:
|
||||
fragment = f'<span>project: {project_id}</span><span>error: {error.detail}</span>'
|
||||
report = None
|
||||
findings = None
|
||||
flowchart = None
|
||||
yield _html5_sse_event("status", fragment)
|
||||
yield _html5_sse_event(
|
||||
"authoring-changes",
|
||||
render_html5_authoring_changes(project_id, _authoring_change_summaries(project_id)),
|
||||
)
|
||||
if report is not None:
|
||||
yield _html5_sse_event("project-report", render_html5_project_report(project_id, report))
|
||||
if findings is not None:
|
||||
yield _html5_sse_event("project-review", render_html5_review(project_id, findings))
|
||||
if flowchart is not None:
|
||||
yield _html5_sse_event("project-flowchart", render_html5_flowchart(project_id, flowchart))
|
||||
if once:
|
||||
break
|
||||
time.sleep(5)
|
||||
await asyncio.sleep(5)
|
||||
|
||||
return StreamingResponse(
|
||||
stream_status(),
|
||||
|
||||
@@ -110,10 +110,13 @@ def test_html5_server_rendered_project_editor(tmp_path: Path):
|
||||
assert "data-html5-symbol-results" in editor.text
|
||||
assert "data-html5-symbol-detail" in editor.text
|
||||
assert "data-html5-flowchart" in editor.text
|
||||
assert 'sse-swap="project-flowchart"' in editor.text
|
||||
assert f'hx-get="/html5/projects/{project_id}/flowchart?depth=1"' in editor.text
|
||||
assert "data-html5-project-report" in editor.text
|
||||
assert 'sse-swap="project-report"' in editor.text
|
||||
assert f'hx-get="/html5/projects/{project_id}/report"' in editor.text
|
||||
assert "data-html5-review" in editor.text
|
||||
assert 'sse-swap="project-review"' in editor.text
|
||||
assert f'hx-get="/html5/projects/{project_id}/review"' in editor.text
|
||||
assert "data-html5-authoring-preview" in editor.text
|
||||
assert "data-html5-authoring-preview-form" in editor.text
|
||||
@@ -147,7 +150,13 @@ def test_html5_server_rendered_project_editor(tmp_path: Path):
|
||||
first_chunk = next(events.iter_text())
|
||||
assert "event: status" in first_chunk
|
||||
assert "event: authoring-changes" in first_chunk
|
||||
assert "event: project-report" in first_chunk
|
||||
assert "event: project-review" in first_chunk
|
||||
assert "event: project-flowchart" in first_chunk
|
||||
assert "data-html5-authoring-changes" in first_chunk
|
||||
assert "data-html5-project-report" in first_chunk
|
||||
assert "data-html5-review" in first_chunk
|
||||
assert "data-html5-flowchart" in first_chunk
|
||||
assert "data:" in first_chunk
|
||||
assert project_id in first_chunk
|
||||
|
||||
@@ -477,6 +486,7 @@ def test_html5_flowchart_fragment(tmp_path: Path):
|
||||
assert "depth=2" in flowchart.text
|
||||
assert 'hx-target="[data-html5-flowchart]"' in flowchart.text
|
||||
assert "data-html5-flowchart-focus" in flowchart.text
|
||||
assert 'sse-swap="project-flowchart"' not in flowchart.text
|
||||
assert 'hx-swap-oob="outerHTML"' not in flowchart.text
|
||||
assert "Карта связей" in flowchart.text
|
||||
assert "Nodes" in flowchart.text
|
||||
|
||||
Reference in New Issue
Block a user