import { Plug } from "lucide-react"; import React, { useMemo, useState } from "react"; import { useI18n } from "../application/i18n/I18nProvider"; import { formatHostPort } from "../domain/host"; import { isPluginHostProtocol } from "../domain/pluginConnection"; import { cn } from "../lib/utils"; import { Host, HostProtocol } from "../types"; import { getProtocolVisualStyle, type ProtocolVisualKey } from "./protocolVisuals"; import { Button } from "./ui/button"; import { Input } from "./ui/input"; interface ProtocolOption { protocol: HostProtocol; port: number; label: string; description: string; enabled: boolean; } interface ProtocolSelectDialogProps { host: Host; onSelect: (protocol: HostProtocol, port: number) => void; onCancel: () => void; } const ProtocolSelectDialog: React.FC = ({ host, onSelect, onCancel, }) => { const { t } = useI18n(); const protocolOptions = useMemo(() => { const options: ProtocolOption[] = []; const pluginOption = isPluginHostProtocol(host.protocol) && host.pluginConnection ? { protocol: host.protocol, port: host.port || 22, label: host.pluginConnection.providerId, description: host.pluginConnection.providerId, enabled: true, } satisfies ProtocolOption : null; if (pluginOption) options.push(pluginOption); const sshEnabled = host.protocol === "ssh" || !host.protocol || host.protocols?.some((p) => p.protocol === "ssh" && p.enabled); if (sshEnabled !== false) { const sshConfig = host.protocols?.find((p) => p.protocol === "ssh"); options.push({ protocol: "ssh", port: sshConfig?.port || host.port || 22, label: "SSH", description: `ssh ${host.hostname}`, enabled: true, }); } if (host.moshEnabled || host.protocols?.some((p) => p.protocol === "mosh" && p.enabled)) { const moshConfig = host.protocols?.find((p) => p.protocol === "mosh"); options.push({ protocol: "mosh", port: moshConfig?.port || host.port || 22, label: "Mosh", description: `mosh ${host.hostname}`, enabled: true, }); } if (host.etEnabled || host.protocols?.some((p) => p.protocol === "et" && p.enabled)) { options.push({ protocol: "et", port: host.port || 22, label: "EternalTerminal", description: `et ${host.hostname}`, enabled: true, }); } if ( host.telnetEnabled || host.protocol === "telnet" || host.protocols?.some((p) => p.protocol === "telnet" && p.enabled) ) { const telnetConfig = host.protocols?.find((p) => p.protocol === "telnet"); options.push({ protocol: "telnet", port: telnetConfig?.port || host.telnetPort || 23, label: "Telnet", description: `telnet ${host.hostname}`, enabled: true, }); } return options; }, [host]); const [ports, setPorts] = useState>(() => { const initial: Record = {}; protocolOptions.forEach((opt) => { initial[opt.protocol] = opt.port; }); return initial as Record; }); const [selectedProtocol, setSelectedProtocol] = useState( protocolOptions[0]?.protocol || "ssh", ); const handlePortChange = (protocol: HostProtocol, value: string) => { const port = parseInt(value, 10); if (!isNaN(port) && port > 0 && port <= 65535) { setPorts((prev) => ({ ...prev, [protocol]: port })); } }; const handleContinue = () => { onSelect(selectedProtocol, ports[selectedProtocol] || 22); }; const hostEndpoint = isPluginHostProtocol(selectedProtocol) ? host.hostname : formatHostPort( host.hostname, ports[selectedProtocol] || host.port || 22, ); return (
e.stopPropagation()} >

{t("quickConnect.connectTitle", { host: host.label?.trim() || host.hostname, })}

{hostEndpoint}

{t("protocolSelect.chooseProtocol")}

{protocolOptions.map((option) => { const visual = isPluginHostProtocol(option.protocol) ? { icon: , selected: "bg-primary text-primary-foreground", idle: "bg-secondary text-muted-foreground", } : getProtocolVisualStyle(option.protocol as ProtocolVisualKey); return ( ); })}
); }; export default ProtocolSelectDialog;