Edge Types
+
Edge Types
-
-
-
+
+ Review
+
+
+
+ Unresolved
+
+
+
+ Profile
+
+
-
+
-
+
@@ -321,6 +392,7 @@ def graph_explorer_page() -> str:
const graphUrl = "/exports/graph-explorer";
const canvas = document.getElementById("graph-canvas");
const popup = document.getElementById("popup");
+ const helpPopup = document.getElementById("help-popup");
const selectionAnchor = document.getElementById("selection-anchor");
const selectionAnchorLabel = document.getElementById("selection-anchor-label");
const searchInput = document.getElementById("search");
@@ -365,6 +437,26 @@ def graph_explorer_page() -> str:
.replaceAll("&", "&").replaceAll("<", "<")
.replaceAll(">", ">").replaceAll('"', """);
+ const showHelp = (target) => {
+ if (!helpPopup || !target?.dataset?.help) return;
+ const bounds = target.getBoundingClientRect();
+ const title = target.dataset.helpTitle || target.textContent || "Help";
+ helpPopup.innerHTML = `${escapeHtml(title)}${escapeHtml(target.dataset.help)}
`;
+ helpPopup.style.display = "block";
+ const width = Math.min(helpPopup.offsetWidth || 300, 300);
+ const left = Math.min(Math.max(12, bounds.left), window.innerWidth - width - 12);
+ const top = bounds.bottom + 8 < window.innerHeight - 80
+ ? bounds.bottom + 8
+ : Math.max(12, bounds.top - helpPopup.offsetHeight - 8);
+ helpPopup.style.left = `${left}px`;
+ helpPopup.style.top = `${top}px`;
+ };
+
+ const hideHelp = () => {
+ if (!helpPopup) return;
+ helpPopup.style.display = "none";
+ };
+
const elementText = (data) => [
data.id, data.stableKey, data.label, data.name, data.description,
data.repo, data.domain, data.kind, data.layer, data.edgeType
@@ -960,6 +1052,13 @@ def graph_explorer_page() -> str:
...element,
data: {...element.data, color: layerColors[element.data.layer] || "#667085"}
}));
+ if (elements.length === 0) {
+ canvas.innerHTML = "No graph entities were returned by the registry.
";
+ counts.textContent = "0 nodes / 0 edges";
+ hiddenSummary.textContent = "Hidden 0";
+ return;
+ }
+ canvas.innerHTML = "";
cy = cytoscape({
container: canvas,
elements,
@@ -1158,12 +1257,21 @@ def graph_explorer_page() -> str:
}
});
});
+ document.querySelectorAll("[data-help]").forEach((target) => {
+ target.addEventListener("mouseenter", () => showHelp(target));
+ target.addEventListener("focus", () => showHelp(target));
+ target.addEventListener("mouseleave", hideHelp);
+ target.addEventListener("blur", hideHelp);
+ });
+ document.addEventListener("keydown", (event) => {
+ if (event.key === "Escape") hideHelp();
+ });
if (!window.cytoscape) {
canvas.innerHTML = "Cytoscape.js could not be loaded.
";
return;
}
boot().catch((error) => {
- canvas.innerHTML = `${escapeHtml(error.message)}
`;
+ canvas.innerHTML = `Could not load graph explorer data: ${escapeHtml(error.message)}
`;
});
})();
diff --git a/tests/test_graph_explorer.py b/tests/test_graph_explorer.py
index ffc62a1..02e85f5 100644
--- a/tests/test_graph_explorer.py
+++ b/tests/test_graph_explorer.py
@@ -210,11 +210,19 @@ def test_registry_serves_graph_explorer_exports(tmp_path: Path) -> None:
assert 'id="node-type-filter"' in page
assert 'id="edge-type-filter"' in page
assert 'id="selection-anchor"' in page
+ assert 'id="help-popup"' in page
assert "updateSelectionAnchor" in page
assert "updateLabelVisibility" in page
+ assert "showHelp" in page
assert "label-hidden" in page
+ assert "Loading graph..." in page
+ assert "No graph entities were returned by the registry." in page
+ assert "Could not load graph explorer data" in page
assert "Node Types" in page
assert "Edge Types" in page
+ assert 'data-help-title="Node Types"' in page
+ assert 'data-help-title="Saved Views"' in page
+ assert "Remove will redraw" in page
assert "Registered only" in page
assert 'id="layer-filter"' not in page
assert '"border-width": 4' not in page
diff --git a/workplans/RAIL-FAB-WP-0009-graph-explorer-ui-refinement.md b/workplans/RAIL-FAB-WP-0009-graph-explorer-ui-refinement.md
index 14c74ac..7112e79 100644
--- a/workplans/RAIL-FAB-WP-0009-graph-explorer-ui-refinement.md
+++ b/workplans/RAIL-FAB-WP-0009-graph-explorer-ui-refinement.md
@@ -123,7 +123,7 @@ Acceptance notes:
```task
id: RAIL-FAB-WP-0009-T03
-status: in_progress
+status: done
priority: high
state_hub_task_id: "3e60397c-c833-4bd7-ba1b-b754b203dade"
```
@@ -176,7 +176,7 @@ Acceptance notes:
```task
id: RAIL-FAB-WP-0009-T05
-status: todo
+status: done
priority: medium
state_hub_task_id: "67a9cbc9-ebaa-4cb1-bec9-46bf250faf41"
```