Add HTML5 object graph context
This commit is contained in:
@@ -326,6 +326,7 @@ def render_html5_object_context(
|
|||||||
knowledge: Iterable[object] | None = None,
|
knowledge: Iterable[object] | None = None,
|
||||||
privacy: object | None = None,
|
privacy: object | None = None,
|
||||||
integrations: Iterable[object] | None = None,
|
integrations: Iterable[object] | None = None,
|
||||||
|
flowchart: object | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
if schema is None or impact is None:
|
if schema is None or impact is None:
|
||||||
return f"""
|
return f"""
|
||||||
@@ -353,6 +354,8 @@ def render_html5_object_context(
|
|||||||
knowledge_items = list(knowledge or [])
|
knowledge_items = list(knowledge or [])
|
||||||
privacy_markers = getattr(privacy, "markers", []) if privacy is not None else []
|
privacy_markers = getattr(privacy, "markers", []) if privacy is not None else []
|
||||||
integration_items = list(integrations or [])
|
integration_items = list(integrations or [])
|
||||||
|
flow_nodes = getattr(flowchart, "nodes", []) if flowchart is not None else []
|
||||||
|
flow_edges = getattr(flowchart, "edges", []) if flowchart is not None else []
|
||||||
return f"""
|
return f"""
|
||||||
<div class="object-context" data-html5-object-context data-html5-object-name="{escape(str(name))}">
|
<div class="object-context" data-html5-object-context data-html5-object-name="{escape(str(name))}">
|
||||||
<div class="panel-title">Object context</div>
|
<div class="panel-title">Object context</div>
|
||||||
@@ -372,6 +375,8 @@ def render_html5_object_context(
|
|||||||
{_metric("Writes", len(writes))}
|
{_metric("Writes", len(writes))}
|
||||||
{_metric("Calls", len(callees))}
|
{_metric("Calls", len(callees))}
|
||||||
{_metric("Integrations", len(integration_items))}
|
{_metric("Integrations", len(integration_items))}
|
||||||
|
{_metric("Graph nodes", len(flow_nodes))}
|
||||||
|
{_metric("Graph edges", len(flow_edges))}
|
||||||
{_metric("Runtime", len(runtime_items))}
|
{_metric("Runtime", len(runtime_items))}
|
||||||
{_metric("Knowledge", len(knowledge_items))}
|
{_metric("Knowledge", len(knowledge_items))}
|
||||||
{_metric("Privacy", len(privacy_markers))}
|
{_metric("Privacy", len(privacy_markers))}
|
||||||
@@ -386,6 +391,7 @@ def render_html5_object_context(
|
|||||||
{''.join(_named_node_item("read", item) for item in query_tables[:4])}
|
{''.join(_named_node_item("read", item) for item in query_tables[:4])}
|
||||||
{''.join(_named_node_item("write", item) for item in writes[:4])}
|
{''.join(_named_node_item("write", item) for item in writes[:4])}
|
||||||
{''.join(_named_node_item("call", item) for item in callees[:6])}
|
{''.join(_named_node_item("call", item) for item in callees[:6])}
|
||||||
|
{''.join(_flowchart_edge_item(item, flow_nodes) for item in flow_edges[:8])}
|
||||||
{''.join(_runtime_summary_item(item) for item in runtime_items[:6])}
|
{''.join(_runtime_summary_item(item) for item in runtime_items[:6])}
|
||||||
{''.join(_knowledge_record_item(item) for item in knowledge_items[:6])}
|
{''.join(_knowledge_record_item(item) for item in knowledge_items[:6])}
|
||||||
{''.join(_privacy_marker_item(item) for item in privacy_markers[:6])}
|
{''.join(_privacy_marker_item(item) for item in privacy_markers[:6])}
|
||||||
@@ -1504,6 +1510,23 @@ def _integration_endpoint_item(endpoint: object) -> str:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def _flowchart_edge_item(edge: object, nodes: Iterable[object]) -> str:
|
||||||
|
node_names = {
|
||||||
|
str(getattr(node, "id", "")): str(getattr(node, "qualified_name", "") or getattr(node, "label", ""))
|
||||||
|
for node in nodes
|
||||||
|
}
|
||||||
|
source = node_names.get(str(getattr(edge, "source", "")), str(getattr(edge, "source", "")))
|
||||||
|
target = node_names.get(str(getattr(edge, "target", "")), str(getattr(edge, "target", "")))
|
||||||
|
label = str(getattr(edge, "label", "") or getattr(edge, "kind", "") or "link")
|
||||||
|
kind = str(getattr(edge, "kind", "") or "FLOW")
|
||||||
|
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>
|
||||||
|
</article>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _authoring_diff_item(line: object) -> str:
|
def _authoring_diff_item(line: object) -> str:
|
||||||
kind = str(getattr(line, "kind", ""))
|
kind = str(getattr(line, "kind", ""))
|
||||||
text = str(getattr(line, "text", ""))
|
text = str(getattr(line, "text", ""))
|
||||||
|
|||||||
@@ -1749,6 +1749,7 @@ async def html5_project_object_context(project_id: str, object_name: str) -> Res
|
|||||||
ui = await get_object_ui(project_id, object_name)
|
ui = await get_object_ui(project_id, object_name)
|
||||||
privacy = await object_privacy(project_id, object_name)
|
privacy = await object_privacy(project_id, object_name)
|
||||||
integrations = _integrations_for_object_context(project_id, impact)
|
integrations = _integrations_for_object_context(project_id, impact)
|
||||||
|
flowchart = await project_flowchart(project_id, focus=object_name, depth=1, limit=40)
|
||||||
runtime = _runtime_for_object_context(project_id, impact)
|
runtime = _runtime_for_object_context(project_id, impact)
|
||||||
knowledge = _knowledge_for_object_context(schema, impact, ui)
|
knowledge = _knowledge_for_object_context(schema, impact, ui)
|
||||||
return Response(
|
return Response(
|
||||||
@@ -1762,6 +1763,7 @@ async def html5_project_object_context(project_id: str, object_name: str) -> Res
|
|||||||
knowledge,
|
knowledge,
|
||||||
privacy,
|
privacy,
|
||||||
integrations,
|
integrations,
|
||||||
|
flowchart,
|
||||||
),
|
),
|
||||||
media_type="text/html; charset=utf-8",
|
media_type="text/html; charset=utf-8",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ def test_html5_object_context_fragment(tmp_path: Path):
|
|||||||
assert "HTTPConnection" in context.text
|
assert "HTTPConnection" in context.text
|
||||||
assert "https://api.example.local/orders" in context.text
|
assert "https://api.example.local/orders" in context.text
|
||||||
assert "OUTBOUND" in context.text
|
assert "OUTBOUND" in context.text
|
||||||
|
assert "data-html5-object-context-item=\"flow-edge\"" in context.text
|
||||||
assert "1 signals" in context.text
|
assert "1 signals" in context.text
|
||||||
assert "1 errors" in context.text
|
assert "1 errors" in context.text
|
||||||
assert "125.0 ms" in context.text
|
assert "125.0 ms" in context.text
|
||||||
|
|||||||
Reference in New Issue
Block a user