Complete local coordination view switching and record remaining blockers
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e3b8-9815-70f2-9ac5-37bcde2c5090
This commit is contained in:
parent
6923d4bfd0
commit
b47dd43b04
7 changed files with 227 additions and 55 deletions
|
|
@ -568,8 +568,8 @@ def graph_explorer_page() -> str:
|
|||
(() => {
|
||||
const manifestUrl = "/exports/graph-explorer/manifest";
|
||||
const pageParams = new URLSearchParams(window.location.search);
|
||||
const graphMode = pageParams.get("mode");
|
||||
const includeResidualsParam = ["1", "true", "yes"].includes(
|
||||
let graphMode = pageParams.get("mode") === "coordination" ? "coordination" : "full";
|
||||
let includeResidualsParam = ["1", "true", "yes"].includes(
|
||||
(pageParams.get("include_residuals") || "").toLowerCase()
|
||||
);
|
||||
const graphUrl = graphMode === "coordination"
|
||||
|
|
@ -2141,6 +2141,7 @@ def graph_explorer_page() -> str:
|
|||
const state = currentViewState();
|
||||
if (state.search) params.set("search", state.search);
|
||||
if (state.mode && state.mode !== "full") params.set("mode", state.mode);
|
||||
if (state.mode === "coordination" && includeResidualsParam) params.set("include_residuals", "true");
|
||||
if (state.layout && state.layout !== "cose") params.set("layout", state.layout);
|
||||
if (state.labelMode && state.labelMode !== "auto") params.set("labelMode", state.labelMode);
|
||||
if (state.nodeTypes.length !== allNodeTypes.length) params.set("nodeTypes", state.nodeTypes.join(","));
|
||||
|
|
@ -2201,6 +2202,10 @@ def graph_explorer_page() -> str:
|
|||
};
|
||||
|
||||
const applyViewState = (state, options = {}) => {
|
||||
if (cy && "mode" in state && ((state.mode === "coordination") !== (graphMode === "coordination"))) {
|
||||
switchGraph(state.mode, includeResidualsParam, state);
|
||||
return;
|
||||
}
|
||||
if ("search" in state) searchInput.value = state.search || "";
|
||||
if ("mode" in state) modeSelect.value = optionExists(modeSelect, state.mode) ? state.mode : "full";
|
||||
if ("layout" in state) layoutSelect.value = optionExists(layoutSelect, state.layout) ? state.layout : "cose";
|
||||
|
|
@ -2828,11 +2833,7 @@ def graph_explorer_page() -> str:
|
|||
residualsWrap.style.display = coordinationActive ? "" : "none";
|
||||
residualsToggle.checked = includeResidualsParam;
|
||||
residualsToggle.addEventListener("change", () => {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set("mode", "coordination");
|
||||
if (residualsToggle.checked) url.searchParams.set("include_residuals", "true");
|
||||
else url.searchParams.delete("include_residuals");
|
||||
window.location.search = url.search;
|
||||
switchGraph("coordination", residualsToggle.checked);
|
||||
});
|
||||
}
|
||||
profiles = loadProfiles();
|
||||
|
|
@ -2841,12 +2842,6 @@ def graph_explorer_page() -> str:
|
|||
...element,
|
||||
data: {...element.data, color: layerColors[element.data.layer] || "#667085"}
|
||||
}));
|
||||
if (elements.length === 0) {
|
||||
canvas.innerHTML = "<p class='canvas-notice'>No graph entities were returned by the registry.</p>";
|
||||
counts.textContent = "0 nodes / 0 edges";
|
||||
hiddenSummary.textContent = "Hidden 0";
|
||||
return;
|
||||
}
|
||||
canvas.innerHTML = "";
|
||||
cy = cytoscape({
|
||||
container: canvas,
|
||||
|
|
@ -2975,6 +2970,69 @@ def graph_explorer_page() -> str:
|
|||
applyViewState(urlState, {skipUrl: true});
|
||||
runLayout();
|
||||
updateUrlState();
|
||||
if (!elements.length) profileSummary.textContent = "No graph entities were returned by the registry.";
|
||||
};
|
||||
|
||||
let graphRequest = 0;
|
||||
const switchGraph = async (mode, includeResiduals = includeResidualsParam, viewState = null) => {
|
||||
const request = ++graphRequest;
|
||||
const coordination = mode === "coordination";
|
||||
const url = coordination
|
||||
? `/exports/graph-explorer?mode=coordination${includeResiduals ? "&include_residuals=true" : ""}`
|
||||
: "/exports/graph-explorer";
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
const payload = await response.json();
|
||||
if (!Array.isArray(payload.elements)) throw new Error("Invalid graph response");
|
||||
if (request !== graphRequest) return;
|
||||
const elements = payload.elements.map((element) => ({
|
||||
...element,
|
||||
data: {...element.data, color: layerColors[element.data.layer] || "#667085"}
|
||||
}));
|
||||
graphMode = coordination ? "coordination" : "full";
|
||||
includeResidualsParam = includeResiduals;
|
||||
activeMode = mode;
|
||||
modeSelect.value = mode;
|
||||
document.getElementById("include-residuals-wrap").style.display = coordination ? "" : "none";
|
||||
document.getElementById("include-residuals").checked = includeResiduals;
|
||||
selected = null;
|
||||
selectedAnchor = null;
|
||||
selectedZoneId = "";
|
||||
focusSet = null;
|
||||
manualOverrides = {};
|
||||
filterRules = [];
|
||||
editingRuleId = "";
|
||||
collapsedZoneSnapshots.clear();
|
||||
zoneContainerState.clear();
|
||||
zoneSummaries.clear();
|
||||
currentProfileId = "";
|
||||
profileSelect.value = "";
|
||||
allEdgeTypes = [...new Set(elements.map(({data}) => data.edgeType).filter(Boolean))].sort();
|
||||
renderChecklist(nodeTypeFilter, allNodeTypes, nodeTypeLabels, "node-type");
|
||||
renderChecklist(edgeTypeFilter, allEdgeTypes, {}, "edge-type");
|
||||
cy.elements().remove();
|
||||
cy.add(elements);
|
||||
popup.style.display = "none";
|
||||
refreshRuleBuilder();
|
||||
renderRules();
|
||||
syncFilterSummaries();
|
||||
if (viewState) applyViewState(viewState);
|
||||
else {
|
||||
applyFilters();
|
||||
runLayout();
|
||||
updateUrlState();
|
||||
}
|
||||
showDetails(null);
|
||||
updateProfileControls();
|
||||
updateProfileSummary();
|
||||
if (!elements.length) profileSummary.textContent = "No graph entities were returned by the registry.";
|
||||
} catch (error) {
|
||||
if (request !== graphRequest) return;
|
||||
modeSelect.value = activeMode;
|
||||
document.getElementById("include-residuals").checked = includeResidualsParam;
|
||||
profileSummary.textContent = `Could not load graph: ${error.message}`;
|
||||
}
|
||||
};
|
||||
|
||||
const handleFilterChange = () => {
|
||||
|
|
@ -2992,27 +3050,14 @@ def graph_explorer_page() -> str:
|
|||
nodeTypeFilter.addEventListener("change", handleFilterChange);
|
||||
edgeTypeFilter.addEventListener("change", handleFilterChange);
|
||||
modeSelect.addEventListener("input", () => {
|
||||
if (modeSelect.value === "coordination" && graphMode !== "coordination") {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set("mode", "coordination");
|
||||
window.location.search = url.search;
|
||||
const mode = modeSelect.value || "full";
|
||||
if ((mode === "coordination") !== (graphMode === "coordination")) {
|
||||
switchGraph(mode);
|
||||
return;
|
||||
}
|
||||
if (graphMode === "coordination" && modeSelect.value !== "coordination") {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.delete("mode");
|
||||
url.searchParams.delete("include_residuals");
|
||||
window.location.search = url.search;
|
||||
return;
|
||||
}
|
||||
activeMode = modeSelect.value || "full";
|
||||
focusSet = null;
|
||||
currentProfileId = "";
|
||||
profileSelect.value = "";
|
||||
applyFilters();
|
||||
updateProfileControls();
|
||||
updateProfileSummary();
|
||||
updateUrlState();
|
||||
graphRequest += 1;
|
||||
activeMode = mode;
|
||||
handleFilterChange();
|
||||
});
|
||||
layoutSelect.addEventListener("input", () => {
|
||||
currentProfileId = "";
|
||||
|
|
@ -3179,8 +3224,8 @@ def graph_explorer_page() -> str:
|
|||
document.querySelector("[data-action='focus']").addEventListener("click", applyFocus);
|
||||
document.querySelector("[data-action='clear']").addEventListener("click", () => {
|
||||
searchInput.value = "";
|
||||
modeSelect.value = "full";
|
||||
activeMode = "full";
|
||||
modeSelect.value = graphMode;
|
||||
activeMode = graphMode;
|
||||
labelSelect.value = "auto";
|
||||
activeLabelMode = "auto";
|
||||
zoneBoundaryToggle.checked = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue