@aidex/admin-react
v1.2.0
Published
Aidex Admin React adapter — useAdmin(controller) plus a set of Admin components (AdminOverview, AIControl, ConnectionList, ObservabilitySummary, plus the styled AI Control Center surfaces Overview, RecentExecutions, RoutingDetail, GuardrailActivity) over
Readme
@aidex/admin-react
Installation
pnpm add @aidex/admin-react @aidex/admin @aidex/admin-theme @aidex/connections @aidex/ai-control @aidex/observability reactnpm install @aidex/admin-react @aidex/admin @aidex/admin-theme @aidex/connections @aidex/ai-control @aidex/observability reactThe React implementation of the Aidex AI Control Center — a full
ControlCenter shell plus every section it composes — built on
useAdmin(controller), a single hook adapting @aidex/admin's
AdminController to React (useSyncExternalStore under the hood). No
business logic lives here — every read and command still goes through the
same AdminController your application already constructed.
Usage
The full AI Control Center shell:
import { AdminController } from '@aidex/admin';
import { ControlCenter } from '@aidex/admin-react';
import '@aidex/admin-theme/tokens.css'; // once, globally
const admin = new AdminController({ connectionManager, aiControl, observability });
function App() {
return <ControlCenter controller={admin} />;
}Or use a single hook/component directly:
import { AdminController } from '@aidex/admin';
import { useAdmin } from '@aidex/admin-react';
const admin = new AdminController({ connectionManager, aiControl, observability });
function AdminPanel() {
const snapshot = useAdmin(admin);
return (
<div>
<p>Health: {snapshot.health}</p>
<p>AI enabled: {String(snapshot.aiControl.enabled)}</p>
<p>Connections: {snapshot.connections.length}</p>
{/* Continue using controller commands directly — no wrapped
command API, no dispatch layer. */}
<button onClick={() => admin.setAIEnabled(!snapshot.aiControl.enabled)}>
Toggle AI
</button>
</div>
);
}Components
AI Control Center (ControlCenter and its composed components)
| Component | Renders |
|---|---|
| ControlCenter | The full application shell — sidebar navigation across 8 sections, mobile drawer, and the shared ExecutionInspector |
| Overview | Overview section: operational metric cards plus embedded RecentExecutions |
| RecentExecutions | Recent executions table with an onInspectExecution callback per row |
| ExecutionInspector | Detail panel for one inspected execution — overview, metadata, error, routing, and guardrail-denial sections, each rendered only when that execution actually has the data |
| RoutingDetail | One execution's Gateway routing decision: candidates considered, the ordered attempt sequence, and the selected candidate, with an onInspectExecution callback |
| GuardrailActivity | Every observed guardrail denial (stage + code only, never the guardrail's free-form reason), with an onInspectExecution callback per row |
| ConnectionsGrid | Card-based connection listing (identity/provider/enabled state) |
| ProvidersGrid | Card-based provider capability discovery, including Gateway routing flags |
| AIControlPanel | Read-only presentation of global AI enabled/disabled and per-feature overrides |
| ObservabilityPanel | Operational summary: tokens, cost, error count, execution count, last activity |
Each component's props type is exported alongside it (e.g. ControlCenterProps,
RoutingDetailProps) — import types the same way: import type { ControlCenterProps } from '@aidex/admin-react'.
Standalone building blocks (independent of ControlCenter)
| Component | Renders |
|---|---|
| AdminOverview | A minimal, health-only summary — predates Overview and remains a deliberately separate, smaller surface some existing consumer may already depend on |
| AIControl | Global AI enabled/disabled + per-feature overrides, interactively (setAIEnabled/setFeatureEnabled/clearFeatureOverride) |
| ConnectionList | Connections, identity/provider/enabled state |
| ObservabilitySummary | Tokens, cost, error count, last activity — a compact summary line |
These four components predate the Control Center shell and remain fully
independent of it — AdminOverview is not Overview under a different
name; it's a deliberately separate, smaller surface, not composed by
ControlCenter.
Design notes
- No
AdminProvider, no React Context.adminis passed touseAdminas a plain argument, the same way you'd pass any object to a hook — there is no ambient/global Admin state to provide.AdminControlleritself remains the single source of truth; this hook never caches or copies its state. - Pass the same
controllerreference across renders (construct it once — module scope, a ref, oruseMemo) so the subscription stays stable; a newcontrolleridentity on every render would resubscribe on every render, which is correct behavior for "the controller actually changed" but wasteful if unintended. - SSR-safe.
AdminController.getSnapshot()is a synchronous in-memory read with nowindow/documentaccess, so the hook's server snapshot is identical to its client one — no hydration mismatch, no extra code. - New
AdminSnapshotfields need no adapter change.useAdmin()hands back the whole snapshot generically —snapshot.providers(capability discovery) andsnapshot.executions(requested-vs-actual, tokens, cost, duration, success/error) are already available with zero changes to this package. See@aidex/admin's own README for their shape.
