Files
Minikura/apps/web/components/topology/nodes/proxy-node.tsx
T

106 lines
3.5 KiB
TypeScript
Raw Normal View History

2026-02-17 18:12:02 +07:00
import type { NodeProps } from "@xyflow/react";
2026-08-13 01:58:19 +07:00
import { Box, Cpu, Globe, HardDrive, Network } from "lucide-react";
2026-02-17 18:12:02 +07:00
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/cn";
import type { ProxyMetadata, TopologyNodeData } from "@/lib/topology-types";
2026-08-13 01:58:19 +07:00
import { CompactRow, CopyableCode, MetricRow, TopologyNodeCard } from "../topology-primitives";
2026-02-17 18:12:02 +07:00
export function ProxyNode({ data, selected }: NodeProps) {
2026-08-13 01:58:19 +07:00
const nodeData = data as TopologyNodeData;
const metadata = nodeData.metadata as ProxyMetadata;
2026-02-17 18:12:02 +07:00
const { proxy, readyPods, podCount, health, connectedServers } = metadata;
2026-08-13 01:58:19 +07:00
const { k8sNodes, connectionInfo, metrics, pods } = metadata;
const restartCount = pods.reduce((sum, pod) => sum + (pod.restarts || 0), 0);
2026-02-17 18:12:02 +07:00
return (
2026-08-13 01:58:19 +07:00
<TopologyNodeCard
selected={selected}
icon={<Globe className="h-4 w-4 text-blue-500" />}
iconClassName="bg-blue-500/10"
title={proxy.id}
description={proxy.description}
health={health}
2026-02-17 18:12:02 +07:00
>
2026-08-13 01:58:19 +07:00
<div className="flex flex-wrap gap-1">
<Badge variant="outline" className="text-[10px] h-5">
{proxy.type}
</Badge>
{connectionInfo && (
2026-02-17 18:12:02 +07:00
<Badge variant="outline" className="text-[10px] h-5">
2026-08-13 01:58:19 +07:00
{connectionInfo.type}
2026-02-17 18:12:02 +07:00
</Badge>
)}
</div>
2026-08-13 01:58:19 +07:00
<CompactRow
label="Pods"
className="text-xs bg-muted/50 rounded px-2 py-1.5"
valueClassName={cn(
"font-semibold",
readyPods === podCount ? "text-green-600" : "text-yellow-600"
)}
>
{readyPods}/{podCount}
</CompactRow>
{proxy.node_port && (
<div className="space-y-1 text-[11px]">
<CompactRow label="NodePort" icon={<Network className="h-3 w-3" />}>
{proxy.node_port}
</CompactRow>
</div>
)}
{connectionInfo?.connectionString && (
<div className="space-y-1 text-[11px] pt-1 border-t">
<CompactRow label="Address" />
<CopyableCode value={connectionInfo.connectionString} />
{connectionInfo.note && (
<p className="text-[10px] text-muted-foreground italic">{connectionInfo.note}</p>
)}
</div>
)}
<div className="space-y-1 text-[11px] pt-1 border-t">
<MetricRow
label="Memory"
icon={<HardDrive className="h-3 w-3" />}
usage={metrics?.memoryUsage}
limit={`${proxy.memory}MB`}
/>
<MetricRow
label="CPU"
icon={<Cpu className="h-3 w-3" />}
usage={metrics?.cpuUsage}
limit={`${proxy.cpu_request || "N/A"}/${proxy.cpu_limit || "N/A"}`}
/>
</div>
{pods.length > 0 && (
<div className="space-y-1 text-[11px] pt-1 border-t">
<CompactRow
label="Restarts"
valueClassName={restartCount > 0 ? "text-yellow-600" : "text-green-600"}
>
{restartCount}
</CompactRow>
{pods[0]?.age && <CompactRow label="Age">{pods[0].age}</CompactRow>}
{pods[0]?.ip && (
<CompactRow label="Pod IP" valueClassName="font-mono text-[10px]">
{pods[0].ip}
</CompactRow>
)}
<CompactRow label="Routing To" valueClassName="font-semibold text-blue-600">
{connectedServers.length} servers
</CompactRow>
{k8sNodes.length > 0 && (
<CompactRow label="K8s Node" icon={<Box className="h-3 w-3" />}>
{k8sNodes[0]}
</CompactRow>
)}
</div>
)}
</TopologyNodeCard>
2026-02-17 18:12:02 +07:00
);
}