import { ChevronDownIcon, CopyIcon } from '@primer/octicons-react' import { Link } from '@remix-run/react' import Menu from '~/components/Menu' import StatusCircle from '~/components/StatusCircle' import { toast } from '~/components/Toaster' import { Machine, Route, User } from '~/types' import { cn } from '~/utils/cn' import MenuOptions from './menu' interface Props { readonly machine: Machine readonly routes: Route[] readonly users: User[] readonly magic?: string } export default function MachineRow({ machine, routes, magic, users }: Props) { const expired = machine.expiry === '0001-01-01 00:00:00' || machine.expiry === '0001-01-01T00:00:00Z' || machine.expiry === null ? false : new Date(machine.expiry).getTime() < Date.now() const tags = [ ...machine.forcedTags, ...machine.validTags, ] if (expired) { tags.unshift('Expired') } let prefix = magic?.startsWith('[user]') ? magic.replace('[user]', machine.user.name) : magic // This is much easier with Object.groupBy but it's too new for us const { exit, subnet, subnetApproved } = routes.reduce((acc, route) => { if (route.prefix === '::/0' || route.prefix === '0.0.0.0/0') { acc.exit.push(route) return acc } if (route.enabled) { acc.subnetApproved.push(route) return acc } acc.subnet.push(route) return acc }, { exit: [], subnetApproved: [], subnet: [] }) const exitEnabled = useMemo(() => { if (exit.length !== 2) return false return exit[0].enabled && exit[1].enabled }, [exit]) if (exitEnabled) { tags.unshift('Exit Node') } if (subnetApproved.length > 0) { tags.unshift('Subnets') } return (
{machine.givenName}
{machine.name}
{machine.online && !expired ? 'Connected' : new Date( machine.lastSeen, ).toLocaleString()}