Add HTML5 object context modes
This commit is contained in:
@@ -437,6 +437,7 @@ def render_html5_object_context(
|
||||
privacy: object | None = None,
|
||||
integrations: Iterable[object] | None = None,
|
||||
flowchart: object | None = None,
|
||||
mode: str = "overview",
|
||||
) -> str:
|
||||
if schema is None or impact is None:
|
||||
return f"""
|
||||
@@ -466,9 +467,50 @@ def render_html5_object_context(
|
||||
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 []
|
||||
normalized_mode = mode if mode in {"overview", "schema", "impact", "privacy"} else "overview"
|
||||
if normalized_mode == "schema":
|
||||
compact_body = (
|
||||
''.join(_named_node_item("attr", item) for item in attributes[:12])
|
||||
or '<p class="muted padded">Реквизиты не найдены</p>'
|
||||
)
|
||||
compact_body += ''.join(_tabular_section_item(item) for item in sections[:8])
|
||||
compact_body += ''.join(_ui_form_item(item) for item in ui_forms[:8])
|
||||
elif normalized_mode == "impact":
|
||||
compact_body = ''.join(_integration_endpoint_item(item) for item in integration_items[:8])
|
||||
compact_body += ''.join(_named_node_item("command", item) for item in commands[:8])
|
||||
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(_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>'
|
||||
elif normalized_mode == "privacy":
|
||||
compact_body = ''.join(_role_access_item(item) for item in grants[:12])
|
||||
compact_body += ''.join(_privacy_marker_item(item) for item in privacy_markers[:12])
|
||||
compact_body = compact_body or '<p class="muted padded">Доступы и privacy-маркеры не найдены</p>'
|
||||
else:
|
||||
compact_body = (
|
||||
''.join(_named_node_item("attr", item) for item in attributes[:6])
|
||||
or '<p class="muted padded">Реквизиты не найдены</p>'
|
||||
)
|
||||
compact_body += ''.join(_tabular_section_item(item) for item in sections[:4])
|
||||
compact_body += ''.join(_ui_form_item(item) for item in ui_forms[:4])
|
||||
compact_body += ''.join(_role_access_item(item) for item in grants[:6])
|
||||
compact_body += ''.join(_integration_endpoint_item(item) for item in integration_items[:4])
|
||||
compact_body += ''.join(_named_node_item("command", item) for item in commands[:6])
|
||||
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(_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])
|
||||
compact_body += ''.join(_named_node_item("routine", item) for item in routines[:6])
|
||||
compact_body += ''.join(_named_node_item("job", item) for item in jobs[:4])
|
||||
return f"""
|
||||
<div class="object-context" data-html5-object-context data-html5-object-name="{escape(str(name))}">
|
||||
<div class="panel-title">Object context</div>
|
||||
<div class="object-context" data-html5-object-context data-html5-object-name="{escape(str(name))}" data-html5-object-mode="{escape(normalized_mode)}">
|
||||
<div class="panel-title">Object context · {escape(normalized_mode)}</div>
|
||||
<article class="object-focus">
|
||||
<strong>{escape(str(name))}</strong>
|
||||
<span>{escape(str(getattr(obj, "kind", "object")))}</span>
|
||||
@@ -493,21 +535,7 @@ def render_html5_object_context(
|
||||
{_metric("Privacy", len(privacy_markers))}
|
||||
</dl>
|
||||
<div class="compact-list">
|
||||
{''.join(_named_node_item("attr", item) for item in attributes[:6]) or '<p class="muted padded">Реквизиты не найдены</p>'}
|
||||
{''.join(_tabular_section_item(item) for item in sections[:4])}
|
||||
{''.join(_ui_form_item(item) for item in ui_forms[:4])}
|
||||
{''.join(_role_access_item(item) for item in grants[:6])}
|
||||
{''.join(_integration_endpoint_item(item) for item in integration_items[:4])}
|
||||
{''.join(_named_node_item("command", item) for item in commands[:6])}
|
||||
{''.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("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(_knowledge_record_item(item) for item in knowledge_items[:6])}
|
||||
{''.join(_privacy_marker_item(item) for item in privacy_markers[:6])}
|
||||
{''.join(_named_node_item("routine", item) for item in routines[:6])}
|
||||
{''.join(_named_node_item("job", item) for item in jobs[:4])}
|
||||
{compact_body}
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
@@ -1539,9 +1567,27 @@ def _object_action_links(project_id: str, object_name: str, lineage_id: object,
|
||||
)
|
||||
return f"""
|
||||
<nav class="object-actions" data-html5-object-actions>
|
||||
<a class="button" href="/projects/{quoted_project}/objects/schema/{quoted_object}">Schema</a>
|
||||
<a class="button" href="/projects/{quoted_project}/objects/impact/{quoted_object}">Impact</a>
|
||||
<a class="button" href="/projects/{quoted_project}/objects/privacy/{quoted_object}">Privacy</a>
|
||||
<a
|
||||
class="button"
|
||||
href="/projects/{quoted_project}/objects/schema/{quoted_object}"
|
||||
hx-get="/html5/projects/{quoted_project}/objects/context/{quoted_object}?mode=schema"
|
||||
hx-target="[data-html5-object-context]"
|
||||
hx-swap="outerHTML"
|
||||
>Schema</a>
|
||||
<a
|
||||
class="button"
|
||||
href="/projects/{quoted_project}/objects/impact/{quoted_object}"
|
||||
hx-get="/html5/projects/{quoted_project}/objects/context/{quoted_object}?mode=impact"
|
||||
hx-target="[data-html5-object-context]"
|
||||
hx-swap="outerHTML"
|
||||
>Impact</a>
|
||||
<a
|
||||
class="button"
|
||||
href="/projects/{quoted_project}/objects/privacy/{quoted_object}"
|
||||
hx-get="/html5/projects/{quoted_project}/objects/context/{quoted_object}?mode=privacy"
|
||||
hx-target="[data-html5-object-context]"
|
||||
hx-swap="outerHTML"
|
||||
>Privacy</a>
|
||||
<a
|
||||
class="button"
|
||||
href="/html5/projects/{quoted_project}/flowchart?focus={quoted_object}"
|
||||
|
||||
@@ -1758,7 +1758,7 @@ async def html5_project_flowchart(
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/objects/context/{object_name}")
|
||||
async def html5_project_object_context(project_id: str, object_name: str) -> Response:
|
||||
async def html5_project_object_context(project_id: str, object_name: str, mode: str = "overview") -> Response:
|
||||
schema = await get_object_schema(project_id, object_name)
|
||||
impact = await get_object_impact(project_id, object_name)
|
||||
access = await get_object_access(project_id, object_name)
|
||||
@@ -1782,6 +1782,7 @@ async def html5_project_object_context(project_id: str, object_name: str) -> Res
|
||||
privacy,
|
||||
integrations,
|
||||
flowchart,
|
||||
mode,
|
||||
)
|
||||
flowchart_context = render_html5_flowchart(project_id, flowchart, focus=object_name, oob=True)
|
||||
source_context = render_html5_source(source_node, oob=True) if source_node is not None else ""
|
||||
|
||||
@@ -318,6 +318,10 @@ def test_html5_object_context_fragment(tmp_path: Path):
|
||||
assert "data-html5-object-actions" in context.text
|
||||
assert f"/projects/{project_id}/objects/schema/%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82.%D0%97%D0%B0%D0%BA%D0%B0%D0%B7%D0%9F%D0%BE%D0%BA%D1%83%D0%BF%D0%B0%D1%82%D0%B5%D0%BB%D1%8F" in context.text
|
||||
assert f"/projects/{project_id}/objects/impact/%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82.%D0%97%D0%B0%D0%BA%D0%B0%D0%B7%D0%9F%D0%BE%D0%BA%D1%83%D0%BF%D0%B0%D1%82%D0%B5%D0%BB%D1%8F" in context.text
|
||||
assert "mode=schema" in context.text
|
||||
assert "mode=impact" in context.text
|
||||
assert "mode=privacy" in context.text
|
||||
assert 'hx-target="[data-html5-object-context]"' in context.text
|
||||
assert 'hx-target="[data-html5-flowchart]"' in context.text
|
||||
assert 'hx-target="[data-html5-source]"' in context.text
|
||||
assert 'hx-target="[data-html5-symbol-detail]"' in context.text
|
||||
@@ -357,6 +361,33 @@ def test_html5_object_context_fragment(tmp_path: Path):
|
||||
assert "read, write, post" in context.text or "post, read, write" in context.text
|
||||
assert "<html" not in context.text
|
||||
|
||||
schema_context = client.get(
|
||||
f"/html5/projects/{project_id}/objects/context/Документ.ЗаказПокупателя",
|
||||
params={"mode": "schema"},
|
||||
)
|
||||
assert schema_context.status_code == 200
|
||||
assert 'data-html5-object-mode="schema"' in schema_context.text
|
||||
assert "Object context · schema" in schema_context.text
|
||||
assert "Контрагент" in schema_context.text
|
||||
|
||||
impact_context = client.get(
|
||||
f"/html5/projects/{project_id}/objects/context/Документ.ЗаказПокупателя",
|
||||
params={"mode": "impact"},
|
||||
)
|
||||
assert impact_context.status_code == 200
|
||||
assert 'data-html5-object-mode="impact"' in impact_context.text
|
||||
assert "Object context · impact" in impact_context.text
|
||||
assert "HTTPConnection" in impact_context.text
|
||||
|
||||
privacy_context = client.get(
|
||||
f"/html5/projects/{project_id}/objects/context/Документ.ЗаказПокупателя",
|
||||
params={"mode": "privacy"},
|
||||
)
|
||||
assert privacy_context.status_code == 200
|
||||
assert 'data-html5-object-mode="privacy"' in privacy_context.text
|
||||
assert "Object context · privacy" in privacy_context.text
|
||||
assert "PERSONAL_DATA" in privacy_context.text
|
||||
|
||||
|
||||
def test_html5_flowchart_fragment(tmp_path: Path):
|
||||
client = TestClient(app)
|
||||
|
||||
Reference in New Issue
Block a user