{
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