{
+ e.stopPropagation();
+ data.onToggle(data.containerId);
+ }}
+ >
+
+
+ {data.isExpanded && ▾}
+ {labelText}
+ {data.hasSearchHits && data.searchHitCount && data.searchHitCount > 0 && (
+
+ 🔍 {data.searchHitCount}
+
+ )}
+
+ {data.childCount}
+
+
+ );
+});
+
+export default ContainerNode;
+```
+
+- [ ] **Step 2: Build to verify it type-checks**
+
+```bash
+pnpm --filter @understand-anything/dashboard build
+```
+
+Expected: build succeeds.
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add understand-anything-plugin/packages/dashboard/src/components/ContainerNode.tsx
+git commit -m "feat(dashboard): ContainerNode component (visual + click toggle)"
+```
+
+---
+
+## Task 9: Switch overview-level layout to ELK
+
+**Files:**
+- Modify: `understand-anything-plugin/packages/dashboard/src/components/GraphView.tsx`
+
+- [ ] **Step 1: Read current useOverviewGraph**
+
+Open `GraphView.tsx`. Locate `useOverviewGraph` (starts ~line 125). Identify the `applyDagreLayout(clusterNodes ..., flowEdges, "TB", dims)` call (line ~202).
+
+- [ ] **Step 2: Convert to async ELK**
+
+Replace the sync layout block. The current shape returns `{ nodes, edges }` from `useMemo`. Change to use `useState` + `useEffect` so the async ELK call sets state. Example replacement (keep existing code building `clusterNodes` and `flowEdges` and `dims`; only change the layout call and surrounding hooks):
+
+```tsx
+ const [overview, setOverview] = useState<{ nodes: Node[]; edges: Edge[] }>({
+ nodes: [],
+ edges: [],
+ });
+
+ useEffect(() => {
+ if (!graph) {
+ setOverview({ nodes: [], edges: [] });
+ return;
+ }
+ let cancelled = false;
+ const elkInput = clusterNodesToElkInput(clusterNodes, flowEdges, dims);
+ applyElkLayout(elkInput, { strict: import.meta.env.DEV }).then(({ positioned }) => {
+ if (cancelled) return;
+ const positionedNodes = mergeElkPositions(clusterNodes as unknown as Node[], positioned);
+ setOverview({ nodes: positionedNodes, edges: flowEdges });
+ });
+ return () => {
+ cancelled = true;
+ };
+ }, [graph, searchResults, drillIntoLayer]);
+
+ return overview;
+```
+
+- [ ] **Step 3: Add helpers `clusterNodesToElkInput` and `mergeElkPositions`**
+
+Append to the bottom of `utils/layout.ts`:
+
+```ts
+import type { ElkInput } from "./elk-layout";
+
+const ELK_DEFAULT_LAYOUT_OPTIONS: Record