import React from 'react'; import { NodeMetric } from '@/store/metricsStore'; import { cn } from '@/lib/utils'; interface Props { node: string; stats: NodeMetric; prevStats?: NodeMetric | null; /** Outer ring diameter in px (default 48). */ size?: number; onClick?: () => void; className?: string; } const CircleProgress: React.FC<{ percent: number; size: number; strokeWidth: number; color: string; offset?: number; }> = ({ percent, size, strokeWidth, color, offset = 0 }) => { const radius = (size - strokeWidth) / 2; const circumference = 2 * Math.PI * radius; const clamped = Math.min(100, Math.max(0, percent)); const dashOffset = circumference - (clamped / 100) * circumference; return ( ); }; const MetricIndicator: React.FC = ({ node, stats, prevStats, size = 48, onClick, className, }) => { const cpu = stats.cpu_utilization ?? 0; const totalMemory = (stats.memory_total ?? 0) + (stats.memory_available ?? 0); const usedMemory = stats.memory_total ?? 0; const memoryPercent = totalMemory > 0 ? (usedMemory / totalMemory) * 100 : 0; const prevCpu = prevStats?.cpu_utilization; const prevTotal = (prevStats?.memory_total ?? 0) + (prevStats?.memory_available ?? 0); const prevUsed = prevStats?.memory_total ?? 0; const prevMemoryPercent = prevTotal > 0 ? (prevUsed / prevTotal) * 100 : null; const cpuColor = cpu > 80 ? '#ef4444' : '#22c55e'; const memColor = memoryPercent > 80 ? '#ef4444' : '#3b82f6'; const stroke = Math.max(3, Math.round(size * 0.12)); const innerSize = Math.round(size * (32 / 48)); const innerOffset = Math.round((size - innerSize) / 2); const fontSize = size <= 36 ? 8 : 10; const shellClass = cn( 'group relative shrink-0', onClick && 'cursor-pointer rounded-full outline-none focus-visible:ring-2 focus-visible:ring-ring', className ); const body = ( <>
{cpu.toFixed(0)}%
{node}
CPU: {cpu.toFixed(1)}%{' '} {prevCpu !== undefined ? `(было ${prevCpu.toFixed(1)}%)` : ''}
Память: {(usedMemory / 1048576).toFixed(0)} / {(totalMemory / 1048576).toFixed(0)} МБ ( {memoryPercent.toFixed(1)}%) {prevMemoryPercent !== null ? ` (было ${prevMemoryPercent.toFixed(1)}%)` : ''}
); if (onClick) { return ( ); } return (
{body}
); }; export default MetricIndicator;