# How the Persona-Adaptive UI in Egonex-AI Understand Anything Adjusts Detail Levels for Different User Types

> Discover how Egonex-AI's persona-adaptive UI tailors detail levels for non-technical, junior, and experienced users by dynamically filtering graph nodes and managing layout caches.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: deep-dive
- Published: 2026-06-13

---

**The persona-adaptive UI leverages a Zustand store to track user personas (`non-technical`, `junior`, `experienced`) and detail levels (`file`, `class`), automatically filtering graph nodes and clearing layout caches to present complexity-appropriate views.**

The Egonex-AI/Understand-Anything repository implements a sophisticated persona-adaptive UI that dynamically adjusts code visualization complexity based on user expertise. This system ensures non-technical stakeholders see architectural overviews while experienced developers access granular implementation details. At its core, the mechanism combines a centralized state store with conditional rendering logic to seamlessly adjust detail levels for different user types.

## Core Architecture of the Persona-Adaptive UI

### The Zustand Store Configuration

State management lives in [`store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/store.ts) where the `useDashboardStore` hook defines both the **persona** and **detail level** states. When users switch between personas, the store triggers a complete cache invalidation to prevent stale visualizations.

The `setPersona` function updates the current user type and clears all layout caches:

```typescript
// store.ts – lines 34-41
setPersona: (persona) =>
  set({
    persona,
    // Clear caches to force re-render with new filtering rules
    containerLayoutCache: new Map(),
    containerSizeMemory: new Map(),
    expandedContainers: new Set(),
    pendingFocusContainer: null,
  }),

```

### Persona Definitions and Filtering Logic

The system recognizes three distinct user types, each with specific filtering rules applied across dashboard components. The **filtering logic** executes in real-time during graph rendering, ensuring nodes are excluded before they reach the layout engine.

## How Personas Filter Code Complexity

### Non-Technical: Architectural Abstraction

For `non-technical` users, the UI strips implementation details to present a high-level architectural view. In [`GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/GraphView.tsx) (line 439), the renderer explicitly skips sub-file node types:

```tsx
// GraphView.tsx – line 439
if (persona === "non-technical" && subFileTypes.has(n.type)) return false;

```

This same filtering applies to export operations. In [`ExportMenu.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ExportMenu.tsx) (lines 186-190), the system builds a filtered graph copy for non-technical users:

```tsx
// ExportMenu.tsx – lines 186-190
let filteredGraphNodes = persona === "non-technical"
  ? // keep only top-level file nodes
    graph.nodes.filter(n => !subFileTypes.has(n.type))
  : graph.nodes;

```

### Junior: Guided Exploration Mode

The `junior` persona maintains file-level visualization while enabling educational features that encourage deeper exploration without overwhelming the user. This persona bridges the gap between architectural overview and code-level detail.

### Experienced: Full Code Visibility

The `experienced` persona bypasses all filters, exposing **class** and **function** nodes alongside advanced navigation capabilities. Users with this persona see the complete knowledge graph without restrictions.

## Detail Level Granularity Controls

### Visual Granularity Options

The UI supports two primary detail levels controlled via `setDetailLevel` in [`store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/store.ts) (lines 42-54):

```typescript
// store.ts – lines 42-54
detailLevel: "file",
setDetailLevel: (level) =>
  set({
    detailLevel: level,
    // resetting caches avoids stale positions after the node set changes
    containerLayoutCache: new Map(),
    containerSizeMemory: new Map(),
    expandedContainers: new Set(),
    pendingFocusContainer: null,
    showFunctionsInClassView: false, // Reset function visibility
  }),

```

The **file** level displays only file nodes for an architectural view, while the **class** level includes both file and class nodes with optional function visibility.

### Cache Invalidation Strategy

When detail levels change, the store resets `containerLayoutCache`, `containerSizeMemory`, and `expandedContainers` to force the layout engine to recompute positions for the newly visible node set. This prevents layout artifacts from previous configurations.

