2026-04-05 22:44:45 -05:00
|
|
|
import { NavLink } from "react-router";
|
|
|
|
|
import {
|
|
|
|
|
MessageSquareText,
|
|
|
|
|
LibraryBig,
|
|
|
|
|
Rotate3d,
|
feat: add Docker entrypoints, LLM providers, pipeline hardening, workbench pages
Phase 9 — four parallel workstreams:
- Stream A: 14 Docker entrypoints for containerized deployment
- Stream B: Pipeline hardening — robust JSON parsing, LLM retry logic,
consumer negative-ack, FalkorDB test import fix
- Stream C: Azure OpenAI, OpenAI-compatible, and Mistral LLM providers
- Stream D: Workbench Prompts, Token Cost, Knowledge Cores pages +
Settings feature switches
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 03:22:55 -05:00
|
|
|
MessageCircleCode,
|
|
|
|
|
Coins,
|
|
|
|
|
BrainCircuit,
|
2026-04-05 22:44:45 -05:00
|
|
|
Workflow,
|
2026-04-12 00:59:20 -05:00
|
|
|
Plug,
|
2026-04-05 22:44:45 -05:00
|
|
|
Settings,
|
|
|
|
|
TestTube2,
|
|
|
|
|
Wifi,
|
|
|
|
|
WifiOff,
|
|
|
|
|
Database,
|
|
|
|
|
ChevronDown,
|
|
|
|
|
} from "lucide-react";
|
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
|
import { useConnectionState } from "@/providers/socket-provider";
|
|
|
|
|
import { useSessionStore } from "@/hooks/use-session-store";
|
|
|
|
|
import { useFlows } from "@/hooks/use-flows";
|
|
|
|
|
import { useSettings } from "@/providers/settings-provider";
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// Nav item
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
interface NavItemProps {
|
|
|
|
|
to: string;
|
|
|
|
|
icon: React.ElementType;
|
|
|
|
|
label: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function NavItem({ to, icon: Icon, label }: NavItemProps) {
|
|
|
|
|
return (
|
fix: comprehensive a11y and contrast QA pass across workbench
Automated QA loop (6 parallel browser agents, 2 rounds) found and fixed
15 accessibility, contrast, and responsive issues across all 8 pages:
- WCAG contrast: light-mode warning (#854d0e), error (#b91c1c), toggle
off-state (surface-400), connection badge (fg-muted)
- ARIA: mode selector group+pressed, tab pattern ids+labelledby, nav
and aside labels, dialog focus-return, alert roles on banners
- Responsive: library header flex-wrap, search/button aria-labels
- Focus: NavLink visible ring, dialog close button ring
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:26:28 -05:00
|
|
|
<NavLink to={to} className="w-full rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 focus-visible:ring-offset-1 focus-visible:ring-offset-surface-50">
|
2026-04-05 22:44:45 -05:00
|
|
|
{({ isActive }) => (
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
"flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors",
|
|
|
|
|
isActive
|
|
|
|
|
? "bg-brand-600/20 text-brand-400"
|
|
|
|
|
: "text-fg-muted hover:bg-surface-200 hover:text-fg",
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
<Icon className="h-4 w-4 shrink-0" />
|
|
|
|
|
<span className="truncate">{label}</span>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</NavLink>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// Connection status badge
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
function ConnectionBadge() {
|
|
|
|
|
const state = useConnectionState();
|
|
|
|
|
|
|
|
|
|
const isConnected =
|
|
|
|
|
state.status === "connected" ||
|
|
|
|
|
state.status === "authenticated" ||
|
|
|
|
|
state.status === "unauthenticated";
|
|
|
|
|
|
2026-04-07 06:33:22 -05:00
|
|
|
const isWarning = state.status === "unauthenticated";
|
|
|
|
|
|
2026-04-05 22:44:45 -05:00
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
"flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-medium",
|
2026-04-07 06:33:22 -05:00
|
|
|
isWarning
|
2026-04-10 07:48:01 -05:00
|
|
|
? "text-warning"
|
2026-04-07 06:33:22 -05:00
|
|
|
: isConnected
|
|
|
|
|
? "text-success"
|
fix: comprehensive a11y and contrast QA pass across workbench
Automated QA loop (6 parallel browser agents, 2 rounds) found and fixed
15 accessibility, contrast, and responsive issues across all 8 pages:
- WCAG contrast: light-mode warning (#854d0e), error (#b91c1c), toggle
off-state (surface-400), connection badge (fg-muted)
- ARIA: mode selector group+pressed, tab pattern ids+labelledby, nav
and aside labels, dialog focus-return, alert roles on banners
- Responsive: library header flex-wrap, search/button aria-labels
- Focus: NavLink visible ring, dialog close button ring
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:26:28 -05:00
|
|
|
: "text-fg-muted",
|
2026-04-05 22:44:45 -05:00
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
<span
|
|
|
|
|
className={cn(
|
|
|
|
|
"h-2 w-2 shrink-0 rounded-full",
|
2026-04-07 06:33:22 -05:00
|
|
|
isWarning
|
2026-04-10 07:48:01 -05:00
|
|
|
? "bg-warning animate-pulse"
|
2026-04-07 06:33:22 -05:00
|
|
|
: isConnected
|
|
|
|
|
? "bg-success animate-pulse"
|
|
|
|
|
: "bg-fg-subtle",
|
2026-04-05 22:44:45 -05:00
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
{isConnected ? (
|
|
|
|
|
<Wifi className="h-3.5 w-3.5" />
|
|
|
|
|
) : (
|
|
|
|
|
<WifiOff className="h-3.5 w-3.5" />
|
|
|
|
|
)}
|
2026-04-07 06:33:22 -05:00
|
|
|
<span className="truncate capitalize">
|
|
|
|
|
{isWarning ? "Connected (no auth)" : state.status}
|
|
|
|
|
</span>
|
2026-04-05 22:44:45 -05:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// Flow selector dropdown
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
function FlowSelectorDropdown() {
|
|
|
|
|
const { flows } = useFlows();
|
|
|
|
|
const flowId = useSessionStore((s) => s.flowId);
|
|
|
|
|
const setFlowId = useSessionStore((s) => s.setFlowId);
|
|
|
|
|
const collection = useSettings((s) => s.settings.collection);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="space-y-2 px-3">
|
|
|
|
|
{/* Flow selector */}
|
|
|
|
|
<div className="space-y-1">
|
2026-04-10 07:48:01 -05:00
|
|
|
<label htmlFor="sidebar-flow-select" className="flex items-center gap-1.5 text-[10px] font-medium uppercase tracking-wider text-fg-subtle">
|
2026-04-05 22:44:45 -05:00
|
|
|
<Workflow className="h-3 w-3" />
|
|
|
|
|
Flow
|
|
|
|
|
</label>
|
|
|
|
|
<div className="relative">
|
|
|
|
|
<select
|
2026-04-10 07:48:01 -05:00
|
|
|
id="sidebar-flow-select"
|
2026-04-05 22:44:45 -05:00
|
|
|
value={flowId}
|
|
|
|
|
onChange={(e) => setFlowId(e.target.value)}
|
|
|
|
|
className="w-full appearance-none rounded-md border border-border bg-surface-100 py-1.5 pl-2.5 pr-7 text-xs text-fg focus:border-brand-500 focus:outline-none focus:ring-1 focus:ring-brand-500"
|
|
|
|
|
>
|
|
|
|
|
<option value="default">default</option>
|
|
|
|
|
{flows.map((f) => (
|
|
|
|
|
<option key={f.id} value={f.id}>
|
|
|
|
|
{f.id}
|
|
|
|
|
</option>
|
|
|
|
|
))}
|
|
|
|
|
</select>
|
|
|
|
|
<ChevronDown className="pointer-events-none absolute right-2 top-1/2 h-3 w-3 -translate-y-1/2 text-fg-subtle" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Collection badge */}
|
|
|
|
|
<div className="flex items-center gap-1.5 rounded-md bg-surface-100 px-2.5 py-1.5 text-xs text-fg-muted">
|
|
|
|
|
<Database className="h-3 w-3 shrink-0 text-fg-subtle" />
|
|
|
|
|
<span className="truncate">{collection}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// Sidebar
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
export function Sidebar() {
|
2026-04-12 00:59:20 -05:00
|
|
|
const { featureSwitches } = useSettings((s) => s.settings);
|
|
|
|
|
|
2026-04-05 22:44:45 -05:00
|
|
|
return (
|
fix: comprehensive a11y and contrast QA pass across workbench
Automated QA loop (6 parallel browser agents, 2 rounds) found and fixed
15 accessibility, contrast, and responsive issues across all 8 pages:
- WCAG contrast: light-mode warning (#854d0e), error (#b91c1c), toggle
off-state (surface-400), connection badge (fg-muted)
- ARIA: mode selector group+pressed, tab pattern ids+labelledby, nav
and aside labels, dialog focus-return, alert roles on banners
- Responsive: library header flex-wrap, search/button aria-labels
- Focus: NavLink visible ring, dialog close button ring
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:26:28 -05:00
|
|
|
<aside aria-label="Sidebar" className="flex h-screen w-sidebar shrink-0 flex-col border-r border-border bg-surface-50">
|
2026-04-05 22:44:45 -05:00
|
|
|
{/* Logo area */}
|
|
|
|
|
<div className="flex h-14 items-center gap-2 px-4">
|
|
|
|
|
<TestTube2 className="h-5 w-5 text-brand-500" />
|
|
|
|
|
<span className="text-lg font-bold text-fg">TrustGraph</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Divider */}
|
|
|
|
|
<div className="mx-3 border-t border-border" />
|
|
|
|
|
|
|
|
|
|
{/* Flow & collection selectors */}
|
|
|
|
|
<div className="py-3">
|
|
|
|
|
<FlowSelectorDropdown />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Divider */}
|
|
|
|
|
<div className="mx-3 border-t border-border" />
|
|
|
|
|
|
|
|
|
|
{/* Navigation links */}
|
fix: comprehensive a11y and contrast QA pass across workbench
Automated QA loop (6 parallel browser agents, 2 rounds) found and fixed
15 accessibility, contrast, and responsive issues across all 8 pages:
- WCAG contrast: light-mode warning (#854d0e), error (#b91c1c), toggle
off-state (surface-400), connection badge (fg-muted)
- ARIA: mode selector group+pressed, tab pattern ids+labelledby, nav
and aside labels, dialog focus-return, alert roles on banners
- Responsive: library header flex-wrap, search/button aria-labels
- Focus: NavLink visible ring, dialog close button ring
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:26:28 -05:00
|
|
|
<nav aria-label="Main navigation" className="flex flex-1 flex-col gap-0.5 overflow-y-auto px-2 py-3">
|
2026-04-05 22:44:45 -05:00
|
|
|
<NavItem to="/chat" icon={MessageSquareText} label="Chat" />
|
|
|
|
|
<NavItem to="/library" icon={LibraryBig} label="Library" />
|
|
|
|
|
<NavItem to="/graph" icon={Rotate3d} label="Graph" />
|
feat: add Docker entrypoints, LLM providers, pipeline hardening, workbench pages
Phase 9 — four parallel workstreams:
- Stream A: 14 Docker entrypoints for containerized deployment
- Stream B: Pipeline hardening — robust JSON parsing, LLM retry logic,
consumer negative-ack, FalkorDB test import fix
- Stream C: Azure OpenAI, OpenAI-compatible, and Mistral LLM providers
- Stream D: Workbench Prompts, Token Cost, Knowledge Cores pages +
Settings feature switches
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 03:22:55 -05:00
|
|
|
<NavItem to="/prompts" icon={MessageCircleCode} label="Prompts" />
|
|
|
|
|
<NavItem to="/token-cost" icon={Coins} label="Token Cost" />
|
fix: comprehensive QA — resolve 13 bugs, add UX improvements across all services
Client SDK: add .catch() to graphRagStreaming/documentRagStreaming (silent timeout),
null-guard JSON.parse in getPrompts/getSystemPrompt/getPrompt.
Backend: implement "getvalues" config operation for token costs, null-check
createTerm() in FalkorDB triples query, add knowledge-cores service entrypoint
and Docker entry, return proper HTTP 400/404 for gateway error responses.
Workbench: cancel button + elapsed timer for chat, clear agent spinner on error,
flow dialog inline validation, responsive header wrapping, knowledge cores
loading timeout, sidebar/page naming consistency, theme toggle indicator.
Infrastructure: enable Grafana Explore for viewers, add gateway Prometheus
scrape target, fix RAG pipeline dashboard layout (6 panels visible),
filter Service Health to configured targets only.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 05:20:10 -05:00
|
|
|
<NavItem to="/knowledge-cores" icon={BrainCircuit} label="Knowledge Cores" />
|
2026-04-05 22:44:45 -05:00
|
|
|
<NavItem to="/flows" icon={Workflow} label="Flows" />
|
2026-04-12 00:59:20 -05:00
|
|
|
{featureSwitches.mcpTools && (
|
|
|
|
|
<NavItem to="/mcp-tools" icon={Plug} label="MCP Tools" />
|
|
|
|
|
)}
|
2026-04-05 22:44:45 -05:00
|
|
|
<NavItem to="/settings" icon={Settings} label="Settings" />
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
{/* Footer: connection badge */}
|
|
|
|
|
<div className="border-t border-border px-2 py-2">
|
|
|
|
|
<ConnectionBadge />
|
|
|
|
|
</div>
|
|
|
|
|
</aside>
|
|
|
|
|
);
|
|
|
|
|
}
|