mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-06 15:22:12 +03:00
feat(topology): add click navigation to provider page and filter inactive providers (#9024)
Validated in local merge-train (devbox-vm-06-dev002) @ combined-tip (FAST gates green: static + changed tests + vitest — only pre-existing audit.test.ts flake). Evidence: /home/diegosouzapw/dev/proxys/OmniRoute/.claude/worktrees/merge-train-20260805-213228-suite.log
This commit is contained in:
@@ -498,6 +498,12 @@ export default function HomePageClient({ machineId }: HomePageClientProps) {
|
||||
const canonicalProviderId = normalizeProviderId(rawProviderId);
|
||||
if (!canonicalProviderId || byProvider.has(canonicalProviderId)) return;
|
||||
|
||||
// Exclude providers with no active connections (or where all connections are deactivated)
|
||||
const hasActiveConn = providerConnections.some(
|
||||
(c) => normalizeProviderId(c.provider) === canonicalProviderId && c.isActive !== false
|
||||
);
|
||||
if (!hasActiveConn) return;
|
||||
|
||||
const resolvedName =
|
||||
getProviderDisplayLabel(rawProviderId, providerNodes) ||
|
||||
name ||
|
||||
@@ -515,10 +521,11 @@ export default function HomePageClient({ machineId }: HomePageClientProps) {
|
||||
providerStats
|
||||
.filter((provider) => provider.total > 0)
|
||||
.forEach((provider) => addProvider(provider.id, provider.provider.name));
|
||||
providerConnections.forEach((conn) => addProvider(conn.provider));
|
||||
Object.keys(providerMetrics).forEach((provider) => addProvider(provider));
|
||||
|
||||
return Array.from(byProvider.values());
|
||||
}, [providerStats, providerMetrics, providerNodes]);
|
||||
}, [providerStats, providerMetrics, providerNodes, providerConnections]);
|
||||
|
||||
const { lastProvider, errorProvider } = providerTopology;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { useMemo, useCallback } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Handle, Position, type Node, type Edge, type NodeTypes } from "@xyflow/react";
|
||||
import { AI_PROVIDERS } from "@/shared/constants/providers";
|
||||
@@ -58,7 +59,7 @@ function ProviderNode({ data }: { data: ProviderNodeData }) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex items-center gap-2 px-2.5 py-1.5 rounded-lg border-2 transition-all duration-300 bg-bg"
|
||||
className="flex items-center gap-2 px-2.5 py-1.5 rounded-lg border-2 transition-all duration-300 bg-bg cursor-pointer hover:scale-105 active:scale-95 shadow-sm hover:shadow-md"
|
||||
style={{
|
||||
borderColor: error ? RED : active ? color : healthy ? GREEN : "var(--color-border)",
|
||||
boxShadow: error
|
||||
@@ -216,9 +217,7 @@ function buildLayout(
|
||||
return 4;
|
||||
};
|
||||
const d = rank(a) - rank(b);
|
||||
return d !== 0
|
||||
? d
|
||||
: a.provider.toLowerCase().localeCompare(b.provider.toLowerCase()); // ASCII kasıtlı
|
||||
return d !== 0 ? d : a.provider.toLowerCase().localeCompare(b.provider.toLowerCase()); // ASCII kasıtlı
|
||||
});
|
||||
|
||||
let provIdx = 0;
|
||||
@@ -330,6 +329,21 @@ export default function ProviderTopology({
|
||||
[providers]
|
||||
);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const handleNodeClick = useCallback(
|
||||
(_event: React.MouseEvent, node: Node) => {
|
||||
if (node.type !== "provider") return;
|
||||
const providerId =
|
||||
(node.data as ProviderNodeData | undefined)?.providerId ||
|
||||
node.id.replace(/^provider-/, "");
|
||||
if (providerId) {
|
||||
router.push(`/dashboard/providers/${providerId}`);
|
||||
}
|
||||
},
|
||||
[router]
|
||||
);
|
||||
|
||||
const containerClass =
|
||||
"h-[300px] w-full min-w-0 rounded-xl border border-border bg-bg-subtle/20 overflow-hidden sm:h-[420px]";
|
||||
|
||||
@@ -351,6 +365,7 @@ export default function ProviderTopology({
|
||||
nodeTypes={nodeTypes}
|
||||
fitKey={providersKey}
|
||||
className={containerClass}
|
||||
onNodeClick={handleNodeClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user