diff --git a/libs/@hashintel/petrinaut/src/ui/views/Notebook/graph-explorer.tsx b/libs/@hashintel/petrinaut/src/ui/views/Notebook/graph-explorer.tsx index e2420532b27..6de4fa9830b 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Notebook/graph-explorer.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Notebook/graph-explorer.tsx @@ -9,6 +9,8 @@ import { CELL_KIND_ICONS, CELL_KIND_LABELS } from "./cell-kinds"; import { NetGraphView } from "./net-graph"; import type { FocusGrid } from "../../worksheet/use-focus-grid"; +import type { CycleGroup } from "./net-cycles"; +import type { InitialPlaceGroup } from "./net-siphons"; import type { CellConnections, NetGraph, NodeRef } from "./notebook-model"; const containerStyle = css({ @@ -34,6 +36,12 @@ const headerActionsStyle = css({ gap: "1", }); +const cycleSummaryStyle = css({ + fontSize: "xs", + color: "neutral.fg.subtle", + whiteSpace: "nowrap", +}); + /** The graph takes every pixel the lists below don't claim. */ const graphPaneStyle = css({ flex: "[1]", @@ -248,6 +256,9 @@ export type ExplorerGraph = { dependencyIds: ReadonlySet; dependentIds: ReadonlySet; placeColors: ReadonlyMap; + cycleByNode: ReadonlyMap; + initialByPlace: ReadonlyMap; + hoveredCycleKey: string | null; /** Set to re-layer the diagram around this node. */ focusId: string | null; }; @@ -260,6 +271,9 @@ export interface GraphExplorerProps { /** Id of the selected cell — keys the connection lists' focus memory. */ selectedCellId: string | null; selectedName: string | null; + /** Every cycle in the net, for the summary in the header. */ + cycleGroups: CycleGroup[]; + onHoverCycle: (cycleKey: string | null) => void; isFocusMode: boolean; /** Focus mode needs a place or transition selected to have something to centre. */ canFocus: boolean; @@ -280,6 +294,8 @@ export const GraphExplorer: React.FC = ({ connections, selectedCellId, selectedName, + cycleGroups, + onHoverCycle, isFocusMode, canFocus, onToggleFocus, @@ -287,12 +303,30 @@ export const GraphExplorer: React.FC = ({ }) => { // How much of the pane the lists claim; the graph fills whatever is left. const [listsHeight, setListsHeight] = useState(DEFAULT_LISTS_HEIGHT); + const initialPlaceCount = graph.initialByPlace.size; return (
Graph explorer
+ {cycleGroups.length > 0 && ( + + ↻ {cycleGroups.length}{" "} + {cycleGroups.length === 1 ? "cycle" : "cycles"} + + )} + {initialPlaceCount > 0 && ( + + ○ {initialPlaceCount} initial + + )}