Link HTML5 review findings to source
This commit is contained in:
@@ -433,7 +433,7 @@ def render_html5_review(
|
|||||||
if not findings:
|
if not findings:
|
||||||
body = '<p class="muted padded">Findings не найдены</p>'
|
body = '<p class="muted padded">Findings не найдены</p>'
|
||||||
else:
|
else:
|
||||||
body = "".join(_review_item(finding) for finding in findings[:12])
|
body = "".join(_review_item(project_id, finding) for finding in findings[:12])
|
||||||
return f"""
|
return f"""
|
||||||
<div
|
<div
|
||||||
class="review-panel"
|
class="review-panel"
|
||||||
@@ -1463,18 +1463,32 @@ def _preflight_item(item: object) -> str:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _review_item(finding: dict) -> str:
|
def _review_item(project_id: str, finding: dict) -> str:
|
||||||
title = str(finding.get("title") or finding.get("code") or "Finding")
|
title = str(finding.get("title") or finding.get("code") or "Finding")
|
||||||
severity = str(finding.get("severity") or finding.get("level") or "INFO")
|
severity = str(finding.get("severity") or finding.get("level") or "INFO")
|
||||||
message = str(finding.get("message") or finding.get("description") or "")
|
message = str(finding.get("message") or finding.get("description") or "")
|
||||||
source_path = str(finding.get("source_path") or finding.get("path") or "")
|
source_path = str(finding.get("source_path") or finding.get("path") or "")
|
||||||
line = finding.get("line_start") or finding.get("line")
|
line = finding.get("line_start") or finding.get("line")
|
||||||
location = f"{source_path}:{line}" if source_path and line else source_path
|
location = f"{source_path}:{line}" if source_path and line else source_path
|
||||||
|
source_link = (
|
||||||
|
f"""
|
||||||
|
<a
|
||||||
|
href="/html5/projects/{quote(project_id)}/source/by-path?path={quote(source_path, safe='')}"
|
||||||
|
hx-get="/html5/projects/{quote(project_id)}/source/by-path?path={quote(source_path, safe='')}"
|
||||||
|
hx-target="[data-html5-source]"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
data-html5-review-source="{escape(source_path)}"
|
||||||
|
>Source</a>
|
||||||
|
"""
|
||||||
|
if source_path
|
||||||
|
else ""
|
||||||
|
)
|
||||||
return f"""
|
return f"""
|
||||||
<article class="review-item" data-html5-review-finding="{escape(severity)}">
|
<article class="review-item" data-html5-review-finding="{escape(severity)}">
|
||||||
<strong>{escape(title)}</strong>
|
<strong>{escape(title)}</strong>
|
||||||
<span>{escape(severity)}</span>
|
<span>{escape(severity)}</span>
|
||||||
<small>{escape(message or location or "no details")}</small>
|
<small>{escape(message or location or "no details")}</small>
|
||||||
|
<span class="inline-actions">{source_link}</span>
|
||||||
</article>
|
</article>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -1713,6 +1713,25 @@ async def html5_project_symbol_detail(project_id: str, lineage_id: str) -> Respo
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/html5/projects/{project_id}/source/by-path")
|
||||||
|
async def html5_project_source_by_path(project_id: str, path: str) -> Response:
|
||||||
|
snapshot = _project_snapshot_or_404(project_id)
|
||||||
|
node = next(
|
||||||
|
(
|
||||||
|
item
|
||||||
|
for item in snapshot.nodes
|
||||||
|
if item.source_ref is not None and item.source_ref.source_path == path
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
if node is None:
|
||||||
|
raise HTTPException(status_code=404, detail=f"Source not found: {path}")
|
||||||
|
return Response(
|
||||||
|
render_html5_source(node),
|
||||||
|
media_type="text/html; charset=utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/html5/projects/{project_id}/source/{lineage_id}")
|
@app.get("/html5/projects/{project_id}/source/{lineage_id}")
|
||||||
async def html5_project_source(project_id: str, lineage_id: str) -> Response:
|
async def html5_project_source(project_id: str, lineage_id: str) -> Response:
|
||||||
snapshot = _project_snapshot_or_404(project_id)
|
snapshot = _project_snapshot_or_404(project_id)
|
||||||
|
|||||||
@@ -171,6 +171,15 @@ def test_html5_server_rendered_project_editor(tmp_path: Path):
|
|||||||
assert "Проверить" in source.text
|
assert "Проверить" in source.text
|
||||||
assert "<html" not in source.text
|
assert "<html" not in source.text
|
||||||
|
|
||||||
|
source_by_path = client.get(
|
||||||
|
f"/html5/projects/{project_id}/source/by-path",
|
||||||
|
params={"path": module_node["source_ref"]["source_path"]},
|
||||||
|
)
|
||||||
|
assert source_by_path.status_code == 200
|
||||||
|
assert "data-html5-source-summary" in source_by_path.text
|
||||||
|
assert "Проверить" in source_by_path.text
|
||||||
|
assert "<html" not in source_by_path.text
|
||||||
|
|
||||||
detail = client.get(f"/html5/projects/{project_id}/symbols/{procedure_node['lineage_id']}/detail")
|
detail = client.get(f"/html5/projects/{project_id}/symbols/{procedure_node['lineage_id']}/detail")
|
||||||
assert detail.status_code == 200
|
assert detail.status_code == 200
|
||||||
assert "text/html" in detail.headers["content-type"]
|
assert "text/html" in detail.headers["content-type"]
|
||||||
@@ -193,6 +202,7 @@ def test_html5_server_rendered_project_editor(tmp_path: Path):
|
|||||||
assert review.status_code == 200
|
assert review.status_code == 200
|
||||||
assert "text/html" in review.headers["content-type"]
|
assert "text/html" in review.headers["content-type"]
|
||||||
assert "data-html5-review" in review.text
|
assert "data-html5-review" in review.text
|
||||||
|
assert "data-html5-review-source" in review.text or "Findings не найдены" in review.text
|
||||||
assert "<html" not in review.text
|
assert "<html" not in review.text
|
||||||
|
|
||||||
authoring = client.get(f"/html5/projects/{project_id}/authoring/changes")
|
authoring = client.get(f"/html5/projects/{project_id}/authoring/changes")
|
||||||
@@ -379,6 +389,7 @@ def test_html5_object_context_fragment(tmp_path: Path):
|
|||||||
assert "Отчет объекта" in context.text
|
assert "Отчет объекта" in context.text
|
||||||
assert "server focused summary" in context.text
|
assert "server focused summary" in context.text
|
||||||
assert "data-html5-review" in context.text
|
assert "data-html5-review" in context.text
|
||||||
|
assert "data-html5-review-source" in context.text
|
||||||
assert "Review объекта" in context.text
|
assert "Review объекта" in context.text
|
||||||
assert "External integration endpoint" in context.text
|
assert "External integration endpoint" in context.text
|
||||||
assert "1 signals" in context.text
|
assert "1 signals" in context.text
|
||||||
|
|||||||
Reference in New Issue
Block a user