import React, { memo, useEffect, useRef, useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faEthernet, faHdd, faMemory, faMicrochip, faServer } from '@fortawesome/free-solid-svg-icons'; import { Link } from 'react-router-dom'; import { Server } from '@/api/server/getServer'; import getServerResourceUsage, { ServerStats } from '@/api/server/getServerResourceUsage'; import { bytesToHuman, megabytesToHuman } from '@/helpers'; import tw from 'twin.macro'; import GreyRowBox from '@/components/elements/GreyRowBox'; import Spinner from '@/components/elements/Spinner'; import styled from 'styled-components/macro'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import isEqual from 'react-fast-compare'; // Determines if the current value is in an alarm threshold so we can show it in red rather // than the more faded default style. const isAlarmState = (current: number, limit: number): boolean => limit > 0 && (current / (limit * 1024 * 1024) >= 0.90); interface IconProps { icon: IconProp; usage: number; limit: string; isAlarm: boolean; } const Icon = memo(styled(FontAwesomeIcon)<{ $alarm: boolean }>` ${props => props.$alarm ? tw`text-red-400` : tw`text-neutral-500`}; `, isEqual); const IconDescription = styled.p<{ $alarm: boolean }>` ${tw`text-sm ml-2`}; ${props => props.$alarm ? tw`text-white` : tw`text-neutral-400`}; `; export default ({ server, className }: { server: Server; className?: string }) => { const interval = useRef(null); const [ stats, setStats ] = useState(null); const [ statsError, setStatsError ] = useState(false); const getStats = () => { setStatsError(false); return getServerResourceUsage(server.uuid) .then(data => setStats(data)) .catch(error => { setStatsError(true); console.error(error); }); }; useEffect(() => { getStats().then(() => { // @ts-ignore interval.current = setInterval(() => getStats(), 20000); }); return () => { interval.current && clearInterval(interval.current); }; }, []); const alarms = { cpu: false, memory: false, disk: false }; if (stats) { alarms.cpu = server.limits.cpu === 0 ? false : (stats.cpuUsagePercent >= (server.limits.cpu * 0.9)); alarms.memory = isAlarmState(stats.memoryUsageInBytes, server.limits.memory); alarms.disk = server.limits.disk === 0 ? false : isAlarmState(stats.diskUsageInBytes, server.limits.disk); } const disklimit = server.limits.disk !== 0 ? megabytesToHuman(server.limits.disk) : 'Unlimited'; const memorylimit = server.limits.memory !== 0 ? megabytesToHuman(server.limits.memory) : 'Unlimited'; return (

{server.name}

{!!server.description &&

{server.description}

}
{!stats ? !statsError ? : server.isInstalling ?
Installing
:
{server.isSuspended ? 'Suspended' : 'Connection Error'}
:
{bytesToHuman(stats.memoryUsageInBytes)}

of {memorylimit}

{bytesToHuman(stats.diskUsageInBytes)}

of {disklimit}

}
); };