import { memo } from 'react'; import { useAppTranslation } from '@features/localization/renderer'; import { formatDistanceToNowStrict } from 'date-fns'; import { ExternalLink, Square, Terminal } from 'lucide-react'; import { MemberBadge } from './MemberBadge'; import type { ResolvedTeamMember, TeamProcess } from '@shared/types'; function formatShortTime(date: Date): string { const distance = formatDistanceToNowStrict(date, { addSuffix: false }); return distance .replace(' seconds', 's') .replace(' second', 's') .replace(' minutes', 'm') .replace(' minute', 'm') .replace(' hours', 'h') .replace(' hour', 'h') .replace(' days', 'd') .replace(' day', 'd') .replace(' weeks', 'w') .replace(' week', 'w') .replace(' months', 'mo') .replace(' month', 'mo') .replace(' years', 'y') .replace(' year', 'y'); } interface ProcessesSectionProps { teamName: string; members: ResolvedTeamMember[]; processes: TeamProcess[]; } function areMembersEquivalent( left: readonly ResolvedTeamMember[], right: readonly ResolvedTeamMember[] ): boolean { if (left === right) return true; if (left.length !== right.length) return false; for (let index = 0; index < left.length; index += 1) { if (left[index].name !== right[index].name || left[index].color !== right[index].color) { return false; } } return true; } function areProcessesEquivalent( left: readonly TeamProcess[], right: readonly TeamProcess[] ): boolean { if (left === right) return true; if (left.length !== right.length) return false; for (let index = 0; index < left.length; index += 1) { const leftProcess = left[index]; const rightProcess = right[index]; if ( leftProcess.id !== rightProcess.id || leftProcess.port !== rightProcess.port || leftProcess.url !== rightProcess.url || leftProcess.label !== rightProcess.label || leftProcess.pid !== rightProcess.pid || leftProcess.registeredBy !== rightProcess.registeredBy || leftProcess.registeredAt !== rightProcess.registeredAt || leftProcess.stoppedAt !== rightProcess.stoppedAt ) { return false; } } return true; } export const ProcessesSection = memo(function ProcessesSection({ teamName, members, processes, }: ProcessesSectionProps): React.JSX.Element | null { const { t } = useAppTranslation('team'); if (!teamName || processes.length === 0) return null; const memberColorMap = new Map(members.map((m) => [m.name, m.color])); const sorted = [...processes].sort((a, b) => { const aAlive = !a.stoppedAt; const bAlive = !b.stoppedAt; if (aAlive !== bAlive) return aAlive ? -1 : 1; return Date.parse(b.registeredAt) - Date.parse(a.registeredAt); }); return (