## Implementation Examples

### Switching Personas via PersonaSelector

The `PersonaSelector` component dispatches persona changes to the store:

```tsx
import { useDashboardStore } from "./store";

function PersonaSelector() {
  const persona = useDashboardStore(s => s.persona);
  const setPersona = useDashboardStore(s => s.setPersona);

  const options = [
    { id: "non-technical", label: "Business",   description: "High-level view" },
    { id: "junior",        label: "Learn",      description: "Guided exploration" },
    { id: "experienced",   label: "Deep Dive",  description: "Full code details" },
  ];

  return (
    <div>
      {options.map(p => (
        <button
          key={p.id}
          onClick={() => setPersona(p.id)}
          disabled={persona === p.id}
        >
          {p.label}
        </button>
      ))}
    </div>
  );
}

```

### Rendering with Persona-Based Filtering

Components read the current persona and filter accordingly:

```tsx
import { useDashboardStore } from "./store";

function GraphNode({ node }) {
  const persona = useDashboardStore(s => s.persona);
  const subFileTypes = new Set(["function", "class"]);

  // Hide sub-file nodes for non-technical users
  if (persona === "non-technical" && subFileTypes.has(node.type)) {
    return null;
  }

  return <NodeComponent data={node} />;
}

```

### Changing Detail Levels

Users toggle between architectural and code-structure views:

```tsx
import { useDashboardStore } from "./store";

function DetailLevelToggle() {
  const detailLevel = useDashboardStore(s => s.detailLevel);
  const setDetailLevel = useDashboardStore(s => s.setDetailLevel);

  return (
    <select
      value={detailLevel}
      onChange={e => setDetailLevel(e.target.value as "file" | "class")}
    >
      <option value="file">Architecture (files only)</option>
      <option value="class">Code structure (files + classes)</option>
    </select>
  );
}

```

## Summary

- The **Zustand store** in [`store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/store.ts) centralizes persona and detail-level state, clearing layout caches on every change to prevent stale visualizations.
- Three personas (`non-technical`, `junior`, `experienced`) control visibility of **function** and **class** nodes through conditional filtering in [`GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/GraphView.tsx) and [`ExportMenu.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ExportMenu.tsx).
- Two detail levels (`file` and `class`) determine visual granularity, with `setDetailLevel` invalidating position caches to maintain layout consistency.
- The **persona-adaptive UI** ensures non-technical stakeholders see architectural overviews while developers access implementation-specific details.

## Frequently Asked Questions

### What personas are available in the Understand-Anything dashboard?

The dashboard supports three personas: `non-technical` (Business view), `junior` (Learn mode with guided exploration), and `experienced` (Deep Dive with full code visibility). Each persona applies distinct filtering rules to the knowledge graph, hiding or exposing function and class nodes based on the user's technical expertise.

### How does the UI prevent layout glitches when switching between detail levels?

The `setDetailLevel` function in [`store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/store.ts) resets `containerLayoutCache`, `containerSizeMemory`, and `expandedContainers` to empty states when the detail level changes. This forced cache invalidation ensures the graph layout engine recomputes node positions from scratch rather than reusing stale coordinates from the previous view configuration.

### Can users manually override the default detail level for their persona?

Yes. While personas set initial filtering constraints (hiding functions/classes for non-technical users), the detail level toggle operates independently within those constraints. Users can switch between `file` (architectural) and `class` (code structure) views regardless of their selected persona, though the underlying persona filters still apply to determine which node types are ultimately visible.

### Where is the filtering logic implemented in the source code?

The primary filtering logic resides in [`GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/GraphView.tsx) at line 439, where the renderer checks `if (persona === "non-technical" && subFileTypes.has(n.type)) return false`. Additionally, [`ExportMenu.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ExportMenu.tsx) (lines 186-190) applies the same filtering rules when generating exported graph data, ensuring consistency between the visual interface and exported artifacts.