Make HTML5 flowchart nodes navigable
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-05-17 01:27:05 +03:00
parent 6cc669f694
commit a735048270
2 changed files with 31 additions and 8 deletions
+29 -8
View File
@@ -275,9 +275,9 @@ def render_html5_flowchart(
nodes = getattr(flowchart, "nodes", []) or []
edges = getattr(flowchart, "edges", []) or []
mode = str(getattr(flowchart, "mode", "overview"))
body = "".join(_flowchart_edge_item(item, nodes) for item in edges[:10])
body = "".join(_flowchart_edge_item(project_id, item, nodes, normalized_depth) for item in edges[:10])
if not body:
body = "".join(_flowchart_node_item(item) for item in nodes[:10])
body = "".join(_flowchart_node_item(project_id, item, normalized_depth) for item in nodes[:10])
if not body:
body = '<p class="muted padded">Связи проекта не найдены</p>'
return f"""
@@ -482,7 +482,7 @@ def render_html5_object_context(
compact_body += ''.join(_named_node_item("read", item) for item in query_tables[:8])
compact_body += ''.join(_named_node_item("write", item) for item in writes[:8])
compact_body += ''.join(_named_node_item("call", item) for item in callees[:8])
compact_body += ''.join(_flowchart_edge_item(item, flow_nodes) for item in flow_edges[:8])
compact_body += ''.join(_flowchart_edge_item(project_id, item, flow_nodes, 1) for item in flow_edges[:8])
compact_body += ''.join(_named_node_item("routine", item) for item in routines[:8])
compact_body += ''.join(_named_node_item("job", item) for item in jobs[:6])
compact_body = compact_body or '<p class="muted padded">Impact-связи не найдены</p>'
@@ -503,7 +503,7 @@ def render_html5_object_context(
compact_body += ''.join(_named_node_item("read", item) for item in query_tables[:4])
compact_body += ''.join(_named_node_item("write", item) for item in writes[:4])
compact_body += ''.join(_named_node_item("call", item) for item in callees[:6])
compact_body += ''.join(_flowchart_edge_item(item, flow_nodes) for item in flow_edges[:8])
compact_body += ''.join(_flowchart_edge_item(project_id, item, flow_nodes, 1) for item in flow_edges[:8])
compact_body += ''.join(_runtime_summary_item(item) for item in runtime_items[:6])
compact_body += ''.join(_knowledge_record_item(item) for item in knowledge_items[:6])
compact_body += ''.join(_privacy_marker_item(item) for item in privacy_markers[:6])
@@ -1734,7 +1734,20 @@ def _integration_endpoint_item(endpoint: object) -> str:
"""
def _flowchart_edge_item(edge: object, nodes: Iterable[object]) -> str:
def _flowchart_focus_link(project_id: str, name: str, depth: int) -> str:
url = _flowchart_url(project_id, name, depth)
return f"""
<a
href="{url}"
hx-get="{url}"
hx-target="[data-html5-flowchart]"
hx-swap="outerHTML"
data-html5-flowchart-focus="{escape(name)}"
>{escape(name)}</a>
"""
def _flowchart_edge_item(project_id: str, edge: object, nodes: Iterable[object], depth: int) -> str:
node_names = {
str(getattr(node, "id", "")): str(getattr(node, "qualified_name", "") or getattr(node, "label", ""))
for node in nodes
@@ -1746,7 +1759,7 @@ def _flowchart_edge_item(edge: object, nodes: Iterable[object]) -> str:
return f"""
<article class="object-context-item" data-html5-object-context-item="flow-edge">
<strong>{escape(label)}</strong>
<small>{escape(source)} -> {escape(target)} · {escape(kind)}</small>
<small>{_flowchart_focus_link(project_id, source, depth)} -> {_flowchart_focus_link(project_id, target, depth)} · {escape(kind)}</small>
</article>
"""
@@ -1779,13 +1792,21 @@ def _flowchart_depth_actions(project_id: str, focus: str | None, active_depth: i
return f'<nav class="object-actions" data-html5-flowchart-actions>{"".join(buttons)}</nav>'
def _flowchart_node_item(node: object) -> str:
def _flowchart_node_item(project_id: str, node: object, depth: int) -> str:
name = str(getattr(node, "qualified_name", "") or getattr(node, "label", "") or "node")
kind = str(getattr(node, "kind", "") or "NODE")
level = getattr(node, "level", 0)
count = getattr(node, "count", 1)
url = _flowchart_url(project_id, name, depth)
return f"""
<article class="object-context-item" data-html5-flowchart-node="{escape(kind)}">
<article
class="object-context-item"
data-html5-flowchart-node="{escape(kind)}"
data-html5-flowchart-focus="{escape(name)}"
hx-get="{url}"
hx-target="[data-html5-flowchart]"
hx-swap="outerHTML"
>
<strong>{escape(name)}</strong>
<small>{escape(kind)} · level {escape(str(level))} · count {escape(str(count))}</small>
</article>