import React from "react";
function ListSection({ title, items, renderItem = (item) => item }) {
if (!items?.length) return null;
return (
{title}
{items.map((item, index) => (
- {renderItem(item)}
))}
);
}
export default function GraphUpdateView({ updateResult }) {
if (!updateResult?.proposal) return null;
const {
resolvedUnknownNodeIds,
affectedNodeIds,
previousActiveUnknownNodeId,
newActiveUnknownNodeId,
selectedQuestion,
changesApplied,
proposal,
previousSituationGraph,
updatedSituationGraph,
reasoningState,
previousReasoningState,
} = updateResult;
const newlySurfacedUnknownNodeIds = (proposal.addedNodes || [])
.filter((node) => node.kind === "unknown")
.map((node) => node.id);
const previousNodesById = new Map(
(previousSituationGraph?.nodes || []).map((node) => [node.id, node]),
);
const updatedNodesById = new Map(
(updatedSituationGraph?.nodes || []).map((node) => [node.id, node]),
);
const proposalUpdatesByNodeId = new Map(
(proposal.updatedNodes || []).map((update) => [update.nodeId, update]),
);
function resolveNodePresentation(nodeId) {
const previousNode = previousNodesById.get(nodeId) || null;
const updatedNode = updatedNodesById.get(nodeId) || null;
const node = updatedNode || previousNode;
const update = proposalUpdatesByNodeId.get(nodeId) || null;
if (!node) {
return (
Unknown node (ID: {nodeId})
);
}
return (
{node.label}
{node.kind} · {node.confidence}
{(update?.previousStatus || update?.newStatus || node.status) && (
{update?.previousStatus ? `Previous status: ${update.previousStatus}` : null}
{update?.previousStatus && update?.newStatus ? " → " : null}
{update?.newStatus
? `New status: ${update.newStatus}`
: !update?.previousStatus
? `Status: ${node.status}`
: null}
)}
{update?.reason &&
{update.reason}
}
);
}
function resolveActiveUnknown(nodeId) {
if (!nodeId) return null;
const node = updatedNodesById.get(nodeId) || previousNodesById.get(nodeId);
if (!node) {
return `Unknown node (ID: ${nodeId})`;
}
return `${node.label} · ${node.status} · ${node.confidence}`;
}
const changeItems = [
changesApplied?.addedNodeCount
? `${changesApplied.addedNodeCount} node(s) added`
: null,
changesApplied?.updatedNodeCount
? `${changesApplied.updatedNodeCount} node(s) updated`
: null,
changesApplied?.addedEdgeCount
? `${changesApplied.addedEdgeCount} edge(s) added`
: null,
changesApplied?.removedEdgeCount
? `${changesApplied.removedEdgeCount} edge(s) removed`
: null,
changesApplied?.resolvedUnknownCount
? `${changesApplied.resolvedUnknownCount} unknown(s) resolved`
: null,
].filter(Boolean);
const previousComparabilityStatus =
previousReasoningState?.comparabilityStatus ||
previousSituationGraph?.reasoningState?.comparabilityStatus ||
null;
const newComparabilityStatus =
reasoningState?.comparabilityStatus ||
updatedSituationGraph?.reasoningState?.comparabilityStatus ||
null;
const relationshipStatus =
reasoningState?.relationshipStatus ||
updatedSituationGraph?.reasoningState?.relationshipStatus ||
null;
const reasoningStagesAfter =
reasoningState?.reasoningStages ||
updatedSituationGraph?.reasoningState?.reasoningStages ||
[];
return (
Graph update applied
{previousActiveUnknownNodeId && (
Previous active unknown:{" "}
{resolveActiveUnknown(previousActiveUnknownNodeId)}
)}
{newActiveUnknownNodeId && (
New active unknown:{" "}
{resolveActiveUnknown(newActiveUnknownNodeId)}
)}
{selectedQuestion?.question && (
Next question:{" "}
{selectedQuestion.question}
)}
{previousComparabilityStatus && newComparabilityStatus && (
Comparability:{" "}
{previousComparabilityStatus} → {newComparabilityStatus}
)}
{relationshipStatus && (
Relationship status:{" "}
{relationshipStatus}
)}
{!selectedQuestion?.question && !newActiveUnknownNodeId && previousActiveUnknownNodeId && (
Next question status: No next question selected yet.
)}
{reasoningStagesAfter.length > 0 && (
Reasoning stages:{" "}
{reasoningStagesAfter
.map((stage) => `${stage.stage}: ${stage.status}`)
.join(" → ")}
)}
Proposal details
{JSON.stringify(proposal, null, 2)}
{JSON.stringify(
{
previousActiveUnknownNodeId,
newActiveUnknownNodeId,
resolvedUnknownNodeIds,
affectedNodeIds,
},
null,
2,
)}
);
}